mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-07 16:28:38 +09:00
Issue #2472 - Part 3: Refactor Fullscreen stack to Top Layer stack
Fullscreen stack isn't part of the spec anymore; it's been changed to a more generic version called Top Layer stack, which is being used by both full-screen APIs and dialog elements. This patch refactors it to Top Layer stack so that it can be reused for dialog elements. Top Layer stack spec: https://fullscreen.spec.whatwg.org/#new-stacking-layer
This commit is contained in:
parent
1f4152a5ac
commit
79c7489bb0
5 changed files with 161 additions and 98 deletions
|
|
@ -169,7 +169,7 @@ DocumentOrShadowRoot::GetFullscreenElement()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Element* element = AsNode().OwnerDoc()->FullScreenStackTop();
|
||||
Element* element = AsNode().OwnerDoc()->GetUnretargetedFullScreenElement();
|
||||
NS_ASSERTION(!element ||
|
||||
element->State().HasState(NS_EVENT_STATE_FULL_SCREEN),
|
||||
"Fullscreen element should have fullscreen styles applied");
|
||||
|
|
|
|||
|
|
@ -8481,7 +8481,7 @@ nsDocument::OnPageHide(bool aPersisted,
|
|||
EnumerateActivityObservers(NotifyActivityChanged, nullptr);
|
||||
|
||||
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
|
||||
|
|
@ -10112,6 +10112,19 @@ nsDocument::GetFullscreenRoot()
|
|||
return root;
|
||||
}
|
||||
|
||||
size_t
|
||||
nsDocument::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_FULL_SCREEN)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::SetFullscreenRoot(nsIDocument* aRoot)
|
||||
{
|
||||
|
|
@ -10175,7 +10188,7 @@ nsIDocument::AsyncExitFullscreen(nsIDocument* aDoc)
|
|||
static bool
|
||||
CountFullscreenSubDocuments(nsIDocument* aDoc, void* aData)
|
||||
{
|
||||
if (aDoc->FullScreenStackTop()) {
|
||||
if (aDoc->GetUnretargetedFullScreenElement()) {
|
||||
uint32_t* count = static_cast<uint32_t*>(aData);
|
||||
(*count)++;
|
||||
}
|
||||
|
|
@ -10195,7 +10208,7 @@ nsDocument::IsFullscreenLeaf()
|
|||
{
|
||||
// A fullscreen leaf document is fullscreen, and has no fullscreen
|
||||
// subdocuments.
|
||||
if (!FullScreenStackTop()) {
|
||||
if (!GetUnretargetedFullScreenElement()) {
|
||||
return false;
|
||||
}
|
||||
return CountFullscreenSubDocuments(this) == 0;
|
||||
|
|
@ -10204,11 +10217,11 @@ nsDocument::IsFullscreenLeaf()
|
|||
static bool
|
||||
ResetFullScreen(nsIDocument* aDocument, void* aData)
|
||||
{
|
||||
if (aDocument->FullScreenStackTop()) {
|
||||
if (aDocument->GetUnretargetedFullScreenElement()) {
|
||||
NS_ASSERTION(CountFullscreenSubDocuments(aDocument) <= 1,
|
||||
"Should have at most 1 fullscreen subdocument.");
|
||||
static_cast<nsDocument*>(aDocument)->CleanupFullscreenState();
|
||||
NS_ASSERTION(!aDocument->FullScreenStackTop(),
|
||||
NS_ASSERTION(!aDocument->GetUnretargetedFullScreenElement(),
|
||||
"Should reset full-screen");
|
||||
auto changed = reinterpret_cast<nsCOMArray<nsIDocument>*>(aData);
|
||||
changed->AppendElement(aDocument);
|
||||
|
|
@ -10256,7 +10269,7 @@ nsIDocument::ExitFullscreenInDocTree(nsIDocument* aMaybeNotARootDoc)
|
|||
UnlockPointer();
|
||||
|
||||
nsCOMPtr<nsIDocument> 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
|
||||
|
|
@ -10285,7 +10298,7 @@ nsIDocument::ExitFullscreenInDocTree(nsIDocument* aMaybeNotARootDoc)
|
|||
DispatchFullScreenChange(changed[changed.Length() - i - 1]);
|
||||
}
|
||||
|
||||
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.
|
||||
|
|
@ -10302,7 +10315,7 @@ GetFullscreenLeaf(nsIDocument* aDoc, void* aData)
|
|||
nsIDocument** result = static_cast<nsIDocument**>(aData);
|
||||
*result = aDoc;
|
||||
return false;
|
||||
} else if (aDoc->FullScreenStackTop()) {
|
||||
} else if (aDoc->GetUnretargetedFullScreenElement()) {
|
||||
aDoc->EnumerateSubDocuments(GetFullscreenLeaf, aData);
|
||||
}
|
||||
return true;
|
||||
|
|
@ -10321,7 +10334,7 @@ GetFullscreenLeaf(nsIDocument* aDoc)
|
|||
nsIDocument* root = nsContentUtils::GetRootDocument(aDoc);
|
||||
// Check that the root is actually fullscreen so we don't waste time walking
|
||||
// around its descendants.
|
||||
if (!root->FullScreenStackTop()) {
|
||||
if (!root->GetUnretargetedFullScreenElement()) {
|
||||
return nullptr;
|
||||
}
|
||||
GetFullscreenLeaf(root, &leaf);
|
||||
|
|
@ -10331,10 +10344,10 @@ GetFullscreenLeaf(nsIDocument* aDoc)
|
|||
void
|
||||
nsDocument::RestorePreviousFullScreenState()
|
||||
{
|
||||
NS_ASSERTION(!FullScreenStackTop() || !FullscreenRoots::IsEmpty(),
|
||||
NS_ASSERTION(!GetUnretargetedFullScreenElement() || !FullscreenRoots::IsEmpty(),
|
||||
"Should have at least 1 fullscreen root when fullscreen!");
|
||||
|
||||
if (!FullScreenStackTop() || !GetWindow() || FullscreenRoots::IsEmpty()) {
|
||||
if (!GetUnretargetedFullScreenElement() || !GetWindow() || FullscreenRoots::IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -10350,10 +10363,10 @@ nsDocument::RestorePreviousFullScreenState()
|
|||
// 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(),
|
||||
Element* top = theDoc->GetUnretargetedFullScreenElement();
|
||||
MOZ_ASSERT(!top,
|
||||
"Ancestor of fullscreen document must also be in fullscreen");
|
||||
if (doc != this) {
|
||||
Element* top = theDoc->FullScreenStackTop();
|
||||
if (top->IsHTMLElement(nsGkAtoms::iframe)) {
|
||||
if (static_cast<HTMLIFrameElement*>(top)->FullscreenFlag()) {
|
||||
// If this is an iframe, and it explicitly requested
|
||||
|
|
@ -10363,14 +10376,14 @@ nsDocument::RestorePreviousFullScreenState()
|
|||
}
|
||||
}
|
||||
exitDocs.AppendElement(theDoc);
|
||||
if (theDoc->mFullScreenStack.Length() > 1) {
|
||||
if (theDoc->CountFullscreenElements() > 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nsDocument* lastDoc = exitDocs.LastElement();
|
||||
if (!lastDoc->GetParentDocument() &&
|
||||
lastDoc->mFullScreenStack.Length() == 1) {
|
||||
size_t fullscreenCount = lastDoc->CountFullscreenElements();
|
||||
if (!lastDoc->GetParentDocument() && fullscreenCount == 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);
|
||||
|
|
@ -10387,8 +10400,8 @@ nsDocument::RestorePreviousFullScreenState()
|
|||
// The last document will either rollback one fullscreen element, or
|
||||
// completely exit from the fullscreen state as well.
|
||||
nsIDocument* newFullscreenDoc;
|
||||
if (lastDoc->mFullScreenStack.Length() > 1) {
|
||||
lastDoc->FullScreenStackPop();
|
||||
if (fullscreenCount > 1) {
|
||||
lastDoc->UnsetFullscreenElement();
|
||||
newFullscreenDoc = lastDoc;
|
||||
} else {
|
||||
lastDoc->CleanupFullscreenState();
|
||||
|
|
@ -10482,93 +10495,131 @@ ClearFullscreenStateOnElement(Element* aElement)
|
|||
void
|
||||
nsDocument::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_FULL_SCREEN)) {
|
||||
ClearFullscreenStateOnElement(element);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
mFullscreenRoot = nullptr;
|
||||
UpdateViewportScrollbarOverrideForFullscreen(this);
|
||||
}
|
||||
|
||||
bool
|
||||
nsDocument::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
|
||||
nsDocument::UnsetFullscreenElement() {
|
||||
Element* removedElement = TopLayerPop([](Element* element) -> bool {
|
||||
return element->State().HasState(NS_EVENT_STATE_FULL_SCREEN);
|
||||
});
|
||||
|
||||
MOZ_ASSERT(removedElement->State().HasState(NS_EVENT_STATE_FULL_SCREEN));
|
||||
ClearFullscreenStateOnElement(removedElement);
|
||||
UpdateViewportScrollbarOverrideForFullscreen(this);
|
||||
}
|
||||
|
||||
bool
|
||||
nsDocument::SetFullscreenElement(Element* aElement) {
|
||||
if (TopLayerPush(aElement)) {
|
||||
EventStateManager::SetFullScreenState(aElement, true);
|
||||
UpdateViewportScrollbarOverrideForFullscreen(this);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
nsDocument::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
|
||||
nsDocument::FullScreenStackPop()
|
||||
{
|
||||
if (mFullScreenStack.IsEmpty()) {
|
||||
return;
|
||||
Element*
|
||||
nsDocument::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 full-screen 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(MakeRange(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_FULL_SCREEN),
|
||||
"Should have already removed full-screen styles");
|
||||
uint32_t last = mFullScreenStack.Length() - 1;
|
||||
mFullScreenStack.RemoveElementAt(last);
|
||||
mTopLayer.RemoveElementAt(mTopLayer.Length() - 1);
|
||||
} else {
|
||||
// The top element of the stack is now an in-doc element. Return here.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateViewportScrollbarOverrideForFullscreen(this);
|
||||
return removedElement;
|
||||
}
|
||||
|
||||
Element*
|
||||
nsDocument::FullScreenStackTop()
|
||||
{
|
||||
if (mFullScreenStack.IsEmpty()) {
|
||||
nsDocument::GetTopLayerTop() {
|
||||
if (mTopLayer.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");
|
||||
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(), "Top layer element should be in doc");
|
||||
NS_ASSERTION(element->OwnerDoc() == this, "Top layer element should be in this doc");
|
||||
return element;
|
||||
}
|
||||
|
||||
/* virtual */ nsTArray<Element*>
|
||||
nsDocument::GetFullscreenStack() const
|
||||
{
|
||||
Element*
|
||||
nsDocument::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 of which the fullscreen flag is set, if any, and null otherwise.
|
||||
if (element && element->State().HasState(NS_EVENT_STATE_FULL_SCREEN)) {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsTArray<Element*>
|
||||
nsDocument::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_FULL_SCREEN));
|
||||
elements.AppendElement(elem);
|
||||
}
|
||||
}
|
||||
|
|
@ -10683,7 +10734,8 @@ nsDocument::FullscreenElementReadyCheck(Element* aElement,
|
|||
{
|
||||
NS_ASSERTION(aElement,
|
||||
"Must pass non-null element to nsDocument::RequestFullScreen");
|
||||
if (!aElement || aElement == FullScreenStackTop()) {
|
||||
Element* fullscreenElement = GetUnretargetedFullScreenElement();
|
||||
if (!aElement || aElement == fullscreenElement) {
|
||||
return false;
|
||||
}
|
||||
if (!aElement->IsInComposedDoc()) {
|
||||
|
|
@ -10712,9 +10764,9 @@ nsDocument::FullscreenElementReadyCheck(Element* aElement,
|
|||
}
|
||||
//XXXsmaug Note, we don't follow the latest fullscreen spec here.
|
||||
// This whole check could be probably removed.
|
||||
if (FullScreenStackTop() &&
|
||||
if (fullscreenElement &&
|
||||
!nsContentUtils::ContentIsHostIncludingDescendantOf(aElement,
|
||||
FullScreenStackTop())) {
|
||||
fullscreenElement)) {
|
||||
// If this document is full-screen, only grant full-screen requests from
|
||||
// a descendant of the current full-screen element.
|
||||
DispatchFullscreenError("FullscreenDeniedNotDescendant");
|
||||
|
|
@ -10871,7 +10923,7 @@ ShouldApplyFullscreenDirectly(nsIDocument* 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.
|
||||
|
|
@ -10994,8 +11046,8 @@ nsDocument::ApplyFullscreen(const FullscreenRequest& aRequest)
|
|||
// Set the full-screen element. This sets the full-screen style on the
|
||||
// element, and the full-screen-ancestor styles on ancestors of the element
|
||||
// in this document.
|
||||
DebugOnly<bool> x = FullScreenStackPush(elem);
|
||||
NS_ASSERTION(x, "Full-screen state of requesting doc should always change!");
|
||||
DebugOnly<bool> x = SetFullscreenElement(elem);
|
||||
MOZ_ASSERT(x, "Full-screen state of requesting doc should always change!");
|
||||
// Set the iframe fullscreen flag.
|
||||
if (elem->IsHTMLElement(nsGkAtoms::iframe)) {
|
||||
static_cast<HTMLIFrameElement*>(elem)->SetFullscreenFlag(true);
|
||||
|
|
@ -11017,14 +11069,14 @@ nsDocument::ApplyFullscreen(const FullscreenRequest& aRequest)
|
|||
}
|
||||
nsIDocument* parent = child->GetParentDocument();
|
||||
Element* element = parent->FindContentForSubDocument(child)->AsElement();
|
||||
if (static_cast<nsDocument*>(parent)->FullScreenStackPush(element)) {
|
||||
if (static_cast<nsDocument*>(parent)->SetFullscreenElement(element)) {
|
||||
changed.AppendElement(parent);
|
||||
child = parent;
|
||||
} else {
|
||||
// We've reached either the root, or a point in the doctree where the
|
||||
// new full-screen element container is the same as the previous
|
||||
// full-screen element's container. No more changes need to be made
|
||||
// to the full-screen stacks of documents further up the tree.
|
||||
// to the top layer of documents further up the tree.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -11294,7 +11346,7 @@ 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 && !d->SetPointerLock(e, NS_STYLE_CURSOR_NONE)) {
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
#include "imgIRequest.h"
|
||||
#include "mozilla/EventListenerManager.h"
|
||||
#include "mozilla/EventStates.h"
|
||||
#include "mozilla/FunctionRef.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/PendingAnimationTracker.h"
|
||||
#include "mozilla/dom/DOMImplementation.h"
|
||||
|
|
@ -77,6 +78,7 @@
|
|||
#define XML_DECLARATION_BITS_STANDALONE_EXISTS (1 << 2)
|
||||
#define XML_DECLARATION_BITS_STANDALONE_YES (1 << 3)
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
class nsDOMStyleSheetSetList;
|
||||
class nsDocument;
|
||||
|
|
@ -638,7 +640,7 @@ public:
|
|||
using mozilla::dom::DocumentOrShadowRoot::GetElementsByTagName;
|
||||
using mozilla::dom::DocumentOrShadowRoot::GetElementsByTagNameNS;
|
||||
using mozilla::dom::DocumentOrShadowRoot::GetElementsByClassName;
|
||||
|
||||
|
||||
// nsIDOMEventTarget
|
||||
virtual nsresult GetEventTargetParent(
|
||||
mozilla::EventChainPreVisitor& aVisitor) override;
|
||||
|
|
@ -850,7 +852,7 @@ public:
|
|||
|
||||
virtual Element* FindImageMap(const nsAString& aNormalizedMapName) override;
|
||||
|
||||
virtual nsTArray<Element*> GetFullscreenStack() const override;
|
||||
virtual nsTArray<Element*> GetTopLayer() const override;
|
||||
virtual void AsyncRequestFullScreen(
|
||||
mozilla::UniquePtr<FullscreenRequest>&& aRequest) override;
|
||||
virtual void RestorePreviousFullScreenState() override;
|
||||
|
|
@ -860,6 +862,7 @@ public:
|
|||
|
||||
virtual nsresult RemoteFrameFullscreenReverted() override;
|
||||
virtual nsIDocument* GetFullscreenRoot() override;
|
||||
virtual size_t CountFullscreenElements() const override;
|
||||
virtual void SetFullscreenRoot(nsIDocument* aRoot) override;
|
||||
|
||||
// Returns the size of the mBlockedTrackingNodes array. (nsIDocument.h)
|
||||
|
|
@ -896,23 +899,29 @@ public:
|
|||
// 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.
|
||||
// Removes all elements with the full-screen flag set from the top layer, and
|
||||
// clears their full-screen flag.
|
||||
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);
|
||||
// Pushes aElement onto the top layer
|
||||
bool TopLayerPush(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();
|
||||
// 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);
|
||||
|
||||
// Returns the top element from the full-screen stack.
|
||||
Element* FullScreenStackTop() override;
|
||||
|
||||
Element* GetTopLayerTop() override;
|
||||
// Return the fullscreen element in the top layer
|
||||
Element* GetUnretargetedFullScreenElement() override;
|
||||
// DOM-exposed fullscreen API
|
||||
bool FullscreenEnabled() override;
|
||||
|
||||
|
|
@ -1193,10 +1202,8 @@ protected:
|
|||
// is a weak reference to avoid leaks due to circular references.
|
||||
nsWeakPtr mScopeObject;
|
||||
|
||||
// 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;
|
||||
// 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.
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/CORSMode.h"
|
||||
#include "mozilla/dom/DocumentOrShadowRoot.h"
|
||||
#include "mozilla/FunctionRef.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/StyleSheet.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
|
@ -1273,9 +1274,9 @@ public:
|
|||
virtual void RemoveFromNameTable(Element* aElement, nsIAtom* aName) = 0;
|
||||
|
||||
/**
|
||||
* Returns all elements in the fullscreen stack in the insertion order.
|
||||
* Returns all elements in the top layer in the insertion order.
|
||||
*/
|
||||
virtual nsTArray<Element*> GetFullscreenStack() const = 0;
|
||||
virtual nsTArray<Element*> GetTopLayer() const = 0;
|
||||
|
||||
/**
|
||||
* Asynchronously requests that the document make aElement the fullscreen
|
||||
|
|
@ -1331,6 +1332,8 @@ public:
|
|||
*/
|
||||
virtual nsIDocument* GetFullscreenRoot() = 0;
|
||||
|
||||
virtual size_t CountFullscreenElements() const = 0;
|
||||
|
||||
/**
|
||||
* Sets the fullscreen root to aRoot. This stores a weak reference to aRoot
|
||||
* in this document.
|
||||
|
|
@ -2607,7 +2610,8 @@ public:
|
|||
nsIURI* GetDocumentURIObject() const;
|
||||
// Not const because all the full-screen goop is not const
|
||||
virtual bool FullscreenEnabled() = 0;
|
||||
virtual Element* FullScreenStackTop() = 0;
|
||||
virtual Element* GetTopLayerTop() = 0;
|
||||
virtual Element* GetUnretargetedFullScreenElement() = 0;
|
||||
bool Fullscreen()
|
||||
{
|
||||
return !!GetFullscreenElement();
|
||||
|
|
|
|||
|
|
@ -123,8 +123,8 @@ ViewportFrame::BuildDisplayListForTopLayer(nsDisplayListBuilder* aBuilder,
|
|||
nsDisplayList* aList)
|
||||
{
|
||||
nsIDocument* doc = PresContext()->Document();
|
||||
nsTArray<Element*> fullscreenStack = doc->GetFullscreenStack();
|
||||
for (Element* elem : fullscreenStack) {
|
||||
nsTArray<Element*> toplayer = doc->GetTopLayer();
|
||||
for (Element* elem : toplayer) {
|
||||
if (nsIFrame* frame = elem->GetPrimaryFrame()) {
|
||||
// There are two cases where an element in fullscreen is not in
|
||||
// the top layer:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue