mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 01:05:45 +00:00
Bug 1527287 - Add support for "noreferrer" feature argument to window.open(); r=qdot
Differential Revision: https://phabricator.services.mozilla.com/D28396 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
f3c17191a1
commit
27e187b37d
@ -5749,8 +5749,13 @@ nsBrowserAccess.prototype = {
|
||||
aWhere = Services.prefs.getIntPref("browser.link.open_newwindow");
|
||||
}
|
||||
|
||||
let referrerInfo = new ReferrerInfo(Ci.nsIHttpChannel.REFERRER_POLICY_UNSET, true,
|
||||
aOpener ? makeURI(aOpener.location.href) : null);
|
||||
let referrerInfo;
|
||||
if (aFlags & Ci.nsIBrowserDOMWindow.OPEN_NO_REFERRER) {
|
||||
referrerInfo = new ReferrerInfo(Ci.nsIHttpChannel.REFERRER_POLICY_UNSET, false, null);
|
||||
} else {
|
||||
referrerInfo = new ReferrerInfo(Ci.nsIHttpChannel.REFERRER_POLICY_UNSET, true,
|
||||
aOpener ? makeURI(aOpener.location.href) : null);
|
||||
}
|
||||
if (aOpener && aOpener.document) {
|
||||
referrerInfo.referrerPolicy = aOpener.document.referrerPolicy;
|
||||
}
|
||||
|
@ -263,13 +263,16 @@ function tunnelToInnerBrowser(outer, inner) {
|
||||
const { detail } = event;
|
||||
event.preventDefault();
|
||||
const uri = Services.io.newURI(detail.url);
|
||||
let flags = Ci.nsIBrowserDOMWindow.OPEN_NEWTAB;
|
||||
if (detail.forceNoReferrer) {
|
||||
flags |= Ci.nsIBrowserDOMWindow.OPEN_NO_REFERRER;
|
||||
}
|
||||
// This API is used mainly because it's near the path used for <a target/> with
|
||||
// regular browser tabs (which calls `openURIInFrame`). The more elaborate APIs
|
||||
// that support openers, window features, etc. didn't seem callable from JS and / or
|
||||
// this event doesn't give enough info to use them.
|
||||
browserWindow.browserDOMWindow
|
||||
.openURI(uri, null, Ci.nsIBrowserDOMWindow.OPEN_NEWTAB,
|
||||
Ci.nsIBrowserDOMWindow.OPEN_NEW,
|
||||
.openURI(uri, null, flags, Ci.nsIBrowserDOMWindow.OPEN_NEW,
|
||||
outer.contentPrincipal);
|
||||
},
|
||||
|
||||
|
@ -7070,6 +7070,7 @@ nsresult nsGlobalWindowOuter::OpenInternal(
|
||||
|
||||
nsAutoCString options;
|
||||
bool forceNoOpener = aForceNoOpener;
|
||||
bool forceNoReferrer = false;
|
||||
// Unlike other window flags, "noopener" comes from splitting on commas with
|
||||
// HTML whitespace trimming...
|
||||
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace> tok(
|
||||
@ -7080,6 +7081,13 @@ nsresult nsGlobalWindowOuter::OpenInternal(
|
||||
forceNoOpener = true;
|
||||
continue;
|
||||
}
|
||||
if (StaticPrefs::dom_window_open_noreferrer_enabled() &&
|
||||
nextTok.LowerCaseEqualsLiteral("noreferrer")) {
|
||||
forceNoReferrer = true;
|
||||
// noreferrer implies noopener
|
||||
forceNoOpener = true;
|
||||
continue;
|
||||
}
|
||||
// Want to create a copy of the options without 'noopener' because having
|
||||
// 'noopener' in the options affects other window features.
|
||||
if (!options.IsEmpty()) {
|
||||
@ -7185,7 +7193,7 @@ nsresult nsGlobalWindowOuter::OpenInternal(
|
||||
rv = pwwatch->OpenWindow2(
|
||||
this, url.IsVoid() ? nullptr : url.get(), name_ptr, options_ptr,
|
||||
/* aCalledFromScript = */ true, aDialog, aNavigate, argv,
|
||||
isPopupSpamWindow, forceNoOpener, aLoadState,
|
||||
isPopupSpamWindow, forceNoOpener, forceNoReferrer, aLoadState,
|
||||
getter_AddRefs(domReturn));
|
||||
} else {
|
||||
// Force a system caller here so that the window watcher won't screw us
|
||||
@ -7205,7 +7213,7 @@ nsresult nsGlobalWindowOuter::OpenInternal(
|
||||
rv = pwwatch->OpenWindow2(
|
||||
this, url.IsVoid() ? nullptr : url.get(), name_ptr, options_ptr,
|
||||
/* aCalledFromScript = */ false, aDialog, aNavigate, aExtraArgument,
|
||||
isPopupSpamWindow, forceNoOpener, aLoadState,
|
||||
isPopupSpamWindow, forceNoOpener, forceNoReferrer, aLoadState,
|
||||
getter_AddRefs(domReturn));
|
||||
}
|
||||
}
|
||||
|
@ -114,6 +114,7 @@ BrowserElementParent::DispatchOpenWindowEvent(Element* aOpenerFrameElement,
|
||||
Element* aPopupFrameElement,
|
||||
const nsAString& aURL,
|
||||
const nsAString& aName,
|
||||
bool aForceNoReferrer,
|
||||
const nsAString& aFeatures) {
|
||||
// Dispatch a CustomEvent at aOpenerFrameElement with a detail object
|
||||
// (OpenWindowEventDetail) containing aPopupFrameElement, aURL, aName, and
|
||||
@ -130,6 +131,7 @@ BrowserElementParent::DispatchOpenWindowEvent(Element* aOpenerFrameElement,
|
||||
detail.mName = aName;
|
||||
detail.mFeatures = aFeatures;
|
||||
detail.mFrameElement = aPopupFrameElement;
|
||||
detail.mForceNoReferrer = aForceNoReferrer;
|
||||
|
||||
nsIGlobalObject* sgo = aPopupFrameElement->OwnerDoc()->GetScopeObject();
|
||||
if (!sgo) {
|
||||
@ -173,7 +175,8 @@ BrowserElementParent::DispatchOpenWindowEvent(Element* aOpenerFrameElement,
|
||||
/*static*/
|
||||
BrowserElementParent::OpenWindowResult BrowserElementParent::OpenWindowOOP(
|
||||
TabParent* aOpenerTabParent, TabParent* aPopupTabParent,
|
||||
const nsAString& aURL, const nsAString& aName, const nsAString& aFeatures) {
|
||||
const nsAString& aURL, const nsAString& aName, bool aForceNoReferrer,
|
||||
const nsAString& aFeatures) {
|
||||
// Create an iframe owned by the same document which owns openerFrameElement.
|
||||
nsCOMPtr<Element> openerFrameElement = aOpenerTabParent->GetOwnerElement();
|
||||
NS_ENSURE_TRUE(openerFrameElement, BrowserElementParent::OPEN_WINDOW_IGNORED);
|
||||
@ -192,8 +195,9 @@ BrowserElementParent::OpenWindowResult BrowserElementParent::OpenWindowOOP(
|
||||
// allowed.
|
||||
popupFrameElement->DisallowCreateFrameLoader();
|
||||
|
||||
OpenWindowResult opened = DispatchOpenWindowEvent(
|
||||
openerFrameElement, popupFrameElement, aURL, aName, aFeatures);
|
||||
OpenWindowResult opened =
|
||||
DispatchOpenWindowEvent(openerFrameElement, popupFrameElement, aURL,
|
||||
aName, aForceNoReferrer, aFeatures);
|
||||
|
||||
if (opened != BrowserElementParent::OPEN_WINDOW_ADDED) {
|
||||
return opened;
|
||||
@ -249,7 +253,7 @@ BrowserElementParent::OpenWindowInProcess(BrowsingContext* aOpenerWindow,
|
||||
|
||||
OpenWindowResult opened = DispatchOpenWindowEvent(
|
||||
openerFrameElement, popupFrameElement, NS_ConvertUTF8toUTF16(spec), aName,
|
||||
NS_ConvertUTF8toUTF16(aFeatures));
|
||||
false, NS_ConvertUTF8toUTF16(aFeatures));
|
||||
|
||||
if (opened != BrowserElementParent::OPEN_WINDOW_ADDED) {
|
||||
return opened;
|
||||
|
@ -90,6 +90,7 @@ class BrowserElementParent {
|
||||
dom::TabParent* aPopupTabParent,
|
||||
const nsAString& aURL,
|
||||
const nsAString& aName,
|
||||
bool aForceNoReferrer,
|
||||
const nsAString& aFeatures);
|
||||
|
||||
/**
|
||||
@ -111,7 +112,7 @@ class BrowserElementParent {
|
||||
private:
|
||||
static OpenWindowResult DispatchOpenWindowEvent(
|
||||
dom::Element* aOpenerFrameElement, dom::Element* aPopupFrameElement,
|
||||
const nsAString& aURL, const nsAString& aName,
|
||||
const nsAString& aURL, const nsAString& aName, bool aForceNoReferrer,
|
||||
const nsAString& aFeatures);
|
||||
};
|
||||
|
||||
|
@ -241,6 +241,7 @@ nsresult OpenWindow(const ClientOpenWindowArgs& aArgs,
|
||||
// opener anyway, and we _do_ want the returned
|
||||
// window.
|
||||
/* aForceNoOpener = */ false,
|
||||
/* aForceNoReferrer = */ false,
|
||||
/* aLoadInfp = */ nullptr, getter_AddRefs(newWindow));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
|
@ -95,6 +95,12 @@ interface nsIBrowserDOMWindow : nsISupports
|
||||
*/
|
||||
const long OPEN_NO_OPENER = 0x4;
|
||||
|
||||
/**
|
||||
* Don't set the referrer on the navigation inside the window which is
|
||||
* being opened.
|
||||
*/
|
||||
const long OPEN_NO_REFERRER = 0x8;
|
||||
|
||||
/**
|
||||
* Create the content window for the given URI.
|
||||
|
||||
|
@ -754,18 +754,18 @@ ContentChild::ProvideWindow(mozIDOMWindowProxy* aParent, uint32_t aChromeFlags,
|
||||
bool aCalledFromJS, bool aPositionSpecified,
|
||||
bool aSizeSpecified, nsIURI* aURI,
|
||||
const nsAString& aName, const nsACString& aFeatures,
|
||||
bool aForceNoOpener,
|
||||
bool aForceNoOpener, bool aForceNoReferrer,
|
||||
nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
|
||||
mozIDOMWindowProxy** aReturn) {
|
||||
return ProvideWindowCommon(nullptr, aParent, false, aChromeFlags,
|
||||
aCalledFromJS, aPositionSpecified, aSizeSpecified,
|
||||
aURI, aName, aFeatures, aForceNoOpener, aLoadState,
|
||||
aWindowIsNew, aReturn);
|
||||
return ProvideWindowCommon(
|
||||
nullptr, aParent, false, aChromeFlags, aCalledFromJS, aPositionSpecified,
|
||||
aSizeSpecified, aURI, aName, aFeatures, aForceNoOpener, aForceNoReferrer,
|
||||
aLoadState, aWindowIsNew, aReturn);
|
||||
}
|
||||
|
||||
static nsresult GetCreateWindowParams(mozIDOMWindowProxy* aParent,
|
||||
nsDocShellLoadState* aLoadState,
|
||||
float* aFullZoom,
|
||||
bool aForceNoReferrer, float* aFullZoom,
|
||||
nsIReferrerInfo** aReferrerInfo,
|
||||
nsIPrincipal** aTriggeringPrincipal,
|
||||
nsIContentSecurityPolicy** aCsp) {
|
||||
@ -781,7 +781,11 @@ static nsresult GetCreateWindowParams(mozIDOMWindowProxy* aParent,
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIReferrerInfo> referrerInfo;
|
||||
if (aLoadState) {
|
||||
if (aForceNoReferrer) {
|
||||
referrerInfo = new ReferrerInfo(
|
||||
nullptr, mozilla::net::ReferrerPolicy::RP_Unset, false);
|
||||
}
|
||||
if (aLoadState && !referrerInfo) {
|
||||
referrerInfo = aLoadState->GetReferrerInfo();
|
||||
}
|
||||
|
||||
@ -842,7 +846,7 @@ nsresult ContentChild::ProvideWindowCommon(
|
||||
TabChild* aTabOpener, mozIDOMWindowProxy* aParent, bool aIframeMoz,
|
||||
uint32_t aChromeFlags, bool aCalledFromJS, bool aPositionSpecified,
|
||||
bool aSizeSpecified, nsIURI* aURI, const nsAString& aName,
|
||||
const nsACString& aFeatures, bool aForceNoOpener,
|
||||
const nsACString& aFeatures, bool aForceNoOpener, bool aForceNoReferrer,
|
||||
nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
|
||||
mozIDOMWindowProxy** aReturn) {
|
||||
*aReturn = nullptr;
|
||||
@ -888,9 +892,10 @@ nsresult ContentChild::ProvideWindowCommon(
|
||||
nsCOMPtr<nsIPrincipal> triggeringPrincipal;
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||
nsCOMPtr<nsIReferrerInfo> referrerInfo;
|
||||
rv = GetCreateWindowParams(
|
||||
aParent, aLoadState, &fullZoom, getter_AddRefs(referrerInfo),
|
||||
getter_AddRefs(triggeringPrincipal), getter_AddRefs(csp));
|
||||
rv = GetCreateWindowParams(aParent, aLoadState, aForceNoReferrer, &fullZoom,
|
||||
getter_AddRefs(referrerInfo),
|
||||
getter_AddRefs(triggeringPrincipal),
|
||||
getter_AddRefs(csp));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
@ -1106,17 +1111,18 @@ nsresult ContentChild::ProvideWindowCommon(
|
||||
|
||||
// NOTE: BrowserFrameOpenWindowPromise is the same type as
|
||||
// CreateWindowPromise, and this code depends on that fact.
|
||||
newChild->SendBrowserFrameOpenWindow(aTabOpener, NS_ConvertUTF8toUTF16(url),
|
||||
name, NS_ConvertUTF8toUTF16(features),
|
||||
std::move(resolve), std::move(reject));
|
||||
newChild->SendBrowserFrameOpenWindow(
|
||||
aTabOpener, NS_ConvertUTF8toUTF16(url), name, aForceNoReferrer,
|
||||
NS_ConvertUTF8toUTF16(features), std::move(resolve), std::move(reject));
|
||||
} else {
|
||||
float fullZoom;
|
||||
nsCOMPtr<nsIPrincipal> triggeringPrincipal;
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||
nsCOMPtr<nsIReferrerInfo> referrerInfo;
|
||||
rv = GetCreateWindowParams(
|
||||
aParent, aLoadState, &fullZoom, getter_AddRefs(referrerInfo),
|
||||
getter_AddRefs(triggeringPrincipal), getter_AddRefs(csp));
|
||||
rv = GetCreateWindowParams(aParent, aLoadState, aForceNoReferrer, &fullZoom,
|
||||
getter_AddRefs(referrerInfo),
|
||||
getter_AddRefs(triggeringPrincipal),
|
||||
getter_AddRefs(csp));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -109,15 +109,13 @@ class ContentChild final : public PContentChild,
|
||||
nsCString sourceURL;
|
||||
};
|
||||
|
||||
nsresult ProvideWindowCommon(TabChild* aTabOpener,
|
||||
mozIDOMWindowProxy* aOpener, bool aIframeMoz,
|
||||
uint32_t aChromeFlags, bool aCalledFromJS,
|
||||
bool aPositionSpecified, bool aSizeSpecified,
|
||||
nsIURI* aURI, const nsAString& aName,
|
||||
const nsACString& aFeatures, bool aForceNoOpener,
|
||||
nsDocShellLoadState* aLoadState,
|
||||
bool* aWindowIsNew,
|
||||
mozIDOMWindowProxy** aReturn);
|
||||
nsresult ProvideWindowCommon(
|
||||
TabChild* aTabOpener, mozIDOMWindowProxy* aParent, bool aIframeMoz,
|
||||
uint32_t aChromeFlags, bool aCalledFromJS, bool aPositionSpecified,
|
||||
bool aSizeSpecified, nsIURI* aURI, const nsAString& aName,
|
||||
const nsACString& aFeatures, bool aForceNoOpener, bool aForceNoReferrer,
|
||||
nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
|
||||
mozIDOMWindowProxy** aReturn);
|
||||
|
||||
bool Init(MessageLoop* aIOLoop, base::ProcessId aParentPid,
|
||||
const char* aParentBuildID, IPC::Channel* aChannel,
|
||||
|
@ -454,7 +454,8 @@ parent:
|
||||
* @param opener the PBrowser whose content called window.open.
|
||||
*/
|
||||
async BrowserFrameOpenWindow(PBrowser opener,
|
||||
nsString aURL, nsString aName, nsString aFeatures)
|
||||
nsString aURL, nsString aName,
|
||||
bool aForceNoReferrer, nsString aFeatures)
|
||||
returns (CreatedWindowInfo window);
|
||||
|
||||
/**
|
||||
|
@ -901,8 +901,9 @@ TabChild::ProvideWindow(mozIDOMWindowProxy* aParent, uint32_t aChromeFlags,
|
||||
bool aCalledFromJS, bool aPositionSpecified,
|
||||
bool aSizeSpecified, nsIURI* aURI,
|
||||
const nsAString& aName, const nsACString& aFeatures,
|
||||
bool aForceNoOpener, nsDocShellLoadState* aLoadState,
|
||||
bool* aWindowIsNew, mozIDOMWindowProxy** aReturn) {
|
||||
bool aForceNoOpener, bool aForceNoReferrer,
|
||||
nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
|
||||
mozIDOMWindowProxy** aReturn) {
|
||||
*aReturn = nullptr;
|
||||
|
||||
// If aParent is inside an <iframe mozbrowser> and this isn't a request to
|
||||
@ -935,8 +936,8 @@ TabChild::ProvideWindow(mozIDOMWindowProxy* aParent, uint32_t aChromeFlags,
|
||||
ContentChild* cc = ContentChild::GetSingleton();
|
||||
return cc->ProvideWindowCommon(
|
||||
this, aParent, iframeMoz, aChromeFlags, aCalledFromJS, aPositionSpecified,
|
||||
aSizeSpecified, aURI, aName, aFeatures, aForceNoOpener, aLoadState,
|
||||
aWindowIsNew, aReturn);
|
||||
aSizeSpecified, aURI, aName, aFeatures, aForceNoOpener, aForceNoReferrer,
|
||||
aLoadState, aWindowIsNew, aReturn);
|
||||
}
|
||||
|
||||
void TabChild::DestroyWindow() {
|
||||
|
@ -2875,14 +2875,16 @@ void TabParent::ApzAwareEventRoutingToChild(ScrollableLayerGuid* aOutTargetGuid,
|
||||
|
||||
mozilla::ipc::IPCResult TabParent::RecvBrowserFrameOpenWindow(
|
||||
PBrowserParent* aOpener, const nsString& aURL, const nsString& aName,
|
||||
const nsString& aFeatures, BrowserFrameOpenWindowResolver&& aResolve) {
|
||||
bool aForceNoReferrer, const nsString& aFeatures,
|
||||
BrowserFrameOpenWindowResolver&& aResolve) {
|
||||
CreatedWindowInfo cwi;
|
||||
cwi.rv() = NS_OK;
|
||||
cwi.maxTouchPoints() = 0;
|
||||
|
||||
BrowserElementParent::OpenWindowResult opened =
|
||||
BrowserElementParent::OpenWindowOOP(TabParent::GetFrom(aOpener), this,
|
||||
aURL, aName, aFeatures);
|
||||
aURL, aName, aForceNoReferrer,
|
||||
aFeatures);
|
||||
cwi.windowOpened() = (opened == BrowserElementParent::OPEN_WINDOW_ADDED);
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (widget) {
|
||||
|
@ -192,7 +192,8 @@ class TabParent final : public PBrowserParent,
|
||||
|
||||
mozilla::ipc::IPCResult RecvBrowserFrameOpenWindow(
|
||||
PBrowserParent* aOpener, const nsString& aURL, const nsString& aName,
|
||||
const nsString& aFeatures, BrowserFrameOpenWindowResolver&& aResolve);
|
||||
bool aForceNoReferrer, const nsString& aFeatures,
|
||||
BrowserFrameOpenWindowResolver&& aResolve);
|
||||
|
||||
mozilla::ipc::IPCResult RecvSyncMessage(
|
||||
const nsString& aMessage, const ClonedMessageData& aData,
|
||||
|
@ -10,11 +10,11 @@ const TESTS = [
|
||||
|
||||
{id: "#test7", name: "", opener: true, newWindow: false},
|
||||
{id: "#test8", name: "", opener: false, newWindow: false},
|
||||
{id: "#test9", name: "", opener: true, newWindow: true},
|
||||
{id: "#test9", name: "", opener: false, newWindow: false},
|
||||
|
||||
{id: "#test10", name: "uniquename1", opener: true, newWindow: false},
|
||||
{id: "#test11", name: "uniquename2", opener: false, newWindow: false},
|
||||
{id: "#test12", name: "uniquename3", opener: true, newWindow: true},
|
||||
{id: "#test12", name: "uniquename3", opener: false, newWindow: false},
|
||||
];
|
||||
|
||||
const TEST_URL = "http://mochi.test:8888/browser/dom/tests/browser/test_noopener_source.html";
|
||||
@ -99,6 +99,10 @@ async function doAllTests() {
|
||||
// constant starting and stopping processes, and opens a new window ~144 times.
|
||||
requestLongerTimeout(25);
|
||||
|
||||
add_task(async function prepare() {
|
||||
await SpecialPowers.pushPrefEnv({set: [["dom.window.open.noreferrer.enabled", true]]});
|
||||
});
|
||||
|
||||
add_task(async function newtab_sameproc() {
|
||||
await SpecialPowers.pushPrefEnv({set: [[OPEN_NEWWINDOW_PREF, OPEN_NEWTAB],
|
||||
[NOOPENER_NEWPROC_PREF, false]]});
|
||||
|
@ -12,6 +12,7 @@ dictionary OpenWindowEventDetail {
|
||||
DOMString name = "";
|
||||
DOMString features = "";
|
||||
Node? frameElement = null;
|
||||
boolean forceNoReferrer = false;
|
||||
};
|
||||
|
||||
dictionary DOMWindowResizeEventDetail {
|
||||
|
@ -3412,10 +3412,11 @@ nsBrowserAccess.prototype = {
|
||||
Services.io.offline = false;
|
||||
|
||||
let referrer;
|
||||
let forceNoReferrer = !!(aFlags & Ci.nsIBrowserDOMWindow.OPEN_NO_REFERRER);
|
||||
if (aOpener) {
|
||||
try {
|
||||
let location = aOpener.location;
|
||||
referrer = Services.io.newURI(location);
|
||||
referrer = forceNoReferrer ? null : Services.io.newURI(location);
|
||||
} catch(e) { }
|
||||
}
|
||||
|
||||
|
@ -590,6 +590,14 @@ VARCACHE_PREF(
|
||||
bool, true
|
||||
)
|
||||
|
||||
// Enable the "noreferrer" feature argument for window.open()
|
||||
VARCACHE_PREF(
|
||||
"dom.window.open.noreferrer.enabled",
|
||||
dom_window_open_noreferrer_enabled,
|
||||
bool, true
|
||||
)
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Extension prefs
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -1,4 +0,0 @@
|
||||
[window-open-noreferrer.html]
|
||||
[window.open() with "noreferrer" tests]
|
||||
expected: FAIL
|
||||
|
@ -106,6 +106,7 @@ interface nsIWindowProvider : nsISupports
|
||||
in AString aName,
|
||||
in AUTF8String aFeatures,
|
||||
in boolean aForceNoOpener,
|
||||
in boolean aForceNoReferrer,
|
||||
in nsDocShellLoadStatePtr aLoadState,
|
||||
out boolean aWindowIsNew);
|
||||
};
|
||||
|
@ -89,6 +89,7 @@ interface nsPIWindowWatcher : nsISupports
|
||||
in nsISupports aArgs,
|
||||
in boolean aIsPopupSpam,
|
||||
in boolean aForceNoOpener,
|
||||
in boolean aForceNoReferrer,
|
||||
in nsDocShellLoadStatePtr aLoadState);
|
||||
|
||||
/**
|
||||
|
@ -292,6 +292,7 @@ nsWindowWatcher::OpenWindow(mozIDOMWindowProxy* aParent, const char* aUrl,
|
||||
/* navigate = */ true, argv,
|
||||
/* aIsPopupSpam = */ false,
|
||||
/* aForceNoOpener = */ false,
|
||||
/* aForceNoReferrer = */ false,
|
||||
/* aLoadState = */ nullptr, aResult);
|
||||
}
|
||||
|
||||
@ -347,6 +348,7 @@ nsWindowWatcher::OpenWindow2(mozIDOMWindowProxy* aParent, const char* aUrl,
|
||||
bool aCalledFromScript, bool aDialog,
|
||||
bool aNavigate, nsISupports* aArguments,
|
||||
bool aIsPopupSpam, bool aForceNoOpener,
|
||||
bool aForceNoReferrer,
|
||||
nsDocShellLoadState* aLoadState,
|
||||
mozIDOMWindowProxy** aResult) {
|
||||
nsCOMPtr<nsIArray> argv = ConvertArgsToArray(aArguments);
|
||||
@ -366,7 +368,8 @@ nsWindowWatcher::OpenWindow2(mozIDOMWindowProxy* aParent, const char* aUrl,
|
||||
|
||||
return OpenWindowInternal(aParent, aUrl, aName, aFeatures, aCalledFromScript,
|
||||
dialog, aNavigate, argv, aIsPopupSpam,
|
||||
aForceNoOpener, aLoadState, aResult);
|
||||
aForceNoOpener, aForceNoReferrer, aLoadState,
|
||||
aResult);
|
||||
}
|
||||
|
||||
// This static function checks if the aDocShell uses an UserContextId equal to
|
||||
@ -578,7 +581,10 @@ nsresult nsWindowWatcher::OpenWindowInternal(
|
||||
mozIDOMWindowProxy* aParent, const char* aUrl, const char* aName,
|
||||
const char* aFeatures, bool aCalledFromJS, bool aDialog, bool aNavigate,
|
||||
nsIArray* aArgv, bool aIsPopupSpam, bool aForceNoOpener,
|
||||
nsDocShellLoadState* aLoadState, mozIDOMWindowProxy** aResult) {
|
||||
bool aForceNoReferrer, nsDocShellLoadState* aLoadState,
|
||||
mozIDOMWindowProxy** aResult) {
|
||||
MOZ_ASSERT_IF(aForceNoReferrer, aForceNoOpener);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
bool isNewToplevelWindow = false;
|
||||
bool windowIsNew = false;
|
||||
@ -761,7 +767,8 @@ nsresult nsWindowWatcher::OpenWindowInternal(
|
||||
rv = provider->ProvideWindow(
|
||||
aParent, chromeFlags, aCalledFromJS, sizeSpec.PositionSpecified(),
|
||||
sizeSpec.SizeSpecified(), uriToLoad, name, features, aForceNoOpener,
|
||||
aLoadState, &windowIsNew, getter_AddRefs(newWindow));
|
||||
aForceNoReferrer, aLoadState, &windowIsNew,
|
||||
getter_AddRefs(newWindow));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
GetWindowTreeItem(newWindow, getter_AddRefs(newDocShellItem));
|
||||
@ -1079,20 +1086,22 @@ nsresult nsWindowWatcher::OpenWindowInternal(
|
||||
"nsWindowWatcher: triggeringPrincipal required");
|
||||
#endif
|
||||
|
||||
/* use the URL from the *extant* document, if any. The usual accessor
|
||||
GetDocument will synchronously create an about:blank document if
|
||||
it has no better answer, and we only care about a real document.
|
||||
Also using GetDocument to force document creation seems to
|
||||
screw up focus in the hidden window; see bug 36016.
|
||||
*/
|
||||
RefPtr<Document> doc = GetEntryDocument();
|
||||
if (!doc && parentWindow) {
|
||||
doc = parentWindow->GetExtantDoc();
|
||||
}
|
||||
if (doc) {
|
||||
nsCOMPtr<nsIReferrerInfo> referrerInfo =
|
||||
new ReferrerInfo(doc->GetDocumentURI(), doc->GetReferrerPolicy());
|
||||
loadState->SetReferrerInfo(referrerInfo);
|
||||
if (!aForceNoReferrer) {
|
||||
/* use the URL from the *extant* document, if any. The usual accessor
|
||||
GetDocument will synchronously create an about:blank document if
|
||||
it has no better answer, and we only care about a real document.
|
||||
Also using GetDocument to force document creation seems to
|
||||
screw up focus in the hidden window; see bug 36016.
|
||||
*/
|
||||
RefPtr<Document> doc = GetEntryDocument();
|
||||
if (!doc && parentWindow) {
|
||||
doc = parentWindow->GetExtantDoc();
|
||||
}
|
||||
if (doc) {
|
||||
nsCOMPtr<nsIReferrerInfo> referrerInfo =
|
||||
new ReferrerInfo(doc->GetDocumentURI(), doc->GetReferrerPolicy());
|
||||
loadState->SetReferrerInfo(referrerInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ class nsWindowWatcher : public nsIWindowWatcher,
|
||||
const char* aName, const char* aFeatures,
|
||||
bool aCalledFromJS, bool aDialog, bool aNavigate,
|
||||
nsIArray* aArgv, bool aIsPopupSpam,
|
||||
bool aForceNoOpener,
|
||||
bool aForceNoOpener, bool aForceNoReferrer,
|
||||
nsDocShellLoadState* aLoadState,
|
||||
mozIDOMWindowProxy** aResult);
|
||||
|
||||
|
@ -703,7 +703,7 @@ nsContentTreeOwner::ProvideWindow(
|
||||
mozIDOMWindowProxy* aParent, uint32_t aChromeFlags, bool aCalledFromJS,
|
||||
bool aPositionSpecified, bool aSizeSpecified, nsIURI* aURI,
|
||||
const nsAString& aName, const nsACString& aFeatures, bool aForceNoOpener,
|
||||
nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
|
||||
bool aForceNoReferrer, nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
|
||||
mozIDOMWindowProxy** aReturn) {
|
||||
NS_ENSURE_ARG_POINTER(aParent);
|
||||
|
||||
@ -797,6 +797,9 @@ nsContentTreeOwner::ProvideWindow(
|
||||
if (aForceNoOpener) {
|
||||
flags |= nsIBrowserDOMWindow::OPEN_NO_OPENER;
|
||||
}
|
||||
if (aForceNoReferrer) {
|
||||
flags |= nsIBrowserDOMWindow::OPEN_NO_REFERRER;
|
||||
}
|
||||
|
||||
// Get a new rendering area from the browserDOMWin.
|
||||
// Since we are not loading any URI, we follow the principle of least
|
||||
|
Loading…
Reference in New Issue
Block a user