Bug 1324255 make webextension panels focused when opened, r=Gijs,rpl

This commit is contained in:
Shane Caraveo 2018-02-15 09:52:54 -07:00
parent 36b417f2c2
commit 2f634add59
6 changed files with 97 additions and 14 deletions

View File

@ -78,6 +78,7 @@ class BasePopup {
});
this.viewNode.addEventListener(this.DESTROY_EVENT, this);
this.panel.addEventListener("popuppositioned", this, {once: true, capture: true});
this.browser = null;
this.browserLoaded = new Promise((resolve, reject) => {
@ -211,6 +212,18 @@ class BasePopup {
this.destroy();
}
break;
case "popuppositioned":
if (!this.destroyed) {
this.browserLoaded.then(() => {
if (this.destroyed) {
return;
}
this.browser.messageManager.sendAsyncMessage("Extension:GrabFocus", {});
}).catch(() => {
// If the panel closes too fast an exception is raised here and tests will fail.
});
}
break;
}
}
@ -438,6 +451,7 @@ class ViewPopup extends BasePopup {
this.viewNode.addEventListener(this.DESTROY_EVENT, this);
this.viewNode.setAttribute("closemenu", "none");
this.panel.addEventListener("popuppositioned", this, {once: true, capture: true});
if (this.extension.remote) {
this.panel.setAttribute("remote", "true");
}

View File

@ -116,6 +116,7 @@ skip-if = (os == 'win' && ccov) # Bug 1423667
[browser_ext_popup_api_injection.js]
[browser_ext_popup_background.js]
[browser_ext_popup_corners.js]
[browser_ext_popup_focus.js]
[browser_ext_popup_sendMessage.js]
[browser_ext_popup_shutdown.js]
[browser_ext_runtime_openOptionsPage.js]

View File

@ -104,11 +104,6 @@ add_task(async function() {
is((await extension.awaitMessage("result")), winId, `${name} is on top (check 3) [${kind}]`);
}
await focusWindow(win1);
await checkWindow("background", winId1, "win1");
await focusWindow(win2);
await checkWindow("background", winId2, "win2");
async function triggerPopup(win, callback) {
await clickBrowserAction(extension, win);
await awaitExtensionPanel(extension, win);
@ -120,13 +115,14 @@ add_task(async function() {
closeBrowserAction(extension, win);
}
// Set focus to some other window.
await focusWindow(window);
await focusWindow(win1);
await checkWindow("background", winId1, "win1");
await triggerPopup(win1, async function() {
await checkWindow("popup", winId1, "win1");
});
await focusWindow(win2);
await checkWindow("background", winId2, "win2");
await triggerPopup(win2, async function() {
await checkWindow("popup", winId2, "win2");
});

View File

@ -148,6 +148,8 @@ add_task(async function() {
await checkViewsWithFilter({tabId: tabId2}, 1);
async function triggerPopup(win, callback) {
// Window needs focus to open popups.
await focusWindow(win);
await clickBrowserAction(extension, win);
await awaitExtensionPanel(extension, win);
@ -158,12 +160,6 @@ add_task(async function() {
closeBrowserAction(extension, win);
}
// The popup occasionally closes prematurely if we open it immediately here.
// I'm not sure what causes it to close (it's something internal, and seems to
// be focus-related, but it's not caused by JS calling hidePopup), but even a
// short timeout seems to consistently fix it.
await new Promise(resolve => win1.setTimeout(resolve, 10));
await triggerPopup(win1, async function() {
await checkViews("background", 2, 1, 0);
await checkViews("popup", 2, 1, 1);

View File

@ -0,0 +1,71 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
const DUMMY_PAGE = "http://example.com/browser/browser/components/extensions/test/browser/file_dummy.html";
add_task(async function testPageActionFocus() {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"page_action": {
"default_popup": "popup.html",
"show_matches": ["<all_urls>"],
},
},
files: {
"popup.html": `<!DOCTYPE html><html><head><meta charset="utf-8">
<script src="popup.js"></script>
</head><body>
</body></html>
`,
"popup.js": function() {
window.addEventListener("focus", (event) => {
browser.test.assertEq(true, document.hasFocus(), "document should be focused");
browser.test.notifyPass("focused");
}, {once: true});
},
},
});
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, DUMMY_PAGE);
await extension.startup();
let finish = extension.awaitFinish("focused");
await clickPageAction(extension);
await finish;
await closePageAction(extension);
await BrowserTestUtils.removeTab(tab);
await extension.unload();
});
add_task(async function testBrowserActionFocus() {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"browser_action": {"default_popup": "popup.html"},
},
files: {
"popup.html": `<!DOCTYPE html><html><head><meta charset="utf-8">
<script src="popup.js"></script>
</head><body>
</body></html>
`,
"popup.js": function() {
window.addEventListener("focus", (event) => {
browser.test.assertEq(true, document.hasFocus(), "document should be focused");
browser.test.notifyPass("focused");
}, {once: true});
},
},
});
await extension.startup();
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, DUMMY_PAGE);
let finish = extension.awaitFinish("focused");
await clickBrowserAction(extension);
await finish;
await closeBrowserAction(extension);
await BrowserTestUtils.removeTab(tab);
await extension.unload();
});

View File

@ -114,6 +114,10 @@ const BrowserListener = {
this.unblockParser();
this.blockingPromise = null;
}
} else if (name === "Extension:GrabFocus") {
content.window.requestAnimationFrame(() => {
Services.focus.focusedWindow = content.window;
});
}
},
@ -304,6 +308,7 @@ const BrowserListener = {
addMessageListener("Extension:InitBrowser", BrowserListener);
addMessageListener("Extension:UnblockParser", BrowserListener);
addMessageListener("Extension:GrabFocus", BrowserListener);
var WebBrowserChrome = {
onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab) {