diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml
index d271e12125..14998ec00c 100644
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -4749,6 +4749,16 @@
null
false
0
+
+
+
+
+
+
+
diff --git a/browser/components/sessionstore/SessionStore.jsm b/browser/components/sessionstore/SessionStore.jsm
index 94f9e103ec..5d98779bd3 100644
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -2996,6 +2996,10 @@ let SessionStoreInternal = {
else
tabbrowser.showTab(tab);
+ if (tabData.userContextId) {
+ tab.setUserContextId(tabData.userContextId);
+ }
+
if ("attributes" in tabData) {
// Ensure that we persist tab attributes restored from previous sessions.
Object.keys(tabData.attributes).forEach(a => TabAttributes.persist(a));
diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
index 7277377e05..19817d6173 100644
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -2521,20 +2521,25 @@ nsDocShell::GetFullscreenAllowed(bool* aFullscreenAllowed)
// Assume false until we determine otherwise...
*aFullscreenAllowed = false;
- // For non-browsers/apps, check that the enclosing iframe element
- // has the allowfullscreen attribute set to true. If any ancestor
- // iframe does not have mozallowfullscreen=true, then fullscreen is
- // prohibited.
nsCOMPtr win = GetWindow();
if (!win) {
return NS_OK;
}
nsCOMPtr frameElement = win->GetFrameElementInternal();
- if (frameElement &&
- frameElement->IsHTMLElement(nsGkAtoms::iframe) &&
- !frameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) &&
- !frameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::mozallowfullscreen)) {
- return NS_OK;
+ if (frameElement && !frameElement->IsXULElement()) {
+ // We do not allow document inside any containing element other
+ // than iframe to enter fullscreen.
+ if (!frameElement->IsHTMLElement(nsGkAtoms::iframe)) {
+ return NS_OK;
+ }
+ // If any ancestor iframe does not have allowfullscreen attribute
+ // set, then fullscreen is not allowed.
+ if (!frameElement->HasAttr(kNameSpaceID_None,
+ nsGkAtoms::allowfullscreen) &&
+ !frameElement->HasAttr(kNameSpaceID_None,
+ nsGkAtoms::mozallowfullscreen)) {
+ return NS_OK;
+ }
}
// If we have no parent then we're the root docshell; no ancestor of the
@@ -3292,23 +3297,23 @@ nsDocShell::SetDocLoaderParent(nsDocLoader* aParent)
nsString customUserAgent;
nsCOMPtr parentAsDocShell(do_QueryInterface(parent));
if (parentAsDocShell) {
- if (NS_SUCCEEDED(parentAsDocShell->GetAllowPlugins(&value))) {
+ if (mAllowPlugins && NS_SUCCEEDED(parentAsDocShell->GetAllowPlugins(&value))) {
SetAllowPlugins(value);
}
- if (NS_SUCCEEDED(parentAsDocShell->GetAllowJavascript(&value))) {
+ if (mAllowJavascript && NS_SUCCEEDED(parentAsDocShell->GetAllowJavascript(&value))) {
SetAllowJavascript(value);
}
- if (NS_SUCCEEDED(parentAsDocShell->GetAllowMetaRedirects(&value))) {
+ if (mAllowMetaRedirects && NS_SUCCEEDED(parentAsDocShell->GetAllowMetaRedirects(&value))) {
SetAllowMetaRedirects(value);
}
- if (NS_SUCCEEDED(parentAsDocShell->GetAllowSubframes(&value))) {
+ if (mAllowSubframes && NS_SUCCEEDED(parentAsDocShell->GetAllowSubframes(&value))) {
SetAllowSubframes(value);
}
if (NS_SUCCEEDED(parentAsDocShell->GetAllowImages(&value))) {
SetAllowImages(value);
}
- SetAllowMedia(parentAsDocShell->GetAllowMedia());
- if (NS_SUCCEEDED(parentAsDocShell->GetAllowWindowControl(&value))) {
+ SetAllowMedia(parentAsDocShell->GetAllowMedia() && mAllowMedia);
+ if (mAllowWindowControl && NS_SUCCEEDED(parentAsDocShell->GetAllowWindowControl(&value))) {
SetAllowWindowControl(value);
}
SetAllowContentRetargeting(
@@ -3326,7 +3331,7 @@ nsDocShell::SetDocLoaderParent(nsDocLoader* aParent)
if (NS_FAILED(parentAsDocShell->GetAllowDNSPrefetch(&value))) {
value = false;
}
- SetAllowDNSPrefetch(value);
+ SetAllowDNSPrefetch(mAllowDNSPrefetch && value);
value = parentAsDocShell->GetAffectPrivateSessionLifetime();
SetAffectPrivateSessionLifetime(value);
uint32_t flags;
@@ -3470,18 +3475,23 @@ nsDocShell::CanAccessItem(nsIDocShellTreeItem* aTargetItem,
nsCOMPtr targetDS = do_QueryInterface(aTargetItem);
nsCOMPtr accessingDS = do_QueryInterface(aAccessingItem);
- if (!!targetDS != !!accessingDS) {
- // We must be able to convert both or neither to nsIDocShell.
+ if (!targetDS || !accessingDS) {
+ // We must be able to convert both to nsIDocShell.
return false;
}
- if (targetDS && accessingDS &&
- (targetDS->GetIsInBrowserElement() !=
- accessingDS->GetIsInBrowserElement() ||
- targetDS->GetAppId() != accessingDS->GetAppId())) {
+ if (targetDS->GetIsInBrowserElement() != accessingDS->GetIsInBrowserElement() ||
+ targetDS->GetAppId() != accessingDS->GetAppId()) {
return false;
}
+ // A private document can't access a non-private one, and vice versa.
+ if (static_cast(targetDS.get())->UsePrivateBrowsing() !=
+ static_cast(accessingDS.get())->UsePrivateBrowsing()) {
+ return false;
+ }
+
+
nsCOMPtr accessingRoot;
aAccessingItem->GetSameTypeRootTreeItem(getter_AddRefs(accessingRoot));
@@ -3984,6 +3994,7 @@ nsDocShell::AddChild(nsIDocShellTreeItem* aChild)
}
aChild->SetTreeOwner(mTreeOwner);
+ childDocShell->SetUserContextId(mUserContextId);
nsCOMPtr childAsDocShell(do_QueryInterface(aChild));
if (!childAsDocShell) {
@@ -12580,13 +12591,9 @@ nsDocShell::ShouldDiscardLayoutState(nsIHttpChannel* aChannel)
}
// figure out if SH should be saving layout state
- nsCOMPtr securityInfo;
- bool noStore = false, noCache = false;
- aChannel->GetSecurityInfo(getter_AddRefs(securityInfo));
+ bool noStore = false;
aChannel->IsNoStoreResponse(&noStore);
- aChannel->IsNoCacheResponse(&noCache);
-
- return (noStore || (noCache && securityInfo));
+ return noStore;
}
NS_IMETHODIMP
@@ -13911,6 +13918,17 @@ NS_IMETHODIMP
nsDocShell::SetUserContextId(uint32_t aUserContextId)
{
mUserContextId = aUserContextId;
+
+ nsTObserverArray::ForwardIterator iter(mChildList);
+ while (iter.HasMore()) {
+ nsCOMPtr docshell = do_QueryObject(iter.GetNext());
+ if (!docshell || docshell->ItemType() != ItemType()) {
+ continue;
+ }
+
+ docshell->SetUserContextId(aUserContextId);
+ }
+
return NS_OK;
}
@@ -14066,7 +14084,9 @@ nsDocShell::GetAsyncPanZoomEnabled(bool* aOut)
return NS_OK;
}
- *aOut = false;
+ // If we don't have a presShell, fall back to the default platform value of
+ // whether or not APZ is enabled.
+ *aOut = gfxPlatform::AsyncPanZoomEnabled();
return NS_OK;
}
@@ -14396,9 +14416,11 @@ nsDocShell::InFrameSwap()
NS_IMETHODIMP
nsDocShell::IssueWarning(uint32_t aWarning, bool aAsError)
{
- nsCOMPtr doc = mContentViewer->GetDocument();
- if (doc) {
- doc->WarnOnceAbout(nsIDocument::DeprecatedOperations(aWarning), aAsError);
+ if (mContentViewer) {
+ nsCOMPtr doc = mContentViewer->GetDocument();
+ if (doc) {
+ doc->WarnOnceAbout(nsIDocument::DeprecatedOperations(aWarning), aAsError);
+ }
}
return NS_OK;
}
diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h
index a68a40f386..70e1f32065 100644
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -235,7 +235,6 @@ public:
NS_IMETHOD GetUseRemoteTabs(bool*) override;
NS_IMETHOD SetRemoteTabs(bool) override;
NS_IMETHOD GetOriginAttributes(JS::MutableHandle) override;
- NS_IMETHOD SetUserContextId(uint32_t);
// Restores a cached presentation from history (mLSHE).
// This method swaps out the content viewer and simulates loads for
diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl
index c78b5e44b6..9aa4889a83 100644
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -46,7 +46,7 @@ interface nsITabParent;
typedef unsigned long nsLoadFlags;
-[scriptable, builtinclass, uuid(bc3524bd-023c-4fc8-ace1-472bc999fb12)]
+[scriptable, builtinclass, uuid(98358234-3936-4b95-b051-fcda4e55b52d)]
interface nsIDocShell : nsIDocShellTreeItem
{
/**
@@ -1079,6 +1079,11 @@ interface nsIDocShell : nsIDocShellTreeItem
* @see https://html.spec.whatwg.org/#dom-history-scroll-restoration
*/
attribute boolean currentScrollRestorationIsManual;
+
+ /*
+ * Sets the user context ID for this docshell.
+ */
+ void setUserContextId(in unsigned long aUserContextId);
};
[scriptable, builtinclass, uuid(395c6a79-80ae-4ede-9e05-93bee6c3d9a1)]
diff --git a/docshell/test/chrome/bug112564_window.xul b/docshell/test/chrome/bug112564_window.xul
index 3f79a7c767..3e3fb66457 100644
--- a/docshell/test/chrome/bug112564_window.xul
+++ b/docshell/test/chrome/bug112564_window.xul
@@ -84,8 +84,9 @@
}
function testsIterator() {
- // Load a secure page with a no-store header, followed by a simple page
- // On pagehide, first page should report it is not being persisted
+ // Load a secure page with a no-cache header, followed by a simple page.
+ // no-cache should not interfere with the bfcache in the way no-store
+ // does.
var test1DocURI = "https://example.com:443/tests/docshell/test/chrome/112564_nocache.html";
gExpected = [{type: "pagehide", persisted: true},
@@ -97,18 +98,16 @@
var test2Doc = "data:text/html,test2" +
"test2";
- gExpected = [{type: "pagehide", title: "test1", persisted: false},
- {type: "unload", title: "test1"},
+ gExpected = [{type: "pagehide", title: "test1", persisted: true},
{type: "load", title: "test2"},
{type: "pageshow", title: "test2", persisted: false}];
gBrowser.loadURI(test2Doc);
yield undefined;
- // Now go back in history. First page should not have been cached.
+ // Now go back in history. First page has been cached.
// Check persisted property to confirm
gExpected = [{type: "pagehide", title: "test2", persisted: true},
- {type: "load", title: "test1"},
- {type: "pageshow", title: "test1", persisted: false}];
+ {type: "pageshow", title: "test1", persisted: true}];
gBrowser.goBack();
yield undefined;
}
diff --git a/docshell/test/chrome/bug215405_window.xul b/docshell/test/chrome/bug215405_window.xul
index ef2dc7f90c..d06df4eb74 100644
--- a/docshell/test/chrome/bug215405_window.xul
+++ b/docshell/test/chrome/bug215405_window.xul
@@ -113,7 +113,8 @@
// https no-cache
testName = "[nocache]";
- // Load a page with a no-cache header
+ // Load a page with a no-cache header. This should not be
+ // restricted like no-store (bug 567365)
gBrowser.loadURI(nocacheURI);
yield undefined;
@@ -141,19 +142,19 @@
yield undefined;
- // Now go back in history. First page should not have been cached.
+ // Now go back in history to the cached page.
gBrowser.goBack();
yield undefined;
- // First uncacheable page will now be reloaded. Check scroll position
- // restored, and form contents not
+ // First page will now be reloaded. Check scroll position
+ // and form contents are restored
is(gBrowser.contentWindow.scrollX, scrollX, testName +
" horizontal axis scroll position not correctly restored");
is(gBrowser.contentWindow.scrollY, scrollY, testName +
" vertical axis scroll position not correctly restored");
var formValue = gBrowser.contentDocument.getElementById("inp").value;
- isnot(formValue, text, testName + " form value incorrectly restored");
+ is(formValue, text, testName + " form value not correctly restored");
// nextTest has to be called from here, as no events are fired in this
// step
diff --git a/dom/base/nsAttrValueInlines.h b/dom/base/nsAttrValueInlines.h
index 7c8cb21ecf..c873c7fa05 100644
--- a/dom/base/nsAttrValueInlines.h
+++ b/dom/base/nsAttrValueInlines.h
@@ -1,3 +1,5 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@@ -8,18 +10,11 @@
#include
#include "nsAttrValue.h"
+#include "mozilla/Attributes.h"
struct MiscContainer;
-namespace mozilla {
-template<>
-struct HasDangerousPublicDestructor
-{
- static const bool value = true;
-};
-}
-
-struct MiscContainer
+struct MiscContainer final
{
typedef nsAttrValue::ValueType ValueType;
@@ -70,6 +65,10 @@ struct MiscContainer
mValue.mCached = 0;
}
+protected:
+ // Only nsAttrValue should be able to delete us.
+ friend class nsAttrValue;
+
~MiscContainer()
{
if (IsRefCounted()) {
@@ -79,6 +78,7 @@ struct MiscContainer
MOZ_COUNT_DTOR(MiscContainer);
}
+public:
bool GetString(nsAString& aString) const;
inline bool IsRefCounted() const
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
index e75b5441b6..52777001c3 100644
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -11961,18 +11961,15 @@ nsDocument::IsFullScreenEnabled(bool aCallerIsChrome, bool aLogFailure)
return false;
}
- // Ensure that all ancestor