From 8a659af44a8205f39e4c0e04146978447ca3f38e Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Fri, 24 Apr 2015 12:02:09 +0100 Subject: Get incognto state directly from chrome.extensions.inIncognitoContext --- background_scripts/main.coffee | 3 +-- content_scripts/vimium_frontend.coffee | 6 ++---- tests/unit_tests/exclusion_test.coffee | 12 ++++-------- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index 31ada357..223b0d74 100644 --- a/background_scripts/main.coffee +++ b/background_scripts/main.coffee @@ -89,12 +89,11 @@ getCurrentTabUrl = (request, sender) -> sender.tab.url # Checks the user's preferences in local storage to determine if Vimium is enabled for the given URL, and # whether any keys should be passed through to the underlying page. # -root.isEnabledForUrl = isEnabledForUrl = (request, sender) -> +root.isEnabledForUrl = isEnabledForUrl = (request) -> rule = Exclusions.getRule(request.url) { isEnabledForUrl: not rule or rule.passKeys passKeys: rule?.passKeys or "" - incognito: sender.tab.incognito } # Retrieves the help dialog HTML template from a file, and populates it with the latest keybindings. diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 6c09ab72..7b99287e 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -12,7 +12,7 @@ findModeInitialRange = null isShowingHelpDialog = false keyPort = null isEnabledForUrl = true -isIncognitoMode = false +isIncognitoMode = chrome.extension.inIncognitoContext passKeys = null keyQueue = null # The user's operating system. @@ -551,9 +551,7 @@ checkIfEnabledForUrl = -> url = window.location.toString() chrome.runtime.sendMessage { handler: "isEnabledForUrl", url: url }, (response) -> - isEnabledForUrl = response.isEnabledForUrl - passKeys = response.passKeys - isIncognitoMode = response.incognito + {isEnabledForUrl, passKeys} = response if isEnabledForUrl initializeWhenEnabled() else if HUD.isReady() diff --git a/tests/unit_tests/exclusion_test.coffee b/tests/unit_tests/exclusion_test.coffee index 287d699d..b3ed7194 100644 --- a/tests/unit_tests/exclusion_test.coffee +++ b/tests/unit_tests/exclusion_test.coffee @@ -21,10 +21,6 @@ extend(global, require "../../background_scripts/exclusions.js") extend(global, require "../../background_scripts/commands.js") extend(global, require "../../background_scripts/main.js") -dummyTab = - tab: - incognito: false - # These tests cover only the most basic aspects of excluded URLs and passKeys. # context "Excluded URLs and pass keys", @@ -40,22 +36,22 @@ context "Excluded URLs and pass keys", ]) should "be disabled for excluded sites", -> - rule = isEnabledForUrl({ url: 'http://mail.google.com/calendar/page' }, dummyTab) + rule = isEnabledForUrl({ url: 'http://mail.google.com/calendar/page' }) assert.isFalse rule.isEnabledForUrl assert.isFalse rule.passKeys should "be disabled for excluded sites, one exclusion", -> - rule = isEnabledForUrl({ url: 'http://www.bbc.com/calendar/page' }, dummyTab) + rule = isEnabledForUrl({ url: 'http://www.bbc.com/calendar/page' }) assert.isFalse rule.isEnabledForUrl assert.isFalse rule.passKeys should "be enabled, but with pass keys", -> - rule = isEnabledForUrl({ url: 'https://www.facebook.com/something' }, dummyTab) + rule = isEnabledForUrl({ url: 'https://www.facebook.com/something' }) assert.isTrue rule.isEnabledForUrl assert.equal rule.passKeys, 'abcd' should "be enabled", -> - rule = isEnabledForUrl({ url: 'http://www.twitter.com/pages' }, dummyTab) + rule = isEnabledForUrl({ url: 'http://www.twitter.com/pages' }) assert.isTrue rule.isEnabledForUrl assert.isFalse rule.passKeys -- cgit v1.2.3 From b3986dcd68a9383b3552ffb99c13c19e94bd08e4 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Fri, 24 Apr 2015 12:16:36 +0100 Subject: Re-check enabled state after history.pushState/location.hash is changed This uses the chrome.webRequest API to detect changes to page URL which *do not* cause the content script to refresh. --- background_scripts/main.coffee | 9 ++++++++ content_scripts/vimium_frontend.coffee | 42 +++++++++++++++++++--------------- manifest.json | 1 + 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index 223b0d74..ab92559f 100644 --- a/background_scripts/main.coffee +++ b/background_scripts/main.coffee @@ -96,6 +96,15 @@ root.isEnabledForUrl = isEnabledForUrl = (request) -> passKeys: rule?.passKeys or "" } +isEnabledForUpdatedUrl = (details) -> + message = isEnabledForUrl details + message.name = "updateEnabledForUrlState" + chrome.tabs.sendMessage details.tabId, message, {frameId: details.frameId} + +# Re-check whether Vimium is enabled for a frame when the url changes without a reload. +chrome.webNavigation.onHistoryStateUpdated.addListener isEnabledForUpdatedUrl # history.pushState. +chrome.webNavigation.onReferenceFragmentUpdated.addListener isEnabledForUpdatedUrl # Hash changed. + # Retrieves the help dialog HTML template from a file, and populates it with the latest keybindings. # This is called by options.coffee. root.helpDialogHtml = (showUnboundCommands, showCommandNames, customTitle) -> diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 7b99287e..862118bc 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -175,12 +175,13 @@ initializePreDomReady = -> currentKeyQueue: (request) -> keyQueue = request.keyQueue handlerStack.bubbleEvent "registerKeyQueue", { keyQueue: keyQueue } + updateEnabledForUrlState: updateEnabledForUrlState chrome.runtime.onMessage.addListener (request, sender, sendResponse) -> # 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 + return unless isEnabledForUrl or request.name in ["updateEnabledForUrlState"] # 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) @@ -550,24 +551,27 @@ onKeyup = (event) -> checkIfEnabledForUrl = -> url = window.location.toString() - chrome.runtime.sendMessage { handler: "isEnabledForUrl", url: url }, (response) -> - {isEnabledForUrl, passKeys} = response - if isEnabledForUrl - initializeWhenEnabled() - 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" + chrome.runtime.sendMessage { handler: "isEnabledForUrl", url: url }, updateEnabledForUrlState + +updateEnabledForUrlState = (response) -> + {isEnabledForUrl, passKeys} = response + if isEnabledForUrl + initializeWhenEnabled() + 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" + null # Exported to window, but only for DOM tests. diff --git a/manifest.json b/manifest.json index 4ba222fb..e8e51407 100644 --- a/manifest.json +++ b/manifest.json @@ -28,6 +28,7 @@ "storage", "sessions", "notifications", + "webNavigation", "" ], "content_scripts": [ -- cgit v1.2.3 From bffbe9edaa31a457823a95a2778aefc68b813957 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Fri, 24 Apr 2015 12:21:38 +0100 Subject: Update minimum_chrome_version to reflect the availability of some APIs Specifically, the chrome.tabs.sendMessage(tabId, message, options, callback) API doesn't exist before Chrome 41, instead taking the form chrome.tabs.sendMessage(tabId, message, callback). --- manifest.json | 1 + 1 file changed, 1 insertion(+) diff --git a/manifest.json b/manifest.json index e8e51407..f0c297c2 100644 --- a/manifest.json +++ b/manifest.json @@ -2,6 +2,7 @@ "manifest_version": 2, "name": "Vimium", "version": "1.49", + "minimum_chrome_version": "41", "description": "The Hacker's Browser. Vimium provides keyboard shortcuts for navigation and control in the spirit of Vim.", "icons": { "16": "icons/icon16.png", "48": "icons/icon48.png", -- cgit v1.2.3 From 16df2200b491e2463b784b4979ba5e9528604b64 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Fri, 24 Apr 2015 12:53:17 +0100 Subject: Add chrome.webNavigation stubs to fix tests --- tests/dom_tests/chrome.coffee | 2 ++ tests/unit_tests/test_chrome_stubs.coffee | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/tests/dom_tests/chrome.coffee b/tests/dom_tests/chrome.coffee index 5f276649..4c9bfa52 100644 --- a/tests/dom_tests/chrome.coffee +++ b/tests/dom_tests/chrome.coffee @@ -29,3 +29,5 @@ root.chrome = set: -> onChanged: addListener: -> + extension: + inIncognitoContext: false diff --git a/tests/unit_tests/test_chrome_stubs.coffee b/tests/unit_tests/test_chrome_stubs.coffee index bc50521a..60f3a890 100644 --- a/tests/unit_tests/test_chrome_stubs.coffee +++ b/tests/unit_tests/test_chrome_stubs.coffee @@ -38,6 +38,12 @@ exports.chrome = addListener: () -> true query: () -> true + webNavigation: + onHistoryStateUpdated: + addListener: () -> + onReferenceFragmentUpdated: + addListener: () -> + windows: onRemoved: addListener: () -> true -- cgit v1.2.3 From 6446cf04c7b44c3d419dc450a73b60bcaf5cdf02 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Fri, 24 Apr 2015 13:53:54 +0100 Subject: Always initialise event listeners early The event listeners were registered late, potentially allowing the page to get priority over us for key events, etc., when: * the original URL was disabled by an exclusion rule * the URL was changed - without a page load (by history.pushState or modifying location.hash), and - the new URL isn't (completely) disabled by any exclusion rules. This forces the event listeners to be registered even when the current URL is disabled, to avoid this problem. --- content_scripts/vimium_frontend.coffee | 7 +++---- tests/dom_tests/dom_tests.coffee | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 862118bc..cc97b515 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -200,7 +200,7 @@ installListener = (element, event, callback) -> # Run this as early as possible, so the page can't register any event handlers before us. # installedListeners = false -window.initializeWhenEnabled = -> +window.initializeWithState = -> unless installedListeners # Key event handlers fire on window before they do on document. Prefer window for key events so the page # can't set handlers to grab the keys before us. @@ -555,9 +555,8 @@ checkIfEnabledForUrl = -> updateEnabledForUrlState = (response) -> {isEnabledForUrl, passKeys} = response - if isEnabledForUrl - initializeWhenEnabled() - else if HUD.isReady() + initializeWithState() + if HUD.isReady() and not isEnabledForUrl # Quickly hide any HUD we might already be showing, e.g. if we entered insert mode on page load. HUD.hide() handlerStack.bubbleEvent "registerStateChange", diff --git a/tests/dom_tests/dom_tests.coffee b/tests/dom_tests/dom_tests.coffee index f81982ac..59970d7c 100644 --- a/tests/dom_tests/dom_tests.coffee +++ b/tests/dom_tests/dom_tests.coffee @@ -1,6 +1,6 @@ # Install frontend event handlers. -initializeWhenEnabled() +initializeWithState() installListener = (element, event, callback) -> element.addEventListener event, (-> callback.apply(this, arguments)), true -- cgit v1.2.3