Bug 1444580: Devirtualize the fullscreen stuff. r=smaug
MozReview-Commit-ID: CgPENqExkQh
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1490,16 +1490,17 @@ nsIDocument::nsIDocument()
mStyleSetFilled(false),
mSSApplicableStateNotificationPending(false),
mMayHaveTitleElement(false),
mDOMLoadingSet(false),
mDOMInteractiveSet(false),
mDOMCompleteSet(false),
mAutoFocusFired(false),
mIsScopedStyleEnabled(eScopedStyle_Unknown),
+ mPendingFullscreenRequests(0),
mCompatMode(eCompatibility_FullStandards),
mReadyState(ReadyState::READYSTATE_UNINITIALIZED),
mStyleBackendType(StyleBackendType::None),
#ifdef MOZILLA_INTERNAL_API
mVisibilityState(dom::VisibilityState::Hidden),
#else
mDummy(0),
#endif
@@ -1546,17 +1547,16 @@ nsDocument::nsDocument(const char* aCont
: nsIDocument()
, mHasWarnedAboutBoxObjects(false)
, mDelayFrameLoaderInitialization(false)
, mSynchronousDOMContentLoaded(false)
, mParserAborted(false)
, mCurrentOrientationAngle(0)
, mCurrentOrientationType(OrientationType::Portrait_primary)
, mReportedUseCounters(false)
- , mPendingFullscreenRequests(0)
, mXMLDeclarationBits(0)
, mBoxObjectTable(nullptr)
, mOnloadBlockCount(0)
, mAsyncOnloadBlockCount(0)
, mPreloadPictureDepth(0)
, mScrolledToRefAlready(0)
, mChangeScrollPosWhenScrollingToRef(0)
, mValidWidth(false)
@@ -10508,24 +10508,24 @@ FullscreenRoots::IsEmpty()
{
return !sInstance;
}
} // end namespace mozilla.
using mozilla::FullscreenRoots;
nsIDocument*
-nsDocument::GetFullscreenRoot()
+nsIDocument::GetFullscreenRoot()
{
nsCOMPtr<nsIDocument> root = do_QueryReferent(mFullscreenRoot);
return root;
}
void
-nsDocument::SetFullscreenRoot(nsIDocument* aRoot)
+nsIDocument::SetFullscreenRoot(nsIDocument* aRoot)
{
mFullscreenRoot = do_GetWeakReference(aRoot);
}
void
nsIDocument::ExitFullscreen()
{
RestorePreviousFullScreenState();
@@ -10595,33 +10595,33 @@ static uint32_t
CountFullscreenSubDocuments(nsIDocument* aDoc)
{
uint32_t count = 0;
aDoc->EnumerateSubDocuments(CountFullscreenSubDocuments, &count);
return count;
}
bool
-nsDocument::IsFullscreenLeaf()
+nsIDocument::IsFullscreenLeaf()
{
// A fullscreen leaf document is fullscreen, and has no fullscreen
// subdocuments.
if (!FullScreenStackTop()) {
return false;
}
return CountFullscreenSubDocuments(this) == 0;
}
static bool
ResetFullScreen(nsIDocument* aDocument, void* aData)
{
if (aDocument->FullScreenStackTop()) {
NS_ASSERTION(CountFullscreenSubDocuments(aDocument) <= 1,
"Should have at most 1 fullscreen subdocument.");
- static_cast<nsDocument*>(aDocument)->CleanupFullscreenState();
+ aDocument->CleanupFullscreenState();
NS_ASSERTION(!aDocument->FullScreenStackTop(),
"Should reset full-screen");
auto changed = reinterpret_cast<nsCOMArray<nsIDocument>*>(aData);
changed->AppendElement(aDocument);
aDocument->EnumerateSubDocuments(ResetFullScreen, aData);
}
return true;
}
@@ -10736,56 +10736,55 @@ GetFullscreenLeaf(nsIDocument* aDoc)
if (!root->FullScreenStackTop()) {
return nullptr;
}
GetFullscreenLeaf(root, &leaf);
return leaf;
}
void
-nsDocument::RestorePreviousFullScreenState()
+nsIDocument::RestorePreviousFullScreenState()
{
NS_ASSERTION(!FullScreenStackTop() || !FullscreenRoots::IsEmpty(),
"Should have at least 1 fullscreen root when fullscreen!");
if (!FullScreenStackTop() || !GetWindow() || FullscreenRoots::IsEmpty()) {
return;
}
nsCOMPtr<nsIDocument> fullScreenDoc = GetFullscreenLeaf(this);
- AutoTArray<nsDocument*, 8> exitDocs;
+ AutoTArray<nsIDocument*, 8> exitDocs;
nsIDocument* doc = fullScreenDoc;
// Collect all subdocuments.
for (; doc != this; doc = doc->GetParentDocument()) {
- exitDocs.AppendElement(static_cast<nsDocument*>(doc));
+ exitDocs.AppendElement(doc);
}
MOZ_ASSERT(doc == this, "Must have reached this doc");
// Collect all ancestor documents which we are going to change.
for (; doc; doc = doc->GetParentDocument()) {
- nsDocument* theDoc = static_cast<nsDocument*>(doc);
- MOZ_ASSERT(!theDoc->mFullScreenStack.IsEmpty(),
+ MOZ_ASSERT(!doc->mFullScreenStack.IsEmpty(),
"Ancestor of fullscreen document must also be in fullscreen");
if (doc != this) {
- Element* top = theDoc->FullScreenStackTop();
+ Element* top = doc->FullScreenStackTop();
if (top->IsHTMLElement(nsGkAtoms::iframe)) {
if (static_cast<HTMLIFrameElement*>(top)->FullscreenFlag()) {
// If this is an iframe, and it explicitly requested
// fullscreen, don't rollback it automatically.
break;
}
}
}
- exitDocs.AppendElement(theDoc);
- if (theDoc->mFullScreenStack.Length() > 1) {
+ exitDocs.AppendElement(doc);
+ if (doc->mFullScreenStack.Length() > 1) {
break;
}
}
- nsDocument* lastDoc = exitDocs.LastElement();
+ nsIDocument* lastDoc = exitDocs.LastElement();
if (!lastDoc->GetParentDocument() &&
lastDoc->mFullScreenStack.Length() == 1) {
// If we are fully exiting fullscreen, don't touch anything here,
// just wait for the window to get out from fullscreen first.
AskWindowToExitFullscreen(this);
return;
}
@@ -10802,17 +10801,17 @@ nsDocument::RestorePreviousFullScreenSta
if (lastDoc->mFullScreenStack.Length() > 1) {
lastDoc->FullScreenStackPop();
newFullscreenDoc = lastDoc;
} else {
lastDoc->CleanupFullscreenState();
newFullscreenDoc = lastDoc->GetParentDocument();
}
// Dispatch the fullscreenchange event to all document listed.
- for (nsDocument* d : exitDocs) {
+ for (nsIDocument* d : exitDocs) {
DispatchFullScreenChange(d);
}
MOZ_ASSERT(newFullscreenDoc, "If we were going to exit from fullscreen on "
"all documents in this doctree, we should've asked the window to "
"exit first instead of reaching here.");
if (fullScreenDoc != newFullscreenDoc &&
!nsContentUtils::HaveEqualPrincipals(fullScreenDoc, newFullscreenDoc)) {
@@ -10840,17 +10839,17 @@ public:
mRequest->GetDocument()->RequestFullScreen(Move(mRequest));
return NS_OK;
}
UniquePtr<FullscreenRequest> mRequest;
};
void
-nsDocument::AsyncRequestFullScreen(UniquePtr<FullscreenRequest>&& aRequest)
+nsIDocument::AsyncRequestFullScreen(UniquePtr<FullscreenRequest>&& aRequest)
{
if (!aRequest->GetElement()) {
MOZ_ASSERT_UNREACHABLE(
"Must pass non-null element to nsDocument::AsyncRequestFullScreen");
return;
}
// Request full-screen asynchronously.
@@ -10889,17 +10888,17 @@ ClearFullscreenStateOnElement(Element* a
EventStateManager::SetFullScreenState(aElement, false);
// Reset iframe fullscreen flag.
if (aElement->IsHTMLElement(nsGkAtoms::iframe)) {
static_cast<HTMLIFrameElement*>(aElement)->SetFullscreenFlag(false);
}
}
void
-nsDocument::CleanupFullscreenState()
+nsIDocument::CleanupFullscreenState()
{
// Iterate the fullscreen stack and clear the fullscreen states.
// Since we also need to clear the fullscreen-ancestor state, and
// currently fullscreen elements can only be placed in hierarchy
// order in the stack, reversely iterating the stack could be more
// efficient. NOTE that fullscreen-ancestor state would be removed
// in bug 1199529, and the elements may not in hierarchy order
// after bug 1195213.
@@ -10909,32 +10908,32 @@ nsDocument::CleanupFullscreenState()
}
}
mFullScreenStack.Clear();
mFullscreenRoot = nullptr;
UpdateViewportScrollbarOverrideForFullscreen(this);
}
bool
-nsDocument::FullScreenStackPush(Element* aElement)
+nsIDocument::FullScreenStackPush(Element* aElement)
{
NS_ASSERTION(aElement, "Must pass non-null to FullScreenStackPush()");
Element* top = FullScreenStackTop();
if (top == aElement || !aElement) {
return false;
}
EventStateManager::SetFullScreenState(aElement, true);
mFullScreenStack.AppendElement(do_GetWeakReference(aElement));
NS_ASSERTION(FullScreenStackTop() == aElement, "Should match");
UpdateViewportScrollbarOverrideForFullscreen(this);
return true;
}
void
-nsDocument::FullScreenStackPop()
+nsIDocument::FullScreenStackPop()
{
if (mFullScreenStack.IsEmpty()) {
return;
}
ClearFullscreenStateOnElement(FullScreenStackTop());
// Remove top element. Note the remaining top element in the stack
@@ -10958,31 +10957,31 @@ nsDocument::FullScreenStackPop()
break;
}
}
UpdateViewportScrollbarOverrideForFullscreen(this);
}
Element*
-nsDocument::FullScreenStackTop()
+nsIDocument::FullScreenStackTop()
{
if (mFullScreenStack.IsEmpty()) {
return nullptr;
}
uint32_t last = mFullScreenStack.Length() - 1;
nsCOMPtr<Element> element(do_QueryReferent(mFullScreenStack[last]));
NS_ASSERTION(element, "Should have full-screen element!");
NS_ASSERTION(element->IsInComposedDoc(), "Full-screen element should be in doc");
NS_ASSERTION(element->OwnerDoc() == this, "Full-screen element should be in this doc");
return element;
}
-/* virtual */ nsTArray<Element*>
-nsDocument::GetFullscreenStack() const
+nsTArray<Element*>
+nsIDocument::GetFullscreenStack() const
{
nsTArray<Element*> elements;
for (const nsWeakPtr& ptr : mFullScreenStack) {
if (nsCOMPtr<Element> elem = do_QueryReferent(ptr)) {
MOZ_ASSERT(elem->State().HasState(NS_EVENT_STATE_FULL_SCREEN));
elements.AppendElement(elem);
}
}
@@ -11023,31 +11022,31 @@ IsInActiveTab(nsIDocument* aDoc)
fm->GetActiveWindow(getter_AddRefs(activeWindow));
if (!activeWindow) {
return false;
}
return activeWindow == rootWin;
}
-nsresult nsDocument::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement)
+nsresult nsIDocument::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement)
{
// Ensure the frame element is the fullscreen element in this document.
// If the frame element is already the fullscreen element in this document,
// this has no effect.
nsCOMPtr<nsIContent> content(do_QueryInterface(aFrameElement));
auto request = MakeUnique<FullscreenRequest>(content->AsElement());
request->mIsCallerChrome = false;
request->mShouldNotifyNewOrigin = false;
RequestFullScreen(Move(request));
return NS_OK;
}
-nsresult nsDocument::RemoteFrameFullscreenReverted()
+nsresult nsIDocument::RemoteFrameFullscreenReverted()
{
RestorePreviousFullScreenState();
return NS_OK;
}
/* static */ bool
nsIDocument::IsUnprefixedFullscreenEnabled(JSContext* aCx, JSObject* aObject)
{
@@ -11086,18 +11085,18 @@ GetFullscreenError(nsIDocument* aDoc, bo
nsCOMPtr<nsIDocShell> docShell(aDoc->GetDocShell());
if (!docShell || !docShell->GetFullscreenAllowed()) {
return "FullscreenDeniedContainerNotAllowed";
}
return nullptr;
}
bool
-nsDocument::FullscreenElementReadyCheck(Element* aElement,
- bool aWasCallerChrome)
+nsIDocument::FullscreenElementReadyCheck(Element* aElement,
+ bool aWasCallerChrome)
{
NS_ASSERTION(aElement,
"Must pass non-null element to nsDocument::RequestFullScreen");
if (!aElement || aElement == FullScreenStackTop()) {
return false;
}
if (!aElement->IsInComposedDoc()) {
DispatchFullscreenError("FullscreenDeniedNotInDocument");
@@ -11305,17 +11304,17 @@ ShouldApplyFullscreenDirectly(nsIDocumen
// if it is already in fullscreen. If we do not apply the state but
// instead add it to the queue and wait for the window as normal,
// we would get stuck.
return true;
}
}
void
-nsDocument::RequestFullScreen(UniquePtr<FullscreenRequest>&& aRequest)
+nsIDocument::RequestFullScreen(UniquePtr<FullscreenRequest>&& aRequest)
{
nsCOMPtr<nsPIDOMWindowOuter> rootWin = GetRootWindow(this);
if (!rootWin) {
return;
}
if (ShouldApplyFullscreenDirectly(this, rootWin)) {
ApplyFullscreen(*aRequest);
@@ -11373,17 +11372,17 @@ ClearPendingFullscreenRequests(nsIDocume
PendingFullscreenRequestList::Iterator iter(
aDoc, PendingFullscreenRequestList::eInclusiveDescendants);
while (!iter.AtEnd()) {
iter.DeleteAndNext();
}
}
bool
-nsDocument::ApplyFullscreen(const FullscreenRequest& aRequest)
+nsIDocument::ApplyFullscreen(const FullscreenRequest& aRequest)
{
Element* elem = aRequest.GetElement();
if (!FullscreenElementReadyCheck(elem, aRequest.mIsCallerChrome)) {
return false;
}
// Stash a reference to any existing fullscreen doc, we'll use this later
// to detect if the origin which is fullscreen has changed.
@@ -11474,17 +11473,17 @@ nsDocument::ApplyFullscreen(const Fullsc
// document, as required by the spec.
for (uint32_t i = 0; i < changed.Length(); ++i) {
DispatchFullScreenChange(changed[changed.Length() - i - 1]);
}
return true;
}
bool
-nsDocument::FullscreenEnabled(CallerType aCallerType)
+nsIDocument::FullscreenEnabled(CallerType aCallerType)
{
return !GetFullscreenError(this, aCallerType == CallerType::System);
}
uint16_t
nsDocument::CurrentOrientationAngle() const
{
return mCurrentOrientationAngle;
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -102,21 +102,21 @@ class Performance;
struct FullscreenRequest : public LinkedListElement<FullscreenRequest>
{
explicit FullscreenRequest(Element* aElement);
FullscreenRequest(const FullscreenRequest&) = delete;
~FullscreenRequest();
Element* GetElement() const { return mElement; }
- nsDocument* GetDocument() const { return mDocument; }
+ nsIDocument* GetDocument() const { return mDocument; }
private:
RefPtr<Element> mElement;
- RefPtr<nsDocument> mDocument;
+ RefPtr<nsIDocument> mDocument;
public:
// This value should be true if the fullscreen request is
// originated from chrome code.
bool mIsCallerChrome = false;
// This value denotes whether we should trigger a NewOrigin event if
// requesting fullscreen in its document causes the origin which is
// fullscreen to change. We may want *not* to trigger that event if
@@ -664,28 +664,16 @@ public:
// Notifies any responsive content added by AddResponsiveContent upon media
// features values changing.
virtual void NotifyMediaFeatureValuesChanged() override;
virtual nsresult GetStateObject(nsIVariant** aResult) override;
virtual Element* FindImageMap(const nsAString& aNormalizedMapName) override;
- virtual nsTArray<Element*> GetFullscreenStack() const override;
- virtual void AsyncRequestFullScreen(
- mozilla::UniquePtr<FullscreenRequest>&& aRequest) override;
- virtual void RestorePreviousFullScreenState() override;
- virtual bool IsFullscreenLeaf() override;
- virtual nsresult
- RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement) override;
-
- virtual nsresult RemoteFrameFullscreenReverted() override;
- virtual nsIDocument* GetFullscreenRoot() override;
- virtual void SetFullscreenRoot(nsIDocument* aRoot) override;
-
// Returns the size of the mBlockedTrackingNodes array. (nsIDocument.h)
//
// This array contains nodes that have been blocked to prevent
// user tracking. They most likely have had their nsIChannel
// canceled by the URL classifier (Safebrowsing).
//
// A script can subsequently use GetBlockedTrackingNodes()
// to get a list of references to these nodes.
@@ -702,44 +690,16 @@ public:
// Returns strong references to mBlockedTrackingNodes. (nsIDocument.h)
//
// This array contains nodes that have been blocked to prevent
// user tracking. They most likely have had their nsIChannel
// canceled by the URL classifier (Safebrowsing).
//
already_AddRefed<nsSimpleContentList> BlockedTrackingNodes() const;
- // Do the "fullscreen element ready check" from the fullscreen spec.
- // It returns true if the given element is allowed to go into fullscreen.
- bool FullscreenElementReadyCheck(Element* aElement, bool aWasCallerChrome);
-
- // This is called asynchronously by nsIDocument::AsyncRequestFullScreen()
- // to move this document into full-screen mode if allowed.
- void RequestFullScreen(mozilla::UniquePtr<FullscreenRequest>&& aRequest);
-
- // Removes all elements from the full-screen stack, removing full-scren
- // styles from the top element in the stack.
- void CleanupFullscreenState();
-
- // Pushes aElement onto the full-screen stack, and removes full-screen styles
- // from the former full-screen stack top, and its ancestors, and applies the
- // styles to aElement. aElement becomes the new "full-screen element".
- bool FullScreenStackPush(Element* aElement);
-
- // Remove the top element from the full-screen stack. Removes the full-screen
- // styles from the former top element, and applies them to the new top
- // element, if there is one.
- void FullScreenStackPop();
-
- // Returns the top element from the full-screen stack.
- Element* FullScreenStackTop() override;
-
- // DOM-exposed fullscreen API
- bool FullscreenEnabled(mozilla::dom::CallerType aCallerType) override;
-
void RequestPointerLock(Element* aElement,
mozilla::dom::CallerType aCallerType) override;
bool SetPointerLock(Element* aElement, int aCursorStyle);
static void UnlockPointer(nsIDocument* aDoc = nullptr);
void SetCurrentOrientation(mozilla::dom::OrientationType aType,
uint16_t aAngle) override;
uint16_t CurrentOrientationAngle() const override;
@@ -815,37 +775,23 @@ protected:
void VerifyRootContentState();
#endif
explicit nsDocument(const char* aContentType);
virtual ~nsDocument();
void EnsureOnloadBlocker();
- // Apply the fullscreen state to the document, and trigger related
- // events. It returns false if the fullscreen element ready check
- // fails and nothing gets changed.
- bool ApplyFullscreen(const FullscreenRequest& aRequest);
-
// Array of owning references to all children
nsAttrAndChildArray mChildren;
// Tracker for animations that are waiting to start.
// nullptr until GetOrCreatePendingAnimationTracker is called.
RefPtr<mozilla::PendingAnimationTracker> mPendingAnimationTracker;
- // Stack of full-screen elements. When we request full-screen we push the
- // full-screen element onto this stack, and when we cancel full-screen we
- // pop one off this stack, restoring the previous full-screen state
- nsTArray<nsWeakPtr> mFullScreenStack;
-
- // The root of the doc tree in which this document is in. This is only
- // non-null when this document is in fullscreen mode.
- nsWeakPtr mFullscreenRoot;
-
public:
RefPtr<mozilla::EventListenerManager> mListenerManager;
RefPtr<mozilla::dom::ScriptLoader> mScriptLoader;
nsClassHashtable<nsStringHashKey, nsRadioGroupStruct> mRadioGroups;
bool mHasWarnedAboutBoxObjects:1;
@@ -869,18 +815,16 @@ public:
// Whether we have reported use counters for this document with Telemetry yet.
// Normally this is only done at document destruction time, but for image
// documents (SVG documents) that are not guaranteed to be destroyed, we
// report use counters when the image cache no longer has any imgRequestProxys
// pointing to them. We track whether we ever reported use counters so
// that we only report them once for the document.
bool mReportedUseCounters:1;
- uint8_t mPendingFullscreenRequests;
-
uint8_t mXMLDeclarationBits;
nsRefPtrHashtable<nsPtrHashKey<nsIContent>, mozilla::dom::BoxObject>* mBoxObjectTable;
// A document "without a browsing context" that owns the content of
// HTMLTemplateElement.
nsCOMPtr<nsIDocument> mTemplateContentsOwner;
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -1606,77 +1606,97 @@ public:
virtual void AddToIdTable(Element* aElement, nsAtom* aId) = 0;
virtual void RemoveFromIdTable(Element* aElement, nsAtom* aId) = 0;
virtual void AddToNameTable(Element* aElement, nsAtom* aName) = 0;
virtual void RemoveFromNameTable(Element* aElement, nsAtom* aName) = 0;
/**
* Returns all elements in the fullscreen stack in the insertion order.
*/
- virtual nsTArray<Element*> GetFullscreenStack() const = 0;
+ nsTArray<Element*> GetFullscreenStack() const;
/**
* Asynchronously requests that the document make aElement the fullscreen
* element, and move into fullscreen mode. The current fullscreen element
* (if any) is pushed onto the fullscreen element stack, and it can be
* returned to fullscreen status by calling RestorePreviousFullScreenState().
*
* Note that requesting fullscreen in a document also makes the element which
* contains this document in this document's parent document fullscreen. i.e.
* the <iframe> or <browser> that contains this document is also mode
* fullscreen. This happens recursively in all ancestor documents.
*/
- virtual void AsyncRequestFullScreen(
- mozilla::UniquePtr<FullscreenRequest>&& aRequest) = 0;
+ void AsyncRequestFullScreen(mozilla::UniquePtr<FullscreenRequest>&&);
+
+ // Do the "fullscreen element ready check" from the fullscreen spec.
+ // It returns true if the given element is allowed to go into fullscreen.
+ bool FullscreenElementReadyCheck(Element* aElement, bool aWasCallerChrome);
+
+ // This is called asynchronously by nsIDocument::AsyncRequestFullScreen()
+ // to move this document into full-screen mode if allowed.
+ void RequestFullScreen(mozilla::UniquePtr<FullscreenRequest>&& aRequest);
+
+ // Removes all elements from the full-screen stack, removing full-scren
+ // styles from the top element in the stack.
+ void CleanupFullscreenState();
+
+ // Pushes aElement onto the full-screen stack, and removes full-screen styles
+ // from the former full-screen stack top, and its ancestors, and applies the
+ // styles to aElement. aElement becomes the new "full-screen element".
+ bool FullScreenStackPush(Element* aElement);
+
+ // Remove the top element from the full-screen stack. Removes the full-screen
+ // styles from the former top element, and applies them to the new top
+ // element, if there is one.
+ void FullScreenStackPop();
/**
* Called when a frame in a child process has entered fullscreen or when a
* fullscreen frame in a child process changes to another origin.
* aFrameElement is the frame element which contains the child-process
* fullscreen document.
*/
- virtual nsresult
- RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement) = 0;
+ nsresult RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement);
/**
* Called when a frame in a remote child document has rolled back fullscreen
* so that all its fullscreen element stacks are empty; we must continue the
* rollback in this parent process' doc tree branch which is fullscreen.
* Note that only one branch of the document tree can have its documents in
* fullscreen state at one time. We're in inconsistent state if a
* fullscreen document has a parent and that parent isn't fullscreen. We
* preserve this property across process boundaries.
*/
- virtual nsresult RemoteFrameFullscreenReverted() = 0;
+ nsresult RemoteFrameFullscreenReverted();
/**
* Restores the previous full-screen element to full-screen status. If there
* is no former full-screen element, this exits full-screen, moving the
* top-level browser window out of full-screen mode.
*/
- virtual void RestorePreviousFullScreenState() = 0;
+ void RestorePreviousFullScreenState();
/**
* Returns true if this document is a fullscreen leaf document, i.e. it
* is in fullscreen mode and has no fullscreen children.
*/
- virtual bool IsFullscreenLeaf() = 0;
+ bool IsFullscreenLeaf();
/**
* Returns the document which is at the root of this document's branch
* in the in-process document tree. Returns nullptr if the document isn't
* fullscreen.
*/
- virtual nsIDocument* GetFullscreenRoot() = 0;
+ nsIDocument* GetFullscreenRoot();
/**
* Sets the fullscreen root to aRoot. This stores a weak reference to aRoot
* in this document.
*/
- virtual void SetFullscreenRoot(nsIDocument* aRoot) = 0;
+ void SetFullscreenRoot(nsIDocument* aRoot);
/**
* Synchronously cleans up the fullscreen state on the given document.
*
* Calling this without performing fullscreen transition could lead
* to undesired effect (the transition happens after document state
* flips), hence it should only be called either by nsGlobalWindow
* when we have performed the transition, or when it is necessary to
@@ -2997,18 +3017,18 @@ public:
{
return IsSyntheticDocument();
}
Element* GetCurrentScript();
void ReleaseCapture() const;
void MozSetImageElement(const nsAString& aImageElementId, Element* aElement);
nsIURI* GetDocumentURIObject() const;
// Not const because all the full-screen goop is not const
- virtual bool FullscreenEnabled(mozilla::dom::CallerType aCallerType) = 0;
- virtual Element* FullScreenStackTop() = 0;
+ bool FullscreenEnabled(mozilla::dom::CallerType aCallerType);
+ Element* FullScreenStackTop();
bool Fullscreen()
{
return !!GetFullscreenElement();
}
void ExitFullscreen();
void ExitPointerLock()
{
UnlockPointer(this);
@@ -3339,16 +3359,21 @@ protected:
// Recomputes the visibility state but doesn't set the new value.
mozilla::dom::VisibilityState ComputeVisibilityState() const;
// Since we wouldn't automatically play media from non-visited page, we need
// to notify window when the page was first visited.
void MaybeActiveMediaComponents();
+ // Apply the fullscreen state to the document, and trigger related
+ // events. It returns false if the fullscreen element ready check
+ // fails and nothing gets changed.
+ bool ApplyFullscreen(const FullscreenRequest& aRequest);
+
bool GetUseCounter(mozilla::UseCounter aUseCounter)
{
return mUseCounters[aUseCounter];
}
void SetChildDocumentUseCounter(mozilla::UseCounter aUseCounter)
{
if (!mChildDocumentUseCounters[aUseCounter]) {
@@ -3776,16 +3801,18 @@ protected:
bool mDOMInteractiveSet: 1;
bool mDOMCompleteSet: 1;
bool mAutoFocusFired: 1;
// Whether <style scoped> support is enabled in this document.
enum { eScopedStyle_Unknown, eScopedStyle_Disabled, eScopedStyle_Enabled };
unsigned int mIsScopedStyleEnabled : 2;
+ uint8_t mPendingFullscreenRequests;
+
// Compatibility mode
nsCompatibility mCompatMode;
// Our readyState
ReadyState mReadyState;
// Whether this document has (or will have, once we have a pres shell) a
// Gecko- or Servo-backed style system.
@@ -4011,16 +4038,25 @@ protected:
// that, unlike mScriptGlobalObject, is never unset once set. This
// is a weak reference to avoid leaks due to circular references.
nsWeakPtr mScopeObject;
// Array of intersection observers
nsTHashtable<nsPtrHashKey<mozilla::dom::DOMIntersectionObserver>>
mIntersectionObservers;
+ // Stack of full-screen elements. When we request full-screen we push the
+ // full-screen element onto this stack, and when we cancel full-screen we
+ // pop one off this stack, restoring the previous full-screen state
+ nsTArray<nsWeakPtr> mFullScreenStack;
+
+ // The root of the doc tree in which this document is in. This is only
+ // non-null when this document is in fullscreen mode.
+ nsWeakPtr mFullscreenRoot;
+
nsTArray<RefPtr<mozilla::StyleSheet>> mOnDemandBuiltInUASheets;
nsTArray<RefPtr<mozilla::StyleSheet>> mAdditionalSheets[AdditionalSheetTypeCount];
// Member to store out last-selected stylesheet set.
nsString mLastStyleSheetSet;
RefPtr<nsDOMStyleSheetSetList> mStyleSheetSetList;
// We lazily calculate declaration blocks for SVG elements with mapped