Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const PAGE =
add_task(async function menuInShadowDOM() {
Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true);
registerCleanupFunction(() => {
Services.prefs.clearUserPref("security.allow_eval_with_system_principal");
});
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
gBrowser.selectedTab = tab;
async function background() {
browser.menus.onShown.addListener(async (info, tab) => {
browser.test.assertTrue(
Number.isInteger(info.targetElementId),
`${info.targetElementId} should be an integer`
);
browser.test.assertEq(
"all,link",
info.contexts.sort().join(","),
"Expected context"
);
browser.test.assertEq(
info.linkUrl,
"Menu target should be a link in the shadow DOM"
);
let code = `{
try {
let elem = browser.menus.getTargetElement(${info.targetElementId});
browser.test.assertTrue(elem, "Shadow element must be found");
browser.test.assertEq("http://example.com/?shadowlink", elem.href, "Element is a link in shadow DOM " - elem.outerHTML);
} catch (e) {
browser.test.fail("Unexpected error in getTargetElement: " + e);
}
}`;
await browser.tabs.executeScript(tab.id, { code });
browser.test.sendMessage(
"onShownMenuAndCheckedInfo",
info.targetElementId
);
});
// Ensure that onShown is registered (workaround for bug 1300234):
await browser.menus.removeAll();
browser.test.sendMessage("ready");
}
let extension = ExtensionTestUtils.loadExtension({
manifest: {
permissions: ["menus", "http://mochi.test/*"],
},
background,
});
await extension.startup();
await extension.awaitMessage("ready");
async function testShadowMenu(setupMenuTarget) {
await openContextMenu(setupMenuTarget);
await extension.awaitMessage("onShownMenuAndCheckedInfo");
await closeContextMenu();
}
info("Clicking in open shadow root");
await testShadowMenu(() => {
let doc = this.document;
doc.body.innerHTML = `<div></div>`;
let host = doc.body.firstElementChild.attachShadow({ mode: "open" });
host.innerHTML = `<a href="http://example.com/?shadowlink">Test open</a>`;
this.document.testTarget = host.firstElementChild;
return this.document.testTarget;
});
info("Clicking in closed shadow root");
await testShadowMenu(() => {
let doc = this.document;
doc.body.innerHTML = `<div></div>`;
let host = doc.body.firstElementChild.attachShadow({ mode: "closed" });
host.innerHTML = `<a href="http://example.com/?shadowlink">Test closed</a>`;
this.document.testTarget = host.firstElementChild;
return this.document.testTarget;
});
info("Clicking in nested shadow DOM");
await testShadowMenu(() => {
let doc = this.document;
let host;
for (let container = doc.body, i = 0; i < 10; ++i) {
container.innerHTML = `<div id="level"></div>`;
host = container.firstElementChild.attachShadow({ mode: "open" });
container = host;
}
host.innerHTML = `<a href="http://example.com/?shadowlink">Test nested</a>`;
this.document.testTarget = host.firstElementChild;
return this.document.testTarget;
});
await extension.unload();
BrowserTestUtils.removeTab(tab);
});