Bug 1748546 - Add support for persistent events to ext-pageAction.js. r=mixedpuppy

Depends on D139786

Differential Revision: https://phabricator.services.mozilla.com/D141664
This commit is contained in:
Luca Greco 2022-03-25 20:38:36 +00:00
Родитель a8452b1a7b
Коммит 33f6843dbd
3 изменённых файлов: 170 добавлений и 61 удалений

Просмотреть файл

@ -62,7 +62,7 @@ class PageAction extends PageActionBase {
}
}
this.pageAction = class extends ExtensionAPI {
this.pageAction = class extends ExtensionAPIPersistent {
static for(extension) {
return pageActionMap.get(extension);
}
@ -340,9 +340,36 @@ this.pageAction = class extends ExtensionAPI {
}
}
getAPI(context) {
const { extension } = context;
PERSISTENT_EVENTS = {
onClicked({ context, fire }) {
const { extension } = this;
const { tabManager } = extension;
let listener = async (_event, tab, clickInfo) => {
if (fire.wakeup) {
await fire.wakeup();
}
// TODO: we should double-check if the tab is already being closed by the time
// the background script got started and we converted the primed listener.
context?.withPendingBrowser(tab.linkedBrowser, () =>
fire.sync(tabManager.convert(tab), clickInfo)
);
};
this.on("click", listener);
return {
unregister: () => {
this.off("click", listener);
},
convert(newFire, extContext) {
fire = newFire;
context = extContext;
},
};
},
};
getAPI(context) {
const { action } = this;
return {
@ -351,20 +378,10 @@ this.pageAction = class extends ExtensionAPI {
onClicked: new EventManager({
context,
name: "pageAction.onClicked",
module: "pageAction",
event: "onClicked",
inputHandling: true,
register: fire => {
let listener = (evt, tab, clickInfo) => {
context.withPendingBrowser(tab.linkedBrowser, () =>
fire.sync(tabManager.convert(tab), clickInfo)
);
};
this.on("click", listener);
return () => {
this.off("click", listener);
};
},
extensionApi: this,
}).api(),
openPopup: () => {

Просмотреть файл

@ -17,14 +17,19 @@ add_task(async function setup() {
});
});
add_task(async function test_clickData() {
async function test_clickData(testAsNonPersistent = false) {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
page_action: {},
background: {
persistent: !testAsNonPersistent,
scripts: ["background.js"],
},
},
async background() {
function onClicked(tab, info) {
files: {
"background.js": async function background() {
function onClicked(_tab, info) {
let button = info.button;
let modifiers = info.modifiers;
browser.test.sendMessage("onClick", { button, modifiers });
@ -39,6 +44,7 @@ add_task(async function test_clickData() {
await browser.pageAction.show(tab.id);
browser.test.sendMessage("ready");
},
},
});
const map = {
@ -96,23 +102,48 @@ add_task(async function test_clickData() {
await extension.startup();
await extension.awaitMessage("ready");
if (testAsNonPersistent) {
assertPersistentListeners(extension, "pageAction", "onClicked", {
primed: false,
});
info("Terminating the background event page");
await extension.terminateBackground();
assertPersistentListeners(extension, "pageAction", "onClicked", {
primed: true,
});
}
info("Clicking the pageAction");
await testClickPageAction(clickPageAction, triggerPageActionWithKeyboard);
if (testAsNonPersistent) {
await extension.awaitMessage("ready");
assertPersistentListeners(extension, "pageAction", "onClicked", {
primed: false,
});
}
await testClickPageAction(
clickPageActionInPanel,
triggerPageActionWithKeyboardInPanel
);
await extension.unload();
});
}
add_task(async function test_clickData_reset() {
async function test_clickData_reset(testAsNonPersistent = false) {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
browser_action: {},
page_action: {},
background: {
persistent: !testAsNonPersistent,
scripts: ["background.js"],
},
},
async background() {
files: {
"background.js": async function background() {
function onBrowserActionClicked(tab, info) {
// openPopup requires user interaction, such as a browser action click.
browser.pageAction.openPopup();
@ -132,6 +163,7 @@ add_task(async function test_clickData_reset() {
await browser.pageAction.show(tab.id);
browser.test.sendMessage("ready");
},
},
});
async function clickPageActionWithModifiers() {
@ -149,8 +181,27 @@ add_task(async function test_clickData_reset() {
await extension.startup();
await extension.awaitMessage("ready");
if (testAsNonPersistent) {
assertPersistentListeners(extension, "pageAction", "onClicked", {
primed: false,
});
info("Terminating the background event page");
await extension.terminateBackground();
assertPersistentListeners(extension, "pageAction", "onClicked", {
primed: true,
});
}
info("Clicking the pageAction");
await clickPageActionWithModifiers();
if (testAsNonPersistent) {
await extension.awaitMessage("ready");
assertPersistentListeners(extension, "pageAction", "onClicked", {
primed: false,
});
}
await clickBrowserAction(extension);
assertInfoReset(await extension.awaitMessage("onClick"));
@ -160,4 +211,28 @@ add_task(async function test_clickData_reset() {
assertInfoReset(await extension.awaitMessage("onClick"));
await extension.unload();
}
add_task(function test_clickData_MV2() {
return test_clickData(/* testAsNonPersistent */ false);
});
add_task(async function test_clickData_MV2_eventPage() {
await SpecialPowers.pushPrefEnv({
set: [["extensions.eventPages.enabled", true]],
});
await test_clickData(/* testAsNonPersistent */ true);
await SpecialPowers.popPrefEnv();
});
add_task(function test_clickData_reset_MV2() {
return test_clickData_reset(/* testAsNonPersistent */ false);
});
add_task(async function test_clickData_reset_MV2_eventPage() {
await SpecialPowers.pushPrefEnv({
set: [["extensions.eventPages.enabled", true]],
});
await test_clickData_reset(/* testAsNonPersistent */ true);
await SpecialPowers.popPrefEnv();
});

Просмотреть файл

@ -75,7 +75,7 @@ class PageAction extends PageActionBase {
}
}
this.pageAction = class extends ExtensionAPI {
this.pageAction = class extends ExtensionAPIPersistent {
async onManifestEntry(entryName) {
const { extension } = this;
const action = new PageAction(extension, this);
@ -98,9 +98,33 @@ this.pageAction = class extends ExtensionAPI {
GeckoViewWebExtension.pageActions.delete(extension);
}
getAPI(context) {
const { extension } = context;
PERSISTENT_EVENTS = {
onClicked({ fire }) {
const { extension } = this;
const { tabManager } = extension;
const listener = async (_event, tab) => {
if (fire.wakeup) {
await fire.wakeup();
}
// TODO: we should double-check if the tab is already being closed by the time
// the background script got started and we converted the primed listener.
fire.async(tabManager.convert(tab));
};
this.on("click", listener);
return {
unregister: () => {
this.off("click", listener);
},
convert(newFire, _extContext) {
fire = newFire;
},
};
},
};
getAPI(context) {
const { action } = this;
return {
@ -109,16 +133,9 @@ this.pageAction = class extends ExtensionAPI {
onClicked: new EventManager({
context,
name: "pageAction.onClicked",
register: fire => {
const listener = (event, tab) => {
fire.async(tabManager.convert(tab));
};
this.on("click", listener);
return () => {
this.off("click", listener);
};
},
module: "pageAction",
event: "onClicked",
extensionApi: this,
}).api(),
openPopup() {