Bug 1270648 part 4 - Make fullscreen enabled flag not be affected after document is loaded. r?smaug
MozReview-Commit-ID: L2dMAUr63qv
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -2516,16 +2516,20 @@ nsDocShell::GetFullscreenAllowed(bool* a
// 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;
}
+ nsIDocument* doc = frameElement->GetUncomposedDoc();
+ if (!doc || !doc->FullscreenEnabledInternal()) {
+ return NS_OK;
+ }
}
// If we have no parent then we're the root docshell; no ancestor of the
// original docshell doesn't have a allowfullscreen attribute, so
// report fullscreen as allowed.
RefPtr<nsDocShell> parent = GetParentDocshell();
if (!parent) {
*aFullscreenAllowed = true;
--- a/dom/base/ImportManager.cpp
+++ b/dom/base/ImportManager.cpp
@@ -591,18 +591,20 @@ ImportLoader::OnStartRequest(nsIRequest*
DocumentFlavorHTML);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_ABORT_ERR);
// The imported document must know which master document it belongs to.
mDocument = do_QueryInterface(importDoc);
nsCOMPtr<nsIDocument> master = mImportParent->MasterDocument();
mDocument->SetMasterDocument(master);
- // We want to inherit the sandbox flags from the master document.
+ // We want to inherit the sandbox flags and fullscreen enabled flag
+ // from the master document.
mDocument->SetSandboxFlags(master->GetSandboxFlags());
+ mDocument->SetFullscreenEnabled(master->FullscreenEnabledInternal());
// We have to connect the blank document we created with the channel we opened,
// and create its own LoadGroup for it.
nsCOMPtr<nsIStreamListener> listener;
nsCOMPtr<nsILoadGroup> loadGroup;
channel->GetLoadGroup(getter_AddRefs(loadGroup));
nsCOMPtr<nsILoadGroup> newLoadGroup = do_CreateInstance(NS_LOADGROUP_CONTRACTID);
NS_ENSURE_TRUE(newLoadGroup, NS_ERROR_OUT_OF_MEMORY);
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1447,16 +1447,17 @@ nsIDocument::nsIDocument()
// unless we get a window, and in that case the docshell value will get
// &&-ed in, this is safe.
mAllowDNSPrefetch(true),
mIsBeingUsedAsImage(false),
mHasLinksToUpdate(false),
mFontFaceSetDirty(true),
mGetUserFontSetCalled(false),
mPostedFlushUserFontSet(false),
+ mFullscreenEnabled(false),
mPartID(0),
mDidFireDOMContentLoaded(true),
mHasScrollLinkedEffect(false),
mUserHasInteracted(false)
{
SetInDocument();
PR_INIT_CLIST(&mDOMMediaQueryLists);
@@ -2574,23 +2575,25 @@ nsDocument::StartDocumentLoad(const char
bool isSrcdocChannel;
inStrmChan->GetIsSrcdocChannel(&isSrcdocChannel);
if (isSrcdocChannel) {
mIsSrcdocDocument = true;
}
}
// If this document is being loaded by a docshell, copy its sandbox flags
- // to the document. These are immutable after being set here.
+ // to the document, and store the fullscreen enabled flag. These are
+ // immutable after being set here.
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(aContainer);
if (docShell) {
nsresult rv = docShell->GetSandboxFlags(&mSandboxFlags);
NS_ENSURE_SUCCESS(rv, rv);
WarnIfSandboxIneffective(docShell, mSandboxFlags, GetChannel());
+ mFullscreenEnabled = docShell->GetFullscreenAllowed();
}
// The CSP directive upgrade-insecure-requests not only applies to the
// toplevel document, but also to nested documents. Let's propagate that
// flag from the parent to the nested document.
nsCOMPtr<nsIDocShellTreeItem> treeItem = this->GetDocShell();
if (treeItem) {
nsCOMPtr<nsIDocShellTreeItem> sameTypeParent;
@@ -11729,24 +11732,19 @@ GetFullscreenError(nsIDocument* aDoc, bo
// in a Runnable, so don't use GetMozFullScreenEnabled() from a
// Runnable!
return nullptr;
}
if (!nsContentUtils::IsFullScreenApiEnabled()) {
return "FullscreenDeniedDisabled";
}
-
- // Ensure that all containing elements are <iframe> and have
- // allowfullscreen attribute set.
- nsCOMPtr<nsIDocShell> docShell(aDoc->GetDocShell());
- if (!docShell || !docShell->GetFullscreenAllowed()) {
+ if (!aDoc->FullscreenEnabledInternal()) {
return "FullscreenDeniedContainerNotAllowed";
}
-
return nullptr;
}
bool
nsDocument::FullscreenElementReadyCheck(Element* aElement,
bool aWasCallerChrome)
{
NS_ASSERTION(aElement,
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -2560,16 +2560,21 @@ public:
// Not const because all the full-screen goop is not const
virtual bool FullscreenEnabled() = 0;
virtual Element* GetFullscreenElement() = 0;
bool Fullscreen()
{
return !!GetFullscreenElement();
}
void ExitFullscreen();
+ bool FullscreenEnabledInternal() const { return mFullscreenEnabled; }
+ void SetFullscreenEnabled(bool aEnabled)
+ {
+ mFullscreenEnabled = aEnabled;
+ }
Element* GetMozPointerLockElement();
void MozExitPointerLock()
{
UnlockPointer(this);
}
bool Hidden() const
{
return mVisibilityState != mozilla::dom::VisibilityState::Visible;
@@ -3019,16 +3024,20 @@ protected:
bool mFontFaceSetDirty : 1;
// Has GetUserFontSet() been called?
bool mGetUserFontSetCalled : 1;
// Do we currently have an event posted to call FlushUserFontSet?
bool mPostedFlushUserFontSet : 1;
+ // Whether fullscreen is enabled for this document. This corresponds
+ // to the "fullscreen enabled flag" in the HTML spec.
+ bool mFullscreenEnabled : 1;
+
enum Type {
eUnknown, // should never be used
eHTML,
eXHTML,
eGenericXML,
eSVG,
eXUL
};
--- a/dom/xul/XULDocument.cpp
+++ b/dom/xul/XULDocument.cpp
@@ -377,16 +377,17 @@ XULDocument::StartDocumentLoad(const cha
}
}
}
// NOTE: If this ever starts calling nsDocument::StartDocumentLoad
// we'll possibly need to reset our content type afterwards.
mStillWalking = true;
mMayStartLayout = false;
mDocumentLoadGroup = do_GetWeakReference(aLoadGroup);
+ mFullscreenEnabled = true;
mChannel = aChannel;
// Get the URI. Note that this should match nsDocShell::OnLoadingSite
nsresult rv =
NS_GetFinalChannelURI(aChannel, getter_AddRefs(mDocumentURI));
NS_ENSURE_SUCCESS(rv, rv);
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -35338,16 +35338,22 @@
}
],
"html/semantics/document-metadata/the-base-element/base_srcdoc.html": [
{
"path": "html/semantics/document-metadata/the-base-element/base_srcdoc.html",
"url": "/html/semantics/document-metadata/the-base-element/base_srcdoc.html"
}
],
+ "html/semantics/embedded-content/the-iframe-element/iframe-allowfullscreen.html": [
+ {
+ "path": "html/semantics/embedded-content/the-iframe-element/iframe-allowfullscreen.html",
+ "url": "/html/semantics/embedded-content/the-iframe-element/iframe-allowfullscreen.html"
+ }
+ ],
"html/semantics/embedded-content/the-iframe-element/iframe-load-event.html": [
{
"path": "html/semantics/embedded-content/the-iframe-element/iframe-load-event.html",
"url": "/html/semantics/embedded-content/the-iframe-element/iframe-load-event.html"
}
],
"html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping.html": [
{
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/semantics/embedded-content/the-iframe-element/iframe-allowfullscreen.html.ini
@@ -0,0 +1,3 @@
+[iframe-allow-fullscreen.html.ini]
+ type: testharness
+ prefs: [full-screen-api.unprefix.enabled:true]
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-allowfullscreen.html
@@ -0,0 +1,63 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Check how allowfullscreen affects fullscreen enabled flag</title>
+<link rel="author" title="Xidorn Quan" href="https://www.upsuper.org">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/browsers.html#initialise-the-document-object">
+<link rel="help" href="https://fullscreen.spec.whatwg.org/#fullscreen-enabled-flag">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="log"></div>
+<script>
+ async_test(function(t) {
+ var iframe = document.createElement("iframe");
+ iframe.src = "support/blank.htm";
+ var eventWatcher = new EventWatcher(t, iframe, "load");
+ document.body.appendChild(iframe);
+ t.add_cleanup(function() {
+ document.body.removeChild(iframe);
+ });
+
+ assert_true(document.fullscreenEnabled, "Top level document has fullscreen enabled flag set");
+ eventWatcher.wait_for("load").then(t.step_func(function() {
+ assert_false(iframe.contentDocument.fullscreenEnabled, "Document inside iframe without allowfullscreen attribute should not have fullscreen enabled flag set");
+ iframe.setAttribute("allowfullscreen", true);
+ assert_false(iframe.contentDocument.fullscreenEnabled, "Setting allowfullscreen attribute after document load should not affect fullscreen enabled flag");
+ iframe.contentWindow.location.reload();
+ return eventWatcher.wait_for("load");
+ })).then(t.step_func(function() {
+ assert_true(iframe.contentDocument.fullscreenEnabled, "Fullscreen enabled flag should be set when a new document is loaded with allowfullscreen attribute present");
+ iframe.removeAttribute("allowfullscreen");
+ assert_true(iframe.contentDocument.fullscreenEnabled, "Removing allowfullscreen attribute should not affect fullscreen enabled flag");
+ iframe.contentWindow.location.reload();
+ return eventWatcher.wait_for("load");
+ })).then(t.step_func_done(function() {
+ assert_false(iframe.contentDocument.fullscreenEnabled, "Fullscreen enabled flag should be reset when a new document is loaded with allowfullscreen attribute absent");
+ }));
+ }, "iframe-allowfullscreen");
+
+ async_test(function(t) {
+ var iframe = document.createElement("iframe");
+ iframe.src = "support/blank.htm";
+ var eventWatcher = new EventWatcher(t, iframe, "load");
+ document.body.appendChild(iframe);
+ t.add_cleanup(function() {
+ document.body.removeChild(iframe);
+ });
+
+ var newWin;
+ assert_true(document.fullscreenEnabled, "Top level document has fullscreen enabled flag set");
+ eventWatcher.wait_for("load").then(t.step_func(function() {
+ assert_false(iframe.contentDocument.fullscreenEnabled, "Document inside iframe without allowfullscreen attribute should not have fullscreen enabled flag set");
+ newWin = iframe.contentWindow.open("support/blank.htm");
+ t.add_cleanup(function() {
+ newWin.close();
+ });
+ var newWinEventWatcher = new EventWatcher(t, newWin, "load");
+ return newWinEventWatcher.wait_for("load");
+ })).then(t.step_func_done(function() {
+ assert_true(newWin.document.fullscreenEnabled, "Document in the new window is a top level document, thus should has fullscreen enabled flag set");
+ }));
+ }, "iframe-allowfullscreen-dialog");
+</script>