From 5aaed906b94337bb2136d74672e16679ab457c49 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Wed, 10 Jun 2015 14:23:58 +0100 Subject: Rank filtered hints by score. Thus, better matches are likely to either be first (so just hitting activates them) or just a or two away. Scoring: - Requires that every search term be matched. - Assigns higher scores to matches at the start of a word, and higher scores still for whole-word matches. --- content_scripts/link_hints.coffee | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'content_scripts') diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee index 107a292e..ae9d3f8f 100644 --- a/content_scripts/link_hints.coffee +++ b/content_scripts/link_hints.coffee @@ -565,13 +565,41 @@ class FilterHints filterLinkHints: (hintMarkers) -> idx = 0 linkSearchString = @linkTextKeystrokeQueue.join("").toLowerCase() + do (scoreFunction = @scoreLinkHint linkSearchString) -> + linkMarker.score = scoreFunction linkMarker for linkMarker in hintMarkers + hintMarkers = hintMarkers[..].sort (a,b) -> b.score - a.score for linkMarker in hintMarkers - continue unless 0 <= linkMarker.linkText.toLowerCase().indexOf linkSearchString + continue unless 0 < linkMarker.score linkMarker.hintString = @generateHintString idx++ @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. + # Note(smblott) if linkSearchString is empty, then every hint get a score of 2. + scoreLinkHint: (linkSearchString) -> + searchWords = linkSearchString.trim().split /\s+/ + (linkMarker) -> + linkWords = linkMarker.linkWords ?= linkMarker.linkText.trim().toLowerCase().split /\s+/ + + searchWordScores = + for searchWord in searchWords + linkWordScores = + for linkWord in linkWords + if linkWord == searchWord + 5 + else if linkWord.startsWith searchWord + 2 + else if 0 <= linkWord.indexOf searchWord + 1 + else + 0 + Math.max linkWordScores... + + addFunc = (a,b) -> a + b + if 0 in searchWordScores then 0 else searchWordScores.reduce addFunc, 0 + # # Make each hint character a span, so that we can highlight the typed characters as you type them. # -- cgit v1.2.3 From ddc747805e08eaad52bf58950b1d2df9bdd2da9c Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Wed, 10 Jun 2015 14:43:00 +0100 Subject: Account for words at start of filter text. We gove these a higher score because it makes it easier for the user to pick a link if they can just start typing at the beginning. --- content_scripts/link_hints.coffee | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'content_scripts') diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee index ae9d3f8f..3dbb4f23 100644 --- a/content_scripts/link_hints.coffee +++ b/content_scripts/link_hints.coffee @@ -586,11 +586,11 @@ class FilterHints searchWordScores = for searchWord in searchWords linkWordScores = - for linkWord in linkWords + for linkWord, idx in linkWords if linkWord == searchWord - 5 + if idx == 0 then 8 else 6 else if linkWord.startsWith searchWord - 2 + if idx == 0 then 4 else 2 else if 0 <= linkWord.indexOf searchWord 1 else -- cgit v1.2.3 From 9b07fa7861620900e0d1da5829b38ddb4e8ff789 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Wed, 10 Jun 2015 15:12:45 +0100 Subject: Note changes in README. --- content_scripts/link_hints.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'content_scripts') diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee index 3dbb4f23..cbb4085e 100644 --- a/content_scripts/link_hints.coffee +++ b/content_scripts/link_hints.coffee @@ -577,7 +577,7 @@ class FilterHints # 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. - # Note(smblott) if linkSearchString is empty, then every hint get a score of 2. + # Note(smblott) if linkSearchString is empty, then every hint get a score of 4. scoreLinkHint: (linkSearchString) -> searchWords = linkSearchString.trim().split /\s+/ (linkMarker) -> -- cgit v1.2.3 From e516bae3a3374780d2cb1b6c32e5fd1f2c13a408 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Wed, 10 Jun 2015 16:14:38 +0100 Subject: Fix incorrect filtering. --- content_scripts/link_hints.coffee | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'content_scripts') diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee index cbb4085e..144400b6 100644 --- a/content_scripts/link_hints.coffee +++ b/content_scripts/link_hints.coffee @@ -564,9 +564,15 @@ class FilterHints # Filter link hints by search string, renumbering the hints as necessary. filterLinkHints: (hintMarkers) -> idx = 0 - linkSearchString = @linkTextKeystrokeQueue.join("").toLowerCase() + linkSearchString = @linkTextKeystrokeQueue.join("").trim().toLowerCase() + return hintMarkers unless 0 < linkSearchString.length + do (scoreFunction = @scoreLinkHint linkSearchString) -> linkMarker.score = scoreFunction linkMarker for linkMarker in hintMarkers + # The Javascript sort() method is known not to be stable. Nevertheless, we require (and assume, here) + # that it is deterministic. So, if the user is typing hint characters, then hints will always end up in + # the same order and hence with the same hint strings (because hint-string filtering happens after the + # filtering here). hintMarkers = hintMarkers[..].sort (a,b) -> b.score - a.score for linkMarker in hintMarkers @@ -577,7 +583,6 @@ class FilterHints # 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. - # Note(smblott) if linkSearchString is empty, then every hint get a score of 4. scoreLinkHint: (linkSearchString) -> searchWords = linkSearchString.trim().split /\s+/ (linkMarker) -> -- cgit v1.2.3 From 61764d812a37ca2c29b3b7ddde878f25250abf81 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Wed, 10 Jun 2015 16:39:02 +0100 Subject: Fix bug relating to duplicate hint strings. (Not sure when this crept in.) We need to ensure that we always generate the same hint strings for the same filter state. Here, we do this by always using the same mechanism (@filterLinkHints) to set the hint strings. --- content_scripts/link_hints.coffee | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'content_scripts') diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee index 144400b6..15af15c5 100644 --- a/content_scripts/link_hints.coffee +++ b/content_scripts/link_hints.coffee @@ -478,7 +478,7 @@ class FilterHints @labelMap[forElement] = labelText generateHintString: (linkHintNumber) -> - numberToHintString linkHintNumber + 1, @linkHintNumbers.toUpperCase() + numberToHintString linkHintNumber, @linkHintNumbers.toUpperCase() generateLinkText: (element) -> linkText = "" @@ -512,8 +512,7 @@ class FilterHints fillInMarkers: (hintMarkers) -> @generateLabelMap() DomUtils.textContent.reset() - for marker, idx in hintMarkers - marker.hintString = @generateHintString(idx) + for marker in hintMarkers linkTextObject = @generateLinkText(marker.clickableItem) marker.linkText = linkTextObject.text marker.showLinkText = linkTextObject.show @@ -522,7 +521,9 @@ class FilterHints @activeHintMarker = hintMarkers[0] @activeHintMarker?.classList.add "vimiumActiveHintMarker" - hintMarkers + # We use @filterLinkHints() here (although we know that all of the hints will match) to fill in the hint + # strings. This ensures that we always get hint strings in the same order. + @filterLinkHints hintMarkers getMatchingHints: (hintMarkers, tabCount = 0) -> delay = 0 @@ -563,10 +564,7 @@ class FilterHints # Filter link hints by search string, renumbering the hints as necessary. filterLinkHints: (hintMarkers) -> - idx = 0 linkSearchString = @linkTextKeystrokeQueue.join("").trim().toLowerCase() - return hintMarkers unless 0 < linkSearchString.length - do (scoreFunction = @scoreLinkHint linkSearchString) -> linkMarker.score = scoreFunction linkMarker for linkMarker in hintMarkers # The Javascript sort() method is known not to be stable. Nevertheless, we require (and assume, here) @@ -575,9 +573,10 @@ class FilterHints # filtering here). hintMarkers = hintMarkers[..].sort (a,b) -> b.score - a.score + linkHintNumber = 1 for linkMarker in hintMarkers continue unless 0 < linkMarker.score - linkMarker.hintString = @generateHintString idx++ + linkMarker.hintString = @generateHintString linkHintNumber++ @renderMarker linkMarker linkMarker -- cgit v1.2.3 From 53d131700e5f33cb9476f00a905c238b0083f3dc Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Thu, 11 Jun 2015 06:25:41 +0100 Subject: Make "a-z" characters work in filter hints mode. When we read hint characters, we read them lower case. When we generate hint markers, we generate them upper case. So they never match. (Exactly why anyone would want to use "abcde" for filtered link hints isn't clear, but at least we should behave correctly.) --- content_scripts/link_hints.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'content_scripts') diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee index 15af15c5..1be762c6 100644 --- a/content_scripts/link_hints.coffee +++ b/content_scripts/link_hints.coffee @@ -532,7 +532,7 @@ class FilterHints # input. use them to filter the link hints accordingly. matchString = @hintKeystrokeQueue.join "" linksMatched = @filterLinkHints hintMarkers - linksMatched = linksMatched.filter (linkMarker) -> linkMarker.hintString.startsWith matchString + linksMatched = linksMatched.filter (linkMarker) -> linkMarker.hintString.toLowerCase().startsWith matchString if linksMatched.length == 1 && @hintKeystrokeQueue.length == 0 and 0 < @linkTextKeystrokeQueue.length # In filter mode, people tend to type out words past the point needed for a unique match. Hence we -- cgit v1.2.3 From a414ed803a33c7af57441fa8527db1dfad79ed41 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Thu, 11 Jun 2015 06:32:04 +0100 Subject: Revert "Make "a-z" characters work in filter hints mode." This reverts commit 53d131700e5f33cb9476f00a905c238b0083f3dc. (This needs more thought.) --- content_scripts/link_hints.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'content_scripts') diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee index 1be762c6..15af15c5 100644 --- a/content_scripts/link_hints.coffee +++ b/content_scripts/link_hints.coffee @@ -532,7 +532,7 @@ class FilterHints # input. use them to filter the link hints accordingly. matchString = @hintKeystrokeQueue.join "" linksMatched = @filterLinkHints hintMarkers - linksMatched = linksMatched.filter (linkMarker) -> linkMarker.hintString.toLowerCase().startsWith matchString + linksMatched = linksMatched.filter (linkMarker) -> linkMarker.hintString.startsWith matchString if linksMatched.length == 1 && @hintKeystrokeQueue.length == 0 and 0 < @linkTextKeystrokeQueue.length # In filter mode, people tend to type out words past the point needed for a unique match. Hence we -- cgit v1.2.3