mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 09:15:35 +00:00
Bug 1585078 - part 1: Divide Document::RequestFullScreen()
into seperate path to clarify the case in content process. r=nika
Differential Revision: https://phabricator.services.mozilla.com/D71961
This commit is contained in:
parent
2a8ae88483
commit
5f73b12af7
@ -13601,55 +13601,68 @@ static nsCOMPtr<nsPIDOMWindowOuter> GetRootWindow(Document* aDoc) {
|
||||
|
||||
static bool ShouldApplyFullscreenDirectly(Document* aDoc,
|
||||
nsPIDOMWindowOuter* aRootWin) {
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
// 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)
|
||||
->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.
|
||||
if (!aRootWin->GetFullScreen()) {
|
||||
return false;
|
||||
}
|
||||
// The iterator not being at end indicates there is still some
|
||||
// pending fullscreen request relates to this document. We have to
|
||||
// push the request to the pending queue so requests are handled
|
||||
// in the correct order.
|
||||
PendingFullscreenChangeList::Iterator<FullscreenRequest> iter(
|
||||
aDoc, PendingFullscreenChangeList::eDocumentsWithSameRoot);
|
||||
if (!iter.AtEnd()) {
|
||||
return false;
|
||||
}
|
||||
// We have to apply the fullscreen state directly in this case,
|
||||
// because nsGlobalWindow::SetFullscreenInternal() will do nothing
|
||||
// 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;
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
// If we are in the chrome process, and the window has not been in
|
||||
// fullscreen, we certainly need to make that fullscreen first.
|
||||
if (!aRootWin->GetFullScreen()) {
|
||||
return false;
|
||||
}
|
||||
// The iterator not being at end indicates there is still some
|
||||
// pending fullscreen request relates to this document. We have to
|
||||
// push the request to the pending queue so requests are handled
|
||||
// in the correct order.
|
||||
PendingFullscreenChangeList::Iterator<FullscreenRequest> iter(
|
||||
aDoc, PendingFullscreenChangeList::eDocumentsWithSameRoot);
|
||||
if (!iter.AtEnd()) {
|
||||
return false;
|
||||
}
|
||||
// We have to apply the fullscreen state directly in this case,
|
||||
// because nsGlobalWindow::SetFullscreenInternal() will do nothing
|
||||
// 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;
|
||||
}
|
||||
|
||||
static bool CheckFullscreenAllowedElementType(const Element* elem) {
|
||||
// Per spec only HTML, <svg>, and <math> should be allowed, but
|
||||
// we also need to allow XUL elements right now.
|
||||
return elem->IsHTMLElement() || elem->IsXULElement() ||
|
||||
elem->IsSVGElement(nsGkAtoms::svg) ||
|
||||
elem->IsMathMLElement(nsGkAtoms::math);
|
||||
}
|
||||
|
||||
void Document::RequestFullscreen(UniquePtr<FullscreenRequest> aRequest,
|
||||
bool applyFullScreenDirectly) {
|
||||
if (XRE_IsContentProcess()) {
|
||||
RequestFullscreenInContentProcess(std::move(aRequest),
|
||||
applyFullScreenDirectly);
|
||||
} else {
|
||||
RequestFullscreenInParentProcess(std::move(aRequest),
|
||||
applyFullScreenDirectly);
|
||||
}
|
||||
}
|
||||
|
||||
void Document::RequestFullscreenInContentProcess(
|
||||
UniquePtr<FullscreenRequest> aRequest, bool applyFullScreenDirectly) {
|
||||
MOZ_ASSERT(XRE_IsContentProcess());
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> rootWin = GetRootWindow(this);
|
||||
if (!rootWin) {
|
||||
aRequest->MayRejectPromise("No active window");
|
||||
return;
|
||||
}
|
||||
|
||||
if (applyFullScreenDirectly || ShouldApplyFullscreenDirectly(this, rootWin)) {
|
||||
// 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.
|
||||
if (applyFullScreenDirectly || !!nsContentUtils::GetRootDocument(this)
|
||||
->GetUnretargetedFullScreenElement()) {
|
||||
ApplyFullscreen(std::move(aRequest));
|
||||
return;
|
||||
}
|
||||
|
||||
// Per spec only HTML, <svg>, and <math> should be allowed, but
|
||||
// we also need to allow XUL elements right now.
|
||||
Element* elem = aRequest->Element();
|
||||
if (!elem->IsHTMLElement() && !elem->IsXULElement() &&
|
||||
!elem->IsSVGElement(nsGkAtoms::svg) &&
|
||||
!elem->IsMathMLElement(nsGkAtoms::math)) {
|
||||
if (!CheckFullscreenAllowedElementType(aRequest->Element())) {
|
||||
aRequest->Reject("FullscreenDeniedNotHTMLSVGOrMathML");
|
||||
return;
|
||||
}
|
||||
@ -13661,16 +13674,41 @@ void Document::RequestFullscreen(UniquePtr<FullscreenRequest> aRequest,
|
||||
}
|
||||
|
||||
PendingFullscreenChangeList::Add(std::move(aRequest));
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
// If we are not the top level process, dispatch an event to make
|
||||
// our parent process go fullscreen first.
|
||||
nsContentUtils::DispatchEventOnlyToChrome(
|
||||
this, ToSupports(this), NS_LITERAL_STRING("MozDOMFullscreen:Request"),
|
||||
CanBubble::eYes, Cancelable::eNo, /* DefaultAction */ nullptr);
|
||||
} else {
|
||||
// Make the window fullscreen.
|
||||
rootWin->SetFullscreenInternal(FullscreenReason::ForFullscreenAPI, true);
|
||||
// If we are not the top level process, dispatch an event to make
|
||||
// our parent process go fullscreen first.
|
||||
nsContentUtils::DispatchEventOnlyToChrome(
|
||||
this, ToSupports(this), NS_LITERAL_STRING("MozDOMFullscreen:Request"),
|
||||
CanBubble::eYes, Cancelable::eNo, /* DefaultAction */ nullptr);
|
||||
}
|
||||
|
||||
void Document::RequestFullscreenInParentProcess(
|
||||
UniquePtr<FullscreenRequest> aRequest, bool applyFullScreenDirectly) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
nsCOMPtr<nsPIDOMWindowOuter> rootWin = GetRootWindow(this);
|
||||
if (!rootWin) {
|
||||
aRequest->MayRejectPromise("No active window");
|
||||
return;
|
||||
}
|
||||
|
||||
if (applyFullScreenDirectly || ShouldApplyFullscreenDirectly(this, rootWin)) {
|
||||
ApplyFullscreen(std::move(aRequest));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CheckFullscreenAllowedElementType(aRequest->Element())) {
|
||||
aRequest->Reject("FullscreenDeniedNotHTMLSVGOrMathML");
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't need to check element ready before this point, because
|
||||
// if we called ApplyFullscreen, it would check that for us.
|
||||
if (!FullscreenElementReadyCheck(*aRequest)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PendingFullscreenChangeList::Add(std::move(aRequest));
|
||||
// Make the window fullscreen.
|
||||
rootWin->SetFullscreenInternal(FullscreenReason::ForFullscreenAPI, true);
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
@ -1894,6 +1894,13 @@ class Document : public nsINode,
|
||||
void RequestFullscreen(UniquePtr<FullscreenRequest> aRequest,
|
||||
bool applyFullScreenDirectly = false);
|
||||
|
||||
private:
|
||||
void RequestFullscreenInContentProcess(UniquePtr<FullscreenRequest> aRequest,
|
||||
bool applyFullScreenDirectly);
|
||||
void RequestFullscreenInParentProcess(UniquePtr<FullscreenRequest> aRequest,
|
||||
bool applyFullScreenDirectly);
|
||||
|
||||
public:
|
||||
// Removes all the elements with fullscreen flag set from the top layer, and
|
||||
// clears their fullscreen flag.
|
||||
void CleanupFullscreenState();
|
||||
|
Loading…
Reference in New Issue
Block a user