diff options
| author | Stephen Blott | 2015-03-17 09:59:59 +0000 | 
|---|---|---|
| committer | Stephen Blott | 2015-03-17 09:59:59 +0000 | 
| commit | 5abde2faa3cbcf070de82c5dffef93c553c7ad02 (patch) | |
| tree | f511877ca52bdd51d98b1da55d773d18da4d371c | |
| parent | 23cb1677bbc79328e7329fab4400f671ea6aee23 (diff) | |
| parent | 5b84f5cf94d32b6e8be75448f9c06aa7f2068582 (diff) | |
| download | vimium-5abde2faa3cbcf070de82c5dffef93c553c7ad02.tar.bz2 | |
Merge branch 'rework-exclusion-rules'
Conflicts:
	content_scripts/vimium_frontend.coffee
| -rw-r--r-- | background_scripts/main.coffee | 56 | ||||
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 48 | ||||
| -rw-r--r-- | pages/options.coffee | 10 | 
3 files changed, 53 insertions, 61 deletions
| diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index fe6cc70b..f70cd8f3 100644 --- a/background_scripts/main.coffee +++ b/background_scripts/main.coffee @@ -26,6 +26,7 @@ validFirstKeys = {}  singleKeyCommands = []  focusedFrame = null  frameIdsForTab = {} +root.urlForTab = {}  # Keys are either literal characters, or "named" - for example <a-b> (alt+b), <left> (left arrow) or <f12>  # This regular expression captures two groups: the first is a named key, the second is the remainder of @@ -368,9 +369,6 @@ updateOpenTabs = (tab, deleteFrames = false) ->    # Frames are recreated on refresh    delete frameIdsForTab[tab.id] if deleteFrames -setBrowserActionIcon = (tabId,path) -> -  chrome.browserAction.setIcon({ tabId: tabId, path: path }) -  chrome.browserAction.setBadgeBackgroundColor    # This is Vimium blue (from the icon).    # color: [102, 176, 226, 255] @@ -390,34 +388,24 @@ setBadge = do ->        # We wait a few moments. This avoids badge flicker when there are rapid changes.        timer = setTimeout updateBadge(badge, sender.tab.id), 50 -# Updates the browserAction icon to indicate whether Vimium is enabled or disabled on the current page. -# Also propagates new enabled/disabled/passkeys state to active window, if necessary. -# This lets you disable Vimium on a page without needing to reload. -# Exported via root because it's called from the page popup. -root.updateActiveState = updateActiveState = (tabId) -> -  enabledIcon = "icons/browser_action_enabled.png" -  disabledIcon = "icons/browser_action_disabled.png" -  partialIcon = "icons/browser_action_partial.png" -  chrome.tabs.get tabId, (tab) -> -    setBadge { badge: "" }, tab: { id: tabId } -    chrome.tabs.sendMessage tabId, { name: "getActiveState" }, (response) -> -      if response -        isCurrentlyEnabled = response.enabled -        currentPasskeys = response.passKeys -        config = isEnabledForUrl { url: tab.url }, { tab: tab } -        enabled = config.isEnabledForUrl -        passKeys = config.passKeys -        if (enabled and passKeys) -          setBrowserActionIcon(tabId,partialIcon) -        else if (enabled) -          setBrowserActionIcon(tabId,enabledIcon) -        else -          setBrowserActionIcon(tabId,disabledIcon) -        # Propagate the new state only if it has changed. -        if (isCurrentlyEnabled != enabled || currentPasskeys != passKeys) -          chrome.tabs.sendMessage(tabId, { name: "setState", enabled: enabled, passKeys: passKeys, incognito: tab.incognito }) -      else -        setBrowserActionIcon tabId, disabledIcon +# Here's how we set the page icon.  The default is "disabled", so if we do nothing else, then we get the +# grey-out disabled icon.  Thereafter, we only set tab-specific icons, so there's no need to update the icon +# when we visit a tab on which Vimium isn't running. +# +# For active tabs, when a frame starts, it requests its active state via isEnabledForUrl.  We also check the +# state every time a frame gets the focus.  Once the frame learns its active state, it updates the current +# tab's badge (but only if that frame has the focus). +# +# Exclusion rule changes (from either the options page or the page popup) propagate via the subsequent focus +# change.  In particular, whenever a frame next gets the focus, it requests its new state and sets the icon +# accordingly. +# +setIcon = (request, sender) -> +  path = switch request.icon +    when "enabled" then "icons/browser_action_enabled.png" +    when "partial" then "icons/browser_action_partial.png" +    when "disabled" then "icons/browser_action_disabled.png" +  chrome.browserAction.setIcon tabId: sender.tab.id, path: path  handleUpdateScrollPosition = (request, sender) ->    updateScrollPosition(sender.tab, request.scrollX, request.scrollY) @@ -434,7 +422,6 @@ chrome.tabs.onUpdated.addListener (tabId, changeInfo, tab) ->      runAt: "document_start"    chrome.tabs.insertCSS tabId, cssConf, -> chrome.runtime.lastError    updateOpenTabs(tab) if changeInfo.url? -  updateActiveState(tabId)  chrome.tabs.onAttached.addListener (tabId, attachedInfo) ->    # We should update all the tabs in the old window and the new window. @@ -469,8 +456,7 @@ chrome.tabs.onRemoved.addListener (tabId) ->    tabInfoMap.deletor = -> delete tabInfoMap[tabId]    setTimeout tabInfoMap.deletor, 1000    delete frameIdsForTab[tabId] - -chrome.tabs.onActiveChanged.addListener (tabId, selectInfo) -> updateActiveState(tabId) +  delete urlForTab[tabId]  unless chrome.sessions    chrome.windows.onRemoved.addListener (windowId) -> delete tabQueue[windowId] @@ -654,6 +640,7 @@ unregisterFrame = (request, sender) ->  handleFrameFocused = (request, sender) ->    tabId = sender.tab.id +  urlForTab[tabId] = request.url    if frameIdsForTab[tabId]?      frameIdsForTab[tabId] =        [request.frameId, (frameIdsForTab[tabId].filter (id) -> id != request.frameId)...] @@ -684,6 +671,7 @@ sendRequestHandlers =    refreshCompleter: refreshCompleter    createMark: Marks.create.bind(Marks)    gotoMark: Marks.goto.bind(Marks) +  setIcon: setIcon    setBadge: setBadge  # We always remove chrome.storage.local/findModeRawQueryListIncognito on startup. diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 429657fc..f3bbb868 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -162,6 +162,7 @@ initializePreDomReady = ->      isEnabledForUrl = false      chrome.runtime.sendMessage = ->      chrome.runtime.connect = -> +    window.removeEventListener "focus", onFocus    requestHandlers =      hideUpgradeNotification: -> HUD.hideUpgradeNotification() @@ -173,8 +174,6 @@ initializePreDomReady = ->      getScrollPosition: -> scrollX: window.scrollX, scrollY: window.scrollY      setScrollPosition: (request) -> setScrollPosition request.scrollX, request.scrollY      executePageCommand: executePageCommand -    getActiveState: getActiveState -    setState: setState      currentKeyQueue: (request) ->        keyQueue = request.keyQueue        handlerStack.bubbleEvent "registerKeyQueue", { keyQueue: keyQueue } @@ -183,7 +182,7 @@ initializePreDomReady = ->      # In the options page, we will receive requests from both content and background scripts. ignore those      # from the former.      return if sender.tab and not sender.tab.url.startsWith 'chrome-extension://' -    return unless isEnabledForUrl or request.name == 'getActiveState' or request.name == 'setState' +    return unless isEnabledForUrl      # These requests are delivered to the options page, but there are no handlers there.      return if request.handler in [ "registerFrame", "frameFocused", "unregisterFrame" ]      sendResponse requestHandlers[request.name](request, sender) @@ -209,30 +208,24 @@ window.initializeWhenEnabled = ->      for type in [ "keydown", "keypress", "keyup", "click", "focus", "blur", "mousedown" ]        do (type) -> installListener window, type, (event) -> handlerStack.bubbleEvent type, event      installListener document, "DOMActivate", (event) -> handlerStack.bubbleEvent 'DOMActivate', event -    installListener window, "focus", registerFocus      installedListeners = true      FindModeHistory.init() -setState = (request) -> -  isEnabledForUrl = request.enabled -  passKeys = request.passKeys -  isIncognitoMode = request.incognito -  initializeWhenEnabled() if isEnabledForUrl -  handlerStack.bubbleEvent "registerStateChange", -    enabled: isEnabledForUrl -    passKeys: passKeys - -getActiveState = -> -  Mode.updateBadge() -  return { enabled: isEnabledForUrl, passKeys: passKeys } -  # -# The backend needs to know which frame has focus. +# Whenever we get the focus: +# - Reload settings (they may have changed). +# - Tell the background page this frame's URL. +# - Check if we should be enabled.  # -registerFocus = -> -  # settings may have changed since the frame last had focus -  settings.load() -  chrome.runtime.sendMessage({ handler: "frameFocused", frameId: frameId }) +onFocus = (event) -> +  if event.target == window +    settings.load() +    chrome.runtime.sendMessage handler: "frameFocused", frameId: frameId, url: window.location.toString() +    checkIfEnabledForUrl() + +# We install this listener directly (that is, we don't use installListener) because we still need to receive +# events when Vimium is not enabled. +window.addEventListener "focus", onFocus  #  # Initialization tasks that must wait for the document to be ready. @@ -565,12 +558,21 @@ checkIfEnabledForUrl = ->      isIncognitoMode = response.incognito      if isEnabledForUrl        initializeWhenEnabled() -    else if (HUD.isReady()) +    else if HUD.isReady()        # Quickly hide any HUD we might already be showing, e.g. if we entered insert mode on page load.        HUD.hide()      handlerStack.bubbleEvent "registerStateChange",        enabled: isEnabledForUrl        passKeys: passKeys +    # Update the page icon, if necessary. +    if document.hasFocus() +      chrome.runtime.sendMessage +        handler: "setIcon" +        icon: +          if isEnabledForUrl and not passKeys then "enabled" +          else if isEnabledForUrl then "partial" +          else "disabled" +  # Exported to window, but only for DOM tests.  window.refreshCompletionKeys = (response) -> diff --git a/pages/options.coffee b/pages/options.coffee index d2950348..6545189b 100644 --- a/pages/options.coffee +++ b/pages/options.coffee @@ -271,8 +271,12 @@ initPopupPage = ->      exclusions = null      document.getElementById("optionsLink").setAttribute "href", chrome.runtime.getURL("pages/options.html") +    # As the active URL, we choose the most recently registered URL from a frame in the tab, or the tab's own +    # URL. +    url = chrome.extension.getBackgroundPage().urlForTab[tab.id] || tab.url +      updateState = -> -      rule = bgExclusions.getRule tab.url, exclusions.readValueFromElement() +      rule = bgExclusions.getRule url, exclusions.readValueFromElement()        $("state").innerHTML = "Vimium will " +          if rule and rule.passKeys            "exclude <span class='code'>#{rule.passKeys}</span>" @@ -291,8 +295,6 @@ initPopupPage = ->        Option.saveOptions()        $("saveOptions").innerHTML = "Saved"        $("saveOptions").disabled = true -      chrome.tabs.query { windowId: chrome.windows.WINDOW_ID_CURRENT, active: true }, (tabs) -> -        chrome.extension.getBackgroundPage().updateActiveState(tabs[0].id)      $("saveOptions").addEventListener "click", saveOptions @@ -302,7 +304,7 @@ initPopupPage = ->          window.close()      # Populate options. Just one, here. -    exclusions = new ExclusionRulesOnPopupOption(tab.url, "exclusionRules", onUpdated) +    exclusions = new ExclusionRulesOnPopupOption url, "exclusionRules", onUpdated      updateState()      document.addEventListener "keyup", updateState | 
