1
0
mirror of https://github.com/roytam1/UXP.git synced 2026-05-26 13:58:49 +00:00

Issue #2135 - Bug 1430305: Implement ShadowRoot.fullscreenElement

This commit is contained in:
FranklinDM
2023-03-03 19:52:43 +08:00
committed by roytam1
parent 3dfffeaeca
commit e286eb8adb
10 changed files with 105 additions and 40 deletions
+20
View File
@@ -160,5 +160,25 @@ DocumentOrShadowRoot::GetPointerLockElement()
retargetedPointerLockedElement->AsElement() : nullptr;
}
Element*
DocumentOrShadowRoot::GetFullscreenElement()
{
if (!AsNode().IsInComposedDoc()) {
return nullptr;
}
Element* element = AsNode().OwnerDoc()->FullScreenStackTop();
NS_ASSERTION(!element ||
element->State().HasState(NS_EVENT_STATE_FULL_SCREEN),
"Fullscreen element should have fullscreen styles applied");
nsIContent* retargeted = Retarget(element);
if (retargeted && retargeted->IsElement()) {
return retargeted->AsElement();
}
return nullptr;
}
}
}
+1
View File
@@ -115,6 +115,7 @@ public:
~DocumentOrShadowRoot() = default;
Element* GetPointerLockElement();
Element* GetFullscreenElement();
protected:
nsIContent* Retarget(nsIContent* aContent) const;
+21 -28
View File
@@ -8603,7 +8603,7 @@ nsDocument::OnPageHide(bool aPersisted,
EnumerateActivityObservers(NotifyActivityChanged, nullptr);
ClearPendingFullscreenRequests(this);
if (GetFullscreenElement()) {
if (FullScreenStackTop()) {
// 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
@@ -10307,7 +10307,7 @@ nsIDocument::AsyncExitFullscreen(nsIDocument* aDoc)
static bool
CountFullscreenSubDocuments(nsIDocument* aDoc, void* aData)
{
if (aDoc->GetFullscreenElement()) {
if (aDoc->FullScreenStackTop()) {
uint32_t* count = static_cast<uint32_t*>(aData);
(*count)++;
}
@@ -10327,7 +10327,7 @@ nsDocument::IsFullscreenLeaf()
{
// A fullscreen leaf document is fullscreen, and has no fullscreen
// subdocuments.
if (!GetFullscreenElement()) {
if (!FullScreenStackTop()) {
return false;
}
return CountFullscreenSubDocuments(this) == 0;
@@ -10336,11 +10336,11 @@ nsDocument::IsFullscreenLeaf()
static bool
ResetFullScreen(nsIDocument* aDocument, void* aData)
{
if (aDocument->GetFullscreenElement()) {
if (aDocument->FullScreenStackTop()) {
NS_ASSERTION(CountFullscreenSubDocuments(aDocument) <= 1,
"Should have at most 1 fullscreen subdocument.");
static_cast<nsDocument*>(aDocument)->CleanupFullscreenState();
NS_ASSERTION(!aDocument->GetFullscreenElement(),
NS_ASSERTION(!aDocument->FullScreenStackTop(),
"Should reset full-screen");
auto changed = reinterpret_cast<nsCOMArray<nsIDocument>*>(aData);
changed->AppendElement(aDocument);
@@ -10388,7 +10388,7 @@ nsIDocument::ExitFullscreenInDocTree(nsIDocument* aMaybeNotARootDoc)
UnlockPointer();
nsCOMPtr<nsIDocument> root = aMaybeNotARootDoc->GetFullscreenRoot();
if (!root || !root->GetFullscreenElement()) {
if (!root || !root->FullScreenStackTop()) {
// 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
@@ -10417,7 +10417,7 @@ nsIDocument::ExitFullscreenInDocTree(nsIDocument* aMaybeNotARootDoc)
DispatchFullScreenChange(changed[changed.Length() - i - 1]);
}
NS_ASSERTION(!root->GetFullscreenElement(),
NS_ASSERTION(!root->FullScreenStackTop(),
"Fullscreen root should no longer be a fullscreen doc...");
// Move the top-level window out of fullscreen mode.
@@ -10434,7 +10434,7 @@ GetFullscreenLeaf(nsIDocument* aDoc, void* aData)
nsIDocument** result = static_cast<nsIDocument**>(aData);
*result = aDoc;
return false;
} else if (aDoc->GetFullscreenElement()) {
} else if (aDoc->FullScreenStackTop()) {
aDoc->EnumerateSubDocuments(GetFullscreenLeaf, aData);
}
return true;
@@ -10453,7 +10453,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->GetFullscreenElement()) {
if (!root->FullScreenStackTop()) {
return nullptr;
}
GetFullscreenLeaf(root, &leaf);
@@ -10463,10 +10463,10 @@ GetFullscreenLeaf(nsIDocument* aDoc)
void
nsDocument::RestorePreviousFullScreenState()
{
NS_ASSERTION(!GetFullscreenElement() || !FullscreenRoots::IsEmpty(),
NS_ASSERTION(!FullScreenStackTop() || !FullscreenRoots::IsEmpty(),
"Should have at least 1 fullscreen root when fullscreen!");
if (!GetFullscreenElement() || !GetWindow() || FullscreenRoots::IsEmpty()) {
if (!FullScreenStackTop() || !GetWindow() || FullscreenRoots::IsEmpty()) {
return;
}
@@ -10641,7 +10641,7 @@ nsDocument::FullScreenStackPush(Element* aElement)
}
EventStateManager::SetFullScreenState(aElement, true);
mFullScreenStack.AppendElement(do_GetWeakReference(aElement));
NS_ASSERTION(GetFullscreenElement() == aElement, "Should match");
NS_ASSERTION(FullScreenStackTop() == aElement, "Should match");
UpdateViewportScrollbarOverrideForFullscreen(this);
return true;
}
@@ -10689,7 +10689,7 @@ nsDocument::FullScreenStackTop()
uint32_t last = mFullScreenStack.Length() - 1;
nsCOMPtr<Element> element(do_QueryReferent(mFullScreenStack[last]));
NS_ASSERTION(element, "Should have full-screen element!");
NS_ASSERTION(element->IsInUncomposedDoc(), "Full-screen element should be in doc");
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;
}
@@ -10767,7 +10767,7 @@ nsresult nsDocument::RemoteFrameFullscreenReverted()
}
/* static */ bool
nsDocument::IsUnprefixedFullscreenEnabled(JSContext* aCx, JSObject* aObject)
nsIDocument::IsUnprefixedFullscreenEnabled(JSContext* aCx, JSObject* aObject)
{
MOZ_ASSERT(NS_IsMainThread());
return nsContentUtils::IsCallerChrome() ||
@@ -10815,10 +10815,10 @@ nsDocument::FullscreenElementReadyCheck(Element* aElement,
{
NS_ASSERTION(aElement,
"Must pass non-null element to nsDocument::RequestFullScreen");
if (!aElement || aElement == GetFullscreenElement()) {
if (!aElement || aElement == FullScreenStackTop()) {
return false;
}
if (!aElement->IsInUncomposedDoc()) {
if (!aElement->IsInComposedDoc()) {
DispatchFullscreenError("FullscreenDeniedNotInDocument");
return false;
}
@@ -10842,8 +10842,11 @@ nsDocument::FullscreenElementReadyCheck(Element* aElement,
DispatchFullscreenError("FullscreenDeniedSubDocFullScreen");
return false;
}
if (GetFullscreenElement() &&
!nsContentUtils::ContentIsDescendantOf(aElement, GetFullscreenElement())) {
//XXXsmaug Note, we don't follow the latest fullscreen spec here.
// This whole check could be probably removed.
if (FullScreenStackTop() &&
!nsContentUtils::ContentIsHostIncludingDescendantOf(aElement,
FullScreenStackTop())) {
// If this document is full-screen, only grant full-screen requests from
// a descendant of the current full-screen element.
DispatchFullscreenError("FullscreenDeniedNotDescendant");
@@ -11203,16 +11206,6 @@ nsDocument::GetMozFullScreenElement(nsIDOMElement **aFullScreenElement)
return NS_OK;
}
Element*
nsDocument::GetFullscreenElement()
{
Element* element = FullScreenStackTop();
NS_ASSERTION(!element ||
element->State().HasState(NS_EVENT_STATE_FULL_SCREEN),
"Fullscreen element should have fullscreen styles applied");
return element;
}
NS_IMETHODIMP
nsDocument::GetMozFullScreen(bool *aFullScreen)
{
+1 -4
View File
@@ -896,8 +896,6 @@ public:
//
already_AddRefed<nsSimpleContentList> BlockedTrackingNodes() const;
static bool IsUnprefixedFullscreenEnabled(JSContext* aCx, JSObject* aObject);
// 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);
@@ -921,11 +919,10 @@ public:
void FullScreenStackPop();
// Returns the top element from the full-screen stack.
Element* FullScreenStackTop();
Element* FullScreenStackTop() override;
// DOM-exposed fullscreen API
bool FullscreenEnabled() override;
Element* GetFullscreenElement() override;
void RequestPointerLock(Element* aElement) override;
bool SetPointerLock(Element* aElement, int aCursorStyle);
+2 -1
View File
@@ -2637,7 +2637,7 @@ public:
nsIURI* GetDocumentURIObject() const;
// Not const because all the full-screen goop is not const
virtual bool FullscreenEnabled() = 0;
virtual Element* GetFullscreenElement() = 0;
virtual Element* FullScreenStackTop() = 0;
bool Fullscreen()
{
return !!GetFullscreenElement();
@@ -2647,6 +2647,7 @@ public:
{
UnlockPointer(this);
}
static bool IsUnprefixedFullscreenEnabled(JSContext* aCx, JSObject* aObject);
#ifdef MOZILLA_INTERNAL_API
bool Hidden() const
{
@@ -0,0 +1,52 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1430305
Bug 1430305 - Implement ShadowRoot.fullscreenElement
-->
<head>
<title>Bug 1430305</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
</script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js">
</script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1430305">
Mozilla Bug 1430305</a>
<div id="host"></div>
<pre id="test">
<script type="application/javascript">
function begin() {
var host = document.getElementById("host");
var shadowRoot = host.attachShadow({mode: "open"});
shadowRoot.innerHTML = "<div>test</div>";
var elem = shadowRoot.firstChild;
var gotFullscreenEvent = false;
document.addEventListener("fullscreenchange", function (e) {
if (document.fullscreenElement === host) {
is(shadowRoot.fullscreenElement, elem,
"Expected element entered fullsceen");
gotFullscreenEvent = true;
document.exitFullscreen();
} else {
opener.ok(gotFullscreenEvent, "Entered fullscreen as expected");
is(shadowRoot.fullscreenElement, null,
"Shouldn't have fullscreenElement anymore.");
is(document.fullscreenElement, null,
"Shouldn't have fullscreenElement anymore.");
opener.nextTest();
}
});
elem.requestFullscreen();
}
</script>
</pre>
</body>
</html>
+1
View File
@@ -72,6 +72,7 @@ support-files =
file_fullscreen-rollback.html
file_fullscreen-scrollbar.html
file_fullscreen-selector.html
file_fullscreen-shadowdom.html
file_fullscreen-svg-element.html
file_fullscreen-top-layer.html
file_fullscreen-unprefix-disabled-inner.html
+3 -1
View File
@@ -39,6 +39,7 @@ var gTestWindows = [
"file_fullscreen-navigation.html",
"file_fullscreen-scrollbar.html",
"file_fullscreen-selector.html",
"file_fullscreen-shadowdom.html",
"file_fullscreen-top-layer.html",
"file_fullscreen-backdrop.html",
"file_fullscreen-nested.html",
@@ -96,7 +97,8 @@ addLoadEvent(function() {
["full-screen-api.unprefix.enabled", true],
["full-screen-api.allow-trusted-requests-only", false],
["full-screen-api.transition-duration.enter", "0 0"],
["full-screen-api.transition-duration.leave", "0 0"]
["full-screen-api.transition-duration.leave", "0 0"],
["dom.webcomponents.enabled", true]
]}, nextTest);
});
SimpleTest.waitForExplicitFinish();
-4
View File
@@ -238,10 +238,6 @@ partial interface Document {
readonly attribute boolean fullscreenEnabled;
[BinaryName="fullscreenEnabled"]
readonly attribute boolean mozFullScreenEnabled;
[LenientSetter, Func="nsDocument::IsUnprefixedFullscreenEnabled"]
readonly attribute Element? fullscreenElement;
[BinaryName="fullscreenElement"]
readonly attribute Element? mozFullScreenElement;
[Func="nsDocument::IsUnprefixedFullscreenEnabled"]
void exitFullscreen();
+4 -2
View File
@@ -23,6 +23,8 @@ interface DocumentOrShadowRoot {
readonly attribute StyleSheetList styleSheets;
readonly attribute Element? pointerLockElement;
// Not implemented yet: bug 1430305.
// readonly attribute Element? fullscreenElement;
[LenientSetter, Func="nsDocument::IsUnprefixedFullscreenEnabled"]
readonly attribute Element? fullscreenElement;
[BinaryName="fullscreenElement"]
readonly attribute Element? mozFullScreenElement;
};