diff options
| author | Stephen Blott | 2016-02-12 06:39:14 +0000 | 
|---|---|---|
| committer | Stephen Blott | 2016-02-12 06:39:14 +0000 | 
| commit | 973e5eebf2fdec5225c9332e5783dc90f5c720ce (patch) | |
| tree | 0531e1998d0925d679956e0a7da9d5fb0e2fb01f | |
| parent | aabd2068e4ba497c9ad7d237a727121fd573b837 (diff) | |
| parent | 1d809afe18d8638b899a1016d9cca0ccc4a32253 (diff) | |
| download | vimium-973e5eebf2fdec5225c9332e5783dc90f5c720ce.tar.bz2 | |
Merge pull request #1984 from smblott-github/previous-tab
New command: visit previous tab.
| -rw-r--r-- | background_scripts/bg_utils.coffee | 51 | ||||
| -rw-r--r-- | background_scripts/commands.coffee | 3 | ||||
| -rw-r--r-- | background_scripts/completion.coffee | 44 | ||||
| -rw-r--r-- | background_scripts/main.coffee | 6 | ||||
| -rw-r--r-- | manifest.json | 1 | ||||
| -rw-r--r-- | tests/unit_tests/completion_test.coffee | 3 | 
6 files changed, 64 insertions, 44 deletions
| diff --git a/background_scripts/bg_utils.coffee b/background_scripts/bg_utils.coffee new file mode 100644 index 00000000..96c1282a --- /dev/null +++ b/background_scripts/bg_utils.coffee @@ -0,0 +1,51 @@ +root = exports ? window + +# TabRecency associates a logical timestamp with each tab id.  These are used to provide an initial +# recency-based ordering in the tabs vomnibar (which allows jumping quickly between recently-visited tabs). +class TabRecency +  timestamp: 1 +  current: -1 +  cache: {} +  lastVisited: null +  lastVisitedTime: null +  timeDelta: 500 # Milliseconds. + +  constructor: -> +    chrome.tabs.onActivated.addListener (activeInfo) => @register activeInfo.tabId +    chrome.tabs.onRemoved.addListener (tabId) => @deregister tabId + +    chrome.tabs.onReplaced.addListener (addedTabId, removedTabId) => +      @deregister removedTabId +      @register addedTabId + +  register: (tabId) -> +    currentTime = new Date() +    # Register tabId if it has been visited for at least @timeDelta ms.  Tabs which are visited only for a +    # very-short time (e.g. those passed through with `5J`) aren't registered as visited at all. +    if @lastVisitedTime? and @timeDelta <= currentTime - @lastVisitedTime +      @cache[@lastVisited] = ++@timestamp + +    @current = @lastVisited = tabId +    @lastVisitedTime = currentTime + +  deregister: (tabId) -> +    if tabId == @lastVisited +      # Ensure we don't register this tab, since it's going away. +      @lastVisited = @lastVisitedTime = null +    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 tabId == @current then 0.0 else @cache[tabId] / @timestamp + +  # Returns a list of tab Ids sorted by recency, most recent tab first. +  getTabsByRecency: -> +    tabIds = (tId for own tId of @cache) +    tabIds.sort (a,b) => @cache[b] - @cache[a] +    tabIds.map (tId) -> parseInt tId + +BgUtils = +  tabRecency: new TabRecency() + +root.BgUtils = BgUtils diff --git a/background_scripts/commands.coffee b/background_scripts/commands.coffee index d42fd9fb..9c958461 100644 --- a/background_scripts/commands.coffee +++ b/background_scripts/commands.coffee @@ -125,6 +125,7 @@ Commands =      tabManipulation:        ["nextTab",        "previousTab", +      "visitPreviousTab",        "firstTab",        "lastTab",        "createTab", @@ -215,6 +216,7 @@ defaultKeyMappings =    "J": "previousTab"    "gt": "nextTab"    "gT": "previousTab" +  "^": "visitPreviousTab"    "<<": "moveTabLeft"    ">>": "moveTabRight"    "g0": "firstTab" @@ -306,6 +308,7 @@ commandDescriptions =    # Manipulating tabs    nextTab: ["Go one tab right", { background: true, passCountToFunction: true }]    previousTab: ["Go one tab left", { background: true, passCountToFunction: true }] +  visitPreviousTab: ["Go to previously-visited tab", { background: true, passCountToFunction: true }]    firstTab: ["Go to the first tab", { background: true, passCountToFunction: true }]    lastTab: ["Go to the last tab", { background: true, passCountToFunction: true }] diff --git a/background_scripts/completion.coffee b/background_scripts/completion.coffee index 2427bad8..c880a26c 100644 --- a/background_scripts/completion.coffee +++ b/background_scripts/completion.coffee @@ -351,47 +351,6 @@ class DomainCompleter    parseDomainAndScheme: (url) ->        Utils.hasFullUrlPrefix(url) and not Utils.hasChromePrefix(url) and url.split("/",3).join "/" -# TabRecency associates a logical timestamp with each tab id.  These are used to provide an initial -# recency-based ordering in the tabs vomnibar (which allows jumping quickly between recently-visited tabs). -class TabRecency -  timestamp: 1 -  current: -1 -  cache: {} -  lastVisited: null -  lastVisitedTime: null -  timeDelta: 500 # Milliseconds. - -  constructor: -> -    chrome.tabs.onActivated.addListener (activeInfo) => @register activeInfo.tabId -    chrome.tabs.onRemoved.addListener (tabId) => @deregister tabId - -    chrome.tabs.onReplaced.addListener (addedTabId, removedTabId) => -      @deregister removedTabId -      @register addedTabId - -  register: (tabId) -> -    currentTime = new Date() -    # Register tabId if it has been visited for at least @timeDelta ms.  Tabs which are visited only for a -    # very-short time (e.g. those passed through with `5J`) aren't registered as visited at all. -    if @lastVisitedTime? and @timeDelta <= currentTime - @lastVisitedTime -      @cache[@lastVisited] = ++@timestamp - -    @current = @lastVisited = tabId -    @lastVisitedTime = currentTime - -  deregister: (tabId) -> -    if tabId == @lastVisited -      # Ensure we don't register this tab, since it's going away. -      @lastVisited = @lastVisitedTime = null -    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 tabId == @current 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) -> @@ -414,7 +373,7 @@ class TabCompleter      if suggestion.queryTerms.length        RankingUtils.wordRelevancy(suggestion.queryTerms, suggestion.url, suggestion.title)      else -      tabRecency.recencyScore(suggestion.tabId) +      BgUtils.tabRecency.recencyScore(suggestion.tabId)  class SearchEngineCompleter    @debug: false @@ -862,4 +821,3 @@ root.SearchEngineCompleter = SearchEngineCompleter  root.HistoryCache = HistoryCache  root.RankingUtils = RankingUtils  root.RegexpCache = RegexpCache -root.TabRecency = TabRecency diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index ad47c399..a1311a46 100644 --- a/background_scripts/main.coffee +++ b/background_scripts/main.coffee @@ -335,6 +335,12 @@ BackgroundCommands =    closeTabsOnRight: -> removeTabsRelative "after"    closeOtherTabs: -> removeTabsRelative "both" +  visitPreviousTab: (count) -> +    chrome.tabs.getSelected null, (tab) -> +      tabIds = BgUtils.tabRecency.getTabsByRecency().filter (tabId) -> tabId != tab.id +      if 0 < tabIds.length +        selectSpecificTab id: tabIds[(count-1) % tabIds.length] +  # Remove tabs before, after, or either side of the currently active tab  removeTabsRelative = (direction) ->    chrome.tabs.query {currentWindow: true}, (tabs) -> diff --git a/manifest.json b/manifest.json index 883abd37..f66319a7 100644 --- a/manifest.json +++ b/manifest.json @@ -12,6 +12,7 @@        "lib/settings.js",        "background_scripts/commands.js",        "lib/clipboard.js", +      "background_scripts/bg_utils.js",        "background_scripts/exclusions.js",        "background_scripts/completion_engines.js",        "background_scripts/completion_search.js", diff --git a/tests/unit_tests/completion_test.coffee b/tests/unit_tests/completion_test.coffee index 9ce0a466..3bb187fd 100644 --- a/tests/unit_tests/completion_test.coffee +++ b/tests/unit_tests/completion_test.coffee @@ -1,5 +1,6 @@  require "./test_helper.js"  extend(global, require "../../lib/utils.js") +extend(global, require "../../background_scripts/bg_utils.js")  extend(global, require "../../background_scripts/completion_engines.js")  extend(global, require "../../background_scripts/completion.js")  extend global, require "./test_chrome_stubs.js" @@ -411,7 +412,7 @@ fakeTimeDeltaElapsing = ->  context "TabRecency",    setup -> -    @tabRecency = new TabRecency() +    @tabRecency = BgUtils.tabRecency      fakeTimeDeltaElapsing = =>        if @tabRecency.lastVisitedTime? | 
