From a938c55e0a08d82abbd200a8e7609ceaa8ee539a Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sun, 18 Jan 2015 13:07:39 +0000 Subject: Give focusInput a memory. - Track the most recently-focused input. - When focusInput is launched (with a count of 1) start with the most recently focused input. This does two things: - If the user is editing an element then comes back, they end up back where they started. - It gives focusInput a memory. --- content_scripts/vimium_frontend.coffee | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'content_scripts') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 35d92f3c..c49c27e2 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -331,6 +331,17 @@ extend window, enterVisualMode: => new VisualMode() +# Track the most-recently focused input element. This is used by focusInput to decide which input to initially +# highlight. +getFocusedElementIndexByRecency = do -> + focusedElement = null + installListener window, "focus", (event) -> + focusedElement = event.target if DomUtils.isEditable event.target + + (elements) -> + Math.max 0, elements.indexOf focusedElement + +extend window, focusInput: (count) -> # Focus the first input element on the page, and create overlays to highlight all the input elements, with # the currently-focused element highlighted specially. Tabbing will shift focus to the next input element. @@ -345,7 +356,11 @@ extend window, return if visibleInputs.length == 0 - selectedInputIndex = Math.min(count - 1, visibleInputs.length - 1) + selectedInputIndex = + if count == 1 + getFocusedElementIndexByRecency visibleInputs.map (visibleInput) -> visibleInput.element + else + Math.min(count, visibleInputs.length) - 1 hints = for tuple in visibleInputs hint = document.createElement("div") -- cgit v1.2.3 From 13592dc5016eff6bf84384a8cef62d1ada1ac80d Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sun, 18 Jan 2015 13:21:49 +0000 Subject: Give focusInput a memory; add tests. --- content_scripts/vimium_frontend.coffee | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'content_scripts') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index c49c27e2..abcf2b36 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -338,7 +338,11 @@ getFocusedElementIndexByRecency = do -> installListener window, "focus", (event) -> focusedElement = event.target if DomUtils.isEditable event.target - (elements) -> + # Only for tests. + window.resetFocusInputFocusedElement = -> + focusedElement = null + + (elements = null) -> Math.max 0, elements.indexOf focusedElement extend window, -- cgit v1.2.3 From d8f2446261887cb9affc50caf27b5793f0339edc Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sun, 18 Jan 2015 15:10:49 +0000 Subject: Give focusInput a memory (fix typo). --- content_scripts/vimium_frontend.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'content_scripts') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index abcf2b36..8b73c766 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -342,7 +342,7 @@ getFocusedElementIndexByRecency = do -> window.resetFocusInputFocusedElement = -> focusedElement = null - (elements = null) -> + (elements) -> Math.max 0, elements.indexOf focusedElement extend window, -- cgit v1.2.3 From 9d7185b78b366abafe52faeb18ec039b242e02b9 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sun, 18 Jan 2015 21:39:00 +0000 Subject: Give focusInput a memory (fix typo). --- content_scripts/vimium_frontend.coffee | 145 ++++++++++++++++----------------- 1 file changed, 69 insertions(+), 76 deletions(-) (limited to 'content_scripts') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 27e813c9..6cc686d2 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -331,84 +331,77 @@ extend window, enterVisualMode: => new VisualMode() -# Track the most-recently focused input element. This is used by focusInput to decide which input to initially -# highlight. -getFocusedElementIndexByRecency = do -> - focusedElement = null - installListener window, "focus", (event) -> - focusedElement = event.target if DomUtils.isEditable event.target - - # Only for tests. - window.resetFocusInputFocusedElement = -> + focusInput: do -> + # Track the most-recently focused input element. focusedElement = null - - (elements) -> - Math.max 0, elements.indexOf focusedElement - -extend window, - focusInput: (count) -> - # Focus the first input element on the page, and create overlays to highlight all the input elements, with - # the currently-focused element highlighted specially. Tabbing will shift focus to the next input element. - # Pressing any other key will remove the overlays and the special tab behavior. - resultSet = DomUtils.evaluateXPath(textInputXPath, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE) - visibleInputs = - for i in [0...resultSet.snapshotLength] by 1 - element = resultSet.snapshotItem(i) - rect = DomUtils.getVisibleClientRect(element) - continue if rect == null - { element: element, rect: rect } - - return if visibleInputs.length == 0 - - selectedInputIndex = - if count == 1 - getFocusedElementIndexByRecency visibleInputs.map (visibleInput) -> visibleInput.element - else - Math.min(count, visibleInputs.length) - 1 - - hints = for tuple in visibleInputs - hint = document.createElement("div") - hint.className = "vimiumReset internalVimiumInputHint vimiumInputHint" - - # minus 1 for the border - hint.style.left = (tuple.rect.left - 1) + window.scrollX + "px" - hint.style.top = (tuple.rect.top - 1) + window.scrollY + "px" - hint.style.width = tuple.rect.width + "px" - hint.style.height = tuple.rect.height + "px" - - hint - - new class FocusSelector extends Mode - constructor: -> - super - name: "focus-selector" - badge: "?" - # We share a singleton with PostFindMode. That way, a new FocusSelector displaces any existing - # PostFindMode. - singleton: PostFindMode - exitOnClick: true - keydown: (event) => - if event.keyCode == KeyboardUtils.keyCodes.tab - hints[selectedInputIndex].classList.remove 'internalVimiumSelectedInputHint' - selectedInputIndex += hints.length + (if event.shiftKey then -1 else 1) - selectedInputIndex %= hints.length - hints[selectedInputIndex].classList.add 'internalVimiumSelectedInputHint' - visibleInputs[selectedInputIndex].element.focus() - @suppressEvent - else unless event.keyCode == KeyboardUtils.keyCodes.shiftKey - @exit() - @continueBubbling - - @onExit -> DomUtils.removeElement hintContainingDiv - hintContainingDiv = DomUtils.addElementList hints, - id: "vimiumInputMarkerContainer" - className: "vimiumReset" - - visibleInputs[selectedInputIndex].element.focus() - if visibleInputs.length == 1 - @exit() + handlerStack.push + focus: (event) -> + focusedElement = event.target if DomUtils.isEditable event.target + + (count) -> + # Focus the first input element on the page, and create overlays to highlight all the input elements, with + # the currently-focused element highlighted specially. Tabbing will shift focus to the next input element. + # Pressing any other key will remove the overlays and the special tab behavior. + resultSet = DomUtils.evaluateXPath(textInputXPath, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE) + visibleInputs = + for i in [0...resultSet.snapshotLength] by 1 + element = resultSet.snapshotItem(i) + rect = DomUtils.getVisibleClientRect(element) + continue if rect == null + { element: element, rect: rect } + + return if visibleInputs.length == 0 + + selectedInputIndex = + if count == 1 + elements = visibleInputs.map (visibleInput) -> visibleInput.element + Math.max 0, elements.indexOf focusedElement else - hints[selectedInputIndex].classList.add 'internalVimiumSelectedInputHint' + Math.min(count, visibleInputs.length) - 1 + + hints = for tuple in visibleInputs + hint = document.createElement("div") + hint.className = "vimiumReset internalVimiumInputHint vimiumInputHint" + + # minus 1 for the border + hint.style.left = (tuple.rect.left - 1) + window.scrollX + "px" + hint.style.top = (tuple.rect.top - 1) + window.scrollY + "px" + hint.style.width = tuple.rect.width + "px" + hint.style.height = tuple.rect.height + "px" + + hint + + new class FocusSelector extends Mode + constructor: -> + super + name: "focus-selector" + badge: "?" + # We share a singleton with PostFindMode. That way, a new FocusSelector displaces any existing + # PostFindMode. + singleton: PostFindMode + exitOnClick: true + keydown: (event) => + if event.keyCode == KeyboardUtils.keyCodes.tab + hints[selectedInputIndex].classList.remove 'internalVimiumSelectedInputHint' + selectedInputIndex += hints.length + (if event.shiftKey then -1 else 1) + selectedInputIndex %= hints.length + hints[selectedInputIndex].classList.add 'internalVimiumSelectedInputHint' + visibleInputs[selectedInputIndex].element.focus() + @suppressEvent + else unless event.keyCode == KeyboardUtils.keyCodes.shiftKey + @exit() + @continueBubbling + + @onExit -> DomUtils.removeElement hintContainingDiv + hintContainingDiv = DomUtils.addElementList hints, + id: "vimiumInputMarkerContainer" + className: "vimiumReset" + + visibleInputs[selectedInputIndex].element.focus() + if visibleInputs.length == 1 + @exit() + else + hints[selectedInputIndex].classList.add 'internalVimiumSelectedInputHint' # Decide whether this keyChar should be passed to the underlying page. # Keystrokes are *never* considered passKeys if the keyQueue is not empty. So, for example, if 't' is a -- cgit v1.2.3 From 7450e1cfc57231457c894d372774c391bf13ac68 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sun, 18 Jan 2015 21:43:28 +0000 Subject: Give focusInput a memory (refactor). This makes the diff look big, but that's mainly due to a change in the indentation. --- content_scripts/vimium_frontend.coffee | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'content_scripts') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 6cc686d2..725d8a53 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -332,21 +332,23 @@ extend window, new VisualMode() focusInput: do -> - # Track the most-recently focused input element. - focusedElement = null + # Track the most recently focused input element. + recentlyFocusedElement = null handlerStack.push + _name: "focus-input-tracker" focus: (event) -> - focusedElement = event.target if DomUtils.isEditable event.target + recentlyFocusedElement = event.target if DomUtils.isEditable event.target + true (count) -> # Focus the first input element on the page, and create overlays to highlight all the input elements, with # the currently-focused element highlighted specially. Tabbing will shift focus to the next input element. # Pressing any other key will remove the overlays and the special tab behavior. - resultSet = DomUtils.evaluateXPath(textInputXPath, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE) + resultSet = DomUtils.evaluateXPath textInputXPath, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE visibleInputs = for i in [0...resultSet.snapshotLength] by 1 - element = resultSet.snapshotItem(i) - rect = DomUtils.getVisibleClientRect(element) + element = resultSet.snapshotItem i + rect = DomUtils.getVisibleClientRect element continue if rect == null { element: element, rect: rect } @@ -354,13 +356,14 @@ extend window, selectedInputIndex = if count == 1 + # As the starting index, we pick that of the most recently focused input element (or 0). elements = visibleInputs.map (visibleInput) -> visibleInput.element - Math.max 0, elements.indexOf focusedElement + Math.max 0, elements.indexOf recentlyFocusedElement else Math.min(count, visibleInputs.length) - 1 hints = for tuple in visibleInputs - hint = document.createElement("div") + hint = document.createElement "div" hint.className = "vimiumReset internalVimiumInputHint vimiumInputHint" # minus 1 for the border -- cgit v1.2.3