From 1a71dc6c8f323cef31eb006a8a6299b4dfe71332 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Fri, 8 Apr 2016 09:42:22 +0100 Subject: Filtered hints; ignore unmatched text. When the user is typing a link's text, any mistyped character exits link hints mode. This makes little sense. In practice, this usually happens because the user mis-typed something. Here, we ignore typed characters which do not match any hints. (Also, add a test for this.) --- content_scripts/link_hints.coffee | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'content_scripts') diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee index 56cea78d..56edf22f 100644 --- a/content_scripts/link_hints.coffee +++ b/content_scripts/link_hints.coffee @@ -465,15 +465,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. -- cgit v1.2.3 From a1dc889746eebb657ff7d82912ff17106cf352b2 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Fri, 8 Apr 2016 10:15:09 +0100 Subject: Show filtered characters in mode indicator. --- content_scripts/link_hints.coffee | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'content_scripts') diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee index 56edf22f..b74a6c96 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, @@ -172,11 +172,17 @@ class LinkHintsMode @hintMarkerContainingDiv = DomUtils.addElementList (marker for marker in @hintMarkers when marker.isLocalMarker), id: "vimiumHintMarkerContainer", className: "vimiumReset" + # TODO(smblott) This is currently doing two somewhat independent things. We should refactor it to "update + # @mode" and "update mode indicator". setOpenLinkMode: (@mode, shouldPropagateToOtherFrames = true) -> - @hintMode.setIndicator @mode.indicator if windowIsFocused() + @hintMode.setIndicator @formatIndicator @mode.indicator if windowIsFocused() if shouldPropagateToOtherFrames HintCoordinator.sendMessage "setOpenLinkMode", modeIndex: availableModes.indexOf @mode + formatIndicator: (indicator) -> + typedCharacters = @markerMatcher.linkTextKeystrokeQueue?.join("") ? "" + indicator + (if typedCharacters then ": '#{typedCharacters}'" else "") + "." + # # Creates a link marker for the given link. # @@ -258,7 +264,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. @@ -289,6 +295,8 @@ class LinkHintsMode @hideMarker marker for marker in @hintMarkers @showMarker matched, @markerMatcher.hintKeystrokeQueue.length for matched in linksMatched + @setOpenLinkMode @mode, false + # 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. -- cgit v1.2.3 From 77ea849b0849219550c7a8caa47698a35ed2fdab Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Fri, 8 Apr 2016 10:55:52 +0100 Subject: Refactor setModeIndicator(). Previously this had two independent functions: set the @mode and update the indicator. We don't always do those two things at the same time. So this refactors things into two separate functions. --- content_scripts/link_hints.coffee | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'content_scripts') diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee index b74a6c96..89875da0 100644 --- a/content_scripts/link_hints.coffee +++ b/content_scripts/link_hints.coffee @@ -134,7 +134,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 @@ -149,7 +149,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 @@ -160,28 +160,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" - # TODO(smblott) This is currently doing two somewhat independent things. We should refactor it to "update - # @mode" and "update mode indicator". setOpenLinkMode: (@mode, shouldPropagateToOtherFrames = true) -> - @hintMode.setIndicator @formatIndicator @mode.indicator if windowIsFocused() if shouldPropagateToOtherFrames HintCoordinator.sendMessage "setOpenLinkMode", modeIndex: availableModes.indexOf @mode + else + @setIndicator() - formatIndicator: (indicator) -> - typedCharacters = @markerMatcher.linkTextKeystrokeQueue?.join("") ? "" - indicator + (if typedCharacters then ": '#{typedCharacters}'" else "") + "." + 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. @@ -295,7 +295,7 @@ class LinkHintsMode @hideMarker marker for marker in @hintMarkers @showMarker matched, @markerMatcher.hintKeystrokeQueue.length for matched in linksMatched - @setOpenLinkMode @mode, false + @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 -- cgit v1.2.3