author | Kris Maglione <maglione.k@gmail.com> |
Sat, 07 Apr 2018 20:38:21 -0700 | |
changeset 412711 | 791f0155deb4500a2acbea31711ed1485df2b79f |
parent 412710 | 9cba61d601f190e32996c481c08461daa8833d1a |
child 412712 | bc2f1762365b6d43b1aeb2056ebe5384bb0522cf |
push id | 101989 |
push user | maglione.k@gmail.com |
push date | Wed, 11 Apr 2018 01:31:15 +0000 |
treeherder | mozilla-inbound@791f0155deb4 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | aswan |
bugs | 1382953 |
milestone | 61.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
browser/components/extensions/test/browser/browser_ext_user_events.js | file | annotate | diff | comparison | revisions | |
browser/modules/ExtensionsUI.jsm | file | annotate | diff | comparison | revisions |
--- a/browser/components/extensions/test/browser/browser_ext_user_events.js +++ b/browser/components/extensions/test/browser/browser_ext_user_events.js @@ -50,25 +50,78 @@ add_task(async function testSources() { browser.contextMenus.create({ id: "menu", title: "test user events", contexts: ["page"], }); browser.contextMenus.onClicked.addListener(() => request("webNavigation")); + browser.test.onMessage.addListener(msg => { + if (msg === "openOptionsPage") { + browser.runtime.openOptionsPage(); + } + }); + browser.test.sendMessage("actions-ready"); }, + files: { + "options.html": `<!DOCTYPE html> + <html lang="en"> + <head> + <meta charset="UTF-8"> + <script src="options.js"></script> + <script src="https://example.com/tests/SimpleTest/EventUtils.js"></script> + </head> + <body> + <a id="link" href="#">Link</a> + </body> + </html>`, + + "options.js"() { + addEventListener("load", async () => { + let link = document.getElementById("link"); + link.onclick = async event => { + event.preventDefault(); + + try { + let result = await browser.permissions.request({ + permissions: ["webRequest"], + }); + browser.test.sendMessage("request", {success: true, result}); + } catch (err) { + browser.test.sendMessage("request", {success: false, errmsg: err.message}); + } + }; + + // Make a few trips through the event loop to make sure the + // options browser is fully visible. This is a bit dodgy, but + // we don't really have a reliable way to detect this from the + // options page side, and synthetic click events won't work + // until it is. + for (let i = 0; i < 10; i++) { + await new Promise(resolve => setTimeout(resolve, 0)); + } + + synthesizeMouseAtCenter(link, {}); + }, {once: true}); + }, + }, + manifest: { browser_action: {default_title: "test"}, page_action: {default_title: "test"}, permissions: ["contextMenus"], - optional_permissions: ["bookmarks", "tabs", "webNavigation"], + optional_permissions: ["bookmarks", "tabs", "webNavigation", "webRequest"], + options_ui: {page: "options.html"}, + content_security_policy: "script-src 'self' https://example.com; object-src 'none';", }, + + useAddonManager: "temporary", }); async function check(what) { let result = await extension.awaitMessage("request"); ok(result.success, `request() did not throw when called from ${what}`); is(result.result, true, `request() succeeded when called from ${what}`); } @@ -100,15 +153,23 @@ add_task(async function testSources() { gBrowser.selectedTab = tab; let menu = await openContextMenu("body"); let items = menu.getElementsByAttribute("label", "test user events"); is(items.length, 1, "Found context menu item"); EventUtils.synthesizeMouseAtCenter(items[0], {}); await check("context menu click"); - BrowserTestUtils.removeTab(tab); + extension.sendMessage("openOptionsPage"); + promisePopupNotificationShown("addon-webext-permissions").then(panel => { + panel.button.click(); + }); + await check("options page link click"); + + await BrowserTestUtils.removeTab(gBrowser.selectedTab); + await BrowserTestUtils.removeTab(tab); await extension.unload(); registerCleanupFunction(() => CustomizableUI.reset()); }); +
--- a/browser/modules/ExtensionsUI.jsm +++ b/browser/modules/ExtensionsUI.jsm @@ -26,16 +26,23 @@ XPCOMUtils.defineLazyPreferenceGetter(th const DEFAULT_EXTENSION_ICON = "chrome://mozapps/skin/extensions/extensionGeneric.svg"; const BROWSER_PROPERTIES = "chrome://browser/locale/browser.properties"; const BRAND_PROPERTIES = "chrome://branding/locale/brand.properties"; const HTML_NS = "http://www.w3.org/1999/xhtml"; +function getTabBrowser(browser) { + while (browser.ownerDocument.docShell.itemType !== Ci.nsIDocShell.typeChrome) { + browser = browser.ownerDocument.docShell.chromeEventHandler; + } + return {browser, window: browser.ownerGlobal}; +} + var ExtensionsUI = { sideloaded: new Set(), updates: new Set(), sideloadListener: null, histogram: null, pendingNotifications: new WeakMap(), @@ -161,19 +168,17 @@ var ExtensionsUI = { AppMenuNotifications.showBadgeOnlyNotification("addon-alert"); } this.emit("change"); }, showAddonsManager(browser, strings, icon, histkey) { let global = browser.selectedBrowser.ownerGlobal; return global.BrowserOpenAddonsMgr("addons://list/extension").then(aomWin => { - let aomBrowser = aomWin.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDocShell) - .chromeEventHandler; + let aomBrowser = aomWin.document.docShell.chromeEventHandler; return this.showPermissionsPrompt(aomBrowser, strings, icon, histkey); }); }, showSideloaded(browser, addon) { addon.markAsSeen(); this.sideloaded.delete(addon); this._updateNotifications(); @@ -203,20 +208,22 @@ var ExtensionsUI = { this._updateNotifications(); }); }, observe(subject, topic, data) { if (topic == "webextension-permission-prompt") { let {target, info} = subject.wrappedJSObject; + let {browser, window} = getTabBrowser(target); + // Dismiss the progress notification. Note that this is bad if // there are multiple simultaneous installs happening, see // bug 1329884 for a longer explanation. - let progressNotification = target.ownerGlobal.PopupNotifications.getNotification("addon-progress", target); + let progressNotification = window.PopupNotifications.getNotification("addon-progress", browser); if (progressNotification) { progressNotification.remove(); } info.unsigned = info.addon.signedState <= AddonManager.SIGNEDSTATE_MISSING; if (info.unsigned && Cu.isInAutomation && Services.prefs.getBoolPref("extensions.ui.ignoreUnsigned", false)) { info.unsigned = false; @@ -240,17 +247,17 @@ var ExtensionsUI = { } else if (info.source == "AMO") { histkey = "installAmo"; } else if (info.source == "local") { histkey = "installLocal"; } else { histkey = "installWeb"; } - this.showPermissionsPrompt(target, strings, icon, histkey) + this.showPermissionsPrompt(browser, strings, icon, histkey) .then(answer => { if (answer) { info.resolve(); } else { info.reject(); } }); } else if (topic == "webextension-update-permissions") { @@ -318,23 +325,23 @@ var ExtensionsUI = { let appName = brandBundle.GetStringFromName("brandShortName"); let info2 = Object.assign({appName}, info); let strings = ExtensionData.formatPermissionStrings(info2, bundle); strings.addonName = info.addon.name; return strings; }, - async showPermissionsPrompt(browser, strings, icon, histkey) { - let win = browser.ownerGlobal; + async showPermissionsPrompt(target, strings, icon, histkey) { + let {browser, window} = getTabBrowser(target); // Wait for any pending prompts in this window to complete before // showing the next one. let pending; - while ((pending = this.pendingNotifications.get(win))) { + while ((pending = this.pendingNotifications.get(window))) { await pending; } let promise = new Promise(resolve => { function eventCallback(topic) { let doc = this.browser.ownerDocument; if (topic == "showing") { let textEl = doc.getElementById("addon-webext-perm-text"); @@ -392,27 +399,27 @@ var ExtensionsUI = { if (histkey) { this.histogram.add(histkey + "Rejected"); } resolve(false); }, }, ]; - win.PopupNotifications.show(browser, "addon-webext-permissions", strings.header, - "addons-notification-icon", action, - secondaryActions, popupOptions); + window.PopupNotifications.show(browser, "addon-webext-permissions", strings.header, + "addons-notification-icon", action, + secondaryActions, popupOptions); }); - this.pendingNotifications.set(win, promise); - promise.finally(() => this.pendingNotifications.delete(win)); + this.pendingNotifications.set(window, promise); + promise.finally(() => this.pendingNotifications.delete(window)); return promise; }, - showDefaultSearchPrompt(browser, strings, icon) { + showDefaultSearchPrompt(target, strings, icon) { return new Promise(resolve => { let popupOptions = { hideClose: true, popupIconURL: icon || DEFAULT_EXTENSION_ICON, persistent: false, removeOnDismissal: true, eventCallback(topic) { if (topic == "removed") { @@ -435,30 +442,30 @@ var ExtensionsUI = { label: strings.cancelText, accessKey: strings.cancelKey, callback: () => { resolve(false); }, }, ]; - let win = browser.ownerGlobal; - win.PopupNotifications.show(browser, "addon-webext-defaultsearch", strings.text, - "addons-notification-icon", action, - secondaryActions, popupOptions); + let {browser, window} = getTabBrowser(target); + window.PopupNotifications.show(browser, "addon-webext-defaultsearch", strings.text, + "addons-notification-icon", action, + secondaryActions, popupOptions); }); }, showInstallNotification(target, addon) { - let win = target.ownerGlobal; - let popups = win.PopupNotifications; + let {browser, window} = getTabBrowser(target); + let popups = window.PopupNotifications; - let brandBundle = win.document.getElementById("bundle_brand"); + let brandBundle = window.document.getElementById("bundle_brand"); let appName = brandBundle.getString("brandShortName"); - let bundle = win.gNavigatorBundle; + let bundle = window.gNavigatorBundle; let message = bundle.getFormattedString("addonPostInstall.message1", ["<>", appName]); return new Promise(resolve => { let action = { label: bundle.getString("addonPostInstall.okay.label"), accessKey: bundle.getString("addonPostInstall.okay.key"), callback: resolve, @@ -474,15 +481,15 @@ var ExtensionsUI = { eventCallback(topic) { if (topic == "dismissed") { resolve(); } }, name: addon.name, }; - popups.show(target, "addon-installed", message, "addons-notification-icon", + popups.show(browser, "addon-installed", message, "addons-notification-icon", action, null, options); }); }, }; EventEmitter.decorate(ExtensionsUI);