зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1616353 - Part 6.1: Implement nsILoadContext on BrowsingContext, r=smaug
This also moves nsDocShell's implementation of nsILoadContext to be based on its BrowsingContext. This patch does not, by itself, fix all places which try to mutate `nsILoadContext`. Those are fixed by the other parts of this patch stack. Differential Revision: https://phabricator.services.mozilla.com/D67045 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
146e915363
Коммит
570fcda0e2
|
@ -215,6 +215,11 @@ already_AddRefed<BrowsingContext> BrowsingContext::CreateDetached(
|
|||
|
||||
BrowsingContext* inherit = aParent ? aParent : aOpener;
|
||||
if (inherit) {
|
||||
context->mPrivateBrowsingId = inherit->mPrivateBrowsingId;
|
||||
context->mUseRemoteTabs = inherit->mUseRemoteTabs;
|
||||
context->mUseRemoteSubframes = inherit->mUseRemoteSubframes;
|
||||
context->mOriginAttributes = inherit->mOriginAttributes;
|
||||
|
||||
// CORPP 3.1.3 https://mikewest.github.io/corpp/#integration-html
|
||||
context->mFields.SetWithoutSyncing<IDX_EmbedderPolicy>(
|
||||
inherit->GetEmbedderPolicy());
|
||||
|
@ -320,6 +325,13 @@ already_AddRefed<BrowsingContext> BrowsingContext::CreateFromIPC(
|
|||
|
||||
context->mWindowless = aInit.mWindowless;
|
||||
|
||||
// NOTE: Call through the `Set` methods for these values to ensure that any
|
||||
// relevant process-local state is also updated.
|
||||
context->SetOriginAttributes(aInit.mOriginAttributes);
|
||||
context->SetRemoteTabs(aInit.mUseRemoteTabs);
|
||||
context->SetRemoteSubframes(aInit.mUseRemoteSubframes);
|
||||
// NOTE: Private browsing ID is set by `SetOriginAttributes`.
|
||||
|
||||
Register(context);
|
||||
|
||||
// Caller handles attaching us to the tree.
|
||||
|
@ -340,13 +352,16 @@ BrowsingContext::BrowsingContext(BrowsingContext* aParent,
|
|||
mBrowsingContextId(aBrowsingContextId),
|
||||
mGroup(aGroup),
|
||||
mParent(aParent),
|
||||
mPrivateBrowsingId(0),
|
||||
mEverAttached(false),
|
||||
mIsInProcess(false),
|
||||
mIsDiscarded(false),
|
||||
mWindowless(false),
|
||||
mDanglingRemoteOuterProxies(false),
|
||||
mPendingInitialization(false),
|
||||
mEmbeddedByThisProcess(false) {
|
||||
mEmbeddedByThisProcess(false),
|
||||
mUseRemoteTabs(false),
|
||||
mUseRemoteSubframes(false) {
|
||||
MOZ_RELEASE_ASSERT(!mParent || mParent->Group() == mGroup);
|
||||
MOZ_RELEASE_ASSERT(mBrowsingContextId != 0);
|
||||
MOZ_RELEASE_ASSERT(mGroup);
|
||||
|
@ -442,10 +457,16 @@ void BrowsingContext::Attach(bool aFromIPC) {
|
|||
MOZ_DIAGNOSTIC_ASSERT(!mEverAttached);
|
||||
mEverAttached = true;
|
||||
|
||||
MOZ_LOG(GetLog(), LogLevel::Debug,
|
||||
("%s: Connecting 0x%08" PRIx64 " to 0x%08" PRIx64,
|
||||
XRE_IsParentProcess() ? "Parent" : "Child", Id(),
|
||||
mParent ? mParent->Id() : 0));
|
||||
if (MOZ_LOG_TEST(GetLog(), LogLevel::Debug)) {
|
||||
nsAutoCString suffix;
|
||||
mOriginAttributes.CreateSuffix(suffix);
|
||||
MOZ_LOG(GetLog(), LogLevel::Debug,
|
||||
("%s: Connecting 0x%08" PRIx64 " to 0x%08" PRIx64
|
||||
" (private=%d, remote=%d, fission=%d, oa=%s)",
|
||||
XRE_IsParentProcess() ? "Parent" : "Child", Id(),
|
||||
mParent ? mParent->Id() : 0, (int)mPrivateBrowsingId,
|
||||
(int)mUseRemoteTabs, (int)mUseRemoteSubframes, suffix.get()));
|
||||
}
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(mGroup);
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mGroup->IsContextCached(this));
|
||||
|
@ -562,6 +583,8 @@ void BrowsingContext::Detach(bool aFromIPC) {
|
|||
mFields.SetWithoutSyncing<IDX_IsPopupSpam>(false);
|
||||
}
|
||||
|
||||
AssertOriginAttributesMatchPrivateBrowsing();
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
Canonical()->CanonicalDiscard();
|
||||
}
|
||||
|
@ -985,6 +1008,239 @@ bool BrowsingContext::ConsumeTransientUserGestureActivation() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool BrowsingContext::CanSetOriginAttributes() {
|
||||
// A discarded BrowsingContext has already been destroyed, and cannot modify
|
||||
// its OriginAttributes.
|
||||
if (NS_WARN_IF(IsDiscarded())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Before attaching is the safest time to set OriginAttributes, and the only
|
||||
// allowed time for content BrowsingContexts.
|
||||
if (!EverAttached()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Attached content BrowsingContexts may have been synced to other processes.
|
||||
if (NS_WARN_IF(IsContent())) {
|
||||
MOZ_CRASH();
|
||||
return false;
|
||||
}
|
||||
MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
// Cannot set OriginAttributes after we've created our child BrowsingContext.
|
||||
if (NS_WARN_IF(!Children().IsEmpty())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only allow setting OriginAttributes if we have no associated document, or
|
||||
// the document is still `about:blank`.
|
||||
// TODO: Bug 1273058 - should have no document when setting origin attributes.
|
||||
if (WindowGlobalParent* window = Canonical()->GetCurrentWindowGlobal()) {
|
||||
if (nsIURI* uri = window->GetDocumentURI()) {
|
||||
MOZ_ASSERT(NS_IsAboutBlank(uri));
|
||||
return NS_IsAboutBlank(uri);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP BrowsingContext::GetAssociatedWindow(
|
||||
mozIDOMWindowProxy** aAssociatedWindow) {
|
||||
nsCOMPtr<mozIDOMWindowProxy> win = GetDOMWindow();
|
||||
win.forget(aAssociatedWindow);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP BrowsingContext::GetTopWindow(mozIDOMWindowProxy** aTopWindow) {
|
||||
return Top()->GetAssociatedWindow(aTopWindow);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP BrowsingContext::GetTopFrameElement(Element** aTopFrameElement) {
|
||||
RefPtr<Element> topFrameElement = Top()->GetEmbedderElement();
|
||||
topFrameElement.forget(aTopFrameElement);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP BrowsingContext::GetNestedFrameId(uint64_t* aNestedFrameId) {
|
||||
// FIXME: nestedFrameId should be removed, as it was only used by B2G.
|
||||
*aNestedFrameId = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP BrowsingContext::GetIsContent(bool* aIsContent) {
|
||||
*aIsContent = IsContent();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP BrowsingContext::GetUsePrivateBrowsing(
|
||||
bool* aUsePrivateBrowsing) {
|
||||
*aUsePrivateBrowsing = mPrivateBrowsingId > 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP BrowsingContext::SetUsePrivateBrowsing(bool aUsePrivateBrowsing) {
|
||||
if (!CanSetOriginAttributes()) {
|
||||
bool changed = aUsePrivateBrowsing != (mPrivateBrowsingId > 0);
|
||||
if (changed) {
|
||||
NS_WARNING("SetUsePrivateBrowsing when !CanSetOriginAttributes()");
|
||||
}
|
||||
return changed ? NS_ERROR_FAILURE : NS_OK;
|
||||
}
|
||||
|
||||
return SetPrivateBrowsing(aUsePrivateBrowsing);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP BrowsingContext::SetPrivateBrowsing(bool aPrivateBrowsing) {
|
||||
if (!CanSetOriginAttributes()) {
|
||||
NS_WARNING("Attempt to set PrivateBrowsing when !CanSetOriginAttributes");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
bool changed = aPrivateBrowsing != (mPrivateBrowsingId > 0);
|
||||
if (changed) {
|
||||
mPrivateBrowsingId = aPrivateBrowsing ? 1 : 0;
|
||||
if (IsContent()) {
|
||||
mOriginAttributes.SyncAttributesWithPrivateBrowsing(aPrivateBrowsing);
|
||||
}
|
||||
}
|
||||
AssertOriginAttributesMatchPrivateBrowsing();
|
||||
|
||||
if (changed && mDocShell) {
|
||||
nsDocShell::Cast(mDocShell)->NotifyPrivateBrowsingChanged();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP BrowsingContext::GetUseRemoteTabs(bool* aUseRemoteTabs) {
|
||||
*aUseRemoteTabs = mUseRemoteTabs;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP BrowsingContext::SetRemoteTabs(bool aUseRemoteTabs) {
|
||||
if (!CanSetOriginAttributes()) {
|
||||
NS_WARNING("Attempt to set RemoteTabs when !CanSetOriginAttributes");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
static bool annotated = false;
|
||||
if (aUseRemoteTabs && !annotated) {
|
||||
annotated = true;
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::DOMIPCEnabled,
|
||||
true);
|
||||
}
|
||||
|
||||
// Don't allow non-remote tabs with remote subframes.
|
||||
if (NS_WARN_IF(!aUseRemoteTabs && mUseRemoteSubframes)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
mUseRemoteTabs = aUseRemoteTabs;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP BrowsingContext::GetUseRemoteSubframes(
|
||||
bool* aUseRemoteSubframes) {
|
||||
*aUseRemoteSubframes = mUseRemoteSubframes;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP BrowsingContext::SetRemoteSubframes(bool aUseRemoteSubframes) {
|
||||
if (!CanSetOriginAttributes()) {
|
||||
NS_WARNING("Attempt to set RemoteSubframes when !CanSetOriginAttributes");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
static bool annotated = false;
|
||||
if (aUseRemoteSubframes && !annotated) {
|
||||
annotated = true;
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::DOMFissionEnabled, true);
|
||||
}
|
||||
|
||||
// Don't allow non-remote tabs with remote subframes.
|
||||
if (NS_WARN_IF(aUseRemoteSubframes && !mUseRemoteTabs)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
mUseRemoteSubframes = aUseRemoteSubframes;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP BrowsingContext::GetUseTrackingProtection(
|
||||
bool* aUseTrackingProtection) {
|
||||
*aUseTrackingProtection = false;
|
||||
|
||||
if (GetForceEnableTrackingProtection() ||
|
||||
StaticPrefs::privacy_trackingprotection_enabled() ||
|
||||
(UsePrivateBrowsing() &&
|
||||
StaticPrefs::privacy_trackingprotection_pbmode_enabled())) {
|
||||
*aUseTrackingProtection = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mParent) {
|
||||
return mParent->GetUseTrackingProtection(aUseTrackingProtection);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP BrowsingContext::SetUseTrackingProtection(
|
||||
bool aUseTrackingProtection) {
|
||||
SetForceEnableTrackingProtection(aUseTrackingProtection);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP BrowsingContext::GetScriptableOriginAttributes(
|
||||
JSContext* aCx, JS::MutableHandle<JS::Value> aVal) {
|
||||
AssertOriginAttributesMatchPrivateBrowsing();
|
||||
|
||||
bool ok = ToJSValue(aCx, mOriginAttributes, aVal);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
BrowsingContext::GetOriginAttributes(OriginAttributes& aAttrs) {
|
||||
aAttrs = mOriginAttributes;
|
||||
AssertOriginAttributesMatchPrivateBrowsing();
|
||||
}
|
||||
|
||||
nsresult BrowsingContext::SetOriginAttributes(const OriginAttributes& aAttrs) {
|
||||
if (!CanSetOriginAttributes()) {
|
||||
NS_WARNING("Attempt to set OriginAttributes when !CanSetOriginAttributes");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
AssertOriginAttributesMatchPrivateBrowsing();
|
||||
mOriginAttributes = aAttrs;
|
||||
|
||||
bool isPrivate = mOriginAttributes.mPrivateBrowsingId !=
|
||||
nsIScriptSecurityManager::DEFAULT_PRIVATE_BROWSING_ID;
|
||||
// Chrome Browsing Context can not contain OriginAttributes.mPrivateBrowsingId
|
||||
if (IsChrome() && isPrivate) {
|
||||
mOriginAttributes.mPrivateBrowsingId =
|
||||
nsIScriptSecurityManager::DEFAULT_PRIVATE_BROWSING_ID;
|
||||
}
|
||||
SetPrivateBrowsing(isPrivate);
|
||||
AssertOriginAttributesMatchPrivateBrowsing();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void BrowsingContext::AssertOriginAttributesMatchPrivateBrowsing() {
|
||||
// Chrome browsing contexts must not have a private browsing OriginAttribute
|
||||
// Content browsing contexts must maintain the equality:
|
||||
// mOriginAttributes.mPrivateBrowsingId == mPrivateBrowsingId
|
||||
if (IsChrome()) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mOriginAttributes.mPrivateBrowsingId == 0);
|
||||
} else {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mOriginAttributes.mPrivateBrowsingId ==
|
||||
mPrivateBrowsingId);
|
||||
}
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BrowsingContext)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
|
@ -1354,6 +1610,9 @@ BrowsingContext::IPCInitializer BrowsingContext::GetIPCInitializer() {
|
|||
init.mParentId = mParent ? mParent->Id() : 0;
|
||||
init.mCached = IsCached();
|
||||
init.mWindowless = mWindowless;
|
||||
init.mUseRemoteTabs = mUseRemoteTabs;
|
||||
init.mUseRemoteSubframes = mUseRemoteSubframes;
|
||||
init.mOriginAttributes = mOriginAttributes;
|
||||
init.mFields = mFields.Fields();
|
||||
return init;
|
||||
}
|
||||
|
@ -1734,6 +1993,9 @@ void IPDLParamTraits<dom::BrowsingContext::IPCInitializer>::Write(
|
|||
WriteIPDLParam(aMessage, aActor, aInit.mParentId);
|
||||
WriteIPDLParam(aMessage, aActor, aInit.mCached);
|
||||
WriteIPDLParam(aMessage, aActor, aInit.mWindowless);
|
||||
WriteIPDLParam(aMessage, aActor, aInit.mUseRemoteTabs);
|
||||
WriteIPDLParam(aMessage, aActor, aInit.mUseRemoteSubframes);
|
||||
WriteIPDLParam(aMessage, aActor, aInit.mOriginAttributes);
|
||||
WriteIPDLParam(aMessage, aActor, aInit.mFields);
|
||||
}
|
||||
|
||||
|
@ -1745,6 +2007,10 @@ bool IPDLParamTraits<dom::BrowsingContext::IPCInitializer>::Read(
|
|||
!ReadIPDLParam(aMessage, aIterator, aActor, &aInit->mParentId) ||
|
||||
!ReadIPDLParam(aMessage, aIterator, aActor, &aInit->mCached) ||
|
||||
!ReadIPDLParam(aMessage, aIterator, aActor, &aInit->mWindowless) ||
|
||||
!ReadIPDLParam(aMessage, aIterator, aActor, &aInit->mUseRemoteTabs) ||
|
||||
!ReadIPDLParam(aMessage, aIterator, aActor,
|
||||
&aInit->mUseRemoteSubframes) ||
|
||||
!ReadIPDLParam(aMessage, aIterator, aActor, &aInit->mOriginAttributes) ||
|
||||
!ReadIPDLParam(aMessage, aIterator, aActor, &aInit->mFields)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "nsTArray.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsILoadInfo.h"
|
||||
#include "nsILoadContext.h"
|
||||
|
||||
class nsDocShellLoadState;
|
||||
class nsGlobalWindowOuter;
|
||||
|
@ -108,6 +109,7 @@ class WindowProxyHolder;
|
|||
FIELD(AllowPlugins, bool) \
|
||||
FIELD(AllowContentRetargeting, bool) \
|
||||
FIELD(AllowContentRetargetingOnChildren, bool) \
|
||||
FIELD(ForceEnableTrackingProtection, bool) \
|
||||
/* These field are used to store the states of autoplay media request on \
|
||||
* GeckoView only, and it would only be modified on the top level browsing \
|
||||
* context. */ \
|
||||
|
@ -136,7 +138,7 @@ class WindowProxyHolder;
|
|||
// Trees of BrowsingContexts should only ever contain nodes of the
|
||||
// same BrowsingContext::Type. This is enforced by asserts in the
|
||||
// BrowsingContext::Create* methods.
|
||||
class BrowsingContext : public nsISupports, public nsWrapperCache {
|
||||
class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
||||
MOZ_DECL_SYNCED_CONTEXT(BrowsingContext, MOZ_EACH_BC_FIELD)
|
||||
|
||||
public:
|
||||
|
@ -436,6 +438,7 @@ class BrowsingContext : public nsISupports, public nsWrapperCache {
|
|||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BrowsingContext)
|
||||
NS_DECL_NSILOADCONTEXT
|
||||
|
||||
const Children& GetChildren() { return mChildren; }
|
||||
const nsTArray<RefPtr<WindowContext>>& GetWindowContexts() {
|
||||
|
@ -504,19 +507,22 @@ class BrowsingContext : public nsISupports, public nsWrapperCache {
|
|||
* This object may be serialized over IPC.
|
||||
*/
|
||||
struct IPCInitializer {
|
||||
uint64_t mId;
|
||||
uint64_t mId = 0;
|
||||
|
||||
// IDs are used for Parent and Opener to allow for this object to be
|
||||
// deserialized before other BrowsingContext in the BrowsingContextGroup
|
||||
// have been initialized.
|
||||
uint64_t mParentId;
|
||||
uint64_t mParentId = 0;
|
||||
already_AddRefed<BrowsingContext> GetParent();
|
||||
already_AddRefed<BrowsingContext> GetOpener();
|
||||
|
||||
uint64_t GetOpenerId() const { return mozilla::Get<IDX_OpenerId>(mFields); }
|
||||
|
||||
bool mCached;
|
||||
bool mWindowless;
|
||||
bool mCached = false;
|
||||
bool mWindowless = false;
|
||||
bool mUseRemoteTabs = false;
|
||||
bool mUseRemoteSubframes = false;
|
||||
OriginAttributes mOriginAttributes;
|
||||
|
||||
FieldTuple mFields;
|
||||
};
|
||||
|
@ -542,6 +548,9 @@ class BrowsingContext : public nsISupports, public nsWrapperCache {
|
|||
bool PendingInitialization() const { return mPendingInitialization; };
|
||||
void SetPendingInitialization(bool aVal) { mPendingInitialization = aVal; };
|
||||
|
||||
const OriginAttributes& OriginAttributesRef() { return mOriginAttributes; }
|
||||
nsresult SetOriginAttributes(const OriginAttributes& aAttrs);
|
||||
|
||||
protected:
|
||||
virtual ~BrowsingContext();
|
||||
BrowsingContext(BrowsingContext* aParent, BrowsingContextGroup* aGroup,
|
||||
|
@ -554,6 +563,12 @@ class BrowsingContext : public nsISupports, public nsWrapperCache {
|
|||
BrowsingContext* FindWithSpecialName(const nsAString& aName,
|
||||
BrowsingContext& aRequestingContext);
|
||||
|
||||
// Is it early enough in the BrowsingContext's lifecycle that it is still
|
||||
// OK to set OriginAttributes?
|
||||
bool CanSetOriginAttributes();
|
||||
|
||||
void AssertOriginAttributesMatchPrivateBrowsing();
|
||||
|
||||
friend class ::nsOuterWindowProxy;
|
||||
friend class ::nsGlobalWindowOuter;
|
||||
friend class WindowContext;
|
||||
|
@ -699,6 +714,16 @@ class BrowsingContext : public nsISupports, public nsWrapperCache {
|
|||
JS::Heap<JSObject*> mWindowProxy;
|
||||
LocationProxy mLocation;
|
||||
|
||||
// OriginAttributes for this BrowsingContext. May not be changed after this
|
||||
// BrowsingContext is attached.
|
||||
OriginAttributes mOriginAttributes;
|
||||
|
||||
// Determines if private browsing should be used. May not be changed after
|
||||
// this BrowsingContext is attached. This field matches mOriginAttributes in
|
||||
// content Browsing Contexts. Currently treated as a binary value: 1 - in
|
||||
// private mode, 0 - not private mode.
|
||||
uint32_t mPrivateBrowsingId;
|
||||
|
||||
// True if Attach() has been called on this BrowsingContext already.
|
||||
bool mEverAttached : 1;
|
||||
|
||||
|
@ -727,6 +752,14 @@ class BrowsingContext : public nsISupports, public nsWrapperCache {
|
|||
// process.
|
||||
bool mEmbeddedByThisProcess : 1;
|
||||
|
||||
// Determines if remote (out-of-process) tabs should be used. May not be
|
||||
// changed after this BrowsingContext is attached.
|
||||
bool mUseRemoteTabs : 1;
|
||||
|
||||
// Determines if out-of-process iframes should be used. May not be changed
|
||||
// after this BrowsingContext is attached.
|
||||
bool mUseRemoteSubframes : 1;
|
||||
|
||||
// The start time of user gesture, this is only available if the browsing
|
||||
// context is in process.
|
||||
TimeStamp mUserGestureStart;
|
||||
|
|
|
@ -360,7 +360,6 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
|
|||
mDefaultLoadFlags(nsIRequest::LOAD_NORMAL),
|
||||
mFailedLoadType(0),
|
||||
mFrameType(FRAME_TYPE_REGULAR),
|
||||
mPrivateBrowsingId(0),
|
||||
mDisplayMode(nsIDocShell::DISPLAY_MODE_BROWSER),
|
||||
mJSRunToCompletionDepth(0),
|
||||
mTouchEventsOverride(nsIDocShell::TOUCHEVENTS_OVERRIDE_NONE),
|
||||
|
@ -387,13 +386,9 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
|
|||
mDisableMetaRefreshWhenInactive(false),
|
||||
mIsAppTab(false),
|
||||
mUseGlobalHistory(false),
|
||||
mUseRemoteTabs(false),
|
||||
mUseRemoteSubframes(false),
|
||||
mUseTrackingProtection(false),
|
||||
mDeviceSizeIsPageSize(false),
|
||||
mWindowDraggingAllowed(false),
|
||||
mInFrameSwap(false),
|
||||
mInheritPrivateBrowsingId(true),
|
||||
mCanExecuteScripts(false),
|
||||
mFiredUnloadEvent(false),
|
||||
mEODForCurrentDocument(false),
|
||||
|
@ -412,8 +407,6 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
|
|||
mWillChangeProcess(false),
|
||||
mWatchedByDevtools(false),
|
||||
mIsNavigating(false) {
|
||||
AssertOriginAttributesMatchPrivateBrowsing();
|
||||
|
||||
// If no outer window ID was provided, generate a new one.
|
||||
if (aContentWindowID == 0) {
|
||||
mContentWindowID = nsContentUtils::GenerateWindowId();
|
||||
|
@ -533,6 +526,12 @@ already_AddRefed<nsDocShell> nsDocShell::Create(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// If our BrowsingContext has private browsing enabled, update the number of
|
||||
// private browsing docshells.
|
||||
if (aBrowsingContext->UsePrivateBrowsing()) {
|
||||
ds->NotifyPrivateBrowsingChanged();
|
||||
}
|
||||
|
||||
// If our parent is present in this process, set up our parent now.
|
||||
RefPtr<BrowsingContext> parent = aBrowsingContext->GetParent();
|
||||
if (parent && parent->GetDocShell()) {
|
||||
|
@ -801,10 +800,12 @@ nsDocShell::LoadURI(nsDocShellLoadState* aLoadState, bool aSetNavigating) {
|
|||
BrowsingContext::Type bcType = mBrowsingContext->GetType();
|
||||
|
||||
// Set up the inheriting principal in LoadState.
|
||||
nsresult rv = aLoadState->SetupInheritingPrincipal(bcType, mOriginAttributes);
|
||||
nsresult rv = aLoadState->SetupInheritingPrincipal(
|
||||
bcType, mBrowsingContext->OriginAttributesRef());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aLoadState->SetupTriggeringPrincipal(mOriginAttributes);
|
||||
rv = aLoadState->SetupTriggeringPrincipal(
|
||||
mBrowsingContext->OriginAttributesRef());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aLoadState->CalculateLoadURIFlags();
|
||||
|
@ -1523,66 +1524,40 @@ nsDocShell::SetAllowJavascript(bool aAllowJavascript) {
|
|||
NS_IMETHODIMP
|
||||
nsDocShell::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing) {
|
||||
NS_ENSURE_ARG_POINTER(aUsePrivateBrowsing);
|
||||
AssertOriginAttributesMatchPrivateBrowsing();
|
||||
*aUsePrivateBrowsing = mPrivateBrowsingId > 0;
|
||||
return NS_OK;
|
||||
return mBrowsingContext->GetUsePrivateBrowsing(aUsePrivateBrowsing);
|
||||
}
|
||||
|
||||
void nsDocShell::NotifyPrivateBrowsingChanged() {
|
||||
MOZ_ASSERT(!mIsBeingDestroyed);
|
||||
|
||||
if (mAffectPrivateSessionLifetime) {
|
||||
if (UsePrivateBrowsing()) {
|
||||
IncreasePrivateDocShellCount();
|
||||
} else {
|
||||
DecreasePrivateDocShellCount();
|
||||
}
|
||||
}
|
||||
|
||||
nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mPrivacyObservers);
|
||||
while (iter.HasMore()) {
|
||||
nsWeakPtr ref = iter.GetNext();
|
||||
nsCOMPtr<nsIPrivacyTransitionObserver> obs = do_QueryReferent(ref);
|
||||
if (!obs) {
|
||||
mPrivacyObservers.RemoveElement(ref);
|
||||
} else {
|
||||
obs->PrivateModeChanged(UsePrivateBrowsing());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetUsePrivateBrowsing(bool aUsePrivateBrowsing) {
|
||||
if (!CanSetOriginAttributes()) {
|
||||
bool changed = aUsePrivateBrowsing != (mPrivateBrowsingId > 0);
|
||||
|
||||
return changed ? NS_ERROR_FAILURE : NS_OK;
|
||||
}
|
||||
|
||||
return SetPrivateBrowsing(aUsePrivateBrowsing);
|
||||
return mBrowsingContext->SetUsePrivateBrowsing(aUsePrivateBrowsing);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetPrivateBrowsing(bool aUsePrivateBrowsing) {
|
||||
MOZ_ASSERT(!mIsBeingDestroyed);
|
||||
|
||||
bool changed = aUsePrivateBrowsing != (mPrivateBrowsingId > 0);
|
||||
if (changed) {
|
||||
mPrivateBrowsingId = aUsePrivateBrowsing ? 1 : 0;
|
||||
|
||||
if (mItemType != typeChrome) {
|
||||
mOriginAttributes.SyncAttributesWithPrivateBrowsing(aUsePrivateBrowsing);
|
||||
}
|
||||
|
||||
if (mAffectPrivateSessionLifetime) {
|
||||
if (aUsePrivateBrowsing) {
|
||||
IncreasePrivateDocShellCount();
|
||||
} else {
|
||||
DecreasePrivateDocShellCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsTObserverArray<nsDocLoader*>::ForwardIterator iter(mChildList);
|
||||
while (iter.HasMore()) {
|
||||
nsCOMPtr<nsILoadContext> shell = do_QueryObject(iter.GetNext());
|
||||
if (shell) {
|
||||
shell->SetPrivateBrowsing(aUsePrivateBrowsing);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mPrivacyObservers);
|
||||
while (iter.HasMore()) {
|
||||
nsWeakPtr ref = iter.GetNext();
|
||||
nsCOMPtr<nsIPrivacyTransitionObserver> obs = do_QueryReferent(ref);
|
||||
if (!obs) {
|
||||
mPrivacyObservers.RemoveElement(ref);
|
||||
} else {
|
||||
obs->PrivateModeChanged(aUsePrivateBrowsing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AssertOriginAttributesMatchPrivateBrowsing();
|
||||
return NS_OK;
|
||||
return mBrowsingContext->SetPrivateBrowsing(aUsePrivateBrowsing);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1596,52 +1571,23 @@ nsDocShell::GetHasLoadedNonBlankURI(bool* aResult) {
|
|||
NS_IMETHODIMP
|
||||
nsDocShell::GetUseRemoteTabs(bool* aUseRemoteTabs) {
|
||||
NS_ENSURE_ARG_POINTER(aUseRemoteTabs);
|
||||
|
||||
*aUseRemoteTabs = mUseRemoteTabs;
|
||||
return NS_OK;
|
||||
return mBrowsingContext->GetUseRemoteTabs(aUseRemoteTabs);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetRemoteTabs(bool aUseRemoteTabs) {
|
||||
if (aUseRemoteTabs) {
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::DOMIPCEnabled,
|
||||
true);
|
||||
}
|
||||
|
||||
// Don't allow non-remote tabs with remote subframes.
|
||||
if (NS_WARN_IF(!aUseRemoteTabs && mUseRemoteSubframes)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
mUseRemoteTabs = aUseRemoteTabs;
|
||||
return NS_OK;
|
||||
return mBrowsingContext->SetRemoteTabs(aUseRemoteTabs);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetUseRemoteSubframes(bool* aUseRemoteSubframes) {
|
||||
NS_ENSURE_ARG_POINTER(aUseRemoteSubframes);
|
||||
|
||||
*aUseRemoteSubframes = mUseRemoteSubframes;
|
||||
return NS_OK;
|
||||
return mBrowsingContext->GetUseRemoteSubframes(aUseRemoteSubframes);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetRemoteSubframes(bool aUseRemoteSubframes) {
|
||||
static bool annotated = false;
|
||||
|
||||
if (aUseRemoteSubframes && !annotated) {
|
||||
annotated = true;
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::DOMFissionEnabled, true);
|
||||
}
|
||||
|
||||
// Don't allow non-remote tabs with remote subframes.
|
||||
if (NS_WARN_IF(aUseRemoteSubframes && !mUseRemoteTabs)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
mUseRemoteSubframes = aUseRemoteSubframes;
|
||||
return NS_OK;
|
||||
return mBrowsingContext->SetRemoteSubframes(aUseRemoteSubframes);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1650,7 +1596,6 @@ nsDocShell::SetAffectPrivateSessionLifetime(bool aAffectLifetime) {
|
|||
|
||||
bool change = aAffectLifetime != mAffectPrivateSessionLifetime;
|
||||
if (change && UsePrivateBrowsing()) {
|
||||
AssertOriginAttributesMatchPrivateBrowsing();
|
||||
if (aAffectLifetime) {
|
||||
IncreasePrivateDocShellCount();
|
||||
} else {
|
||||
|
@ -1839,18 +1784,6 @@ nsDocShell::SetAllowContentRetargetingOnChildren(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetInheritPrivateBrowsingId(bool* aInheritPrivateBrowsingId) {
|
||||
*aInheritPrivateBrowsingId = mInheritPrivateBrowsingId;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetInheritPrivateBrowsingId(bool aInheritPrivateBrowsingId) {
|
||||
mInheritPrivateBrowsingId = aInheritPrivateBrowsingId;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetFullscreenAllowed(bool* aFullscreenAllowed) {
|
||||
NS_ENSURE_ARG_POINTER(aFullscreenAllowed);
|
||||
|
@ -2629,9 +2562,6 @@ void nsDocShell::RecomputeCanExecuteScripts() {
|
|||
|
||||
nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) {
|
||||
bool wasFrame = IsFrame();
|
||||
#ifdef DEBUG
|
||||
bool wasPrivate = UsePrivateBrowsing();
|
||||
#endif
|
||||
|
||||
nsresult rv = nsDocLoader::SetDocLoaderParent(aParent);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -2678,10 +2608,8 @@ nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) {
|
|||
value = false;
|
||||
}
|
||||
SetAllowDNSPrefetch(mAllowDNSPrefetch && value);
|
||||
if (mInheritPrivateBrowsingId) {
|
||||
value = parentAsDocShell->GetAffectPrivateSessionLifetime();
|
||||
SetAffectPrivateSessionLifetime(value);
|
||||
}
|
||||
SetAffectPrivateSessionLifetime(
|
||||
parentAsDocShell->GetAffectPrivateSessionLifetime());
|
||||
uint32_t flags;
|
||||
if (NS_SUCCEEDED(parentAsDocShell->GetDefaultLoadFlags(&flags))) {
|
||||
SetDefaultLoadFlags(flags);
|
||||
|
@ -2694,12 +2622,6 @@ nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) {
|
|||
// like this that might be embedded within it.
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadContext> parentAsLoadContext(do_QueryInterface(parent));
|
||||
if (parentAsLoadContext && mInheritPrivateBrowsingId &&
|
||||
NS_SUCCEEDED(parentAsLoadContext->GetUsePrivateBrowsing(&value))) {
|
||||
SetPrivateBrowsing(value);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURIContentListener> parentURIListener(do_GetInterface(parent));
|
||||
if (parentURIListener) {
|
||||
mContentListener->SetParentContentListener(parentURIListener);
|
||||
|
@ -2713,9 +2635,6 @@ nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) {
|
|||
MaybeClearStorageAccessFlag();
|
||||
}
|
||||
|
||||
NS_ASSERTION(mInheritPrivateBrowsingId || wasPrivate == UsePrivateBrowsing(),
|
||||
"Private browsing state changed while inheritance was disabled");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2829,18 +2748,6 @@ nsDocShell::GetSameTypeRootTreeItemIgnoreBrowserBoundaries(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsDocShell::AssertOriginAttributesMatchPrivateBrowsing() {
|
||||
// Chrome docshells must not have a private browsing OriginAttribute
|
||||
// Content docshells must maintain the equality:
|
||||
// mOriginAttributes.mPrivateBrowsingId == mPrivateBrowsingId
|
||||
if (mItemType == typeChrome) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mOriginAttributes.mPrivateBrowsingId == 0);
|
||||
} else {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mOriginAttributes.mPrivateBrowsingId ==
|
||||
mPrivateBrowsingId);
|
||||
}
|
||||
}
|
||||
|
||||
bool nsDocShell::IsSandboxedFrom(BrowsingContext* aTargetBC) {
|
||||
// If no target then not sandboxed.
|
||||
if (!aTargetBC) {
|
||||
|
@ -3059,9 +2966,6 @@ nsDocShell::AddChild(nsIDocShellTreeItem* aChild) {
|
|||
childDocShell->SetUseGlobalHistory(true);
|
||||
}
|
||||
|
||||
Cast(childDocShell)->SetRemoteTabs(mUseRemoteTabs);
|
||||
Cast(childDocShell)->SetRemoteSubframes(mUseRemoteSubframes);
|
||||
|
||||
if (aChild->ItemType() != mItemType) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -3678,19 +3582,20 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI,
|
|||
do_GetService(NS_SSSERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI, flags,
|
||||
mOriginAttributes, nullptr, nullptr, &isStsHost);
|
||||
GetOriginAttributes(), nullptr, nullptr,
|
||||
&isStsHost);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HPKP, aURI, flags,
|
||||
mOriginAttributes, nullptr, nullptr,
|
||||
GetOriginAttributes(), nullptr, nullptr,
|
||||
&isPinnedHost);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
mozilla::dom::ContentChild* cc =
|
||||
mozilla::dom::ContentChild::GetSingleton();
|
||||
cc->SendIsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI, flags,
|
||||
mOriginAttributes, &isStsHost);
|
||||
GetOriginAttributes(), &isStsHost);
|
||||
cc->SendIsSecureURI(nsISiteSecurityService::HEADER_HPKP, aURI, flags,
|
||||
mOriginAttributes, &isPinnedHost);
|
||||
GetOriginAttributes(), &isPinnedHost);
|
||||
}
|
||||
|
||||
if (Preferences::GetBool("browser.xul.error_pages.expert_bad_cert",
|
||||
|
@ -4449,8 +4354,6 @@ nsDocShell::Destroy() {
|
|||
NS_ASSERTION(mItemType == typeContent || mItemType == typeChrome,
|
||||
"Unexpected item type in docshell");
|
||||
|
||||
AssertOriginAttributesMatchPrivateBrowsing();
|
||||
|
||||
nsCOMPtr<nsIObserverService> serv = services::GetObserverService();
|
||||
if (serv) {
|
||||
const char* msg = mItemType == typeContent
|
||||
|
@ -4558,12 +4461,8 @@ nsDocShell::Destroy() {
|
|||
// to break the cycle between us and the timers.
|
||||
CancelRefreshURITimers();
|
||||
|
||||
if (UsePrivateBrowsing()) {
|
||||
mPrivateBrowsingId = nsIScriptSecurityManager::DEFAULT_PRIVATE_BROWSING_ID;
|
||||
mOriginAttributes.SyncAttributesWithPrivateBrowsing(false);
|
||||
if (mAffectPrivateSessionLifetime) {
|
||||
DecreasePrivateDocShellCount();
|
||||
}
|
||||
if (UsePrivateBrowsing() && mAffectPrivateSessionLifetime) {
|
||||
DecreasePrivateDocShellCount();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -5100,7 +4999,6 @@ nsDocShell::SetTitle(const nsAString& aTitle) {
|
|||
}
|
||||
}
|
||||
|
||||
AssertOriginAttributesMatchPrivateBrowsing();
|
||||
if (mCurrentURI && mLoadType != LOAD_ERROR_PAGE) {
|
||||
UpdateGlobalHistoryTitle(mCurrentURI);
|
||||
}
|
||||
|
@ -6498,7 +6396,8 @@ nsresult nsDocShell::CreateAboutBlankContentViewer(
|
|||
|
||||
if (aPrincipal && !aPrincipal->IsSystemPrincipal() &&
|
||||
mItemType != typeChrome) {
|
||||
MOZ_ASSERT(aPrincipal->OriginAttributesRef() == mOriginAttributes);
|
||||
MOZ_ASSERT(aPrincipal->OriginAttributesRef() ==
|
||||
mBrowsingContext->OriginAttributesRef());
|
||||
}
|
||||
|
||||
// Make sure timing is created. But first record whether we had it
|
||||
|
@ -11950,63 +11849,27 @@ nsDocShell::GetAssociatedWindow(mozIDOMWindowProxy** aWindow) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetTopWindow(mozIDOMWindowProxy** aWindow) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> win = GetWindow();
|
||||
if (win) {
|
||||
win = win->GetInProcessTop();
|
||||
}
|
||||
win.forget(aWindow);
|
||||
return NS_OK;
|
||||
return mBrowsingContext->GetTopWindow(aWindow);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetTopFrameElement(Element** aElement) {
|
||||
*aElement = nullptr;
|
||||
nsCOMPtr<nsPIDOMWindowOuter> win = GetWindow();
|
||||
if (!win) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> top = win->GetInProcessScriptableTop();
|
||||
NS_ENSURE_TRUE(top, NS_ERROR_FAILURE);
|
||||
|
||||
// GetFrameElementInternal, /not/ GetScriptableFrameElement -- if |top| is
|
||||
// inside <iframe mozbrowser>, we want to return the iframe, not null.
|
||||
// And we want to cross the content/chrome boundary.
|
||||
RefPtr<Element> elt = top->GetFrameElementInternal();
|
||||
elt.forget(aElement);
|
||||
return NS_OK;
|
||||
return mBrowsingContext->GetTopFrameElement(aElement);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetNestedFrameId(uint64_t* aId) {
|
||||
*aId = 0;
|
||||
return NS_OK;
|
||||
return mBrowsingContext->GetNestedFrameId(aId);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetUseTrackingProtection(bool* aUseTrackingProtection) {
|
||||
*aUseTrackingProtection = false;
|
||||
|
||||
if (mUseTrackingProtection ||
|
||||
StaticPrefs::privacy_trackingprotection_enabled() ||
|
||||
(UsePrivateBrowsing() &&
|
||||
StaticPrefs::privacy_trackingprotection_pbmode_enabled())) {
|
||||
*aUseTrackingProtection = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<nsDocShell> parent = GetInProcessParentDocshell();
|
||||
if (parent) {
|
||||
return parent->GetUseTrackingProtection(aUseTrackingProtection);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return mBrowsingContext->GetUseTrackingProtection(aUseTrackingProtection);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetUseTrackingProtection(bool aUseTrackingProtection) {
|
||||
mUseTrackingProtection = aUseTrackingProtection;
|
||||
return NS_OK;
|
||||
return mBrowsingContext->SetUseTrackingProtection(aUseTrackingProtection);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -12642,42 +12505,14 @@ NS_IMETHODIMP nsDocShell::GetIsTopLevelContentDocShell(
|
|||
NS_IMETHODIMP
|
||||
nsDocShell::GetScriptableOriginAttributes(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aVal) {
|
||||
return GetOriginAttributes(aCx, aVal);
|
||||
return mBrowsingContext->GetScriptableOriginAttributes(aCx, aVal);
|
||||
}
|
||||
|
||||
// Implements nsIDocShell.GetOriginAttributes()
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetOriginAttributes(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aVal) {
|
||||
bool ok = ToJSValue(aCx, mOriginAttributes, aVal);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool nsDocShell::CanSetOriginAttributes() {
|
||||
MOZ_ASSERT(mChildList.IsEmpty());
|
||||
if (!mChildList.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Bug 1273058 - mContentViewer should be null when setting origin
|
||||
// attributes.
|
||||
if (mContentViewer) {
|
||||
Document* doc = mContentViewer->GetDocument();
|
||||
if (doc) {
|
||||
nsIURI* uri = doc->GetDocumentURI();
|
||||
if (!uri) {
|
||||
return false;
|
||||
}
|
||||
nsCString uriSpec = uri->GetSpecOrDefault();
|
||||
MOZ_ASSERT(uriSpec.EqualsLiteral("about:blank"));
|
||||
if (!uriSpec.EqualsLiteral("about:blank")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return mBrowsingContext->GetScriptableOriginAttributes(aCx, aVal);
|
||||
}
|
||||
|
||||
bool nsDocShell::ServiceWorkerAllowedToControlWindow(nsIPrincipal* aPrincipal,
|
||||
|
@ -12703,26 +12538,7 @@ bool nsDocShell::ServiceWorkerAllowedToControlWindow(nsIPrincipal* aPrincipal,
|
|||
|
||||
nsresult nsDocShell::SetOriginAttributes(const OriginAttributes& aAttrs) {
|
||||
MOZ_ASSERT(!mIsBeingDestroyed);
|
||||
|
||||
if (!CanSetOriginAttributes()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
AssertOriginAttributesMatchPrivateBrowsing();
|
||||
mOriginAttributes = aAttrs;
|
||||
|
||||
bool isPrivate = mOriginAttributes.mPrivateBrowsingId !=
|
||||
nsIScriptSecurityManager::DEFAULT_PRIVATE_BROWSING_ID;
|
||||
// Chrome docshell can not contain OriginAttributes.mPrivateBrowsingId
|
||||
if (mItemType == typeChrome && isPrivate) {
|
||||
mOriginAttributes.mPrivateBrowsingId =
|
||||
nsIScriptSecurityManager::DEFAULT_PRIVATE_BROWSING_ID;
|
||||
}
|
||||
|
||||
SetPrivateBrowsing(isPrivate);
|
||||
AssertOriginAttributesMatchPrivateBrowsing();
|
||||
|
||||
return NS_OK;
|
||||
return mBrowsingContext->SetOriginAttributes(aAttrs);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -13029,7 +12845,7 @@ nsDocShell::GetAwaitingLargeAlloc(bool* aResult) {
|
|||
|
||||
NS_IMETHODIMP_(void)
|
||||
nsDocShell::GetOriginAttributes(mozilla::OriginAttributes& aAttrs) {
|
||||
aAttrs = mOriginAttributes;
|
||||
mBrowsingContext->GetOriginAttributes(aAttrs);
|
||||
}
|
||||
|
||||
HTMLEditor* nsIDocShell::GetHTMLEditor() {
|
||||
|
|
|
@ -430,7 +430,7 @@ class nsDocShell final : public nsDocLoader,
|
|||
}
|
||||
|
||||
const mozilla::OriginAttributes& GetOriginAttributes() {
|
||||
return mOriginAttributes;
|
||||
return mBrowsingContext->OriginAttributesRef();
|
||||
}
|
||||
|
||||
// Determine whether this docshell corresponds to the given history entry,
|
||||
|
@ -989,10 +989,6 @@ class nsDocShell final : public nsDocLoader,
|
|||
// Convenience method for getting our parent docshell. Can return null
|
||||
already_AddRefed<nsDocShell> GetInProcessParentDocshell();
|
||||
|
||||
// Helper assertion to enforce that mInPrivateBrowsing is in sync with
|
||||
// OriginAttributes.mPrivateBrowsingId
|
||||
void AssertOriginAttributesMatchPrivateBrowsing();
|
||||
|
||||
// Internal implementation of nsIDocShell::FirePageHideNotification.
|
||||
// If aSkipCheckingDynEntries is true, it will not try to remove dynamic
|
||||
// subframe entries. This is to avoid redundant RemoveDynEntries calls in all
|
||||
|
@ -1096,6 +1092,9 @@ class nsDocShell final : public nsDocLoader,
|
|||
nsresult HandleSameDocumentNavigation(nsDocShellLoadState* aLoadState,
|
||||
SameDocumentNavigationState& aState);
|
||||
|
||||
// Called when the Private Browsing state of a nsDocShell changes.
|
||||
void NotifyPrivateBrowsingChanged();
|
||||
|
||||
private: // data members
|
||||
static nsIURIFixup* sURIFixup;
|
||||
|
||||
|
@ -1111,7 +1110,6 @@ class nsDocShell final : public nsDocLoader,
|
|||
nsTObserverArray<nsWeakPtr> mPrivacyObservers;
|
||||
nsTObserverArray<nsWeakPtr> mReflowObservers;
|
||||
nsTObserverArray<nsWeakPtr> mScrollObservers;
|
||||
mozilla::OriginAttributes mOriginAttributes;
|
||||
mozilla::UniquePtr<mozilla::dom::ClientSource> mInitialClientSource;
|
||||
nsCOMPtr<nsINetworkInterceptController> mInterceptController;
|
||||
RefPtr<nsDOMNavigationTiming> mTiming;
|
||||
|
@ -1242,13 +1240,6 @@ class nsDocShell final : public nsDocLoader,
|
|||
// Are we a regular frame, a browser frame, or an app frame?
|
||||
FrameType mFrameType;
|
||||
|
||||
// This represents the state of private browsing in the docshell.
|
||||
// Currently treated as a binary value: 1 - in private mode, 0 - not private
|
||||
// mode On content docshells mPrivateBrowsingId ==
|
||||
// mOriginAttributes.mPrivateBrowsingId On chrome docshells this value will be
|
||||
// set, but not have the corresponding origin attribute set.
|
||||
uint32_t mPrivateBrowsingId;
|
||||
|
||||
// This represents the CSS display-mode we are currently using. This is mostly
|
||||
// used for media queries.
|
||||
DisplayMode mDisplayMode;
|
||||
|
@ -1308,13 +1299,9 @@ class nsDocShell final : public nsDocLoader,
|
|||
bool mDisableMetaRefreshWhenInactive : 1;
|
||||
bool mIsAppTab : 1;
|
||||
bool mUseGlobalHistory : 1;
|
||||
bool mUseRemoteTabs : 1;
|
||||
bool mUseRemoteSubframes : 1;
|
||||
bool mUseTrackingProtection : 1;
|
||||
bool mDeviceSizeIsPageSize : 1;
|
||||
bool mWindowDraggingAllowed : 1;
|
||||
bool mInFrameSwap : 1;
|
||||
bool mInheritPrivateBrowsingId : 1;
|
||||
|
||||
// Because scriptability depends on the mAllowJavascript values of our
|
||||
// ancestors, we cache the effective scriptability and recompute it when
|
||||
|
|
|
@ -238,15 +238,6 @@ interface nsIDocShell : nsIDocShellTreeItem
|
|||
*/
|
||||
[infallible] attribute boolean allowContentRetargetingOnChildren;
|
||||
|
||||
/**
|
||||
* True if this docShell should inherit the private browsing ID from
|
||||
* its parent when reparented.
|
||||
*
|
||||
* NOTE: This should *not* be set false in new code, or for docShells
|
||||
* inserted anywhere other than as children of panels.
|
||||
*/
|
||||
[infallible] attribute boolean inheritPrivateBrowsingId;
|
||||
|
||||
/**
|
||||
* Get an array of this docShell and its children.
|
||||
*
|
||||
|
|
|
@ -2049,7 +2049,9 @@ nsresult nsFrameLoader::MaybeCreateDocShell() {
|
|||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
mPendingBrowsingContext->EnsureAttached();
|
||||
if (!EnsureBrowsingContextAttached()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// nsDocShell::Create will attach itself to the passed browsing
|
||||
// context inside of nsDocShell::Create
|
||||
|
@ -2137,37 +2139,6 @@ nsresult nsFrameLoader::MaybeCreateDocShell() {
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
OriginAttributes attrs;
|
||||
if (parentDocShell->ItemType() == docShell->ItemType()) {
|
||||
attrs = parentDocShell->GetOriginAttributes();
|
||||
}
|
||||
|
||||
// Inherit origin attributes from parent document if
|
||||
// 1. It's in a content docshell.
|
||||
// 2. its nodePrincipal is not a SystemPrincipal.
|
||||
// 3. It's not a mozbrowser frame.
|
||||
//
|
||||
// For example, firstPartyDomain is computed from top-level document, it
|
||||
// doesn't exist in the top-level docshell.
|
||||
if (parentIsContent && !doc->NodePrincipal()->IsSystemPrincipal() &&
|
||||
!OwnerIsMozBrowserFrame()) {
|
||||
OriginAttributes oa = doc->NodePrincipal()->OriginAttributesRef();
|
||||
|
||||
// Assert on the firstPartyDomain from top-level docshell should be empty
|
||||
MOZ_ASSERT_IF(mIsTopLevelContent, attrs.mFirstPartyDomain.IsEmpty());
|
||||
|
||||
// So far we want to make sure Inherit doesn't override any other origin
|
||||
// attribute than firstPartyDomain.
|
||||
MOZ_ASSERT(
|
||||
attrs.mUserContextId == oa.mUserContextId,
|
||||
"docshell and document should have the same userContextId attribute.");
|
||||
MOZ_ASSERT(attrs.mPrivateBrowsingId == oa.mPrivateBrowsingId,
|
||||
"docshell and document should have the same privateBrowsingId "
|
||||
"attribute.");
|
||||
|
||||
attrs = oa;
|
||||
}
|
||||
|
||||
if (OwnerIsMozBrowserFrame()) {
|
||||
docShell->SetFrameType(nsIDocShell::FRAME_TYPE_BROWSER);
|
||||
} else if (mPendingBrowsingContext->GetParent()) {
|
||||
|
@ -2185,19 +2156,6 @@ nsresult nsFrameLoader::MaybeCreateDocShell() {
|
|||
}
|
||||
ApplySandboxFlags(sandboxFlags);
|
||||
|
||||
// Grab the userContextId from owner
|
||||
nsresult rv = PopulateOriginContextIdsFromAttributes(attrs);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool isPrivate = false;
|
||||
rv = parentDocShell->GetUsePrivateBrowsing(&isPrivate);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
attrs.SyncAttributesWithPrivateBrowsing(isPrivate);
|
||||
|
||||
if (OwnerIsMozBrowserFrame()) {
|
||||
// For inproc frames, set the docshell properties.
|
||||
nsAutoString name;
|
||||
|
@ -2208,25 +2166,8 @@ nsresult nsFrameLoader::MaybeCreateDocShell() {
|
|||
mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) ||
|
||||
mOwnerContent->HasAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::mozallowfullscreen));
|
||||
bool isPrivate = mOwnerContent->HasAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::mozprivatebrowsing);
|
||||
if (isPrivate) {
|
||||
if (docShell->GetHasLoadedNonBlankURI()) {
|
||||
nsContentUtils::ReportToConsoleNonLocalized(
|
||||
NS_LITERAL_STRING("We should not switch to Private Browsing after "
|
||||
"loading a document."),
|
||||
nsIScriptError::warningFlag,
|
||||
NS_LITERAL_CSTRING("mozprivatebrowsing"), nullptr);
|
||||
} else {
|
||||
// This handles the case where a frames private browsing is set by
|
||||
// chrome flags and not inherited by its parent.
|
||||
attrs.SyncAttributesWithPrivateBrowsing(isPrivate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
docShell->SetOriginAttributes(attrs);
|
||||
|
||||
// Typically there will be a window, however for some cases such as printing
|
||||
// the document is cloned with a docshell that has no window. We check
|
||||
// that the window exists to ensure we don't try to gather ancestors for
|
||||
|
@ -2537,7 +2478,9 @@ bool nsFrameLoader::TryRemoteBrowserInternal() {
|
|||
return false;
|
||||
}
|
||||
|
||||
mPendingBrowsingContext->EnsureAttached();
|
||||
if (!EnsureBrowsingContextAttached()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<ContentParent> openerContentParent;
|
||||
RefPtr<nsIPrincipal> openerContentPrincipal;
|
||||
|
@ -3576,3 +3519,88 @@ void nsFrameLoader::MaybeNotifyCrashed(BrowsingContext* aBrowsingContext,
|
|||
EventDispatcher::DispatchDOMEvent(mOwnerContent, nullptr, event, nullptr,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
bool nsFrameLoader::EnsureBrowsingContextAttached() {
|
||||
nsresult rv;
|
||||
|
||||
Document* parentDoc = mOwnerContent->OwnerDoc();
|
||||
MOZ_ASSERT(parentDoc);
|
||||
BrowsingContext* parentContext = parentDoc->GetBrowsingContext();
|
||||
MOZ_ASSERT(parentContext);
|
||||
|
||||
// Inherit the `use` flags from our parent BrowsingContext.
|
||||
bool usePrivateBrowsing = parentContext->UsePrivateBrowsing();
|
||||
bool useRemoteSubframes = parentContext->UseRemoteSubframes();
|
||||
bool useRemoteTabs = parentContext->UseRemoteTabs();
|
||||
|
||||
// Determine the exact OriginAttributes which should be used for our
|
||||
// BrowsingContext. This will be used to initialize OriginAttributes if the
|
||||
// BrowsingContext has not already been created.
|
||||
OriginAttributes attrs;
|
||||
if (mPendingBrowsingContext->IsContent()) {
|
||||
if (mPendingBrowsingContext->GetParent()) {
|
||||
MOZ_ASSERT(mPendingBrowsingContext->GetParent() == parentContext);
|
||||
parentContext->GetOriginAttributes(attrs);
|
||||
}
|
||||
|
||||
// Inherit the `mFirstPartyDomain` flag from our parent document's result
|
||||
// principal, if it was set.
|
||||
if (parentContext->IsContent() &&
|
||||
!parentDoc->NodePrincipal()->IsSystemPrincipal() &&
|
||||
!OwnerIsMozBrowserFrame()) {
|
||||
OriginAttributes docAttrs =
|
||||
parentDoc->NodePrincipal()->OriginAttributesRef();
|
||||
// We only want to inherit firstPartyDomain here, other attributes should
|
||||
// be constant.
|
||||
MOZ_ASSERT(attrs.EqualsIgnoringFPD(docAttrs));
|
||||
attrs.mFirstPartyDomain = docAttrs.mFirstPartyDomain;
|
||||
}
|
||||
|
||||
// Inherit the PrivateBrowsing flag across content/chrome boundaries.
|
||||
attrs.SyncAttributesWithPrivateBrowsing(usePrivateBrowsing);
|
||||
|
||||
// A <browser> element may have overridden userContextId or
|
||||
// geckoViewUserContextId.
|
||||
rv = PopulateOriginContextIdsFromAttributes(attrs);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// <iframe mozbrowser> is allowed to set `mozprivatebrowsing` to
|
||||
// force-enable private browsing.
|
||||
if (OwnerIsMozBrowserFrame()) {
|
||||
if (mOwnerContent->HasAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::mozprivatebrowsing)) {
|
||||
attrs.SyncAttributesWithPrivateBrowsing(true);
|
||||
usePrivateBrowsing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we've already been attached, return.
|
||||
if (mPendingBrowsingContext->EverAttached()) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mPendingBrowsingContext->UsePrivateBrowsing() ==
|
||||
usePrivateBrowsing);
|
||||
MOZ_DIAGNOSTIC_ASSERT(mPendingBrowsingContext->UseRemoteTabs() ==
|
||||
useRemoteTabs);
|
||||
MOZ_DIAGNOSTIC_ASSERT(mPendingBrowsingContext->UseRemoteSubframes() ==
|
||||
useRemoteSubframes);
|
||||
// Don't assert that our OriginAttributes match, as we could have different
|
||||
// OriginAttributes in the case where we were opened using window.open.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Initialize non-synced OriginAttributes and related fields.
|
||||
rv = mPendingBrowsingContext->SetOriginAttributes(attrs);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
rv = mPendingBrowsingContext->SetUsePrivateBrowsing(usePrivateBrowsing);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
rv = mPendingBrowsingContext->SetRemoteTabs(useRemoteTabs);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
rv = mPendingBrowsingContext->SetRemoteSubframes(useRemoteSubframes);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
// Finish attaching.
|
||||
mPendingBrowsingContext->EnsureAttached();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -470,6 +470,8 @@ class nsFrameLoader final : public nsStubMutationObserver,
|
|||
nsresult PopulateOriginContextIdsFromAttributes(
|
||||
mozilla::OriginAttributes& aAttr);
|
||||
|
||||
bool EnsureBrowsingContextAttached();
|
||||
|
||||
RefPtr<mozilla::dom::BrowsingContext> mPendingBrowsingContext;
|
||||
nsCOMPtr<nsIURI> mURIToLoad;
|
||||
nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
|
||||
|
|
Загрузка…
Ссылка в новой задаче