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:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +115,7 @@ public:
|
||||
~DocumentOrShadowRoot() = default;
|
||||
|
||||
Element* GetPointerLockElement();
|
||||
Element* GetFullscreenElement();
|
||||
|
||||
protected:
|
||||
nsIContent* Retarget(nsIContent* aContent) const;
|
||||
|
||||
+21
-28
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user