From b8b0e4b612cfbf7122f4f45c5a72944f856aa3d7 Mon Sep 17 00:00:00 2001 From: Shane Caraveo Date: Tue, 20 Nov 2018 18:24:38 +0000 Subject: [PATCH] Bug 1506653 support disabling page action for private windows, r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D11805 --HG-- extra : moz-landing-system : lando --- .../browser/browser_ext_incognito_popup.js | 29 +++++++++++++++++ browser/modules/PageActions.jsm | 31 +++++++++++++++++-- .../test/browser/browser_PageActions.js | 25 +++++++++++++++ 3 files changed, 82 insertions(+), 3 deletions(-) diff --git a/browser/components/extensions/test/browser/browser_ext_incognito_popup.js b/browser/components/extensions/test/browser/browser_ext_incognito_popup.js index 620d0cab9d45..f93926faa01d 100644 --- a/browser/components/extensions/test/browser/browser_ext_incognito_popup.js +++ b/browser/components/extensions/test/browser/browser_ext_incognito_popup.js @@ -106,3 +106,32 @@ add_task(async function testIncognitoPopup() { await extension.awaitFinish("incognito"); await extension.unload(); }); + +add_task(async function test_pageAction_incognito_not_allowed() { + const URL = "http://example.com/"; + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + "permissions": ["*://example.com/*"], + "page_action": { + "show_matches": [""], + "pinned": true, + }, + }, + incognitoOverride: "not_allowed", + }); + + await extension.startup(); + let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, URL, true, true); + let privateWindow = await BrowserTestUtils.openNewBrowserWindow({private: true}); + await BrowserTestUtils.openNewForegroundTab(privateWindow.gBrowser, URL, true, true); + + let elem = await getPageActionButton(extension, window); + ok(elem, "pageAction button state correct in non-PB"); + + elem = await getPageActionButton(extension, privateWindow); + ok(!elem, "pageAction button state correct in private window"); + + BrowserTestUtils.removeTab(tab); + await BrowserTestUtils.closeWindow(privateWindow); + await extension.unload(); +}); diff --git a/browser/modules/PageActions.jsm b/browser/modules/PageActions.jsm index af682725f0e4..5830aa984893 100644 --- a/browser/modules/PageActions.jsm +++ b/browser/modules/PageActions.jsm @@ -21,7 +21,8 @@ ChromeUtils.defineModuleGetter(this, "AsyncShutdown", "resource://gre/modules/AsyncShutdown.jsm"); ChromeUtils.defineModuleGetter(this, "BinarySearch", "resource://gre/modules/BinarySearch.jsm"); - +ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils", + "resource://gre/modules/PrivateBrowsingUtils.jsm"); const ACTION_ID_BOOKMARK = "bookmark"; const ACTION_ID_BOOKMARK_SEPARATOR = "bookmarkSeparator"; @@ -523,6 +524,8 @@ var PageActions = { * clicked. * @param wantsSubview (bool, optional) * Pass true to make an action that shows a panel subview when clicked. + * @param disablePrivateBrowsing (bool, optional) + * Pass true to prevent the action from showing in a private browsing window. */ function Action(options) { setProperties(this, options, { @@ -550,6 +553,7 @@ function Action(options) { urlbarIDOverride: false, wantsIframe: false, wantsSubview: false, + disablePrivateBrowsing: false, // private @@ -618,6 +622,25 @@ Action.prototype = { return this._id; }, + get disablePrivateBrowsing() { + return !!this._disablePrivateBrowsing; + }, + + /** + * Verifies that the action can be shown in a private window. For + * extensions, verifies the extension has access to the window. + */ + canShowInWindow(browserWindow) { + if (this._extensionID) { + let policy = WebExtensionPolicy.getByID(this._extensionID); + if (!policy.canAccessWindow(browserWindow)) { + return false; + } + } + return !(this.disablePrivateBrowsing && + PrivateBrowsingUtils.isWindowPrivate(browserWindow)); + }, + /** * True if the action is pinned to the urlbar. The action is shown in the * urlbar if it's pinned and not disabled. (bool) @@ -1021,7 +1044,8 @@ Action.prototype = { * disabled. */ shouldShowInPanel(browserWindow) { - return !this.__transient || !this.getDisabled(browserWindow); + return (!this.__transient || !this.getDisabled(browserWindow)) && + this.canShowInWindow(browserWindow); }, /** @@ -1033,7 +1057,8 @@ Action.prototype = { * should be shown if it's both pinned and not disabled. */ shouldShowInUrlbar(browserWindow) { - return this.pinnedToUrlbar && !this.getDisabled(browserWindow); + return (this.pinnedToUrlbar && !this.getDisabled(browserWindow)) && + this.canShowInWindow(browserWindow); }, get _isBuiltIn() { diff --git a/browser/modules/test/browser/browser_PageActions.js b/browser/modules/test/browser/browser_PageActions.js index 8290e1e8b54e..879224101a69 100644 --- a/browser/modules/test/browser/browser_PageActions.js +++ b/browser/modules/test/browser/browser_PageActions.js @@ -1657,6 +1657,31 @@ add_task(async function transient() { otherAction.remove(); }); +add_task(async function action_disablePrivateBrowsing() { + let id = "testWidget"; + let action = PageActions.addAction(new PageActions.Action({ + id, + disablePrivateBrowsing: true, + title: "title", + disabled: false, + pinnedToUrlbar: true, + })); + // Open an actionable page so that the main page action button appears. + let url = "http://example.com/"; + let privateWindow = await BrowserTestUtils.openNewBrowserWindow({private: true}); + await BrowserTestUtils.openNewForegroundTab(privateWindow.gBrowser, url, true, true); + + Assert.ok(action.canShowInWindow(window), "should show in default window"); + Assert.ok(!action.canShowInWindow(privateWindow), "should not show in private browser"); + Assert.ok(action.shouldShowInUrlbar(window), "should show in default urlbar"); + Assert.ok(!action.shouldShowInUrlbar(privateWindow), "should not show in default urlbar"); + Assert.ok(action.shouldShowInPanel(window), "should show in default urlbar"); + Assert.ok(!action.shouldShowInPanel(privateWindow), "should not show in default urlbar"); + + action.remove(); + + privateWindow.close(); +}); function assertActivatedPageActionPanelHidden() { Assert.ok(!document.getElementById(BrowserPageActions._activatedActionPanelID));