/** * 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,`; 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); } } }