зеркало из https://github.com/mozilla/gecko-dev.git
357 строки
10 KiB
JavaScript
357 строки
10 KiB
JavaScript
/**
|
|
* Tests that chromeFlags are set properly on windows that are
|
|
* being opened from content.
|
|
*/
|
|
|
|
// The following features set chrome flags on new windows and are
|
|
// supported by web content. The schema for each property on this
|
|
// object is as follows:
|
|
//
|
|
// <feature string>: {
|
|
// flag: <associated nsIWebBrowserChrome flag>,
|
|
// defaults_to: <what this feature defaults to normally>
|
|
// }
|
|
const ALLOWED = {
|
|
toolbar: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_TOOLBAR,
|
|
defaults_to: true,
|
|
},
|
|
personalbar: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_PERSONAL_TOOLBAR,
|
|
defaults_to: true,
|
|
},
|
|
menubar: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_MENUBAR,
|
|
defaults_to: true,
|
|
},
|
|
scrollbars: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_SCROLLBARS,
|
|
defaults_to: false,
|
|
},
|
|
minimizable: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_WINDOW_MIN,
|
|
defaults_to: true,
|
|
},
|
|
};
|
|
|
|
// Construct a features string that flips all ALLOWED features
|
|
// to not be their defaults.
|
|
const ALLOWED_STRING = Object.keys(ALLOWED)
|
|
.map(feature => {
|
|
let toValue = ALLOWED[feature].defaults_to ? "no" : "yes";
|
|
return `${feature}=${toValue}`;
|
|
})
|
|
.join(",");
|
|
|
|
// The following are not allowed from web content, at least
|
|
// in the default case (since some are disabled by default
|
|
// via the dom.disable_window_open_feature pref branch).
|
|
const DISALLOWED = {
|
|
location: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_LOCATIONBAR,
|
|
defaults_to: true,
|
|
},
|
|
chrome: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_OPENAS_CHROME,
|
|
defaults_to: false,
|
|
},
|
|
dialog: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_OPENAS_DIALOG,
|
|
defaults_to: false,
|
|
},
|
|
private: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_PRIVATE_WINDOW,
|
|
defaults_to: false,
|
|
},
|
|
"non-private": {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_NON_PRIVATE_WINDOW,
|
|
defaults_to: false,
|
|
},
|
|
// "all":
|
|
// checked manually, since this is an aggregate
|
|
// flag.
|
|
//
|
|
// "remote":
|
|
// checked manually, since its default value will
|
|
// depend on whether or not e10s is enabled by default.
|
|
popup: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_WINDOW_POPUP,
|
|
defaults_to: false,
|
|
},
|
|
alwaysLowered: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_WINDOW_LOWERED,
|
|
defaults_to: false,
|
|
},
|
|
"z-lock": {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_WINDOW_LOWERED, // Renamed to alwaysLowered
|
|
defaults_to: false,
|
|
},
|
|
alwaysRaised: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_WINDOW_RAISED,
|
|
defaults_to: false,
|
|
},
|
|
alwaysOnTop: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_ALWAYS_ON_TOP,
|
|
defaults_to: false,
|
|
},
|
|
suppressanimation: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_SUPPRESS_ANIMATION,
|
|
defaults_to: false,
|
|
},
|
|
extrachrome: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_EXTRA,
|
|
defaults_to: false,
|
|
},
|
|
centerscreen: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_CENTER_SCREEN,
|
|
defaults_to: false,
|
|
},
|
|
dependent: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_DEPENDENT,
|
|
defaults_to: false,
|
|
},
|
|
modal: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_MODAL,
|
|
defaults_to: false,
|
|
},
|
|
titlebar: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_TITLEBAR,
|
|
defaults_to: true,
|
|
},
|
|
close: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_WINDOW_CLOSE,
|
|
defaults_to: true,
|
|
},
|
|
resizable: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_WINDOW_RESIZE,
|
|
defaults_to: true,
|
|
},
|
|
status: {
|
|
flag: Ci.nsIWebBrowserChrome.CHROME_STATUSBAR,
|
|
defaults_to: true,
|
|
},
|
|
};
|
|
|
|
// This magic value of 2 means that by default, when content tries
|
|
// to open a new window, it'll actually open in a new window instead
|
|
// of a new tab.
|
|
Services.prefs.setIntPref("browser.link.open_newwindow", 2);
|
|
registerCleanupFunction(() => {
|
|
Services.prefs.clearUserPref("browser.link.open_newwindow");
|
|
});
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
/**
|
|
* Given some nsIDOMWindow for a window running in the parent process,
|
|
* asynchronously return the nsIWebBrowserChrome chrome flags for the
|
|
* associated content window.
|
|
*
|
|
* @param win (nsIDOMWindow)
|
|
* @returns int
|
|
*/
|
|
function getContentChromeFlags(win) {
|
|
let b = win.gBrowser.selectedBrowser;
|
|
return SpecialPowers.spawn(b, [], async function() {
|
|
// Content scripts provide docShell as a global.
|
|
/* global docShell */
|
|
docShell.QueryInterface(Ci.nsIInterfaceRequestor);
|
|
try {
|
|
// This will throw if we're not a remote browser.
|
|
return docShell
|
|
.getInterface(Ci.nsIBrowserChild)
|
|
.QueryInterface(Ci.nsIWebBrowserChrome).chromeFlags;
|
|
} catch (e) {
|
|
// This must be a non-remote browser...
|
|
return docShell.treeOwner.QueryInterface(
|
|
Ci.nsIWebBrowserChrome
|
|
).chromeFlags;
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* For some chromeFlags, ensures that flags that are in the
|
|
* ALLOWED group were modified, and that flags in the DISALLOWED
|
|
* group were not modified.
|
|
*
|
|
* @param chromeFlags (int)
|
|
* Some chromeFlags to check.
|
|
*/
|
|
function assertContentFlags(chromeFlags) {
|
|
for (let feature in ALLOWED) {
|
|
let flag = ALLOWED[feature].flag;
|
|
|
|
if (ALLOWED[feature].defaults_to) {
|
|
// The feature is supposed to default to true, so we should
|
|
// have been able to flip it off.
|
|
Assert.ok(
|
|
!(chromeFlags & flag),
|
|
`Expected feature ${feature} to be disabled`
|
|
);
|
|
} else {
|
|
// The feature is supposed to default to false, so we should
|
|
// have been able to flip it on.
|
|
Assert.ok(
|
|
chromeFlags & flag,
|
|
`Expected feature ${feature} to be enabled`
|
|
);
|
|
}
|
|
}
|
|
|
|
for (let feature in DISALLOWED) {
|
|
let flag = DISALLOWED[feature].flag;
|
|
Assert.ok(flag, "Expected flag to be a non-zeroish value");
|
|
if (DISALLOWED[feature].defaults_to) {
|
|
// The feature is supposed to default to true, so it should
|
|
// stay true.
|
|
Assert.ok(
|
|
chromeFlags & flag,
|
|
`Expected feature ${feature} to be unchanged`
|
|
);
|
|
} else {
|
|
// The feature is supposed to default to false, so it should
|
|
// stay false.
|
|
Assert.ok(
|
|
!(chromeFlags & flag),
|
|
`Expected feature ${feature} to be unchanged`
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Opens a window from content using window.open with the
|
|
* features computed from ALLOWED and DISALLOWED. The computed
|
|
* feature string attempts to flip every feature away from their
|
|
* default.
|
|
*/
|
|
add_task(async function test_new_remote_window_flags() {
|
|
// Construct a features string that flips all DISALLOWED features
|
|
// to not be their defaults.
|
|
const DISALLOWED_STRING = Object.keys(DISALLOWED)
|
|
.map(feature => {
|
|
let toValue = DISALLOWED[feature].defaults_to ? "no" : "yes";
|
|
return `${feature}=${toValue}`;
|
|
})
|
|
.join(",");
|
|
|
|
const FEATURES = [ALLOWED_STRING, DISALLOWED_STRING].join(",");
|
|
|
|
const SCRIPT_PAGE = `data:text/html,<script>window.open("about:blank", "_blank", "${FEATURES}");</script>`;
|
|
const SCRIPT_PAGE_FOR_CHROME_ALL = `data:text/html,<script>window.open("about:blank", "_blank", "all");</script>`;
|
|
|
|
let newWinPromise = BrowserTestUtils.waitForNewWindow();
|
|
|
|
await BrowserTestUtils.withNewTab(
|
|
{
|
|
gBrowser,
|
|
url: SCRIPT_PAGE,
|
|
},
|
|
async function(browser) {
|
|
let win = await newWinPromise;
|
|
let parentChromeFlags = getParentChromeFlags(win);
|
|
assertContentFlags(parentChromeFlags);
|
|
|
|
if (win.gMultiProcessBrowser) {
|
|
Assert.ok(
|
|
parentChromeFlags & Ci.nsIWebBrowserChrome.CHROME_REMOTE_WINDOW,
|
|
"Should be remote by default"
|
|
);
|
|
} else {
|
|
Assert.ok(
|
|
!(parentChromeFlags & Ci.nsIWebBrowserChrome.CHROME_REMOTE_WINDOW),
|
|
"Should not be remote by default"
|
|
);
|
|
}
|
|
|
|
// Confusingly, chromeFlags also exist in the content process
|
|
// as part of the BrowserChild, so we have to check those too.
|
|
let contentChromeFlags = await getContentChromeFlags(win);
|
|
assertContentFlags(contentChromeFlags);
|
|
|
|
Assert.equal(
|
|
parentChromeFlags & Ci.nsIWebBrowserChrome.CHROME_REMOTE_WINDOW,
|
|
contentChromeFlags & Ci.nsIWebBrowserChrome.CHROME_REMOTE_WINDOW,
|
|
"Should have matching remote value in parent and content"
|
|
);
|
|
|
|
Assert.equal(
|
|
parentChromeFlags & Ci.nsIWebBrowserChrome.CHROME_FISSION_WINDOW,
|
|
contentChromeFlags & Ci.nsIWebBrowserChrome.CHROME_FISSION_WINDOW,
|
|
"Should have matching fission value in parent and content"
|
|
);
|
|
|
|
await BrowserTestUtils.closeWindow(win);
|
|
}
|
|
);
|
|
|
|
// We check "all" manually, since that's an aggregate flag
|
|
// and doesn't fit nicely into the ALLOWED / DISALLOWED scheme
|
|
newWinPromise = BrowserTestUtils.waitForNewWindow();
|
|
|
|
await BrowserTestUtils.withNewTab(
|
|
{
|
|
gBrowser,
|
|
url: SCRIPT_PAGE_FOR_CHROME_ALL,
|
|
},
|
|
async function(browser) {
|
|
let win = await newWinPromise;
|
|
let parentChromeFlags = getParentChromeFlags(win);
|
|
Assert.notEqual(
|
|
parentChromeFlags & Ci.nsIWebBrowserChrome.CHROME_ALL,
|
|
Ci.nsIWebBrowserChrome.CHROME_ALL,
|
|
"Should not have been able to set CHROME_ALL"
|
|
);
|
|
await BrowserTestUtils.closeWindow(win);
|
|
}
|
|
);
|
|
});
|
|
|
|
/**
|
|
* Opens a window with some chrome flags specified, which should not affect
|
|
* scrollbars flag which defaults to true when not disabled explicitly.
|
|
*/
|
|
add_task(async function test_scrollbars_flag() {
|
|
const SCRIPT = 'window.open("about:blank", "_blank", "toolbar=0");';
|
|
const SCRIPT_PAGE = `data:text/html,<script>${SCRIPT}</script>`;
|
|
|
|
let newWinPromise = BrowserTestUtils.waitForNewWindow();
|
|
await BrowserTestUtils.withNewTab(
|
|
{
|
|
gBrowser,
|
|
url: SCRIPT_PAGE,
|
|
},
|
|
async function(browser) {
|
|
let win = await newWinPromise;
|
|
|
|
let parentChromeFlags = getParentChromeFlags(win);
|
|
Assert.ok(
|
|
parentChromeFlags & Ci.nsIWebBrowserChrome.CHROME_SCROLLBARS,
|
|
"Should have scrollbars when not disabled explicitly"
|
|
);
|
|
|
|
let contentChromeFlags = await getContentChromeFlags(win);
|
|
Assert.ok(
|
|
contentChromeFlags & Ci.nsIWebBrowserChrome.CHROME_SCROLLBARS,
|
|
"Should have scrollbars when not disabled explicitly"
|
|
);
|
|
|
|
await BrowserTestUtils.closeWindow(win);
|
|
}
|
|
);
|
|
});
|