Bug 1491212 part 3 - Have Document.exitFullscreen return a Promise. r=smaug

Depends on D5989

Differential Revision: https://phabricator.services.mozilla.com/D5990

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Xidorn Quan 2018-09-17 23:25:10 +00:00
parent 93d16f9841
commit 2d731ee18d
7 changed files with 59 additions and 20 deletions

View File

@ -151,6 +151,35 @@ private:
}
};
class FullscreenExit : public FullscreenChange
{
public:
static const ChangeType kType = eExit;
static UniquePtr<FullscreenExit> Create(nsIDocument* aDoc, ErrorResult& aRv)
{
RefPtr<Promise> promise = Promise::Create(aDoc->GetOwnerGlobal(), aRv);
return WrapUnique(new FullscreenExit(aDoc, promise.forget()));
}
static UniquePtr<FullscreenExit> CreateForRemote(nsIDocument* aDoc)
{
return WrapUnique(new FullscreenExit(aDoc, nullptr));
}
~FullscreenExit()
{
MOZ_COUNT_DTOR(FullscreenExit);
}
private:
FullscreenExit(nsIDocument* aDoc, already_AddRefed<Promise> aPromise)
: FullscreenChange(kType, aDoc, std::move(aPromise))
{
MOZ_COUNT_CTOR(FullscreenExit);
}
};
} // namespace mozilla
#endif // mozilla_FullscreenRequest_h

View File

@ -10730,10 +10730,13 @@ nsIDocument::SetFullscreenRoot(nsIDocument* aRoot)
mFullscreenRoot = do_GetWeakReference(aRoot);
}
void
nsIDocument::ExitFullscreen()
already_AddRefed<Promise>
nsIDocument::ExitFullscreen(ErrorResult& aRv)
{
RestorePreviousFullscreenState();
UniquePtr<FullscreenExit> exit = FullscreenExit::Create(this, aRv);
RefPtr<Promise> promise = exit->GetPromise();
RestorePreviousFullscreenState(std::move(exit));
return promise.forget();
}
static void
@ -10905,6 +10908,14 @@ nsIDocument::ExitFullscreenInDocTree(nsIDocument* aMaybeNotARootDoc)
// Unlock the pointer
UnlockPointer();
// Resolve all promises which waiting for exit fullscreen.
PendingFullscreenChangeList::Iterator<FullscreenExit> iter(
aMaybeNotARootDoc, PendingFullscreenChangeList::eDocumentsWithSameRoot);
while (!iter.AtEnd()) {
UniquePtr<FullscreenExit> exit = iter.TakeAndNext();
exit->MayResolvePromise();
}
nsCOMPtr<nsIDocument> root = aMaybeNotARootDoc->GetFullscreenRoot();
if (!root || !root->FullscreenStackTop()) {
// If a document was detached before exiting from fullscreen, it is
@ -10948,12 +10959,13 @@ DispatchFullscreenNewOriginEvent(nsIDocument* aDoc)
}
void
nsIDocument::RestorePreviousFullscreenState()
nsIDocument::RestorePreviousFullscreenState(UniquePtr<FullscreenExit> aExit)
{
NS_ASSERTION(!FullscreenStackTop() || !FullscreenRoots::IsEmpty(),
"Should have at least 1 fullscreen root when fullscreen!");
if (!FullscreenStackTop() || !GetWindow() || FullscreenRoots::IsEmpty()) {
aExit->MayRejectPromise();
return;
}
@ -10994,6 +11006,7 @@ nsIDocument::RestorePreviousFullscreenState()
lastDoc->mFullscreenStack.Length() == 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));
AskWindowToExitFullscreen(this);
return;
}
@ -11021,6 +11034,7 @@ nsIDocument::RestorePreviousFullscreenState()
for (Element* e : Reversed(exitElements)) {
DispatchFullscreenChange(e->OwnerDoc(), e);
}
aExit->MayResolvePromise();
MOZ_ASSERT(newFullscreenDoc, "If we were going to exit from fullscreen on "
"all documents in this doctree, we should've asked the window to "
@ -11229,7 +11243,8 @@ nsresult nsIDocument::RemoteFrameFullscreenChanged(Element* aFrameElement)
nsresult nsIDocument::RemoteFrameFullscreenReverted()
{
RestorePreviousFullscreenState();
UniquePtr<FullscreenExit> exit = FullscreenExit::CreateForRemote(this);
RestorePreviousFullscreenState(std::move(exit));
return NS_OK;
}

View File

@ -126,6 +126,7 @@ class Encoding;
class ErrorResult;
class EventStates;
class EventListenerManager;
class FullscreenExit;
class FullscreenRequest;
class PendingAnimationTracker;
class ServoStyleSet;
@ -1811,7 +1812,8 @@ public:
* is no former fullscreen element, this exits fullscreen, moving the
* top-level browser window out of fullscreen mode.
*/
void RestorePreviousFullscreenState();
void RestorePreviousFullscreenState(
mozilla::UniquePtr<mozilla::FullscreenExit>);
/**
* Returns true if this document is a fullscreen leaf document, i.e. it
@ -3293,7 +3295,7 @@ public:
{
return !!GetFullscreenElement();
}
void ExitFullscreen();
already_AddRefed<mozilla::dom::Promise> ExitFullscreen(ErrorResult&);
void ExitPointerLock()
{
UnlockPointer(this);

View File

@ -109,7 +109,7 @@ function enter2(event) {
// the full-screen element to the previous full-screen element. This causes
// a fullscreenchange event.
addFullscreenChangeContinuation("exit", exit2);
document.exitFullscreen();
promise = document.exitFullscreen();
}
function exit2(event) {
@ -117,6 +117,7 @@ function exit2(event) {
"Full-screen element should have rolled back.");
is(iframe.contentDocument.fullscreenElement, null,
"Full-screen element in subframe should be null");
assertPromiseResolved(promise, "in exit2");
addFullscreenChangeContinuation("enter", enter3);
promise = FULLSCREEN_ELEMENT.requestFullscreen();

View File

@ -269,10 +269,10 @@ partial interface Document {
[BinaryName="fullscreenEnabled", NeedsCallerType]
readonly attribute boolean mozFullScreenEnabled;
[Func="nsDocument::IsUnprefixedFullscreenEnabled"]
void exitFullscreen();
[BinaryName="exitFullscreen"]
void mozCancelFullScreen();
[Throws, Func="nsDocument::IsUnprefixedFullscreenEnabled"]
Promise<void> exitFullscreen();
[Throws, BinaryName="exitFullscreen"]
Promise<void> mozCancelFullScreen();
// Events handlers
[Func="nsDocument::IsUnprefixedFullscreenEnabled"]

View File

@ -1,4 +0,0 @@
[promises-reject.html]
[Promises#reject 1]
expected: FAIL

View File

@ -1,4 +0,0 @@
[idlharness.window.html]
[Document interface: operation exitFullscreen()]
expected: FAIL