mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-12 23:12:21 +00:00
Bug 1580603 - Refactor Fullscreen stack to Top Layer stack r=smaug,xidorn
Fullscreen stack isn't part of the spec anymore, it's changed to a more generic version called Top Layer stack, which is being used by both fullscreen APIs and dialog elements. This patch refactors it to Top Layer stack so that it can be reused for dialog element. Top Layer stack : https://fullscreen.spec.whatwg.org/#new-stacking-layer Differential Revision: https://phabricator.services.mozilla.com/D68478 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
2734904e17
commit
c950be9883
@ -10947,7 +10947,7 @@ void Document::OnPageHide(bool aPersisted, EventTarget* aDispatchStartTarget,
|
||||
EnumerateActivityObservers(NotifyActivityChanged);
|
||||
|
||||
ClearPendingFullscreenRequests(this);
|
||||
if (FullscreenStackTop()) {
|
||||
if (GetUnretargetedFullScreenElement()) {
|
||||
// If this document was fullscreen, we should exit fullscreen in this
|
||||
// doctree branch. This ensures that if the user navigates while in
|
||||
// fullscreen mode we don't leave its still visible ancestor documents
|
||||
@ -12979,6 +12979,18 @@ Document* Document::GetFullscreenRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
size_t Document::CountFullscreenElements() const {
|
||||
size_t count = 0;
|
||||
for (const nsWeakPtr& ptr : mTopLayer) {
|
||||
if (nsCOMPtr<Element> elem = do_QueryReferent(ptr)) {
|
||||
if (elem->State().HasState(NS_EVENT_STATE_FULLSCREEN)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void Document::SetFullscreenRoot(Document* aRoot) {
|
||||
mFullscreenRoot = do_GetWeakReference(aRoot);
|
||||
}
|
||||
@ -13035,7 +13047,7 @@ static uint32_t CountFullscreenSubDocuments(Document& aDoc) {
|
||||
uint32_t count = 0;
|
||||
// FIXME(emilio): Should this be recursive and dig into our nested subdocs?
|
||||
auto subDoc = [&count](Document& aSubDoc) {
|
||||
if (aSubDoc.FullscreenStackTop()) {
|
||||
if (aSubDoc.GetUnretargetedFullScreenElement()) {
|
||||
count++;
|
||||
}
|
||||
return CallState::Continue;
|
||||
@ -13047,7 +13059,7 @@ static uint32_t CountFullscreenSubDocuments(Document& aDoc) {
|
||||
bool Document::IsFullscreenLeaf() {
|
||||
// A fullscreen leaf document is fullscreen, and has no fullscreen
|
||||
// subdocuments.
|
||||
if (!FullscreenStackTop()) {
|
||||
if (!GetUnretargetedFullScreenElement()) {
|
||||
return false;
|
||||
}
|
||||
return CountFullscreenSubDocuments(*this) == 0;
|
||||
@ -13057,7 +13069,7 @@ static Document* GetFullscreenLeaf(Document& aDoc) {
|
||||
if (aDoc.IsFullscreenLeaf()) {
|
||||
return &aDoc;
|
||||
}
|
||||
if (!aDoc.FullscreenStackTop()) {
|
||||
if (!aDoc.GetUnretargetedFullScreenElement()) {
|
||||
return nullptr;
|
||||
}
|
||||
Document* leaf = nullptr;
|
||||
@ -13080,11 +13092,12 @@ static Document* GetFullscreenLeaf(Document* aDoc) {
|
||||
}
|
||||
|
||||
static CallState ResetFullscreen(Document& aDocument) {
|
||||
if (Element* fsElement = aDocument.FullscreenStackTop()) {
|
||||
if (Element* fsElement = aDocument.GetUnretargetedFullScreenElement()) {
|
||||
NS_ASSERTION(CountFullscreenSubDocuments(aDocument) <= 1,
|
||||
"Should have at most 1 fullscreen subdocument.");
|
||||
aDocument.CleanupFullscreenState();
|
||||
NS_ASSERTION(!aDocument.FullscreenStackTop(), "Should reset fullscreen");
|
||||
NS_ASSERTION(!aDocument.GetUnretargetedFullScreenElement(),
|
||||
"Should reset fullscreen");
|
||||
DispatchFullscreenChange(aDocument, fsElement);
|
||||
aDocument.EnumerateSubDocuments(ResetFullscreen);
|
||||
}
|
||||
@ -13137,7 +13150,7 @@ void Document::ExitFullscreenInDocTree(Document* aMaybeNotARootDoc) {
|
||||
}
|
||||
|
||||
nsCOMPtr<Document> root = aMaybeNotARootDoc->GetFullscreenRoot();
|
||||
if (!root || !root->FullscreenStackTop()) {
|
||||
if (!root || !root->GetUnretargetedFullScreenElement()) {
|
||||
// If a document was detached before exiting from fullscreen, it is
|
||||
// possible that the root had left fullscreen state. In this case,
|
||||
// we would not get anything from the ResetFullscreen() call. Root's
|
||||
@ -13158,7 +13171,7 @@ void Document::ExitFullscreenInDocTree(Document* aMaybeNotARootDoc) {
|
||||
// Walk the tree of fullscreen documents, and reset their fullscreen state.
|
||||
ResetFullscreen(*root);
|
||||
|
||||
NS_ASSERTION(!root->FullscreenStackTop(),
|
||||
NS_ASSERTION(!root->GetUnretargetedFullScreenElement(),
|
||||
"Fullscreen root should no longer be a fullscreen doc...");
|
||||
|
||||
// Move the top-level window out of fullscreen mode.
|
||||
@ -13176,14 +13189,15 @@ static void DispatchFullscreenNewOriginEvent(Document* aDoc) {
|
||||
}
|
||||
|
||||
void Document::RestorePreviousFullscreenState(UniquePtr<FullscreenExit> aExit) {
|
||||
NS_ASSERTION(!FullscreenStackTop() || !FullscreenRoots::IsEmpty(),
|
||||
"Should have at least 1 fullscreen root when fullscreen!");
|
||||
NS_ASSERTION(
|
||||
!GetUnretargetedFullScreenElement() || !FullscreenRoots::IsEmpty(),
|
||||
"Should have at least 1 fullscreen root when fullscreen!");
|
||||
|
||||
if (!GetWindow()) {
|
||||
aExit->MayRejectPromise("No active window");
|
||||
return;
|
||||
}
|
||||
if (!FullscreenStackTop() || FullscreenRoots::IsEmpty()) {
|
||||
if (!GetUnretargetedFullScreenElement() || FullscreenRoots::IsEmpty()) {
|
||||
aExit->MayRejectPromise("Not in fullscreen mode");
|
||||
return;
|
||||
}
|
||||
@ -13194,7 +13208,7 @@ void Document::RestorePreviousFullscreenState(UniquePtr<FullscreenExit> aExit) {
|
||||
Document* doc = fullScreenDoc;
|
||||
// Collect all subdocuments.
|
||||
for (; doc != this; doc = doc->GetInProcessParentDocument()) {
|
||||
Element* fsElement = doc->FullscreenStackTop();
|
||||
Element* fsElement = doc->GetUnretargetedFullScreenElement();
|
||||
MOZ_ASSERT(fsElement,
|
||||
"Parent document of "
|
||||
"a fullscreen document without fullscreen element?");
|
||||
@ -13203,9 +13217,9 @@ void Document::RestorePreviousFullscreenState(UniquePtr<FullscreenExit> aExit) {
|
||||
MOZ_ASSERT(doc == this, "Must have reached this doc");
|
||||
// Collect all ancestor documents which we are going to change.
|
||||
for (; doc; doc = doc->GetInProcessParentDocument()) {
|
||||
MOZ_ASSERT(!doc->mFullscreenStack.IsEmpty(),
|
||||
Element* fsElement = doc->GetUnretargetedFullScreenElement();
|
||||
MOZ_ASSERT(fsElement,
|
||||
"Ancestor of fullscreen document must also be in fullscreen");
|
||||
Element* fsElement = doc->FullscreenStackTop();
|
||||
if (doc != this) {
|
||||
if (auto* iframe = HTMLIFrameElement::FromNode(fsElement)) {
|
||||
if (iframe->FullscreenFlag()) {
|
||||
@ -13216,14 +13230,14 @@ void Document::RestorePreviousFullscreenState(UniquePtr<FullscreenExit> aExit) {
|
||||
}
|
||||
}
|
||||
exitElements.AppendElement(fsElement);
|
||||
if (doc->mFullscreenStack.Length() > 1) {
|
||||
if (doc->CountFullscreenElements() > 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Document* lastDoc = exitElements.LastElement()->OwnerDoc();
|
||||
if (!lastDoc->GetInProcessParentDocument() &&
|
||||
lastDoc->mFullscreenStack.Length() == 1) {
|
||||
size_t fullscreenCount = lastDoc->CountFullscreenElements();
|
||||
if (!lastDoc->GetInProcessParentDocument() && fullscreenCount == 1) {
|
||||
// If we are fully exiting fullscreen, don't touch anything here,
|
||||
// just wait for the window to get out from fullscreen first.
|
||||
PendingFullscreenChangeList::Add(std::move(aExit));
|
||||
@ -13241,8 +13255,8 @@ void Document::RestorePreviousFullscreenState(UniquePtr<FullscreenExit> aExit) {
|
||||
// The last document will either rollback one fullscreen element, or
|
||||
// completely exit from the fullscreen state as well.
|
||||
Document* newFullscreenDoc;
|
||||
if (lastDoc->mFullscreenStack.Length() > 1) {
|
||||
lastDoc->FullscreenStackPop();
|
||||
if (fullscreenCount > 1) {
|
||||
lastDoc->UnsetFullscreenElement();
|
||||
newFullscreenDoc = lastDoc;
|
||||
} else {
|
||||
lastDoc->CleanupFullscreenState();
|
||||
@ -13309,19 +13323,27 @@ static void ClearFullscreenStateOnElement(Element* aElement) {
|
||||
}
|
||||
|
||||
void Document::CleanupFullscreenState() {
|
||||
// Iterate the fullscreen stack and clear the fullscreen states.
|
||||
// Iterate the top layer 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.
|
||||
for (nsWeakPtr& weakPtr : Reversed(mFullscreenStack)) {
|
||||
if (nsCOMPtr<Element> element = do_QueryReferent(weakPtr)) {
|
||||
ClearFullscreenStateOnElement(element);
|
||||
mTopLayer.RemoveElementsBy([&](const nsWeakPtr& weakPtr) {
|
||||
nsCOMPtr<Element> element(do_QueryReferent(weakPtr));
|
||||
if (!element || !element->IsInComposedDoc() ||
|
||||
element->OwnerDoc() != this) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
mFullscreenStack.Clear();
|
||||
|
||||
if (element->State().HasState(NS_EVENT_STATE_FULLSCREEN)) {
|
||||
ClearFullscreenStateOnElement(element);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
mFullscreenRoot = nullptr;
|
||||
|
||||
// Restore the zoom level that was in place prior to entering fullscreen.
|
||||
@ -13335,71 +13357,102 @@ void Document::CleanupFullscreenState() {
|
||||
UpdateViewportScrollbarOverrideForFullscreen(this);
|
||||
}
|
||||
|
||||
bool Document::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");
|
||||
void Document::UnsetFullscreenElement() {
|
||||
Element* removedElement = TopLayerPop([](Element* element) -> bool {
|
||||
return element->State().HasState(NS_EVENT_STATE_FULLSCREEN);
|
||||
});
|
||||
|
||||
MOZ_ASSERT(removedElement->State().HasState(NS_EVENT_STATE_FULLSCREEN));
|
||||
ClearFullscreenStateOnElement(removedElement);
|
||||
UpdateViewportScrollbarOverrideForFullscreen(this);
|
||||
}
|
||||
|
||||
bool Document::SetFullscreenElement(Element* aElement) {
|
||||
if (TopLayerPush(aElement)) {
|
||||
EventStateManager::SetFullscreenState(aElement, true);
|
||||
UpdateViewportScrollbarOverrideForFullscreen(this);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Document::TopLayerPush(Element* aElement) {
|
||||
NS_ASSERTION(aElement, "Must pass non-null to TopLayerPush()");
|
||||
auto predictFunc = [&aElement](Element* element) {
|
||||
return element == aElement;
|
||||
};
|
||||
TopLayerPop(predictFunc);
|
||||
|
||||
mTopLayer.AppendElement(do_GetWeakReference(aElement));
|
||||
NS_ASSERTION(GetTopLayerTop() == aElement, "Should match");
|
||||
return true;
|
||||
}
|
||||
|
||||
void Document::FullscreenStackPop() {
|
||||
if (mFullscreenStack.IsEmpty()) {
|
||||
return;
|
||||
Element* Document::TopLayerPop(FunctionRef<bool(Element*)> aPredicateFunc) {
|
||||
if (mTopLayer.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ClearFullscreenStateOnElement(FullscreenStackTop());
|
||||
|
||||
// Remove top element. Note the remaining top element in the stack
|
||||
// will not have fullscreen style bits set, so we will need to restore
|
||||
// them on the new top element before returning.
|
||||
uint32_t last = mFullscreenStack.Length() - 1;
|
||||
mFullscreenStack.RemoveElementAt(last);
|
||||
// Remove the topmost element that qualifies aPredicate; This
|
||||
// is required is because the top layer contains not only
|
||||
// fullscreen elements, but also dialog elements.
|
||||
Element* removedElement;
|
||||
for (auto i : Reversed(IntegerRange(mTopLayer.Length()))) {
|
||||
nsCOMPtr<Element> element(do_QueryReferent(mTopLayer[i]));
|
||||
if (element && aPredicateFunc(element)) {
|
||||
removedElement = element;
|
||||
mTopLayer.RemoveElementAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Pop from the stack null elements (references to elements which have
|
||||
// been GC'd since they were added to the stack) and elements which are
|
||||
// no longer in this document.
|
||||
while (!mFullscreenStack.IsEmpty()) {
|
||||
Element* element = FullscreenStackTop();
|
||||
while (!mTopLayer.IsEmpty()) {
|
||||
Element* element = GetTopLayerTop();
|
||||
if (!element || !element->IsInUncomposedDoc() ||
|
||||
element->OwnerDoc() != this) {
|
||||
NS_ASSERTION(!element->State().HasState(NS_EVENT_STATE_FULLSCREEN),
|
||||
"Should have already removed fullscreen styles");
|
||||
uint32_t last = mFullscreenStack.Length() - 1;
|
||||
mFullscreenStack.RemoveElementAt(last);
|
||||
mTopLayer.RemoveLastElement();
|
||||
} else {
|
||||
// The top element of the stack is now an in-doc element. Return here.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateViewportScrollbarOverrideForFullscreen(this);
|
||||
return removedElement;
|
||||
}
|
||||
|
||||
Element* Document::FullscreenStackTop() {
|
||||
if (mFullscreenStack.IsEmpty()) {
|
||||
Element* Document::GetTopLayerTop() {
|
||||
if (mTopLayer.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
uint32_t last = mFullscreenStack.Length() - 1;
|
||||
nsCOMPtr<Element> element(do_QueryReferent(mFullscreenStack[last]));
|
||||
NS_ASSERTION(element, "Should have fullscreen element!");
|
||||
uint32_t last = mTopLayer.Length() - 1;
|
||||
nsCOMPtr<Element> element(do_QueryReferent(mTopLayer[last]));
|
||||
NS_ASSERTION(element, "Should have a top layer element!");
|
||||
NS_ASSERTION(element->IsInComposedDoc(),
|
||||
"Fullscreen element should be in doc");
|
||||
"Top layer element should be in doc");
|
||||
NS_ASSERTION(element->OwnerDoc() == this,
|
||||
"Fullscreen element should be in this doc");
|
||||
"Top layer element should be in this doc");
|
||||
return element;
|
||||
}
|
||||
|
||||
nsTArray<Element*> Document::GetFullscreenStack() const {
|
||||
Element* Document::GetUnretargetedFullScreenElement() {
|
||||
for (const nsWeakPtr& weakPtr : Reversed(mTopLayer)) {
|
||||
nsCOMPtr<Element> element(do_QueryReferent(weakPtr));
|
||||
// Per spec, the fullscreen element is the topmost element in the document’s
|
||||
// top layer whose fullscreen flag is set, if any, and null otherwise.
|
||||
if (element && element->State().HasState(NS_EVENT_STATE_FULLSCREEN)) {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsTArray<Element*> Document::GetTopLayer() const {
|
||||
nsTArray<Element*> elements;
|
||||
for (const nsWeakPtr& ptr : mFullscreenStack) {
|
||||
for (const nsWeakPtr& ptr : mTopLayer) {
|
||||
if (nsCOMPtr<Element> elem = do_QueryReferent(ptr)) {
|
||||
MOZ_ASSERT(elem->State().HasState(NS_EVENT_STATE_FULLSCREEN));
|
||||
elements.AppendElement(elem);
|
||||
}
|
||||
}
|
||||
@ -13514,7 +13567,8 @@ bool Document::FullscreenElementReadyCheck(FullscreenRequest& aRequest) {
|
||||
// is already the fullscreen element requests fullscreen, nothing
|
||||
// should change and no event should be dispatched, but we still need
|
||||
// to resolve the returned promise.
|
||||
if (elem == FullscreenStackTop()) {
|
||||
Element* fullscreenElement = GetUnretargetedFullScreenElement();
|
||||
if (elem == fullscreenElement) {
|
||||
aRequest.MayResolvePromise();
|
||||
return false;
|
||||
}
|
||||
@ -13540,9 +13594,8 @@ bool Document::FullscreenElementReadyCheck(FullscreenRequest& aRequest) {
|
||||
}
|
||||
// XXXsmaug Note, we don't follow the latest fullscreen spec here.
|
||||
// This whole check could be probably removed.
|
||||
if (FullscreenStackTop() &&
|
||||
!nsContentUtils::ContentIsHostIncludingDescendantOf(
|
||||
elem, FullscreenStackTop())) {
|
||||
if (fullscreenElement && !nsContentUtils::ContentIsHostIncludingDescendantOf(
|
||||
elem, fullscreenElement)) {
|
||||
// If this document is fullscreen, only grant fullscreen requests from
|
||||
// a descendant of the current fullscreen element.
|
||||
aRequest.Reject("FullscreenDeniedNotDescendant");
|
||||
@ -13583,7 +13636,8 @@ static bool ShouldApplyFullscreenDirectly(Document* aDoc,
|
||||
// If we are in the content process, we can apply the fullscreen
|
||||
// state directly only if we have been in DOM fullscreen, because
|
||||
// otherwise we always need to notify the chrome.
|
||||
return !!nsContentUtils::GetRootDocument(aDoc)->GetFullscreenElement();
|
||||
return !!nsContentUtils::GetRootDocument(aDoc)
|
||||
->GetUnretargetedFullScreenElement();
|
||||
} else {
|
||||
// If we are in the chrome process, and the window has not been in
|
||||
// fullscreen, we certainly need to make that fullscreen first.
|
||||
@ -13703,8 +13757,8 @@ bool Document::ApplyFullscreen(UniquePtr<FullscreenRequest> aRequest) {
|
||||
// element, and the fullscreen-ancestor styles on ancestors of the element
|
||||
// in this document.
|
||||
Element* elem = aRequest->Element();
|
||||
DebugOnly<bool> x = FullscreenStackPush(elem);
|
||||
NS_ASSERTION(x, "Fullscreen state of requesting doc should always change!");
|
||||
DebugOnly<bool> x = SetFullscreenElement(elem);
|
||||
MOZ_ASSERT(x, "Fullscreen state of requesting doc should always change!");
|
||||
// Set the iframe fullscreen flag.
|
||||
if (auto* iframe = HTMLIFrameElement::FromNode(elem)) {
|
||||
iframe->SetFullscreenFlag(true);
|
||||
@ -13744,14 +13798,14 @@ bool Document::ApplyFullscreen(UniquePtr<FullscreenRequest> aRequest) {
|
||||
}
|
||||
Document* parent = child->GetInProcessParentDocument();
|
||||
Element* element = parent->FindContentForSubDocument(child);
|
||||
if (parent->FullscreenStackPush(element)) {
|
||||
if (parent->SetFullscreenElement(element)) {
|
||||
changed.AppendElement(parent);
|
||||
child = parent;
|
||||
} else {
|
||||
// We've reached either the root, or a point in the doctree where the
|
||||
// new fullscreen element container is the same as the previous
|
||||
// fullscreen element's container. No more changes need to be made
|
||||
// to the fullscreen stacks of documents further up the tree.
|
||||
// to the top layer of documents further up the tree.
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -13785,7 +13839,7 @@ bool Document::ApplyFullscreen(UniquePtr<FullscreenRequest> aRequest) {
|
||||
// reversed so that events are dispatched in the tree order as
|
||||
// indicated in the spec.
|
||||
for (Document* d : Reversed(changed)) {
|
||||
DispatchFullscreenChange(*d, d->FullscreenStackTop());
|
||||
DispatchFullscreenChange(*d, d->GetUnretargetedFullScreenElement());
|
||||
}
|
||||
aRequest->MayResolvePromise();
|
||||
return true;
|
||||
@ -13959,7 +14013,8 @@ PointerLockRequest::Run() {
|
||||
}
|
||||
// If it is neither user input initiated, nor requested in fullscreen,
|
||||
// it should be rejected.
|
||||
if (!error && !mUserInputOrChromeCaller && !doc->GetFullscreenElement()) {
|
||||
if (!error && !mUserInputOrChromeCaller &&
|
||||
!doc->GetUnretargetedFullScreenElement()) {
|
||||
error = "PointerLockDeniedNotInputDriven";
|
||||
}
|
||||
if (!error && !doc->SetPointerLock(e, StyleCursorKind::None)) {
|
||||
|
@ -1871,14 +1871,14 @@ class Document : public nsINode,
|
||||
void RemoveFromNameTable(Element* aElement, nsAtom* aName);
|
||||
|
||||
/**
|
||||
* Returns all elements in the fullscreen stack in the insertion order.
|
||||
* Returns all elements in the top layer in the insertion order.
|
||||
*/
|
||||
nsTArray<Element*> GetFullscreenStack() const;
|
||||
nsTArray<Element*> GetTopLayer() 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
|
||||
* (if any) is pushed onto the top layer, and it can be
|
||||
* returned to fullscreen status by calling RestorePreviousFullscreenState().
|
||||
*
|
||||
* Note that requesting fullscreen in a document also makes the element which
|
||||
@ -1898,19 +1898,24 @@ class Document : public nsINode,
|
||||
void RequestFullscreen(UniquePtr<FullscreenRequest> aRequest,
|
||||
bool applyFullScreenDirectly = false);
|
||||
|
||||
// Removes all elements from the fullscreen stack, removing full-scren
|
||||
// styles from the top element in the stack.
|
||||
// Removes all the elements with fullscreen flag set from the top layer, and
|
||||
// clears their fullscreen flag.
|
||||
void CleanupFullscreenState();
|
||||
|
||||
// Pushes aElement onto the fullscreen stack, and removes fullscreen styles
|
||||
// from the former fullscreen stack top, and its ancestors, and applies the
|
||||
// styles to aElement. aElement becomes the new "fullscreen element".
|
||||
bool FullscreenStackPush(Element* aElement);
|
||||
// Pushes aElement onto the top layer
|
||||
bool TopLayerPush(Element* aElement);
|
||||
|
||||
// Remove the top element from the fullscreen stack. Removes the fullscreen
|
||||
// styles from the former top element, and applies them to the new top
|
||||
// element, if there is one.
|
||||
void FullscreenStackPop();
|
||||
// Removes the topmost element which have aPredicate return true from the top
|
||||
// layer. The removed element, if any, is returned.
|
||||
Element* TopLayerPop(FunctionRef<bool(Element*)> aPredicateFunc);
|
||||
|
||||
// Pops the fullscreen element from the top layer and clears its
|
||||
// fullscreen flag.
|
||||
void UnsetFullscreenElement();
|
||||
|
||||
// Pushes the given element into the top of top layer and set fullscreen
|
||||
// flag.
|
||||
bool SetFullscreenElement(Element* aElement);
|
||||
|
||||
/**
|
||||
* Called when a frame in a child process has entered fullscreen or when a
|
||||
@ -1922,7 +1927,7 @@ class Document : public nsINode,
|
||||
|
||||
/**
|
||||
* 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
|
||||
* so that all its top layer 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
|
||||
@ -1951,6 +1956,8 @@ class Document : public nsINode,
|
||||
*/
|
||||
Document* GetFullscreenRoot();
|
||||
|
||||
size_t CountFullscreenElements() const;
|
||||
|
||||
/**
|
||||
* Sets the fullscreen root to aRoot. This stores a weak reference to aRoot
|
||||
* in this document.
|
||||
@ -3345,7 +3352,9 @@ class Document : public nsINode,
|
||||
nsIURI* GetDocumentURIObject() const;
|
||||
// Not const because all the fullscreen goop is not const
|
||||
bool FullscreenEnabled(CallerType aCallerType);
|
||||
Element* FullscreenStackTop();
|
||||
Element* GetTopLayerTop();
|
||||
// Return the fullscreen element in the top layer
|
||||
Element* GetUnretargetedFullScreenElement();
|
||||
bool Fullscreen() { return !!GetFullscreenElement(); }
|
||||
already_AddRefed<Promise> ExitFullscreen(ErrorResult&);
|
||||
void ExitPointerLock() { UnlockPointer(this); }
|
||||
@ -4912,10 +4921,8 @@ class Document : public nsINode,
|
||||
|
||||
RefPtr<DOMIntersectionObserver> mLazyLoadImageObserver;
|
||||
|
||||
// Stack of fullscreen elements. When we request fullscreen we push the
|
||||
// fullscreen element onto this stack, and when we cancel fullscreen we
|
||||
// pop one off this stack, restoring the previous fullscreen state
|
||||
nsTArray<nsWeakPtr> mFullscreenStack;
|
||||
// Stack of top layer elements.
|
||||
nsTArray<nsWeakPtr> mTopLayer;
|
||||
|
||||
// The root of the doc tree in which this document is in. This is only
|
||||
// non-null when this document is in fullscreen mode.
|
||||
|
@ -315,7 +315,7 @@ Element* DocumentOrShadowRoot::GetFullscreenElement() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Element* element = AsNode().OwnerDoc()->FullscreenStackTop();
|
||||
Element* element = AsNode().OwnerDoc()->GetUnretargetedFullScreenElement();
|
||||
NS_ASSERTION(!element || element->State().HasState(NS_EVENT_STATE_FULLSCREEN),
|
||||
"Fullscreen element should have fullscreen styles applied");
|
||||
|
||||
|
@ -116,9 +116,8 @@ static void BuildDisplayListForTopLayerFrame(nsDisplayListBuilder* aBuilder,
|
||||
|
||||
void ViewportFrame::BuildDisplayListForTopLayer(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayList* aList) {
|
||||
nsTArray<dom::Element*> fullscreenStack =
|
||||
PresContext()->Document()->GetFullscreenStack();
|
||||
for (dom::Element* elem : fullscreenStack) {
|
||||
nsTArray<dom::Element*> topLayer = PresContext()->Document()->GetTopLayer();
|
||||
for (dom::Element* elem : topLayer) {
|
||||
if (nsIFrame* frame = elem->GetPrimaryFrame()) {
|
||||
// There are two cases where an element in fullscreen is not in
|
||||
// the top layer:
|
||||
|
Loading…
x
Reference in New Issue
Block a user