diff options
| -rw-r--r-- | background_scripts/main.coffee | 38 | ||||
| -rw-r--r-- | background_scripts/settings.coffee | 10 | ||||
| -rw-r--r-- | background_scripts/sync.coffee | 2 | ||||
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 70 | 
4 files changed, 49 insertions, 71 deletions
| diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index b4eac4f1..286781b4 100644 --- a/background_scripts/main.coffee +++ b/background_scripts/main.coffee @@ -188,20 +188,7 @@ handleSettings = (args, port) ->      value = Settings.get(args.key)      port.postMessage({ key: args.key, value: value })    else # operation == "set" -    Settings.set(args.key, args.value) unless args.incognito and args.key in [ "findModeRawQueryList" ] -    # For some settings, we propagate changes to all tabs immediately. -    # In the case of findModeRawQueryList, this allows each tab to accurately track the find-mode history. -    if args.key in [ "findModeRawQueryList" ] -      sendRequestToAllTabs extend args, name: "updateSettings" -    # We also track the incognito find-mode history setting in the tabInfoMap for all incognito tabs. -    if args.incognito and args.key == "findModeRawQueryList" -      for own _, map of tabInfoMap -        map.findModeRawQueryList = args.value if map.incognito - -# Search through the active tab map for an up-to-date find-mode history for an incognito-mode tab. -getIncognitoRawQueryList = -> -  for own id, map of tabInfoMap -    return map.findModeRawQueryList if map.findModeRawQueryList +    Settings.set(args.key, args.value)  refreshCompleter = (request) -> completers[request.name].refresh() @@ -346,8 +333,6 @@ updateOpenTabs = (tab) ->      scrollX: null      scrollY: null      deletor: null -    incognito: tab.incognito -    findModeRawQueryList: null    # Frames are recreated on refresh    delete frameIdsForTab[tab.id] @@ -604,15 +589,12 @@ checkKeyQueue = (keysToCheck, tabId, frameId) ->  #  # Message all tabs. Args should be the arguments hash used by the Chrome sendRequest API. -# Normally, the request is sent to all tabs.  However, if args.incognito is set, then the request is only sent -# to incognito tabs.  #  sendRequestToAllTabs = (args) ->    chrome.windows.getAll({ populate: true }, (windows) ->      for window in windows        for tab in window.tabs -        if not args.incognito or tab.incognito -          chrome.tabs.sendMessage(tab.id, args, null)) +        chrome.tabs.sendMessage(tab.id, args, null))  #  # Returns true if the current extension version is greater than the previously recorded version in @@ -672,7 +654,21 @@ sendRequestHandlers =    createMark: Marks.create.bind(Marks)    gotoMark: Marks.goto.bind(Marks)    setBadge: setBadge -  getIncognitoRawQueryList: getIncognitoRawQueryList + +# We always remove chrome.storage.local/findModeRawQueryListIncognito on startup. +chrome.storage.local.remove "findModeRawQueryListIncognito" + +# Remove chrome.storage.local/findModeRawQueryListIncognito if there are no remaining incognito-mode tabs. +# Since the common case is that there are none to begin with, we first check whether the key is set at all. +chrome.tabs.onRemoved.addListener (tabId) -> +  chrome.storage.local.get "findModeRawQueryListIncognito", (items) -> +    if items.findModeRawQueryListIncognito +      chrome.windows.getAll { populate: true }, (windows) -> +        for window in windows +          for tab in window.tabs +            return if tab.incognito and tab.id != tabId +        # There are no remaining incognito-mode tabs, and findModeRawQueryListIncognito is set. +        chrome.storage.local.remove "findModeRawQueryListIncognito"  # Convenience function for development use.  window.runTests = -> open(chrome.runtime.getURL('tests/dom_tests/dom_tests.html')) diff --git a/background_scripts/settings.coffee b/background_scripts/settings.coffee index 70b94429..7430145c 100644 --- a/background_scripts/settings.coffee +++ b/background_scripts/settings.coffee @@ -116,7 +116,6 @@ root.Settings = Settings =      settingsVersion: Utils.getCurrentVersion() -  # We use settingsVersion to coordinate any necessary schema changes.  if Utils.compareVersions("1.42", Settings.get("settingsVersion")) != -1    Settings.set("scrollStepSize", parseFloat Settings.get("scrollStepSize")) @@ -124,8 +123,9 @@ Settings.set("settingsVersion", Utils.getCurrentVersion())  # Migration (after 1.49, 2015/2/1).  # Legacy setting: findModeRawQuery (a string). -# New setting: findModeRawQueryList (a list of strings). -unless Settings.has "findModeRawQueryList" -  rawQuery = Settings.get "findModeRawQuery" -  Settings.set "findModeRawQueryList", (if rawQuery then [ rawQuery ] else []) +# New setting: findModeRawQueryList (a list of strings), now stored in chrome.storage.local (not localStorage). +chrome.storage.local.get "findModeRawQueryList", (items) -> +  unless chrome.runtime.lastError or items.findModeRawQueryList +    rawQuery = Settings.get "findModeRawQuery" +    chrome.storage.local.set findModeRawQueryList: (if rawQuery then [ rawQuery ] else []) diff --git a/background_scripts/sync.coffee b/background_scripts/sync.coffee index f1850438..866faca1 100644 --- a/background_scripts/sync.coffee +++ b/background_scripts/sync.coffee @@ -42,7 +42,7 @@ root.Sync = Sync =    # Only ever called from asynchronous synced-storage callbacks (fetchAsync and handleStorageUpdate).    storeAndPropagate: (key, value) -> -    return if not key of Settings.defaults +    return unless key of Settings.defaults      return if not @shouldSyncKey key      return if value and key of localStorage and localStorage[key] is value      defaultValue = Settings.defaults[key] diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 3d40e307..9a50d373 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -43,11 +43,10 @@ settings =    values: {}    loadedValues: 0    valuesToLoad: [ "scrollStepSize", "linkHintCharacters", "linkHintNumbers", "filterLinkHints", "hideHud", -    "previousPatterns", "nextPatterns", "findModeRawQuery", "findModeRawQueryList", "regexFindMode", -    "userDefinedLinkHintCss", "helpDialog_showAdvancedCommands", "smoothScroll" ] +    "previousPatterns", "nextPatterns", "regexFindMode", "userDefinedLinkHintCss", +    "helpDialog_showAdvancedCommands", "smoothScroll" ]    isLoaded: false    eventListeners: {} -  postUpdateHooks: {}    init: ->      @port = chrome.runtime.connect({ name: "settings" }) @@ -64,17 +63,11 @@ settings =    get: (key) -> @values[key] -  # This is used when an updated value is received from the background page. -  update: (key, value) -> -    @values[key] = value -    @postUpdateHooks[key]? value - -  # This is used when the current tab sets a new value for a setting.    set: (key, value) ->      @init() unless @port      @values[key] = value -    @port.postMessage({ operation: "set", key: key, value: value, incognito: isIncognitoMode }) +    @port.postMessage({ operation: "set", key: key, value: value })    load: ->      @init() unless @port @@ -84,7 +77,7 @@ settings =    receiveMessage: (args) ->      # not using 'this' due to issues with binding on callback -    settings.update args.key, args.value +    settings.values[args.key] = args.value      # since load() can be called more than once, loadedValues can be greater than valuesToLoad, but we test      # for equality so initializeOnReady only runs once      if (++settings.loadedValues == settings.valuesToLoad.length) @@ -123,12 +116,6 @@ window.initializeModes = ->    new InsertMode permanent: true  # -# Called if we learn that this frame is in incognito mode. -# -goIncognito = -> -  FindModeHistory.goIncognito() - -#  # Complete initialization work that sould be done prior to DOMReady.  #  initializePreDomReady = -> @@ -164,9 +151,6 @@ initializePreDomReady = ->      currentKeyQueue: (request) ->        keyQueue = request.keyQueue        handlerStack.bubbleEvent "registerKeyQueue", { keyQueue: keyQueue } -    updateSettings: (request) -> -      settings.update request.key, request.value -      FindModeHistory.updateFindModeHistory request.value if request.key = "findModeRawQueryList"    chrome.runtime.onMessage.addListener (request, sender, sendResponse) ->      # In the options page, we will receive requests from both content and background scripts. ignore those @@ -203,9 +187,9 @@ window.initializeWhenEnabled = ->  setState = (request) ->    isEnabledForUrl = request.enabled    passKeys = request.passKeys -  goIncognito() if request.incognito and not isIncognitoMode    isIncognitoMode = request.incognito    initializeWhenEnabled() if isEnabledForUrl +  FindModeHistory.init()    handlerStack.bubbleEvent "registerStateChange",      enabled: isEnabledForUrl      passKeys: passKeys @@ -556,38 +540,36 @@ isValidFirstKey = (keyChar) ->  # This implements find-mode query history (using the "findModeRawQueryList" setting) as a list of raw queries,  # most recent first.  FindModeHistory = +  storage: chrome.storage.local +  key: "findModeRawQueryList"    max: 50    rawQueryList: null -  postUpdateHook: do -> -    # This update path is only used to initialize @rawQueryList.  Thereafter, we use updateFindModeHistory to -    # track the history. -    settings.postUpdateHooks.findModeRawQueryList = (args...) -> FindModeHistory.postUpdateHook args... -    (rawQueryList) -> @rawQueryList = rawQueryList unless @rawQueryList? - -  # This is called when we receive an updateSettings message from the background page.  It is called -  # synchronously with the update from another tab.  Therefore, we know that only the most-recent query can -  # have changed. -  updateFindModeHistory: (rawQueryList) -> -    @updateRawQueryList rawQueryList[0] if rawQueryList[0]? - -  # Register query as the most-recent query, removing any existing occurrences.  Note: this is idempotent when -  # called repeatedly with the same argument. -  updateRawQueryList: (query) -> -    @rawQueryList = ([ query ].concat @rawQueryList.filter (q) => q != query)[0..@max] +  init: -> +    unless @rawQueryList +      @rawQueryList = [] # Prevent repeated initialization. +      @key = "findModeRawQueryListIncognito" if isIncognitoMode +      @storage.get @key, (items) => +        unless chrome.runtime.lastError +          @rawQueryList = items[@key] +          if isIncognitoMode and not @rawQueryList +            # This is the first incognito tab, we need to initialize the incognito-mode query history. +            @storage.get "findModeRawQueryList", (items) => +              unless chrome.runtime.lastError +                @rawQueryList = items.findModeRawQueryList +                @storage.set findModeRawQueryListIncognito: @rawQueryList + +    chrome.storage.onChanged.addListener (changes, area) => +      @rawQueryList = changes[@key].newValue if changes[@key]?.newValue?    getQuery: (index = 0) ->      @rawQueryList?[index] or ""    saveQuery: (query) ->      if 0 < query.length -      @updateRawQueryList query -      settings.set "findModeRawQueryList", @rawQueryList - -  goIncognito: -> -    # In incognito mode, we try to fetch the query history from another incognito tab.  See #1465. -    chrome.runtime.sendMessage { handler: "getIncognitoRawQueryList" }, (response) => -      @rawQueryList = response if response +      @rawQueryList = ([ query ].concat @rawQueryList.filter (q) => q != query)[0..@max] +      newSetting = {}; newSetting[@key] = @rawQueryList +      @storage.set newSetting  # should be called whenever rawQuery is modified.  updateFindModeQuery = -> | 
