зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 100bc29bbb72 (bug 1625593) for Browser-chrome failures in gfx/layers/apz/test/mochitest/browser_test_scrollbar_in_extension_popup_window.js. CLOSED TREE
This commit is contained in:
Родитель
85e20aac7c
Коммит
9d50e72c4a
|
@ -105,10 +105,6 @@ class BrowserAction extends BrowserActionBase {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
dispatchClick(tab, clickInfo) {
|
||||
this.buttonDelegate.emit("click", tab, clickInfo);
|
||||
}
|
||||
}
|
||||
|
||||
this.browserAction = class extends ExtensionAPI {
|
||||
|
@ -266,8 +262,12 @@ this.browserAction = class extends ExtensionAPI {
|
|||
let tabbrowser = document.defaultView.gBrowser;
|
||||
|
||||
let tab = tabbrowser.selectedTab;
|
||||
let popupURL = this.action.triggerClickOrPopup(tab, this.lastClickInfo);
|
||||
let popupURL = this.action.getProperty(tab, "popup");
|
||||
this.tabManager.addActiveTabPermission(tab);
|
||||
|
||||
// Popups are shown only if a popup URL is defined; otherwise
|
||||
// a "click" event is dispatched. This is done for compatibility with the
|
||||
// Google Chrome onClicked extension API.
|
||||
if (popupURL) {
|
||||
try {
|
||||
let popup = this.getPopup(document.defaultView, popupURL);
|
||||
|
@ -301,6 +301,7 @@ this.browserAction = class extends ExtensionAPI {
|
|||
// This isn't not a hack, but it seems to provide the correct behavior
|
||||
// with the fewest complications.
|
||||
event.preventDefault();
|
||||
this.emit("click", tabbrowser.selectedBrowser);
|
||||
// Ensure we close any popups this node was in:
|
||||
CustomizableUI.hidePanelForNode(event.target);
|
||||
}
|
||||
|
@ -342,15 +343,14 @@ this.browserAction = class extends ExtensionAPI {
|
|||
let widget = this.widget.forWindow(window);
|
||||
let tab = window.gBrowser.selectedTab;
|
||||
|
||||
if (!widget.node) {
|
||||
if (!widget.node || !this.action.getProperty(tab, "enabled")) {
|
||||
return;
|
||||
}
|
||||
|
||||
let popupUrl = this.action.triggerClickOrPopup(tab, {
|
||||
button: 0,
|
||||
modifiers: [],
|
||||
});
|
||||
if (popupUrl) {
|
||||
// Popups are shown only if a popup URL is defined; otherwise
|
||||
// a "click" event is dispatched. This is done for compatibility with the
|
||||
// Google Chrome onClicked extension API.
|
||||
if (this.action.getProperty(tab, "popup")) {
|
||||
if (this.widget.areaType == CustomizableUI.TYPE_MENU_PANEL) {
|
||||
await window.document.getElementById("nav-bar").overflowable.show();
|
||||
}
|
||||
|
@ -360,6 +360,10 @@ this.browserAction = class extends ExtensionAPI {
|
|||
cancelable: true,
|
||||
});
|
||||
widget.node.dispatchEvent(event);
|
||||
} else {
|
||||
this.tabManager.addActiveTabPermission(tab);
|
||||
this.lastClickInfo = { button: 0, modifiers: [] };
|
||||
this.emit("click");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -370,18 +374,25 @@ this.browserAction = class extends ExtensionAPI {
|
|||
switch (event.type) {
|
||||
case "mousedown":
|
||||
if (event.button == 0) {
|
||||
let tab = window.gBrowser.selectedTab;
|
||||
|
||||
// Begin pre-loading the browser for the popup, so it's more likely to
|
||||
// be ready by the time we get a complete click.
|
||||
let popupURL = this.action.getPopupUrl(tab);
|
||||
let tab = window.gBrowser.selectedTab;
|
||||
let popupURL = this.action.getProperty(tab, "popup");
|
||||
let enabled = this.action.getProperty(tab, "enabled");
|
||||
|
||||
if (
|
||||
popupURL &&
|
||||
enabled &&
|
||||
(this.pendingPopup || !ViewPopup.for(this.extension, window))
|
||||
) {
|
||||
// Add permission for the active tab so it will exist for the popup.
|
||||
this.action.setActiveTabForPreload(tab);
|
||||
this.eventQueue.push("Mousedown");
|
||||
// Add permission for the active tab so it will exist for the popup.
|
||||
// Store the tab to revoke the permission during clearPopup.
|
||||
if (!this.tabManager.hasActiveTabPermission(tab)) {
|
||||
this.tabManager.addActiveTabPermission(tab);
|
||||
this.tabToRevokeDuringClearPopup = tab;
|
||||
}
|
||||
|
||||
this.pendingPopup = this.getPopup(window, popupURL);
|
||||
window.addEventListener("mouseup", this, true);
|
||||
} else {
|
||||
|
@ -413,10 +424,12 @@ this.browserAction = class extends ExtensionAPI {
|
|||
// Begin pre-loading the browser for the popup, so it's more likely to
|
||||
// be ready by the time we get a complete click.
|
||||
let tab = window.gBrowser.selectedTab;
|
||||
let popupURL = this.action.getPopupUrl(tab);
|
||||
let popupURL = this.action.getProperty(tab, "popup");
|
||||
let enabled = this.action.getProperty(tab, "enabled");
|
||||
|
||||
if (
|
||||
popupURL &&
|
||||
enabled &&
|
||||
(this.pendingPopup || !ViewPopup.for(this.extension, window))
|
||||
) {
|
||||
this.eventQueue.push("Hover");
|
||||
|
@ -463,10 +476,12 @@ this.browserAction = class extends ExtensionAPI {
|
|||
|
||||
let { gBrowser } = window;
|
||||
if (this.action.getProperty(gBrowser.selectedTab, "enabled")) {
|
||||
this.action.dispatchClick(gBrowser.selectedTab, {
|
||||
this.lastClickInfo = {
|
||||
button: 1,
|
||||
modifiers: clickModifiersFromEvent(event),
|
||||
});
|
||||
};
|
||||
|
||||
this.emit("click", gBrowser.selectedBrowser);
|
||||
// Ensure we close any popups this node was in:
|
||||
CustomizableUI.hidePanelForNode(event.target);
|
||||
}
|
||||
|
@ -527,11 +542,16 @@ this.browserAction = class extends ExtensionAPI {
|
|||
*/
|
||||
clearPopup() {
|
||||
this.clearPopupTimeout();
|
||||
this.action.setActiveTabForPreload(null);
|
||||
if (this.pendingPopup) {
|
||||
if (this.tabToRevokeDuringClearPopup) {
|
||||
this.tabManager.revokeActiveTabPermission(
|
||||
this.tabToRevokeDuringClearPopup
|
||||
);
|
||||
}
|
||||
this.pendingPopup.destroy();
|
||||
this.pendingPopup = null;
|
||||
}
|
||||
this.tabToRevokeDuringClearPopup = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -642,9 +662,12 @@ this.browserAction = class extends ExtensionAPI {
|
|||
name: "browserAction.onClicked",
|
||||
inputHandling: true,
|
||||
register: fire => {
|
||||
let listener = (event, tab, clickInfo) => {
|
||||
context.withPendingBrowser(tab.linkedBrowser, () =>
|
||||
fire.sync(tabManager.convert(tab), clickInfo)
|
||||
let listener = (event, browser) => {
|
||||
context.withPendingBrowser(browser, () =>
|
||||
fire.sync(
|
||||
tabManager.convert(tabTracker.activeTab),
|
||||
this.lastClickInfo
|
||||
)
|
||||
);
|
||||
};
|
||||
this.on("click", listener);
|
||||
|
|
|
@ -50,10 +50,6 @@ class PageAction extends PageActionBase {
|
|||
this.buttonDelegate.updateButton(target.ownerGlobal);
|
||||
}
|
||||
|
||||
dispatchClick(tab, clickInfo) {
|
||||
this.buttonDelegate.emit("click", tab, clickInfo);
|
||||
}
|
||||
|
||||
getTab(tabId) {
|
||||
if (tabId !== null) {
|
||||
return tabTracker.getTab(tabId);
|
||||
|
@ -112,16 +108,18 @@ this.pageAction = class extends ExtensionAPI {
|
|||
return;
|
||||
}
|
||||
|
||||
this.lastClickInfo = {
|
||||
button: event.button,
|
||||
modifiers: clickModifiersFromEvent(event),
|
||||
};
|
||||
|
||||
// The panel is not automatically closed when middle-clicked.
|
||||
if (isPanel) {
|
||||
buttonNode.closest("#pageActionPanel").hidePopup();
|
||||
}
|
||||
let window = event.target.ownerGlobal;
|
||||
let tab = window.gBrowser.selectedTab;
|
||||
this.action.dispatchClick(tab, {
|
||||
button: event.button,
|
||||
modifiers: clickModifiersFromEvent(event),
|
||||
});
|
||||
this.emit("click", tab);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -134,10 +132,11 @@ this.pageAction = class extends ExtensionAPI {
|
|||
pinnedToUrlbar: this.action.getPinned(),
|
||||
disabled: !this.action.getProperty(null, "enabled"),
|
||||
onCommand: (event, buttonNode) => {
|
||||
this.handleClick(event.target.ownerGlobal, {
|
||||
this.lastClickInfo = {
|
||||
button: event.button || 0,
|
||||
modifiers: clickModifiersFromEvent(event),
|
||||
});
|
||||
};
|
||||
this.handleClick(event.target.ownerGlobal);
|
||||
},
|
||||
onBeforePlacedInWindow: browserWindow => {
|
||||
if (
|
||||
|
@ -244,7 +243,10 @@ this.pageAction = class extends ExtensionAPI {
|
|||
* @param {Window} window
|
||||
*/
|
||||
triggerAction(window) {
|
||||
this.handleClick(window, { button: 0, modifiers: [] });
|
||||
if (this.action.isShownForTab(window.gBrowser.selectedTab)) {
|
||||
this.lastClickInfo = { button: 0, modifiers: [] };
|
||||
this.handleClick(window);
|
||||
}
|
||||
}
|
||||
|
||||
handleEvent(event) {
|
||||
|
@ -274,12 +276,14 @@ this.pageAction = class extends ExtensionAPI {
|
|||
// If the page action has a |popup| property, a panel is opened to
|
||||
// that URL. Otherwise, a "click" event is emitted, and dispatched to
|
||||
// the any click listeners in the add-on.
|
||||
async handleClick(window, clickInfo) {
|
||||
async handleClick(window) {
|
||||
const { extension } = this;
|
||||
|
||||
ExtensionTelemetry.pageActionPopupOpen.stopwatchStart(extension, this);
|
||||
let tab = window.gBrowser.selectedTab;
|
||||
let popupURL = this.action.triggerClickOrPopup(tab, clickInfo);
|
||||
let popupURL = this.action.getProperty(tab, "popup");
|
||||
|
||||
this.tabManager.addActiveTabPermission(tab);
|
||||
|
||||
// If the widget has a popup URL defined, we open a popup, but do not
|
||||
// dispatch a click event to the extension.
|
||||
|
@ -318,6 +322,7 @@ this.pageAction = class extends ExtensionAPI {
|
|||
ExtensionTelemetry.pageActionPopupOpen.stopwatchFinish(extension, this);
|
||||
} else {
|
||||
ExtensionTelemetry.pageActionPopupOpen.stopwatchCancel(extension, this);
|
||||
this.emit("click", tab);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -335,9 +340,9 @@ this.pageAction = class extends ExtensionAPI {
|
|||
name: "pageAction.onClicked",
|
||||
inputHandling: true,
|
||||
register: fire => {
|
||||
let listener = (evt, tab, clickInfo) => {
|
||||
let listener = (evt, tab) => {
|
||||
context.withPendingBrowser(tab.linkedBrowser, () =>
|
||||
fire.sync(tabManager.convert(tab), clickInfo)
|
||||
fire.sync(tabManager.convert(tab), this.lastClickInfo)
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ add_task(async function testBrowserActionClickCanceled() {
|
|||
|
||||
is(browserAction.pendingPopupTimeout, null, "Have no pending popup timeout");
|
||||
|
||||
is(browserAction.action.activeTabForPreload, tab, "Tab to revoke was saved");
|
||||
is(browserAction.tabToRevokeDuringClearPopup, tab, "Tab to revoke was saved");
|
||||
is(
|
||||
browserAction.tabManager.hasActiveTabPermission(tab),
|
||||
true,
|
||||
|
@ -80,7 +80,7 @@ add_task(async function testBrowserActionClickCanceled() {
|
|||
is(browserAction.pendingPopupTimeout, null, "Have no pending popup timeout");
|
||||
|
||||
is(
|
||||
browserAction.action.activeTabForPreload,
|
||||
browserAction.tabToRevokeDuringClearPopup,
|
||||
null,
|
||||
"Tab to revoke was removed"
|
||||
);
|
||||
|
|
|
@ -69,6 +69,21 @@ add_task(async function testGoodPermissions() {
|
|||
true
|
||||
);
|
||||
|
||||
info("Test explicit host permission");
|
||||
await testHasPermission({
|
||||
manifest: { permissions: ["http://mochi.test/"] },
|
||||
});
|
||||
|
||||
info("Test explicit host subdomain permission");
|
||||
await testHasPermission({
|
||||
manifest: { permissions: ["http://*.mochi.test/"] },
|
||||
});
|
||||
|
||||
info("Test explicit <all_urls> permission");
|
||||
await testHasPermission({
|
||||
manifest: { permissions: ["<all_urls>"] },
|
||||
});
|
||||
|
||||
info("Test activeTab permission with a command key press");
|
||||
await testHasPermission({
|
||||
manifest: {
|
||||
|
@ -149,6 +164,69 @@ add_task(async function testGoodPermissions() {
|
|||
},
|
||||
});
|
||||
|
||||
info("Test activeTab permission with a browser action click");
|
||||
await testHasPermission({
|
||||
manifest: {
|
||||
permissions: ["activeTab"],
|
||||
browser_action: {},
|
||||
},
|
||||
contentSetup: function() {
|
||||
browser.browserAction.onClicked.addListener(() => {
|
||||
browser.test.log("Clicked.");
|
||||
});
|
||||
return Promise.resolve();
|
||||
},
|
||||
setup: clickBrowserAction,
|
||||
tearDown: closeBrowserAction,
|
||||
});
|
||||
|
||||
info("Test activeTab permission with a page action click");
|
||||
await testHasPermission({
|
||||
manifest: {
|
||||
permissions: ["activeTab"],
|
||||
page_action: {},
|
||||
},
|
||||
contentSetup: async () => {
|
||||
let [tab] = await browser.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true,
|
||||
});
|
||||
await browser.pageAction.show(tab.id);
|
||||
},
|
||||
setup: clickPageAction,
|
||||
tearDown: closePageAction,
|
||||
});
|
||||
|
||||
info("Test activeTab permission with a browser action w/popup click");
|
||||
await testHasPermission({
|
||||
manifest: {
|
||||
permissions: ["activeTab"],
|
||||
browser_action: { default_popup: "panel.html" },
|
||||
},
|
||||
setup: async extension => {
|
||||
await clickBrowserAction(extension);
|
||||
return awaitExtensionPanel(extension, window, "panel.html");
|
||||
},
|
||||
tearDown: closeBrowserAction,
|
||||
});
|
||||
|
||||
info("Test activeTab permission with a page action w/popup click");
|
||||
await testHasPermission({
|
||||
manifest: {
|
||||
permissions: ["activeTab"],
|
||||
page_action: { default_popup: "panel.html" },
|
||||
},
|
||||
contentSetup: async () => {
|
||||
let [tab] = await browser.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true,
|
||||
});
|
||||
await browser.pageAction.show(tab.id);
|
||||
},
|
||||
setup: clickPageAction,
|
||||
tearDown: closePageAction,
|
||||
});
|
||||
|
||||
info("Test activeTab permission with a context menu click");
|
||||
await testHasPermission({
|
||||
manifest: {
|
||||
|
|
|
@ -52,20 +52,14 @@ class BrowserAction extends BrowserActionBase {
|
|||
|
||||
openPopup() {
|
||||
const tab = tabTracker.activeTab;
|
||||
const popupUri = this.triggerClickOrPopup(tab);
|
||||
const actionObject = this.getContextData(tab);
|
||||
const action = this.helper.extractProperties(actionObject);
|
||||
this.helper.sendRequest(tab.id, {
|
||||
action,
|
||||
type: "GeckoView:BrowserAction:OpenPopup",
|
||||
popupUri,
|
||||
});
|
||||
}
|
||||
|
||||
triggerClickOrPopup(tab = tabTracker.activeTab) {
|
||||
return super.triggerClickOrPopup(tab);
|
||||
}
|
||||
|
||||
getTab(tabId) {
|
||||
return this.helper.getTab(tabId);
|
||||
}
|
||||
|
@ -74,7 +68,7 @@ class BrowserAction extends BrowserActionBase {
|
|||
return this.helper.getWindow(windowId);
|
||||
}
|
||||
|
||||
dispatchClick() {
|
||||
click() {
|
||||
this.clickDelegate.onClick();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,26 +51,19 @@ class PageAction extends PageActionBase {
|
|||
}
|
||||
|
||||
openPopup() {
|
||||
const tab = tabTracker.activeTab;
|
||||
const popupUri = this.triggerClickOrPopup(tab);
|
||||
const actionObject = this.getContextData(tab);
|
||||
const actionObject = this.getContextData(tabTracker.activeTab);
|
||||
const action = this.helper.extractProperties(actionObject);
|
||||
this.helper.sendRequest(tab.id, {
|
||||
this.helper.sendRequest(tabTracker.activeTab.id, {
|
||||
action,
|
||||
type: "GeckoView:PageAction:OpenPopup",
|
||||
popupUri,
|
||||
});
|
||||
}
|
||||
|
||||
triggerClickOrPopup(tab = tabTracker.activeTab) {
|
||||
return super.triggerClickOrPopup(tab);
|
||||
}
|
||||
|
||||
getTab(tabId) {
|
||||
return this.helper.getTab(tabId);
|
||||
}
|
||||
|
||||
dispatchClick() {
|
||||
click() {
|
||||
this.clickDelegate.onClick();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ skip-if = !is_fennec # times out; bug 1534640 webextension url
|
|||
[test_ext_tabs_events.html]
|
||||
[test_ext_tabs_executeScript.html]
|
||||
[test_ext_tabs_executeScript_bad.html]
|
||||
[test_ext_tabs_executeScript_good.html]
|
||||
[test_ext_tabs_executeScript_no_create.html]
|
||||
[test_ext_tabs_executeScript_runAt.html]
|
||||
[test_ext_tabs_get.html]
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Tabs executeScript Good Test</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
|
||||
<script type="text/javascript" src="head.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
async function testHasPermission(params) {
|
||||
const contentSetup = params.contentSetup || (() => Promise.resolve());
|
||||
|
||||
async function background(contentSetup) {
|
||||
browser.runtime.onMessage.addListener((msg, sender) => {
|
||||
browser.test.assertEq(msg, "script ran", "script ran");
|
||||
browser.test.notifyPass("executeScript");
|
||||
});
|
||||
|
||||
browser.test.onMessage.addListener(msg => {
|
||||
browser.test.assertEq(msg, "execute-script");
|
||||
|
||||
browser.tabs.executeScript({
|
||||
file: "script.js",
|
||||
});
|
||||
});
|
||||
|
||||
await contentSetup();
|
||||
|
||||
browser.test.sendMessage("ready");
|
||||
}
|
||||
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: params.manifest,
|
||||
|
||||
background: `(${background})(${contentSetup})`,
|
||||
|
||||
files: {
|
||||
"script.js": function() {
|
||||
browser.runtime.sendMessage("script ran");
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
await extension.awaitMessage("ready");
|
||||
|
||||
if (params.setup) {
|
||||
await params.setup(extension);
|
||||
}
|
||||
|
||||
extension.sendMessage("execute-script");
|
||||
|
||||
await extension.awaitFinish("executeScript");
|
||||
|
||||
if (params.tearDown) {
|
||||
await params.tearDown(extension);
|
||||
}
|
||||
|
||||
await extension.unload();
|
||||
}
|
||||
|
||||
add_task(async function testGoodPermissions() {
|
||||
const win = window.open("http://mochi.test:8888/");
|
||||
|
||||
info("Test explicit host permission");
|
||||
await testHasPermission({
|
||||
manifest: {"permissions": ["http://mochi.test/"]},
|
||||
});
|
||||
|
||||
info("Test explicit host subdomain permission");
|
||||
await testHasPermission({
|
||||
manifest: {"permissions": ["http://*.mochi.test/"]},
|
||||
});
|
||||
|
||||
info("Test explicit <all_urls> permission");
|
||||
await testHasPermission({
|
||||
manifest: {"permissions": ["<all_urls>"]},
|
||||
});
|
||||
|
||||
win.close();
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1271,6 +1271,17 @@ public class WebExtension {
|
|||
* browserAction/setIcon</a>
|
||||
*/
|
||||
final public @Nullable Image icon;
|
||||
/**
|
||||
* URI of the Popup to display when the user taps on the icon for this
|
||||
* Action.
|
||||
*
|
||||
* See also:
|
||||
* <a target=_blank href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pageAction/getPopup">
|
||||
* pageAction/getPopup</a>,
|
||||
* <a target=_blank href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/getPopup">
|
||||
* browserAction/getPopup</a>
|
||||
*/
|
||||
final private @Nullable String mPopupUri;
|
||||
/**
|
||||
* Whether this action is enabled and should be visible.
|
||||
*
|
||||
|
@ -1331,6 +1342,7 @@ public class WebExtension {
|
|||
/* package */ Action(final @ActionType int type,
|
||||
final GeckoBundle bundle, final WebExtension extension) {
|
||||
mExtension = extension;
|
||||
mPopupUri = bundle.getString("popup");
|
||||
|
||||
this.type = type;
|
||||
|
||||
|
@ -1370,6 +1382,7 @@ public class WebExtension {
|
|||
return "Action {\n"
|
||||
+ "\ttitle: " + this.title + ",\n"
|
||||
+ "\ticon: " + this.icon + ",\n"
|
||||
+ "\tpopupUri: " + this.mPopupUri + ",\n"
|
||||
+ "\tenabled: " + this.enabled + ",\n"
|
||||
+ "\tbadgeText: " + this.badgeText + ",\n"
|
||||
+ "\tbadgeTextColor: " + this.badgeTextColor + ",\n"
|
||||
|
@ -1381,6 +1394,7 @@ public class WebExtension {
|
|||
protected Action() {
|
||||
type = TYPE_BROWSER_ACTION;
|
||||
mExtension = null;
|
||||
mPopupUri = null;
|
||||
title = null;
|
||||
icon = null;
|
||||
enabled = null;
|
||||
|
@ -1420,6 +1434,7 @@ public class WebExtension {
|
|||
|
||||
title = source.title != null ? source.title : defaultValue.title;
|
||||
icon = source.icon != null ? source.icon : defaultValue.icon;
|
||||
mPopupUri = source.mPopupUri != null ? source.mPopupUri : defaultValue.mPopupUri;
|
||||
enabled = source.enabled != null ? source.enabled : defaultValue.enabled;
|
||||
badgeText = source.badgeText != null ? source.badgeText : defaultValue.badgeText;
|
||||
badgeTextColor = source.badgeTextColor != null
|
||||
|
@ -1433,39 +1448,34 @@ public class WebExtension {
|
|||
*/
|
||||
@UiThread
|
||||
public void click() {
|
||||
final GeckoBundle bundle = new GeckoBundle(1);
|
||||
bundle.putString("extensionId", mExtension.id);
|
||||
|
||||
// The click event will return the popup uri if we should open a popup in
|
||||
// response to clicking on the action button.
|
||||
final GeckoResult<String> popupUri;
|
||||
if (type == TYPE_BROWSER_ACTION) {
|
||||
popupUri = EventDispatcher.getInstance()
|
||||
.queryString("GeckoView:BrowserAction:Click", bundle);
|
||||
} else if (type == TYPE_PAGE_ACTION) {
|
||||
popupUri = EventDispatcher.getInstance()
|
||||
.queryString("GeckoView:PageAction:Click", bundle);
|
||||
} else {
|
||||
throw new IllegalStateException("Unknown Action type");
|
||||
}
|
||||
|
||||
popupUri.accept(uri -> {
|
||||
if (uri == null || uri.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mPopupUri != null && !mPopupUri.isEmpty()) {
|
||||
final ActionDelegate delegate = mExtension.mDelegateController.getActionDelegate();
|
||||
if (delegate == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
GeckoResult<GeckoSession> popup = delegate.onTogglePopup(mExtension, this);
|
||||
openPopup(popup, uri);
|
||||
});
|
||||
openPopup(popup);
|
||||
|
||||
// When popupUri is specified, the extension doesn't get a callback
|
||||
return;
|
||||
}
|
||||
|
||||
final GeckoBundle bundle = new GeckoBundle(1);
|
||||
bundle.putString("extensionId", mExtension.id);
|
||||
|
||||
if (type == TYPE_BROWSER_ACTION) {
|
||||
EventDispatcher.getInstance().dispatch(
|
||||
"GeckoView:BrowserAction:Click", bundle);
|
||||
} else if (type == TYPE_PAGE_ACTION) {
|
||||
EventDispatcher.getInstance().dispatch(
|
||||
"GeckoView:PageAction:Click", bundle);
|
||||
} else {
|
||||
throw new IllegalStateException("Unknown Action type");
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ void openPopup(final GeckoResult<GeckoSession> popup,
|
||||
final String popupUri) {
|
||||
/* package */ void openPopup(final GeckoResult<GeckoSession> popup) {
|
||||
if (popup == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -1476,7 +1486,7 @@ public class WebExtension {
|
|||
}
|
||||
|
||||
session.getSettings().setIsPopup(true);
|
||||
session.loadUri(popupUri);
|
||||
session.loadUri(mPopupUri);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1227,7 +1227,6 @@ public class WebExtensionController {
|
|||
|
||||
final WebExtension.Action action = new WebExtension.Action(
|
||||
actionType, message.bundle.getBundle("action"), extension);
|
||||
final String popupUri = message.bundle.getString("popupUri");
|
||||
|
||||
final WebExtension.ActionDelegate delegate = actionDelegateFor(extension, message.session);
|
||||
if (delegate == null) {
|
||||
|
@ -1235,7 +1234,7 @@ public class WebExtensionController {
|
|||
}
|
||||
|
||||
final GeckoResult<GeckoSession> popup = delegate.onOpenPopup(extension, action);
|
||||
action.openPopup(popup, popupUri);
|
||||
action.openPopup(popup);
|
||||
}
|
||||
|
||||
private WebExtension.ActionDelegate actionDelegateFor(final WebExtension extension,
|
||||
|
|
|
@ -665,29 +665,29 @@ var GeckoViewWebExtension = {
|
|||
async browserActionClick(aId) {
|
||||
const policy = WebExtensionPolicy.getByID(aId);
|
||||
if (!policy) {
|
||||
return undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
const browserAction = this.browserActions.get(policy.extension);
|
||||
if (!browserAction) {
|
||||
return undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
return browserAction.triggerClickOrPopup();
|
||||
browserAction.click();
|
||||
},
|
||||
|
||||
async pageActionClick(aId) {
|
||||
const policy = WebExtensionPolicy.getByID(aId);
|
||||
if (!policy) {
|
||||
return undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
const pageAction = this.pageActions.get(policy.extension);
|
||||
if (!pageAction) {
|
||||
return undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
return pageAction.triggerClickOrPopup();
|
||||
pageAction.click();
|
||||
},
|
||||
|
||||
async actionDelegateAttached(aId) {
|
||||
|
@ -802,13 +802,11 @@ var GeckoViewWebExtension = {
|
|||
|
||||
switch (aEvent) {
|
||||
case "GeckoView:BrowserAction:Click": {
|
||||
const popupUrl = await this.browserActionClick(aData.extensionId);
|
||||
aCallback.onSuccess(popupUrl);
|
||||
this.browserActionClick(aData.extensionId);
|
||||
break;
|
||||
}
|
||||
case "GeckoView:PageAction:Click": {
|
||||
const popupUrl = await this.pageActionClick(aData.extensionId);
|
||||
aCallback.onSuccess(popupUrl);
|
||||
this.pageActionClick(aData.extensionId);
|
||||
break;
|
||||
}
|
||||
case "GeckoView:WebExtension:MenuClick": {
|
||||
|
|
|
@ -48,11 +48,6 @@ class PanelActionBase {
|
|||
this.tabContext.on("tab-select", (evt, tab) => {
|
||||
this.updateOnChange(tab);
|
||||
});
|
||||
|
||||
// When preloading a popup we temporarily grant active tab permissions to
|
||||
// the preloaded popup. If we don't end up opening we need to clear this
|
||||
// permission when clearing the popup.
|
||||
this.activeTabForPreload = null;
|
||||
}
|
||||
|
||||
onShutdown() {
|
||||
|
@ -162,77 +157,6 @@ class PanelActionBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the popup url for a given tab.
|
||||
*
|
||||
* @param {XULElement} tab
|
||||
* The tab the popup refers to.
|
||||
* @returns {string}
|
||||
* The popup URL if a popup is present, undefined otherwise.
|
||||
*/
|
||||
getPopupUrl(tab) {
|
||||
if (!this.isShownForTab(tab)) {
|
||||
return undefined;
|
||||
}
|
||||
let popupUrl = this.getProperty(tab, "popup");
|
||||
return popupUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grants activeTab permission for a tab when preloading the popup.
|
||||
*
|
||||
* Will clear any existing activeTab permissions previously granted for any
|
||||
* other tab.
|
||||
*
|
||||
* @param {XULElement} tab
|
||||
* The tab that should be granted activeTab permission for. Set to
|
||||
* null to clear previously granted activeTab permission.
|
||||
*/
|
||||
setActiveTabForPreload(tab = null) {
|
||||
let oldTab = this.activeTabForPreload;
|
||||
if (oldTab === tab) {
|
||||
return;
|
||||
}
|
||||
this.activeTabForPreload = tab;
|
||||
if (tab) {
|
||||
this.extension.tabManager.addActiveTabPermission(tab);
|
||||
}
|
||||
if (oldTab) {
|
||||
this.extension.tabManager.revokeActiveTabPermission(oldTab);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers this action and sends the appropriate event if needed.
|
||||
*
|
||||
* @param {XULElement} tab
|
||||
* The tab on which the action was fired.
|
||||
* @param {object} clickInfo
|
||||
* Extra data passed to the second parameter to the action API's
|
||||
* onClicked event.
|
||||
* @returns {string}
|
||||
* the popup URL if a popup should be open, undefined otherwise.
|
||||
*/
|
||||
triggerClickOrPopup(tab, clickInfo = undefined) {
|
||||
if (!this.isShownForTab(tab)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Now that the action is actually being triggered we can clear any
|
||||
// existing preloaded activeTab permission.
|
||||
this.setActiveTabForPreload(null);
|
||||
this.extension.tabManager.addActiveTabPermission(tab);
|
||||
|
||||
let popupUrl = this.getProperty(tab, "popup");
|
||||
// The "click" event is only dispatched when the popup is not shown. This
|
||||
// is done for compatibility with the Google Chrome onClicked extension
|
||||
// API.
|
||||
if (!popupUrl) {
|
||||
this.dispatchClick(tab, clickInfo);
|
||||
}
|
||||
return popupUrl;
|
||||
}
|
||||
|
||||
api(context) {
|
||||
let { extension } = context;
|
||||
return {
|
||||
|
@ -312,28 +236,6 @@ class PanelActionBase {
|
|||
getTargetFromDetails({ tabId, windowId }) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers a click event.
|
||||
*
|
||||
* @param {XULElement} tab
|
||||
* The tab where this event should be fired.
|
||||
* @param {object} clickInfo
|
||||
* Extra data passed to the second parameter to the action API's
|
||||
* onClicked event.
|
||||
*/
|
||||
dispatchClick(tab, clickInfo) {}
|
||||
|
||||
/**
|
||||
* Checks whether this action is shown.
|
||||
*
|
||||
* @param {XULElement} tab
|
||||
* The tab to be checked
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isShownForTab(tab) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class PageActionBase extends PanelActionBase {
|
||||
|
@ -562,10 +464,6 @@ class BrowserActionBase extends PanelActionBase {
|
|||
return result;
|
||||
}
|
||||
|
||||
isShownForTab(tab) {
|
||||
return this.getProperty(tab, "enabled");
|
||||
}
|
||||
|
||||
api(context) {
|
||||
return {
|
||||
...super.api(context),
|
||||
|
|
|
@ -94,7 +94,7 @@ skip-if = headless # Bug 1405872
|
|||
[test_ext_contentscript_about_blank.html]
|
||||
skip-if = os == 'android' # bug 1369440
|
||||
[test_ext_contentscript_activeTab.html]
|
||||
skip-if = fission
|
||||
skip-if = os == 'android' || fission
|
||||
[test_ext_contentscript_cache.html]
|
||||
skip-if = (os == 'linux' && debug) || (toolkit == 'android' && debug) # bug 1348241
|
||||
fail-if = xorigin # TypeError: can't access property "staticScripts", ext is undefined - Should not throw any errors
|
||||
|
@ -161,7 +161,6 @@ skip-if =
|
|||
[test_ext_subframes_privileges.html]
|
||||
skip-if = os == 'android' || verify # bug 1489771
|
||||
[test_ext_tabs_captureTab.html]
|
||||
[test_ext_tabs_executeScript_good.html]
|
||||
[test_ext_tabs_query_popup.html]
|
||||
[test_ext_tabs_permissions.html]
|
||||
[test_ext_tabs_sendMessage.html]
|
||||
|
|
|
@ -46,9 +46,7 @@ function makeExtension(background) {
|
|||
}
|
||||
|
||||
return ExtensionTestUtils.loadExtension({
|
||||
useAddonManager: "permanent",
|
||||
manifest: {
|
||||
applications: { gecko: { id: `active-tab@tests.mozilla.org` } },
|
||||
permissions: ["activeTab", "webNavigation"],
|
||||
},
|
||||
background: `${awaitLoad}\n${gatherFrameSources}\n${ExtensionTestCommon.serializeScript(background)}`,
|
||||
|
|
|
@ -1,166 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Tabs executeScript Test</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
|
||||
<script type="text/javascript" src="head.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
async function testHasPermission(params) {
|
||||
let contentSetup = params.contentSetup || (() => Promise.resolve());
|
||||
|
||||
async function background(contentSetup) {
|
||||
browser.runtime.onMessage.addListener((msg, sender) => {
|
||||
browser.test.assertEq(msg, "script ran", "script ran");
|
||||
browser.test.notifyPass("executeScript");
|
||||
});
|
||||
|
||||
browser.test.onMessage.addListener(msg => {
|
||||
browser.test.assertEq(msg, "execute-script");
|
||||
|
||||
browser.tabs.executeScript({
|
||||
file: "script.js",
|
||||
});
|
||||
});
|
||||
|
||||
await contentSetup();
|
||||
|
||||
browser.test.sendMessage("ready");
|
||||
}
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
useAddonManager: "permanent",
|
||||
manifest: {
|
||||
applications: { gecko: { id: "executeScript@tests.mozilla.org" } },
|
||||
...params.manifest,
|
||||
},
|
||||
|
||||
background: `(${background})(${contentSetup})`,
|
||||
|
||||
files: {
|
||||
"panel.html": `<!DOCTYPE html>
|
||||
<html>
|
||||
<head><meta charset="utf-8"></head>
|
||||
<body>
|
||||
</body>
|
||||
</html>`,
|
||||
"script.js": function() {
|
||||
browser.runtime.sendMessage("script ran");
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
await extension.awaitMessage("ready");
|
||||
|
||||
if (params.setup) {
|
||||
await params.setup(extension);
|
||||
}
|
||||
|
||||
extension.sendMessage("execute-script");
|
||||
|
||||
await extension.awaitFinish("executeScript");
|
||||
|
||||
if (params.tearDown) {
|
||||
await params.tearDown(extension);
|
||||
}
|
||||
|
||||
await extension.unload();
|
||||
}
|
||||
|
||||
add_task(async function testGoodPermissions() {
|
||||
let tab = await AppTestDelegate.openNewForegroundTab(
|
||||
window,
|
||||
"http://mochi.test:8888/",
|
||||
true
|
||||
);
|
||||
|
||||
info("Test explicit host permission");
|
||||
await testHasPermission({
|
||||
manifest: { permissions: ["http://mochi.test/"] },
|
||||
});
|
||||
|
||||
info("Test explicit host subdomain permission");
|
||||
await testHasPermission({
|
||||
manifest: { permissions: ["http://*.mochi.test/"] },
|
||||
});
|
||||
|
||||
info("Test explicit <all_urls> permission");
|
||||
await testHasPermission({
|
||||
manifest: { permissions: ["<all_urls>"] },
|
||||
});
|
||||
|
||||
info("Test activeTab permission with a browser action click");
|
||||
await testHasPermission({
|
||||
manifest: {
|
||||
permissions: ["activeTab"],
|
||||
browser_action: {},
|
||||
},
|
||||
contentSetup: function() {
|
||||
browser.browserAction.onClicked.addListener(() => {
|
||||
browser.test.log("Clicked.");
|
||||
});
|
||||
return Promise.resolve();
|
||||
},
|
||||
setup: extension => AppTestDelegate.clickBrowserAction(window, extension),
|
||||
tearDown: extension => AppTestDelegate.closeBrowserAction(window, extension),
|
||||
});
|
||||
|
||||
info("Test activeTab permission with a page action click");
|
||||
await testHasPermission({
|
||||
manifest: {
|
||||
permissions: ["activeTab"],
|
||||
page_action: {},
|
||||
},
|
||||
contentSetup: async () => {
|
||||
let [tab] = await browser.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true,
|
||||
});
|
||||
await browser.pageAction.show(tab.id);
|
||||
},
|
||||
setup: extension => AppTestDelegate.clickPageAction(window, extension),
|
||||
tearDown: extension => AppTestDelegate.closePageAction(window, extension),
|
||||
});
|
||||
|
||||
info("Test activeTab permission with a browser action w/popup click");
|
||||
await testHasPermission({
|
||||
manifest: {
|
||||
permissions: ["activeTab"],
|
||||
browser_action: { default_popup: "panel.html" },
|
||||
},
|
||||
setup: async extension => {
|
||||
await AppTestDelegate.clickBrowserAction(window, extension);
|
||||
return AppTestDelegate.awaitExtensionPanel(window, extension);
|
||||
},
|
||||
tearDown: extension => AppTestDelegate.closeBrowserAction(window, extension),
|
||||
});
|
||||
|
||||
info("Test activeTab permission with a page action w/popup click");
|
||||
await testHasPermission({
|
||||
manifest: {
|
||||
permissions: ["activeTab"],
|
||||
page_action: { default_popup: "panel.html" },
|
||||
},
|
||||
contentSetup: async () => {
|
||||
let [tab] = await browser.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true,
|
||||
});
|
||||
await browser.pageAction.show(tab.id);
|
||||
},
|
||||
setup: extension => AppTestDelegate.clickPageAction(window, extension),
|
||||
tearDown: extension => AppTestDelegate.closePageAction(window, extension),
|
||||
});
|
||||
|
||||
await AppTestDelegate.removeTab(window, tab);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче