Source code

Revision control

Copy as Markdown

Other Tools

/**
* Given some nsIDOMWindow for a window running in the parent
* process, return the nsIWebBrowserChrome chrome flags for
* the associated XUL window.
*
* @param win (nsIDOMWindow)
* Some window in the parent process.
* @returns int
*/
function getParentChromeFlags(win) {
return win.docShell.treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIAppWindow).chromeFlags;
}
const WINDOW_OPEN_FEATURES_PATTERNS = [
{ features: "", popup: false },
// If features isn't empty, the following should be true to open tab/window:
// * location or toolbar (defaults to false)
// * menubar (defaults to false)
// * resizable (defaults to true)
// * scrollbars (defaults to false)
// * status (defaults to false)
{ features: "location,menubar,resizable,scrollbars,status", popup: false },
{ features: "toolbar,menubar,resizable,scrollbars,status", popup: false },
// resizable defaults to true.
{ features: "location,menubar,scrollbars,status", popup: false },
// The following testcases use "location,menubar,scrollbars,status"
// as the base non-popup case, and test the boundary between popup
// vs non-popup.
// If either location or toolbar is true, not popup.
{
features: "toolbar,menubar,resizable,scrollbars,status",
popup: false,
},
{
features: "location,menubar,resizable,scrollbars,status",
popup: false,
},
// If both location and toolbar are false, popup.
{ features: "menubar,scrollbars,status", popup: true },
// If menubar is false, popup.
{ features: "location,resizable,scrollbars,status", popup: true },
// If resizable is true, not popup.
{
features: "location,menubar,resizable=yes,scrollbars,status",
popup: false,
},
// If resizable is false, popup.
{ features: "location,menubar,resizable=0,scrollbars,status", popup: true },
// If scrollbars is false, popup.
{ features: "location,menubar,resizable,status", popup: true },
// If status is false, popup.
{ features: "location,menubar,resizable,scrollbars", popup: true },
// position and size have no effect.
{
features:
"location,menubar,scrollbars,status," +
"left=100,screenX=100,top=100,screenY=100," +
"width=100,innerWidth=100,outerWidth=100," +
"height=100,innerHeight=100,outerHeight=100",
popup: false,
},
// Most feature defaults to false if the feature is not empty.
// Specifying only some of them opens a popup.
{ features: "location,toolbar,menubar", popup: true },
{ features: "resizable,scrollbars,status", popup: true },
// Specifying unknown feature makes the feature not empty.
{ features: "someunknownfeature", popup: true },
// noopener and noreferrer are removed before testing if feature is empty.
{ features: "noopener,noreferrer", popup: false },
];
const WINDOW_CHROME_FLAGS = {
CHROME_WINDOW_BORDERS: true,
CHROME_WINDOW_CLOSE: true,
CHROME_WINDOW_RESIZE: true,
CHROME_LOCATIONBAR: true,
CHROME_STATUSBAR: true,
CHROME_SCROLLBARS: true,
CHROME_TITLEBAR: true,
CHROME_MENUBAR: true,
CHROME_TOOLBAR: true,
CHROME_PERSONAL_TOOLBAR: true,
};
const POPUP_CHROME_FLAGS = {
CHROME_WINDOW_BORDERS: true,
CHROME_WINDOW_CLOSE: true,
CHROME_WINDOW_RESIZE: true,
CHROME_LOCATIONBAR: true,
CHROME_STATUSBAR: true,
CHROME_SCROLLBARS: true,
CHROME_TITLEBAR: true,
CHROME_MENUBAR: false,
CHROME_TOOLBAR: false,
CHROME_PERSONAL_TOOLBAR: false,
};
async function testPopupPatterns(nonPopup) {
for (const { features, popup } of WINDOW_OPEN_FEATURES_PATTERNS) {
const BLANK_PAGE = "data:text/html,";
const OPEN_PAGE = "data:text/plain,hello";
const SCRIPT_PAGE = `data:text/html,<script>window.open("${OPEN_PAGE}", "", "${features}");</script>`;
async function testNewWindow(flags) {
await BrowserTestUtils.withNewTab(
{
gBrowser,
url: BLANK_PAGE,
},
async function () {
const newWinPromise = BrowserTestUtils.waitForNewWindow();
BrowserTestUtils.startLoadingURIString(gBrowser, SCRIPT_PAGE);
const win = await newWinPromise;
const parentChromeFlags = getParentChromeFlags(win);
for (const [name, visible] of Object.entries(flags)) {
if (visible) {
Assert.equal(
!!(parentChromeFlags & Ci.nsIWebBrowserChrome[name]),
true,
`${name} should be present for features "${features}"`
);
} else {
Assert.equal(
!!(parentChromeFlags & Ci.nsIWebBrowserChrome[name]),
false,
`${name} should not be present for features "${features}"`
);
}
}
await BrowserTestUtils.closeWindow(win);
}
);
}
async function testNewTab() {
await BrowserTestUtils.withNewTab(
{
gBrowser,
url: BLANK_PAGE,
},
async function () {
const newTabPromise = BrowserTestUtils.waitForNewTab(
gBrowser,
OPEN_PAGE
);
BrowserTestUtils.startLoadingURIString(gBrowser, SCRIPT_PAGE);
let tab = await newTabPromise;
BrowserTestUtils.removeTab(tab);
}
);
}
async function testCurrentTab() {
await BrowserTestUtils.withNewTab(
{
gBrowser,
url: BLANK_PAGE,
},
async function (browser) {
const pagePromise = BrowserTestUtils.browserLoaded(
browser,
false,
OPEN_PAGE
);
BrowserTestUtils.startLoadingURIString(gBrowser, SCRIPT_PAGE);
await pagePromise;
}
);
}
if (!popup) {
if (nonPopup == "window") {
await testNewWindow(WINDOW_CHROME_FLAGS);
} else if (nonPopup == "tab") {
await testNewTab();
} else {
// current tab
await testCurrentTab();
}
} else {
await testNewWindow(POPUP_CHROME_FLAGS);
}
}
}