From 93d16f98410f67e39dde0b8e8c9f96d95935beda Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Mon, 17 Sep 2018 23:20:28 +0000 Subject: [PATCH] Bug 1491212 part 2 - Have a new FullscreenChange superclass split from FullscreenRequest. r=smaug The next patch would create another subclass of FullscreenChange for handling fullscreen exit. Depends on D5988 Differential Revision: https://phabricator.services.mozilla.com/D5989 --HG-- rename : dom/base/FullscreenRequest.h => dom/base/FullscreenChange.h extra : moz-landing-system : lando --- dom/base/Element.cpp | 2 +- ...FullscreenRequest.h => FullscreenChange.h} | 99 ++++++++++++------- dom/base/moz.build | 2 +- dom/base/nsDocument.cpp | 86 ++++++++-------- dom/base/nsIDocument.h | 2 +- 5 files changed, 113 insertions(+), 78 deletions(-) rename dom/base/{FullscreenRequest.h => FullscreenChange.h} (80%) diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 8d01e371e64d..496a6546c1c7 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -65,7 +65,7 @@ #include "mozilla/EventListenerManager.h" #include "mozilla/EventStateManager.h" #include "mozilla/EventStates.h" -#include "mozilla/FullscreenRequest.h" +#include "mozilla/FullscreenChange.h" #include "mozilla/InternalMutationEvent.h" #include "mozilla/MouseEvents.h" #include "mozilla/RestyleManager.h" diff --git a/dom/base/FullscreenRequest.h b/dom/base/FullscreenChange.h similarity index 80% rename from dom/base/FullscreenRequest.h rename to dom/base/FullscreenChange.h index 9f82ea4e1b1c..4653956942c0 100644 --- a/dom/base/FullscreenRequest.h +++ b/dom/base/FullscreenChange.h @@ -21,36 +21,18 @@ namespace mozilla { -struct FullscreenRequest : public LinkedListElement +class FullscreenChange : public LinkedListElement { - typedef dom::Promise Promise; +public: + FullscreenChange(const FullscreenChange&) = delete; - static UniquePtr Create(Element* aElement, - dom::CallerType aCallerType, - ErrorResult& aRv) + enum ChangeType { - RefPtr promise = Promise::Create(aElement->GetOwnerGlobal(), aRv); - return WrapUnique(new FullscreenRequest(aElement, promise.forget(), - aCallerType, true)); - } + eEnter, + eExit, + }; - static UniquePtr CreateForRemote(Element* aElement) - { - return WrapUnique(new FullscreenRequest(aElement, nullptr, - dom::CallerType::NonSystem, - false)); - } - - FullscreenRequest(const FullscreenRequest&) = delete; - - ~FullscreenRequest() - { - MOZ_COUNT_DTOR(FullscreenRequest); - MOZ_ASSERT_IF(mPromise, - mPromise->State() != Promise::PromiseState::Pending); - } - - dom::Element* Element() const { return mElement; } + ChangeType Type() const { return mType; } nsIDocument* Document() const { return mDocument; } dom::Promise* GetPromise() const { return mPromise; } @@ -70,28 +52,78 @@ struct FullscreenRequest : public LinkedListElement } } +protected: + typedef dom::Promise Promise; + + FullscreenChange(ChangeType aType, nsIDocument* aDocument, + already_AddRefed aPromise) + : mType(aType) + , mDocument(aDocument) + , mPromise(aPromise) + { + MOZ_ASSERT(aDocument); + } + + ~FullscreenChange() + { + MOZ_ASSERT_IF(mPromise, + mPromise->State() != Promise::PromiseState::Pending); + } + +private: + ChangeType mType; + nsCOMPtr mDocument; + RefPtr mPromise; +}; + +class FullscreenRequest : public FullscreenChange +{ +public: + static const ChangeType kType = eEnter; + + static UniquePtr Create(Element* aElement, + dom::CallerType aCallerType, + ErrorResult& aRv) + { + RefPtr promise = Promise::Create(aElement->GetOwnerGlobal(), aRv); + return WrapUnique(new FullscreenRequest(aElement, promise.forget(), + aCallerType, true)); + } + + static UniquePtr CreateForRemote(Element* aElement) + { + return WrapUnique(new FullscreenRequest(aElement, nullptr, + dom::CallerType::NonSystem, + false)); + } + + ~FullscreenRequest() + { + MOZ_COUNT_DTOR(FullscreenRequest); + } + + dom::Element* Element() const { return mElement; } + // Reject the fullscreen request with the given reason. // It will dispatch the fullscreenerror event. void Reject(const char* aReason) const { - if (nsPresContext* presContext = mDocument->GetPresContext()) { + if (nsPresContext* presContext = Document()->GetPresContext()) { auto pendingEvent = MakeUnique( - FullscreenEventType::Error, mDocument, mElement); + FullscreenEventType::Error, Document(), mElement); presContext->RefreshDriver()-> ScheduleFullscreenEvent(std::move(pendingEvent)); } MayRejectPromise(); nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, NS_LITERAL_CSTRING("DOM"), - mDocument, + Document(), nsContentUtils::eDOM_PROPERTIES, aReason); } private: RefPtr mElement; - RefPtr mDocument; - RefPtr mPromise; public: // This value should be true if the fullscreen request is @@ -110,9 +142,8 @@ private: already_AddRefed aPromise, dom::CallerType aCallerType, bool aShouldNotifyNewOrigin) - : mElement(aElement) - , mDocument(aElement->OwnerDoc()) - , mPromise(aPromise) + : FullscreenChange(kType, aElement->OwnerDoc(), std::move(aPromise)) + , mElement(aElement) , mCallerType(aCallerType) , mShouldNotifyNewOrigin(aShouldNotifyNewOrigin) { diff --git a/dom/base/moz.build b/dom/base/moz.build index 08a790a786c1..447aef561d54 100644 --- a/dom/base/moz.build +++ b/dom/base/moz.build @@ -131,7 +131,7 @@ EXPORTS.mozilla += [ 'CORSMode.h', 'FeedWriterEnabled.h', 'FlushType.h', - 'FullscreenRequest.h', + 'FullscreenChange.h', 'RangeBoundary.h', 'SelectionChangeEventDispatcher.h', 'TextInputProcessor.h', diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 3d0b4777b807..3688f04f3677 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -58,7 +58,7 @@ #include "mozilla/BasicEvents.h" #include "mozilla/EventListenerManager.h" #include "mozilla/EventStateManager.h" -#include "mozilla/FullscreenRequest.h" +#include "mozilla/FullscreenChange.h" #include "mozilla/dom/Attr.h" #include "mozilla/dom/BindingDeclarations.h" @@ -10613,22 +10613,23 @@ FullscreenRoots::IsEmpty() return !sInstance; } -// Any fullscreen request waiting for the widget to finish being full- -// screen is queued here. This is declared static instead of a member -// of nsDocument because in the majority of time, there would be at most -// one document requesting fullscreen. We shouldn't waste the space to -// hold for it in every document. -class PendingFullscreenRequestList +// Any fullscreen change waiting for the widget to finish transition +// is queued here. This is declared static instead of a member of +// nsDocument because in the majority of time, there would be at most +// one document requesting or exiting fullscreen. We shouldn't waste +// the space to hold for it in every document. +class PendingFullscreenChangeList { public: - PendingFullscreenRequestList() = delete; + PendingFullscreenChangeList() = delete; - static void Add(UniquePtr aRequest) + template + static void Add(UniquePtr aChange) { - sList.insertBack(aRequest.release()); + sList.insertBack(aChange.release()); } - static const FullscreenRequest* GetLast() + static const FullscreenChange* GetLast() { return sList.getLast(); } @@ -10645,11 +10646,12 @@ public: eInclusiveDescendants }; + template class Iterator { public: explicit Iterator(nsIDocument* aDoc, IteratorOption aOption) - : mCurrent(PendingFullscreenRequestList::sList.getFirst()) + : mCurrent(PendingFullscreenChangeList::sList.getFirst()) , mRootShellForIteration(aDoc->GetDocShell()) { if (mCurrent) { @@ -10661,55 +10663,57 @@ public: } } - UniquePtr TakeAndNext() + UniquePtr TakeAndNext() { - auto thisRequest = TakeAndNextInternal(); + auto thisChange = TakeAndNextInternal(); SkipToNextMatch(); - return thisRequest; + return thisChange; } bool AtEnd() const { return mCurrent == nullptr; } private: - UniquePtr TakeAndNextInternal() + UniquePtr TakeAndNextInternal() { - UniquePtr thisRequest(mCurrent); + FullscreenChange* thisChange = mCurrent; + MOZ_ASSERT(thisChange->Type() == T::kType); mCurrent = mCurrent->removeAndGetNext(); - return thisRequest; + return WrapUnique(static_cast(thisChange)); } void SkipToNextMatch() { while (mCurrent) { - nsCOMPtr - docShell = mCurrent->Document()->GetDocShell(); - if (!docShell) { - // Always automatically drop fullscreen requests which is from - // a document detached from the doc shell. - UniquePtr request = TakeAndNextInternal(); - request->MayRejectPromise(); - } else { + if (mCurrent->Type() == T::kType) { + nsCOMPtr + docShell = mCurrent->Document()->GetDocShell(); + if (!docShell) { + // Always automatically drop fullscreen changes which are + // from a document detached from the doc shell. + UniquePtr change = TakeAndNextInternal(); + change->MayRejectPromise(); + continue; + } while (docShell && docShell != mRootShellForIteration) { docShell->GetParent(getter_AddRefs(docShell)); } - if (!docShell) { - // We've gone over the root, but haven't find the target - // ancestor, so skip this item. - mCurrent = mCurrent->getNext(); - } else { + if (docShell) { break; } } + // The current one either don't have matched type, or isn't + // inside the given subtree, so skip this item. + mCurrent = mCurrent->getNext(); } } - FullscreenRequest* mCurrent; + FullscreenChange* mCurrent; nsCOMPtr mRootShellForIteration; }; private: - static LinkedList sList; + static LinkedList sList; }; -/* static */ LinkedList PendingFullscreenRequestList::sList; +/* static */ LinkedList PendingFullscreenChangeList::sList; } // end namespace mozilla. @@ -11367,8 +11371,8 @@ ShouldApplyFullscreenDirectly(nsIDocument* aDoc, // 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. - PendingFullscreenRequestList::Iterator - iter(aDoc, PendingFullscreenRequestList::eDocumentsWithSameRoot); + PendingFullscreenChangeList::Iterator iter( + aDoc, PendingFullscreenChangeList::eDocumentsWithSameRoot); if (!iter.AtEnd()) { return false; } @@ -11411,7 +11415,7 @@ nsIDocument::RequestFullscreen(UniquePtr aRequest) return; } - PendingFullscreenRequestList::Add(std::move(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. @@ -11428,8 +11432,8 @@ nsIDocument::RequestFullscreen(UniquePtr aRequest) nsIDocument::HandlePendingFullscreenRequests(nsIDocument* aDoc) { bool handled = false; - PendingFullscreenRequestList::Iterator iter( - aDoc, PendingFullscreenRequestList::eDocumentsWithSameRoot); + PendingFullscreenChangeList::Iterator iter( + aDoc, PendingFullscreenChangeList::eDocumentsWithSameRoot); while (!iter.AtEnd()) { UniquePtr request = iter.TakeAndNext(); nsIDocument* doc = request->Document(); @@ -11443,8 +11447,8 @@ nsIDocument::HandlePendingFullscreenRequests(nsIDocument* aDoc) static void ClearPendingFullscreenRequests(nsIDocument* aDoc) { - PendingFullscreenRequestList::Iterator iter( - aDoc, PendingFullscreenRequestList::eInclusiveDescendants); + PendingFullscreenChangeList::Iterator iter( + aDoc, PendingFullscreenChangeList::eInclusiveDescendants); while (!iter.AtEnd()) { UniquePtr request = iter.TakeAndNext(); request->MayRejectPromise(); diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index 8ae4531bee49..47e99fa04aa8 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -126,7 +126,7 @@ class Encoding; class ErrorResult; class EventStates; class EventListenerManager; -struct FullscreenRequest; +class FullscreenRequest; class PendingAnimationTracker; class ServoStyleSet; template class OwningNonNull;