From 3876a4f06de77d190fdaecc6cf99eb57134d0372 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sun, 15 Mar 2015 12:32:42 +0000 Subject: Populate popup with frame's URL. Previously, we have been populating the suggested exclusion URL in the page popup with the tab's URL. This uses the active frame's URL instead: - because this is the URL which will affect the current frame (without this, a user can naively add an exclusion rule and it has no effect), and - because, without this, the user has no reasonable way to add exclusion rules for frames such as the hangouts frame on gmail (for which, the URL is not displayed in the address bar). --- background_scripts/main.coffee | 3 +++ 1 file changed, 3 insertions(+) (limited to 'background_scripts') diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index b390fe1c..ecf18bef 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 (alt+b), (left arrow) or # This regular expression captures two groups: the first is a named key, the second is the remainder of @@ -462,6 +463,7 @@ chrome.tabs.onRemoved.addListener (tabId) -> tabInfoMap.deletor = -> delete tabInfoMap[tabId] setTimeout tabInfoMap.deletor, 1000 delete frameIdsForTab[tabId] + delete urlForTab[tabId] chrome.tabs.onActiveChanged.addListener (tabId, selectInfo) -> updateActiveState(tabId) @@ -647,6 +649,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)...] -- cgit v1.2.3 From ea05de3f114dcc81a91bf863538f20754641cadd Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sun, 15 Mar 2015 13:14:26 +0000 Subject: Propagate exclusion rules to all frames. When the active tab changes, we call updateActiveState to update the icon and propagate any changed exclusion-rule state to the tab. All frames received the request. However, only one response is received by the background page. Therefore, new exclusion rules are only propagated to one frame. Here's what can go wrong... On gmail, open the hangouts frame. Add an exclusion rule sepcific to the hangouts frame. Save it. The update is propagated only to the main frame. The new exclusion rule is not in effect in the hangouts frame. That's wierd and obviously wrong. In this commit, every frame receiving the getActiveState request also calls checkIfEnabledForUrl to ensure that any new exclusion-rule state is propagated. This is overkill, to some extent. We should really move settings to chrome.storage and have each frame check locally for changes affecting it. --- background_scripts/main.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'background_scripts') diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index ecf18bef..a5d7ac31 100644 --- a/background_scripts/main.coffee +++ b/background_scripts/main.coffee @@ -398,7 +398,8 @@ root.updateActiveState = updateActiveState = (tabId) -> if response isCurrentlyEnabled = response.enabled currentPasskeys = response.passKeys - config = isEnabledForUrl { url: tab.url }, { tab: tab } + currentURL = response.url + config = isEnabledForUrl { url: currentURL }, { tab: tab } enabled = config.isEnabledForUrl passKeys = config.passKeys if (enabled and passKeys) -- cgit v1.2.3 From fb24c770645ce1b8178729d4be612d58497ffa5f Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sun, 15 Mar 2015 15:04:23 +0000 Subject: Rework page icon handling. Setting the page icon is now driven from the corrently-active frame. - Eliminates a race condition. - Icon matches actual frame state (not tab URL state). - Exclusion-rule changes propagate to all frames. --- background_scripts/main.coffee | 54 +++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 35 deletions(-) (limited to 'background_scripts') diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index a5d7ac31..a6e5a4eb 100644 --- a/background_scripts/main.coffee +++ b/background_scripts/main.coffee @@ -362,9 +362,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] @@ -384,35 +381,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 - currentURL = response.url - config = isEnabledForUrl { url: currentURL }, { 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) @@ -429,7 +415,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. @@ -466,8 +451,6 @@ chrome.tabs.onRemoved.addListener (tabId) -> delete frameIdsForTab[tabId] delete urlForTab[tabId] -chrome.tabs.onActiveChanged.addListener (tabId, selectInfo) -> updateActiveState(tabId) - unless chrome.sessions chrome.windows.onRemoved.addListener (windowId) -> delete tabQueue[windowId] @@ -681,6 +664,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. -- cgit v1.2.3