diff options
| author | Stephen Blott | 2016-04-08 13:36:24 +0100 |
|---|---|---|
| committer | Stephen Blott | 2016-04-08 13:36:24 +0100 |
| commit | 9d7351903d0148373a2ad4c06d006e8ee0613be2 (patch) | |
| tree | 0bd0437e687b04412cca2e49e3789a053fbac84d | |
| parent | 5704688e2ab7effef701f2ac5282b3bd4e0c53c7 (diff) | |
| parent | 77ea849b0849219550c7a8caa47698a35ed2fdab (diff) | |
| download | vimium-9d7351903d0148373a2ad4c06d006e8ee0613be2.tar.bz2 | |
Merge pull request #2088 from smblott-github/filtered-hints-better-typed-text-matching
Filtered hints: better typed text handling.
| -rw-r--r-- | content_scripts/link_hints.coffee | 54 | ||||
| -rw-r--r-- | tests/dom_tests/dom_tests.coffee | 12 |
2 files changed, 46 insertions, 20 deletions
diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee index 70c51eac..c012edba 100644 --- a/content_scripts/link_hints.coffee +++ b/content_scripts/link_hints.coffee @@ -13,22 +13,22 @@ isMac = KeyboardUtils.platform == "Mac" OPEN_IN_CURRENT_TAB = name: "curr-tab" - indicator: "Open link in current tab." + indicator: "Open link in current tab" OPEN_IN_NEW_BG_TAB = name: "bg-tab" - indicator: "Open link in new tab." + indicator: "Open link in new tab" clickModifiers: metaKey: isMac, ctrlKey: not isMac OPEN_IN_NEW_FG_TAB = name: "fg-tab" - indicator: "Open link in new tab and switch to it." + indicator: "Open link in new tab and switch to it" clickModifiers: shiftKey: true, metaKey: isMac, ctrlKey: not isMac OPEN_WITH_QUEUE = name: "queue" - indicator: "Open multiple links in new tabs." + indicator: "Open multiple links in new tabs" clickModifiers: metaKey: isMac, ctrlKey: not isMac COPY_LINK_URL = name: "link" - indicator: "Copy link URL to Clipboard." + indicator: "Copy link URL to Clipboard" linkActivator: (link) -> if link.href? chrome.runtime.sendMessage handler: "copyToClipboard", data: link.href @@ -39,11 +39,11 @@ COPY_LINK_URL = HUD.showForDuration "No link to yank.", 2000 OPEN_INCOGNITO = name: "incognito" - indicator: "Open link in incognito window." + indicator: "Open link in incognito window" linkActivator: (link) -> chrome.runtime.sendMessage handler: 'openUrlInIncognito', url: link.href DOWNLOAD_LINK_URL = name: "download" - indicator: "Download link URL." + indicator: "Download link URL" clickModifiers: altKey: true, ctrlKey: false, metaKey: false availableModes = [OPEN_IN_CURRENT_TAB, OPEN_IN_NEW_BG_TAB, OPEN_IN_NEW_FG_TAB, OPEN_WITH_QUEUE, COPY_LINK_URL, @@ -138,7 +138,7 @@ class LinkHintsMode # A count of the number of Tab presses since the last non-Tab keyboard event. tabCount: 0 - constructor: (hintDescriptors, mode = OPEN_IN_CURRENT_TAB) -> + constructor: (hintDescriptors, @mode = OPEN_IN_CURRENT_TAB) -> # We need documentElement to be ready in order to append links. return unless document.documentElement @@ -153,7 +153,7 @@ class LinkHintsMode @markerMatcher.fillInMarkers @hintMarkers @hintMode = new Mode - name: "hint/#{mode.name}" + name: "hint/#{@mode.name}" indicator: false singleton: "link-hints-mode" passInitialKeyupEvents: true @@ -164,22 +164,28 @@ class LinkHintsMode keydown: @onKeyDownInMode.bind this keypress: @onKeyPressInMode.bind this + @setIndicator() @hintMode.onExit (event) => if event?.type == "click" or (event?.type == "keydown" and (KeyboardUtils.isEscape(event) or event.keyCode in [keyCodes.backspace, keyCodes.deleteKey])) HintCoordinator.sendMessage "exit", isSuccess: false - @setOpenLinkMode mode, false - # Note(philc): Append these markers as top level children instead of as child nodes to the link itself, # because some clickable elements cannot contain children, e.g. submit buttons. @hintMarkerContainingDiv = DomUtils.addElementList (marker for marker in @hintMarkers when marker.isLocalMarker), id: "vimiumHintMarkerContainer", className: "vimiumReset" setOpenLinkMode: (@mode, shouldPropagateToOtherFrames = true) -> - @hintMode.setIndicator @mode.indicator if windowIsFocused() if shouldPropagateToOtherFrames HintCoordinator.sendMessage "setOpenLinkMode", modeIndex: availableModes.indexOf @mode + else + @setIndicator() + + setIndicator: -> + if windowIsFocused() + typedCharacters = @markerMatcher.linkTextKeystrokeQueue?.join("") ? "" + indicator = @mode.indicator + (if typedCharacters then ": \"#{typedCharacters}\"" else "") + "." + @hintMode.setIndicator indicator # # Creates a link marker for the given link. @@ -262,7 +268,7 @@ class LinkHintsMode else return - # We've handled the event, so suppress it. + # We've handled the event, so suppress it and update the mode indicator. DomUtils.suppressEvent event # Handles normal input. @@ -293,6 +299,8 @@ class LinkHintsMode @hideMarker marker for marker in @hintMarkers @showMarker matched, @markerMatcher.hintKeystrokeQueue.length for matched in linksMatched + @setIndicator() + # When only one hint remains, activate it in the appropriate way. The current frame may or may not contain # the matched link, and may or may not have the focus. The resulting four cases are accounted for here by # selectively pushing the appropriate HintCoordinator.onExit handlers. @@ -469,15 +477,21 @@ class FilterHints linkSearchString = @linkTextKeystrokeQueue.join("").trim().toLowerCase() do (scoreFunction = @scoreLinkHint linkSearchString) -> linkMarker.score = scoreFunction linkMarker for linkMarker in hintMarkers - hintMarkers = hintMarkers[..].sort (a,b) -> + matchingHintMarkers = hintMarkers[..].sort (a,b) -> if b.score == a.score then b.stableSortCount - a.stableSortCount else b.score - a.score - linkHintNumber = 1 - for linkMarker in hintMarkers - continue unless 0 < linkMarker.score - linkMarker.hintString = @generateHintString linkHintNumber++ - @renderMarker linkMarker - linkMarker + matchingHintMarkers = (linkMarker for linkMarker in matchingHintMarkers when 0 < linkMarker.score) + + if matchingHintMarkers.length == 0 and @hintKeystrokeQueue.length == 0 and 0 < @linkTextKeystrokeQueue.length + # We don't accept typed text which doesn't match any hints. + @linkTextKeystrokeQueue.pop() + @filterLinkHints hintMarkers + else + linkHintNumber = 1 + for linkMarker in matchingHintMarkers + linkMarker.hintString = @generateHintString linkHintNumber++ + @renderMarker linkMarker + linkMarker # Assign a score to a filter match (higher is better). We assign a higher score for matches at the start of # a word, and a considerably higher score still for matches which are whole words. diff --git a/tests/dom_tests/dom_tests.coffee b/tests/dom_tests/dom_tests.coffee index 76c09f13..75cc5da7 100644 --- a/tests/dom_tests/dom_tests.coffee +++ b/tests/dom_tests/dom_tests.coffee @@ -284,6 +284,18 @@ context "Filtered link hints", sendKeyboardEvent "A" assert.equal "1", hintMarkers[3].hintString + # This test is the same as above, but with an extra non-matching character. + should "narrow the hints and ignore typing mistakes", -> + hintMarkers = getHintMarkers() + sendKeyboardEvent "T" + sendKeyboardEvent "R" + sendKeyboardEvent "X" + assert.equal "none", hintMarkers[0].style.display + assert.equal "3", hintMarkers[1].hintString + assert.equal "", hintMarkers[1].style.display + sendKeyboardEvent "A" + assert.equal "1", hintMarkers[3].hintString + context "Image hints", setup -> |
