Bug 1647972 - Add a new PlatformOverride field onto BrowsingContext r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D81285
This commit is contained in:
Gabriel Luong 2020-06-26 14:17:08 +00:00
Родитель 3bcc76fc93
Коммит bcf1de6e49
10 изменённых файлов: 146 добавлений и 2 удалений

Просмотреть файл

@ -2037,6 +2037,21 @@ void BrowsingContext::DidSet(FieldIndex<IDX_UserAgentOverride>) {
});
}
void BrowsingContext::SetCustomPlatform(const nsAString& aPlatform) {
Top()->SetPlatformOverride(aPlatform);
}
void BrowsingContext::DidSet(FieldIndex<IDX_PlatformOverride>) {
MOZ_ASSERT(IsTop());
PreOrderWalk([&](BrowsingContext* aContext) {
nsIDocShell* shell = aContext->GetDocShell();
if (shell) {
shell->ClearCachedPlatform();
}
});
}
bool BrowsingContext::CheckOnlyOwningProcessCanSet(ContentParent* aSource) {
if (aSource) {
MOZ_ASSERT(XRE_IsParentProcess());
@ -2148,6 +2163,16 @@ bool BrowsingContext::CanSet(FieldIndex<IDX_UserAgentOverride>,
return CheckOnlyOwningProcessCanSet(aSource);
}
bool BrowsingContext::CanSet(FieldIndex<IDX_PlatformOverride>,
const nsString& aPlatform,
ContentParent* aSource) {
if (!IsTop()) {
return false;
}
return CheckOnlyOwningProcessCanSet(aSource);
}
bool BrowsingContext::CheckOnlyEmbedderCanSet(ContentParent* aSource) {
if (aSource) {
// Set by a content process, verify that it's this BC's embedder.

Просмотреть файл

@ -148,7 +148,8 @@ class WindowProxyHolder;
* This is only ever set to true on the top BC, so consumers need to get \
* the value from the top BC! */ \
FIELD(HasSessionHistory, bool) \
FIELD(UseErrorPages, bool)
FIELD(UseErrorPages, bool) \
FIELD(PlatformOverride, nsString)
// BrowsingContext, in this context, is the cross process replicated
// environment in which information about documents is stored. In
@ -557,6 +558,11 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
}
void SetCustomUserAgent(const nsAString& aUserAgent);
void GetCustomPlatform(nsAString& aPlatform) {
aPlatform = Top()->GetPlatformOverride();
}
void SetCustomPlatform(const nsAString& aPlatform);
JSObject* WrapObject(JSContext* aCx);
static JSObject* ReadStructuredClone(JSContext* aCx,
@ -750,6 +756,10 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
void DidSet(FieldIndex<IDX_AncestorLoading>);
void DidSet(FieldIndex<IDX_PlatformOverride>);
bool CanSet(FieldIndex<IDX_PlatformOverride>,
const nsString& aPlatformOverride, ContentParent* aSource);
void DidSet(FieldIndex<IDX_UserAgentOverride>);
bool CanSet(FieldIndex<IDX_UserAgentOverride>, const nsString& aUserAgent,
ContentParent* aSource);

Просмотреть файл

@ -2148,6 +2148,20 @@ nsDocShell::SetCustomUserAgent(const nsAString& aCustomUserAgent) {
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::ClearCachedPlatform() {
RefPtr<nsGlobalWindowInner> win =
mScriptGlobal ? mScriptGlobal->GetCurrentInnerWindowInternal() : nullptr;
if (win) {
Navigator* navigator = win->Navigator();
if (navigator) {
navigator->ClearPlatformCache();
}
}
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::ClearCachedUserAgent() {
RefPtr<nsGlobalWindowInner> win =

Просмотреть файл

@ -395,6 +395,8 @@ interface nsIDocShell : nsIDocShellTreeItem
void clearCachedUserAgent();
void clearCachedPlatform();
/* Track whether we're currently restoring a document presentation. */
readonly attribute boolean restoringDocument;

Просмотреть файл

@ -133,6 +133,7 @@ skip-if = (os == 'win' && !debug) # bug 1300351
[browser_overlink.js]
support-files =
overlink_test.html
[browser_platform_emulation.js]
[browser_search_notification.js]
[browser_tab_touch_events.js]
[browser_timelineMarkers-01.js]

Просмотреть файл

@ -0,0 +1,69 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const URL = "data:text/html;charset=utf-8,<iframe id='test-iframe'></iframe>";
async function contentTaskNoOverride() {
let docshell = docShell;
is(
docshell.browsingContext.customPlatform,
"",
"There should initially be no customPlatform"
);
}
async function contentTaskOverride() {
let docshell = docShell;
is(
docshell.browsingContext.customPlatform,
"foo",
"The platform should be changed to foo"
);
is(
content.navigator.platform,
"foo",
"The platform should be changed to foo"
);
let frameWin = content.document.querySelector("#test-iframe").contentWindow;
is(
frameWin.navigator.platform,
"foo",
"The platform should be passed on to frames."
);
let newFrame = content.document.createElement("iframe");
content.document.body.appendChild(newFrame);
let newFrameWin = newFrame.contentWindow;
is(
newFrameWin.navigator.platform,
"foo",
"Newly created frames should use the new platform"
);
newFrameWin.location.reload();
await ContentTaskUtils.waitForEvent(newFrameWin, "load");
is(
newFrameWin.navigator.platform,
"foo",
"New platform should persist across reloads"
);
}
add_task(async function() {
await BrowserTestUtils.withNewTab({ gBrowser, url: URL }, async function(
browser
) {
await SpecialPowers.spawn(browser, [], contentTaskNoOverride);
let browsingContext = BrowserTestUtils.getBrowsingContextFrom(browser);
browsingContext.customPlatform = "foo";
await SpecialPowers.spawn(browser, [], contentTaskOverride);
});
});

Просмотреть файл

@ -400,6 +400,19 @@ void Navigator::GetLanguages(nsTArray<nsString>& aLanguages) {
void Navigator::GetPlatform(nsAString& aPlatform, CallerType aCallerType,
ErrorResult& aRv) const {
if (mWindow) {
BrowsingContext* bc = mWindow->GetBrowsingContext();
nsString customPlatform;
if (bc) {
bc->GetCustomPlatform(customPlatform);
if (!customPlatform.IsEmpty()) {
aPlatform = customPlatform;
return;
}
}
}
nsCOMPtr<Document> doc = mWindow->GetExtantDoc();
nsresult rv = GetPlatform(
@ -1769,6 +1782,10 @@ already_AddRefed<nsPIDOMWindowInner> Navigator::GetWindowFromGlobal(
return win.forget();
}
void Navigator::ClearPlatformCache() {
Navigator_Binding::ClearCachedPlatformValue(this);
}
nsresult Navigator::GetPlatform(nsAString& aPlatform,
nsIPrincipal* aCallerPrincipal,
bool aUsePrefOverriddenValue) {

Просмотреть файл

@ -148,6 +148,10 @@ class Navigator final : public nsISupports, public nsWrapperCache {
nsIPrincipal* aCallerPrincipal,
bool aIsCallerChrome, nsAString& aUserAgent);
// Clears the platform cache by calling:
// Navigator_Binding::ClearCachedPlatformValue(this);
void ClearPlatformCache();
// Clears the user agent cache by calling:
// Navigator_Binding::ClearCachedUserAgentValue(this);
void ClearUserAgentCache();

Просмотреть файл

@ -66,6 +66,8 @@ interface BrowsingContext {
readonly attribute WindowContext? topWindowContext;
attribute [TreatNullAs=EmptyString] DOMString customPlatform;
attribute [TreatNullAs=EmptyString] DOMString customUserAgent;
/**

Просмотреть файл

@ -50,7 +50,7 @@ interface mixin NavigatorID {
readonly attribute DOMString appName;
[Constant, Cached, Throws, NeedsCallerType]
readonly attribute DOMString appVersion;
[Constant, Cached, Throws, NeedsCallerType]
[Pure, Cached, Throws, NeedsCallerType]
readonly attribute DOMString platform;
[Pure, Cached, Throws, NeedsCallerType]
readonly attribute DOMString userAgent;