diff options
Diffstat (limited to 'background_scripts/main.coffee')
| -rw-r--r-- | background_scripts/main.coffee | 129 |
1 files changed, 47 insertions, 82 deletions
diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index 0c7d9343..a26fd8a8 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 @@ -57,7 +58,7 @@ completers = bookmarks: new MultiCompleter([completionSources.bookmarks]) tabs: new MultiCompleter([completionSources.tabs]) -chrome.runtime.onConnect.addListener((port, name) -> +chrome.runtime.onConnect.addListener (port, name) -> senderTabId = if port.sender.tab then port.sender.tab.id else null # If this is a tab we've been waiting to open, execute any "tab loaded" handlers, e.g. to restore # the tab's scroll position. Wait until domReady before doing this; otherwise operations like restoring @@ -69,14 +70,8 @@ chrome.runtime.onConnect.addListener((port, name) -> delete tabLoadedHandlers[senderTabId] toCall.call() - # domReady is the appropriate time to show the "vimium has been upgraded" message. - # TODO: This might be broken on pages with frames. - if (shouldShowUpgradeMessage()) - chrome.tabs.sendMessage(senderTabId, { name: "showUpgradeNotification", version: currentVersion }) - if (portHandlers[port.name]) port.onMessage.addListener(portHandlers[port.name]) -) chrome.runtime.onMessage.addListener((request, sender, sendResponse) -> if (sendRequestHandlers[request.handler]) @@ -183,14 +178,6 @@ openUrlInIncognito = (request) -> chrome.windows.create({ url: Utils.convertToUrl(request.url), incognito: true}) # -# Called when the user has clicked the close icon on the "Vimium has been updated" message. -# We should now dismiss that message in all tabs. -# -upgradeNotificationClosed = (request) -> - Settings.set("previousVersion", currentVersion) - sendRequestToAllTabs({ name: "hideUpgradeNotification" }) - -# # Copies or pastes some data (request.data) to/from the clipboard. # We return null to avoid the return value from the copy operations being passed to sendResponse. # @@ -368,56 +355,23 @@ 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] - # This is a slightly darker blue. It makes the badge more striking in the corner of the eye, and the symbol - # easier to read. - color: [82, 156, 206, 255] - -setBadge = do -> - current = null - timer = null - updateBadge = (badge, tabId) -> -> chrome.browserAction.setBadgeText text: badge, tabId: tabId - (request, sender) -> - badge = request.badge - if badge? and badge != current - current = badge - clearTimeout timer if timer - # 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. In both cases, the frame then updates the tab's icon accordingly. +# +# 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 +388,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 +422,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] @@ -627,16 +579,6 @@ sendRequestToAllTabs = (args) -> for tab in window.tabs chrome.tabs.sendMessage(tab.id, args, null)) -# -# Returns true if the current extension version is greater than the previously recorded version in -# localStorage, and false otherwise. -# -shouldShowUpgradeMessage = -> - # Avoid showing the upgrade notification when previousVersion is undefined, which is the case for new - # installs. - Settings.set("previousVersion", currentVersion) unless Settings.get("previousVersion") - Utils.compareVersions(currentVersion, Settings.get("previousVersion")) == 1 - openOptionsPageInNewTab = -> chrome.tabs.getSelected(null, (tab) -> chrome.tabs.create({ url: chrome.runtime.getURL("pages/options.html"), index: tab.index + 1 })) @@ -654,6 +596,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)...] @@ -687,7 +630,6 @@ sendRequestHandlers = unregisterFrame: unregisterFrame frameFocused: handleFrameFocused nextFrame: (request) -> BackgroundCommands.nextFrame 1, request.frameId - upgradeNotificationClosed: upgradeNotificationClosed updateScrollPosition: handleUpdateScrollPosition copyToClipboard: copyToClipboard pasteFromClipboard: pasteFromClipboard @@ -696,7 +638,7 @@ sendRequestHandlers = refreshCompleter: refreshCompleter createMark: Marks.create.bind(Marks) gotoMark: Marks.goto.bind(Marks) - setBadge: setBadge + setIcon: setIcon sendMessageToFrames: sendMessageToFrames log: bgLog @@ -727,8 +669,30 @@ if Settings.has("keyMappings") populateValidFirstKeys() populateSingleKeyCommands() -if shouldShowUpgradeMessage() - sendRequestToAllTabs({ name: "showUpgradeNotification", version: currentVersion }) + +# Show notification on upgrade. +showUpgradeMessage = -> + # Avoid showing the upgrade notification when previousVersion is undefined, which is the case for new + # installs. + Settings.set "previousVersion", currentVersion unless Settings.get "previousVersion" + if Utils.compareVersions(currentVersion, Settings.get "previousVersion" ) == 1 + notificationId = "VimiumUpgradeNotification" + notification = + type: "basic" + iconUrl: chrome.runtime.getURL "icons/vimium.png" + title: "Vimium Upgrade" + message: "Vimium has been upgraded to version #{currentVersion}. Click here for more information." + isClickable: true + if chrome.notifications?.create? + chrome.notifications.create notificationId, notification, -> + unless chrome.runtime.lastError + Settings.set "previousVersion", currentVersion + chrome.notifications.onClicked.addListener (id) -> + if id == notificationId + openUrlInNewTab url: "https://github.com/philc/vimium#release-notes" + else + # We need to wait for the user to accept the "notifications" permission. + chrome.permissions.onAdded.addListener showUpgradeMessage # Ensure that tabInfoMap is populated when Vimium is installed. chrome.windows.getAll { populate: true }, (windows) -> @@ -741,3 +705,4 @@ chrome.windows.getAll { populate: true }, (windows) -> # Start pulling changes from synchronized storage. Sync.init() +showUpgradeMessage() |
