From d1220f3879365b3463581e2e21126813135e010e Mon Sep 17 00:00:00 2001 From: kartynnik Date: Thu, 20 Nov 2014 02:52:33 +0300 Subject: [PATCH 1/3] Port overlapping link hint rotation by Space from VimFx --- CREDITS | 1 + content_scripts/link_hints.coffee | 74 +++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/CREDITS b/CREDITS index 60a5acaa7..4b5ea0379 100644 --- a/CREDITS +++ b/CREDITS @@ -42,5 +42,6 @@ Contributors: Werner Laurensse (github: ab3) Timo Sand (github: deiga) Shiyong Chen (github: UncleBill) + Yury Kartynnik (github: kartynnik) Feel free to add real names in addition to GitHub usernames. diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee index 24bd7126a..2d54ee9ce 100644 --- a/content_scripts/link_hints.coffee +++ b/content_scripts/link_hints.coffee @@ -15,6 +15,7 @@ OPEN_WITH_QUEUE = {} COPY_LINK_URL = {} OPEN_INCOGNITO = {} DOWNLOAD_LINK_URL = {} +MARKER_MINIMUM_Z_INDEX = 2000000000 LinkHints = hintMarkerContainingDiv: null @@ -65,6 +66,8 @@ LinkHints = @setOpenLinkMode(mode) hintMarkers = (@createMarkerFor(el) for el in @getVisibleClickableElements()) + for marker, index in hintMarkers + marker.style.setProperty('z-index', MARKER_MINIMUM_Z_INDEX + index, 'important') @getMarkerMatcher().fillInMarkers(hintMarkers) # Note(philc): Append these markers as top level children instead of as child nodes to the link itself, @@ -193,6 +196,10 @@ LinkHints = else # event.keyCode == keyCodes.ctrlKey @setOpenLinkMode(if @mode is OPEN_IN_NEW_FG_TAB then OPEN_IN_NEW_BG_TAB else OPEN_IN_NEW_FG_TAB) + if event.keyCode == KeyboardUtils.keyCodes.space + rotateOverlappingMarkers(hintMarkers, yes) + return + # TODO(philc): Ignore keys that have modifiers. if (KeyboardUtils.isEscape(event)) @deactivateMode() @@ -502,6 +509,73 @@ numberToHintString = (number, characterSet, numHintDigits = 0) -> hintString.join("") +# +# Finds all stacks of markers that overlap each other (by using `getStackFor`) (#1), and rotates +# their `z-index`:es (#2), thus alternating which markers are visible. +# Ported from VimFx (https://github.com/akhodakivskiy/VimFx). +# +rotateOverlappingMarkers = (originalMarkers, forward) -> + # Shallow working copy. This is necessary since `markers` will be mutated and eventually empty. + markers = originalMarkers[..] + + # (#1) + stacks = (getStackFor(markers.pop(), markers) while markers.length > 0) + + # (#2) + # Stacks of length 1 don't participate in any overlapping, and can therefore be skipped. + for stack in stacks when stack.length > 1 + # This sort is not required, but makes the rotation more predictable. + stack.sort((a, b) -> a.style.zIndex - b.style.zIndex) + + # Array of z-indices + indexStack = (marker.style.zIndex for marker in stack) + # Shift the array of indices one item forward or back + if forward + indexStack.unshift(indexStack.pop()) + else + indexStack.push(indexStack.shift()) + + for marker, index in stack + marker.style.setProperty('z-index', indexStack[index], 'important') + +# +# Return the boundaries of a marker. +# +getRect = (marker) -> + top = parseInt(marker.style.top) + bottom = top + marker.offsetHeight + left = parseInt(marker.style.left) + right = top + marker.offsetWidth + + { top, left, bottom, right } + +# +# Get an array containing `marker` and all markers that overlap `marker`, if any, which is called +# a "stack". All markers in the returned stack are spliced out from `markers`, thus mutating it. +# Ported from VimFx (https://github.com/akhodakivskiy/VimFx). +# +getStackFor = (marker, markers) -> + stack = [marker] + + { top, left, bottom, right } = getRect(marker) + + index = 0 + while index < markers.length + nextMarker = markers[index] + + { top: nextTop, bottom: nextBottom, left: nextLeft, right: nextRight } = getRect(nextMarker) + overlapsVertically = (nextBottom >= top and nextTop <= bottom) + overlapsHorizontally = (nextRight >= left and nextLeft <= right) + + if overlapsVertically and overlapsHorizontally + # Also get all markers overlapping this one + markers.splice(index, 1) + stack = stack.concat(getStackFor(nextMarker, markers)) + else + # Continue the search + index++ + + stack root = exports ? window root.LinkHints = LinkHints From af7acb1de7fda34af0bf683b3d5dada9fdad3228 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 20 Nov 2014 14:56:14 +0000 Subject: [PATCH 2/3] Stop link hints from handling shift incorrectly --- content_scripts/link_hints.coffee | 6 +++--- lib/keyboard_utils.coffee | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee index 2d54ee9ce..4f4d04942 100644 --- a/content_scripts/link_hints.coffee +++ b/content_scripts/link_hints.coffee @@ -196,12 +196,12 @@ LinkHints = else # event.keyCode == keyCodes.ctrlKey @setOpenLinkMode(if @mode is OPEN_IN_NEW_FG_TAB then OPEN_IN_NEW_BG_TAB else OPEN_IN_NEW_FG_TAB) - if event.keyCode == KeyboardUtils.keyCodes.space - rotateOverlappingMarkers(hintMarkers, yes) + else if event.keyCode == keyCodes.space + rotateOverlappingMarkers(hintMarkers, not event.shiftKey) return # TODO(philc): Ignore keys that have modifiers. - if (KeyboardUtils.isEscape(event)) + else if (KeyboardUtils.isEscape(event)) @deactivateMode() else keyResult = @getMarkerMatcher().matchHintsByKey(hintMarkers, event) diff --git a/lib/keyboard_utils.coffee b/lib/keyboard_utils.coffee index d2a843f9f..165e20501 100644 --- a/lib/keyboard_utils.coffee +++ b/lib/keyboard_utils.coffee @@ -46,7 +46,9 @@ KeyboardUtils = correctedIdentifiers = @keyIdentifierCorrectionMap[keyIdentifier] keyIdentifier = if event.shiftKey then correctedIdentifiers[1] else correctedIdentifiers[0] unicodeKeyInHex = "0x" + keyIdentifier.substring(2) - character = String.fromCharCode(parseInt(unicodeKeyInHex)).toLowerCase() + keyCode = parseInt(unicodeKeyInHex) + return "" unless keyCode < 128 + character = String.fromCharCode(keyCode).toLowerCase() if event.shiftKey then character.toUpperCase() else character isPrimaryModifierKey: (event) -> if (@platform == "Mac") then event.metaKey else event.ctrlKey From b52f0050d49949b696eac8f0ffa847fc84b5414a Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 20 Nov 2014 22:31:39 +0000 Subject: [PATCH 3/3] Remove unnecessary return --- content_scripts/link_hints.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee index 4f4d04942..851d99654 100644 --- a/content_scripts/link_hints.coffee +++ b/content_scripts/link_hints.coffee @@ -198,7 +198,6 @@ LinkHints = else if event.keyCode == keyCodes.space rotateOverlappingMarkers(hintMarkers, not event.shiftKey) - return # TODO(philc): Ignore keys that have modifiers. else if (KeyboardUtils.isEscape(event))