diff options
| author | Stephen Blott | 2014-11-09 06:29:25 +0000 | 
|---|---|---|
| committer | Stephen Blott | 2014-11-09 06:29:25 +0000 | 
| commit | 2687fbe835e447beb875f399c4c150dfe919535e (patch) | |
| tree | bd96e8ba0d48e2f34b27199965854a0f8e99d22e | |
| parent | 3d647c9d062a84082d0337ac0b0004d31eb64969 (diff) | |
| parent | 5492249ba4f36e40c8dcb4eff9916fa29bf0f94a (diff) | |
| download | vimium-2687fbe835e447beb875f399c4c150dfe919535e.tar.bz2 | |
Merge pull request #1231 from smblott-github/tabs-order
Tabs order; order tabs by recency for empty searches.
| -rw-r--r-- | background_scripts/completion.coffee | 29 | ||||
| -rw-r--r-- | tests/unit_tests/completion_test.coffee | 42 | ||||
| -rw-r--r-- | tests/unit_tests/test_chrome_stubs.coffee | 4 | 
3 files changed, 73 insertions, 2 deletions
| diff --git a/background_scripts/completion.coffee b/background_scripts/completion.coffee index b75ebb87..b6a52a15 100644 --- a/background_scripts/completion.coffee +++ b/background_scripts/completion.coffee @@ -261,6 +261,29 @@ class DomainCompleter    # Suggestions from the Domain completer have the maximum relevancy. They should be shown first in the list.    computeRelevancy: -> 1 +# TabRecency associates a logical timestamp with each tab id. +class TabRecency +  constructor: -> +    @timestamp = 1 +    @cache = {} + +    chrome.tabs.onActivated.addListener (activeInfo) => @add activeInfo.tabId +    chrome.tabs.onRemoved.addListener (tabId) => @remove tabId + +    chrome.tabs.onReplaced.addListener (addedTabId, removedTabId) => +      @remove removedTabId +      @add addedTabId + +  add: (tabId) -> @cache[tabId] = ++@timestamp +  remove: (tabId) -> delete @cache[tabId] + +  # Recently-visited tabs get a higher score (except the current tab, which gets a low score). +  recencyScore: (tabId) -> +    @cache[tabId] ||= 1 +    if @cache[tabId] == @timestamp then 0.0 else @cache[tabId] / @timestamp + +tabRecency = new TabRecency() +  # Searches through all open tabs, matching on title and URL.  class TabCompleter    filter: (queryTerms, onComplete) -> @@ -276,7 +299,10 @@ class TabCompleter        onComplete(suggestions)    computeRelevancy: (suggestion) -> -    RankingUtils.wordRelevancy(suggestion.queryTerms, suggestion.url, suggestion.title) +    if suggestion.queryTerms.length +      RankingUtils.wordRelevancy(suggestion.queryTerms, suggestion.url, suggestion.title) +    else +      tabRecency.recencyScore(suggestion.tabId)  # A completer which will return your search engines  class SearchEngineCompleter @@ -549,3 +575,4 @@ root.SearchEngineCompleter = SearchEngineCompleter  root.HistoryCache = HistoryCache  root.RankingUtils = RankingUtils  root.RegexpCache = RegexpCache +root.TabRecency = TabRecency diff --git a/tests/unit_tests/completion_test.coffee b/tests/unit_tests/completion_test.coffee index 44989267..88f59b7e 100644 --- a/tests/unit_tests/completion_test.coffee +++ b/tests/unit_tests/completion_test.coffee @@ -1,8 +1,8 @@  require "./test_helper.js"  extend(global, require "../../lib/utils.js")  extend(global, require "../../background_scripts/completion.js") +extend global, require "./test_chrome_stubs.js" -global.chrome = {}  global.document =    createElement: -> {} @@ -399,6 +399,46 @@ context "RegexpCache",    should "search for a string with a prefix/suffix (negative case)", ->      assert.isTrue "hound dog".search(RegexpCache.get("do", "\\b", "\\b")) == -1 +context "TabRecency", +  setup -> +    @tabRecency = new TabRecency() +    @tabRecency.add 3 +    @tabRecency.add 2 +    @tabRecency.add 9 +    @tabRecency.add 1 +    @tabRecency.remove 9 +    @tabRecency.add 4 + +  should "have entries for active tabs", -> +    assert.isTrue @tabRecency.cache[1] +    assert.isTrue @tabRecency.cache[2] +    assert.isTrue @tabRecency.cache[3] +    assert.isTrue @tabRecency.cache[4] + +  should "not have entries for removed tabs", -> +    assert.isFalse @tabRecency.cache[9] + +  should "give a high score to the most recent tab", -> +    assert.isTrue @tabRecency.recencyScore(4) < @tabRecency.recencyScore 1 +    assert.isTrue @tabRecency.recencyScore(3) < @tabRecency.recencyScore 1 +    assert.isTrue @tabRecency.recencyScore(2) < @tabRecency.recencyScore 1 + +  should "give a low score to the current tab", -> +    assert.isTrue @tabRecency.recencyScore(1) > @tabRecency.recencyScore 4 +    assert.isTrue @tabRecency.recencyScore(2) > @tabRecency.recencyScore 4 +    assert.isTrue @tabRecency.recencyScore(3) > @tabRecency.recencyScore 4 + +  should "rank tabs by recency", -> +    assert.isTrue @tabRecency.recencyScore(3) < @tabRecency.recencyScore 2 +    assert.isTrue @tabRecency.recencyScore(2) < @tabRecency.recencyScore 1 +    @tabRecency.add 3 +    @tabRecency.add 4 # Making 3 the most recent tab which isn't the current tab. +    assert.isTrue @tabRecency.recencyScore(1) < @tabRecency.recencyScore 3 +    assert.isTrue @tabRecency.recencyScore(2) < @tabRecency.recencyScore 3 +    assert.isTrue @tabRecency.recencyScore(4) < @tabRecency.recencyScore 3 +    assert.isTrue @tabRecency.recencyScore(4) < @tabRecency.recencyScore 1 +    assert.isTrue @tabRecency.recencyScore(4) < @tabRecency.recencyScore 2 +  # A convenience wrapper around completer.filter() so it can be called synchronously in tests.  filterCompleter = (completer, queryTerms) ->    results = [] diff --git a/tests/unit_tests/test_chrome_stubs.coffee b/tests/unit_tests/test_chrome_stubs.coffee index 2abd26c9..80750337 100644 --- a/tests/unit_tests/test_chrome_stubs.coffee +++ b/tests/unit_tests/test_chrome_stubs.coffee @@ -30,6 +30,10 @@ exports.chrome =        addListener: () -> true      onActiveChanged:        addListener: () -> true +    onActivated: +      addListener: () -> true +    onReplaced: +      addListener: () -> true      query: () -> true    windows: | 
