зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1606660 - Move allowfullscreen checks to the browsing context. r=nika
So that they work properly on fission iframes. Differential Revision: https://phabricator.services.mozilla.com/D78702
This commit is contained in:
Родитель
9890093d16
Коммит
6b709b5f55
|
@ -16,6 +16,7 @@
|
|||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/HTMLEmbedElement.h"
|
||||
#include "mozilla/dom/HTMLIFrameElement.h"
|
||||
#include "mozilla/dom/Location.h"
|
||||
#include "mozilla/dom/LocationBinding.h"
|
||||
|
@ -293,6 +294,10 @@ already_AddRefed<BrowsingContext> BrowsingContext::CreateDetached(
|
|||
context->mFields.SetWithoutSyncing<IDX_AllowContentRetargetingOnChildren>(
|
||||
allowContentRetargeting);
|
||||
|
||||
// Assume top allows fullscreen for its children unless otherwise stated.
|
||||
// Subframes start with it false unless otherwise noted in SetEmbedderElement.
|
||||
context->mFields.SetWithoutSyncing<IDX_FullscreenAllowedByOwner>(!aParent);
|
||||
|
||||
const bool allowPlugins = inherit ? inherit->GetAllowPlugins() : true;
|
||||
context->mFields.SetWithoutSyncing<IDX_AllowPlugins>(allowPlugins);
|
||||
|
||||
|
@ -470,11 +475,34 @@ void BrowsingContext::CleanUpDanglingRemoteOuterWindowProxies(
|
|||
js::RemapRemoteWindowProxies(aCx, &cb, aOuter);
|
||||
}
|
||||
|
||||
bool BrowsingContext::FullscreenAllowed() const {
|
||||
for (auto* current = this; current; current = current->GetParent()) {
|
||||
if (!current->GetFullscreenAllowedByOwner()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool OwnerAllowsFullscreen(const Element& aEmbedder) {
|
||||
if (aEmbedder.IsXULElement()) {
|
||||
return !aEmbedder.HasAttr(nsGkAtoms::disablefullscreen);
|
||||
}
|
||||
if (const auto* iframe = HTMLIFrameElement::FromNode(aEmbedder)) {
|
||||
return iframe->AllowFullscreen();
|
||||
}
|
||||
if (const auto* embed = HTMLEmbedElement::FromNode(aEmbedder)) {
|
||||
return embed->AllowFullscreen();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void BrowsingContext::SetEmbedderElement(Element* aEmbedder) {
|
||||
mEmbeddedByThisProcess = true;
|
||||
|
||||
// Update embedder-element-specific fields in a shared transaction.
|
||||
// this when clearing our embedder, as we're being destroyed either way.
|
||||
// Don't do this when clearing our embedder, as we're being destroyed either
|
||||
// way.
|
||||
if (aEmbedder) {
|
||||
Transaction txn;
|
||||
txn.SetEmbedderElementType(Some(aEmbedder->LocalName()));
|
||||
|
@ -482,6 +510,7 @@ void BrowsingContext::SetEmbedderElement(Element* aEmbedder) {
|
|||
do_QueryInterface(aEmbedder->GetOwnerGlobal())) {
|
||||
txn.SetEmbedderInnerWindowId(inner->WindowID());
|
||||
}
|
||||
txn.SetFullscreenAllowedByOwner(OwnerAllowsFullscreen(*aEmbedder));
|
||||
if (XRE_IsParentProcess() && IsTopContent()) {
|
||||
nsAutoString messageManagerGroup;
|
||||
if (aEmbedder->IsXULElement()) {
|
||||
|
@ -2024,6 +2053,11 @@ bool BrowsingContext::CanSet(FieldIndex<IDX_AllowPlugins>,
|
|||
return CheckOnlyOwningProcessCanSet(aSource);
|
||||
}
|
||||
|
||||
bool BrowsingContext::CanSet(FieldIndex<IDX_FullscreenAllowedByOwner>,
|
||||
const bool& aAllowed, ContentParent* aSource) {
|
||||
return CheckOnlyEmbedderCanSet(aSource);
|
||||
}
|
||||
|
||||
// We map `watchedByDevTools` WebIDL attribute to `watchedByDevToolsInternal`
|
||||
// BC field. And we map it to the top level BrowsingContext.
|
||||
bool BrowsingContext::WatchedByDevTools() {
|
||||
|
|
|
@ -116,6 +116,7 @@ class WindowProxyHolder;
|
|||
FIELD(AllowContentRetargetingOnChildren, bool) \
|
||||
FIELD(ForceEnableTrackingProtection, bool) \
|
||||
FIELD(UseGlobalHistory, bool) \
|
||||
FIELD(FullscreenAllowedByOwner, 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. */ \
|
||||
|
@ -388,6 +389,8 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
|||
bool WatchedByDevTools();
|
||||
void SetWatchedByDevTools(bool aWatchedByDevTools, ErrorResult& aRv);
|
||||
|
||||
bool FullscreenAllowed() const;
|
||||
|
||||
float FullZoom() const { return GetFullZoom(); }
|
||||
float TextZoom() const { return GetTextZoom(); }
|
||||
|
||||
|
@ -746,6 +749,8 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
|||
ContentParent* aSource);
|
||||
bool CanSet(FieldIndex<IDX_AllowPlugins>, const bool& aAllowPlugins,
|
||||
ContentParent* aSource);
|
||||
bool CanSet(FieldIndex<IDX_FullscreenAllowedByOwner>, const bool&,
|
||||
ContentParent*);
|
||||
bool CanSet(FieldIndex<IDX_WatchedByDevToolsInternal>,
|
||||
const bool& aWatchedByDevToolsInternal, ContentParent* aSource);
|
||||
|
||||
|
|
|
@ -1743,74 +1743,6 @@ nsDocShell::SetAllowContentRetargetingOnChildren(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetFullscreenAllowed(bool* aFullscreenAllowed) {
|
||||
NS_ENSURE_ARG_POINTER(aFullscreenAllowed);
|
||||
|
||||
// Assume false until we determine otherwise...
|
||||
*aFullscreenAllowed = false;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> win = GetWindow();
|
||||
if (!win) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// FIXME(emilio, bug 1606660): What makes this work in fission?
|
||||
if (nsCOMPtr<Element> frameElement = win->GetFrameElementInternal()) {
|
||||
if (frameElement->IsXULElement()) {
|
||||
if (frameElement->HasAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::disablefullscreen)) {
|
||||
// Document inside this frame is explicitly disabled.
|
||||
return NS_OK;
|
||||
}
|
||||
} else {
|
||||
// We do not allow document inside any containing element other
|
||||
// than iframe to enter fullscreen.
|
||||
if (auto* iframe = HTMLIFrameElement::FromNode(*frameElement)) {
|
||||
// If any ancestor iframe does not have allowfullscreen attribute
|
||||
// set, then fullscreen is not allowed.
|
||||
if (!iframe->AllowFullscreen()) {
|
||||
return NS_OK;
|
||||
}
|
||||
} else if (frameElement->IsHTMLElement(nsGkAtoms::embed)) {
|
||||
// Respect allowfullscreen only if this is a rewritten YouTube embed.
|
||||
nsCOMPtr<nsIObjectLoadingContent> objectLoadingContent =
|
||||
do_QueryInterface(frameElement);
|
||||
if (!objectLoadingContent) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsObjectLoadingContent* olc =
|
||||
static_cast<nsObjectLoadingContent*>(objectLoadingContent.get());
|
||||
if (!olc->IsRewrittenYoutubeEmbed()) {
|
||||
return NS_OK;
|
||||
}
|
||||
// We don't have to check prefixed attributes because Flash does not
|
||||
// support them.
|
||||
if (!frameElement->HasAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::allowfullscreen)) {
|
||||
return NS_OK;
|
||||
}
|
||||
} else {
|
||||
// neither iframe nor embed
|
||||
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 = GetInProcessParentDocshell();
|
||||
if (!parent) {
|
||||
*aFullscreenAllowed = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Otherwise, we have a parent, continue the checking for
|
||||
// mozFullscreenAllowed in the parent docshell's ancestors.
|
||||
return parent->GetFullscreenAllowed(aFullscreenAllowed);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetMayEnableCharacterEncodingMenu(
|
||||
bool* aMayEnableCharacterEncodingMenu) {
|
||||
|
|
|
@ -698,19 +698,6 @@ interface nsIDocShell : nsIDocShellTreeItem
|
|||
*/
|
||||
[noscript, notxpcom] bool pluginsAllowedInCurrentDoc();
|
||||
|
||||
|
||||
/**
|
||||
* Attribute that determines whether fullscreen is allowed to be entered for
|
||||
* this subtree of the docshell tree. This is true when all iframes containing
|
||||
* this docshell have their "allowfullscreen" attribute set to "true".
|
||||
* fullscreenAllowed is only writable at content boundaries, where it is used
|
||||
* to propagate the value of the cross process parent's iframe's
|
||||
* "allowfullscreen" attribute to the child process. Setting
|
||||
* fullscreenAllowed on docshells which aren't content boundaries throws an
|
||||
* exception.
|
||||
*/
|
||||
[infallible] readonly attribute boolean fullscreenAllowed;
|
||||
|
||||
[noscript, infallible] attribute boolean affectPrivateSessionLifetime;
|
||||
|
||||
/**
|
||||
|
|
|
@ -13587,12 +13587,13 @@ static const char* GetFullscreenError(Document* aDoc, CallerType aCallerType) {
|
|||
return "FullscreenDeniedHidden";
|
||||
}
|
||||
|
||||
// Ensure that all containing elements are <iframe> and have
|
||||
// allowfullscreen attribute set.
|
||||
nsCOMPtr<nsIDocShell> docShell(aDoc->GetDocShell());
|
||||
if (!docShell || !docShell->GetFullscreenAllowed()) {
|
||||
// Ensure that all containing elements are <iframe> and have allowfullscreen
|
||||
// attribute set.
|
||||
BrowsingContext* bc = aDoc->GetBrowsingContext();
|
||||
if (!bc || !bc->FullscreenAllowed()) {
|
||||
return "FullscreenDeniedContainerNotAllowed";
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsFrameLoader.h"
|
||||
#ifdef XP_MACOSX
|
||||
# include "mozilla/EventDispatcher.h"
|
||||
# include "mozilla/dom/Event.h"
|
||||
|
@ -119,6 +120,13 @@ nsresult HTMLEmbedElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (aNamespaceID == kNameSpaceID_None &&
|
||||
aName == nsGkAtoms::allowfullscreen && mFrameLoader) {
|
||||
if (auto* bc = mFrameLoader->GetExtantBrowsingContext()) {
|
||||
bc->SetFullscreenAllowedByOwner(AllowFullscreen());
|
||||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLElement::AfterSetAttr(
|
||||
aNamespaceID, aName, aValue, aOldValue, aSubjectPrincipal, aNotify);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,12 @@ class HTMLEmbedElement final : public nsGenericHTMLElement,
|
|||
NS_IMETHOD PostHandleEvent(EventChainPostVisitor& aVisitor) override;
|
||||
#endif
|
||||
|
||||
bool AllowFullscreen() const {
|
||||
// We don't need to check prefixed attributes because Flash does not support
|
||||
// them.
|
||||
return IsRewrittenYoutubeEmbed() && GetBoolAttr(nsGkAtoms::allowfullscreen);
|
||||
}
|
||||
|
||||
// EventTarget
|
||||
virtual void AsyncEventRunning(AsyncEventDispatcher* aEvent) override;
|
||||
|
||||
|
|
|
@ -169,6 +169,15 @@ nsresult HTMLIFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
|
|||
// alreay been updated.
|
||||
mFrameLoader->ApplySandboxFlags(GetSandboxFlags());
|
||||
}
|
||||
} else if (aName == nsGkAtoms::allowfullscreen ||
|
||||
aName == nsGkAtoms::mozallowfullscreen) {
|
||||
if (mFrameLoader) {
|
||||
if (auto* bc = mFrameLoader->GetExtantBrowsingContext()) {
|
||||
// This could be simpler if we didn't support the prefixed
|
||||
// attribute, then it could just use !!aValue.
|
||||
bc->SetFullscreenAllowedByOwner(AllowFullscreen());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (StaticPrefs::dom_security_featurePolicy_enabled()) {
|
||||
|
|
|
@ -172,8 +172,14 @@ nsresult XULFrameElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
|
|||
const nsAttrValue* aOldValue,
|
||||
nsIPrincipal* aSubjectPrincipal,
|
||||
bool aNotify) {
|
||||
if (aNamespaceID == kNameSpaceID_None && aName == nsGkAtoms::src && aValue) {
|
||||
LoadSrc();
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
if (aName == nsGkAtoms::src && aValue) {
|
||||
LoadSrc();
|
||||
} else if (aName == nsGkAtoms::disablefullscreen && mFrameLoader) {
|
||||
if (auto* bc = mFrameLoader->GetExtantBrowsingContext()) {
|
||||
bc->SetFullscreenAllowedByOwner(!aValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsXULElement::AfterSetAttr(aNamespaceID, aName, aValue, aOldValue,
|
||||
|
|
Загрузка…
Ссылка в новой задаче