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
This commit is contained in:
Xidorn Quan 2018-09-17 23:20:28 +00:00
Родитель f398a3ed0e
Коммит 93d16f9841
5 изменённых файлов: 113 добавлений и 78 удалений

Просмотреть файл

@ -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"

Просмотреть файл

@ -21,36 +21,18 @@
namespace mozilla {
struct FullscreenRequest : public LinkedListElement<FullscreenRequest>
class FullscreenChange : public LinkedListElement<FullscreenChange>
{
typedef dom::Promise Promise;
public:
FullscreenChange(const FullscreenChange&) = delete;
static UniquePtr<FullscreenRequest> Create(Element* aElement,
dom::CallerType aCallerType,
ErrorResult& aRv)
enum ChangeType
{
RefPtr<Promise> promise = Promise::Create(aElement->GetOwnerGlobal(), aRv);
return WrapUnique(new FullscreenRequest(aElement, promise.forget(),
aCallerType, true));
}
eEnter,
eExit,
};
static UniquePtr<FullscreenRequest> 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<FullscreenRequest>
}
}
protected:
typedef dom::Promise Promise;
FullscreenChange(ChangeType aType, nsIDocument* aDocument,
already_AddRefed<Promise> aPromise)
: mType(aType)
, mDocument(aDocument)
, mPromise(aPromise)
{
MOZ_ASSERT(aDocument);
}
~FullscreenChange()
{
MOZ_ASSERT_IF(mPromise,
mPromise->State() != Promise::PromiseState::Pending);
}
private:
ChangeType mType;
nsCOMPtr<nsIDocument> mDocument;
RefPtr<Promise> mPromise;
};
class FullscreenRequest : public FullscreenChange
{
public:
static const ChangeType kType = eEnter;
static UniquePtr<FullscreenRequest> Create(Element* aElement,
dom::CallerType aCallerType,
ErrorResult& aRv)
{
RefPtr<Promise> promise = Promise::Create(aElement->GetOwnerGlobal(), aRv);
return WrapUnique(new FullscreenRequest(aElement, promise.forget(),
aCallerType, true));
}
static UniquePtr<FullscreenRequest> 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<PendingFullscreenEvent>(
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<dom::Element> mElement;
RefPtr<nsIDocument> mDocument;
RefPtr<dom::Promise> mPromise;
public:
// This value should be true if the fullscreen request is
@ -110,9 +142,8 @@ private:
already_AddRefed<dom::Promise> 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)
{

Просмотреть файл

@ -131,7 +131,7 @@ EXPORTS.mozilla += [
'CORSMode.h',
'FeedWriterEnabled.h',
'FlushType.h',
'FullscreenRequest.h',
'FullscreenChange.h',
'RangeBoundary.h',
'SelectionChangeEventDispatcher.h',
'TextInputProcessor.h',

Просмотреть файл

@ -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<FullscreenRequest> aRequest)
template<typename T>
static void Add(UniquePtr<T> 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<typename T>
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<FullscreenRequest> TakeAndNext()
UniquePtr<T> TakeAndNext()
{
auto thisRequest = TakeAndNextInternal();
auto thisChange = TakeAndNextInternal();
SkipToNextMatch();
return thisRequest;
return thisChange;
}
bool AtEnd() const { return mCurrent == nullptr; }
private:
UniquePtr<FullscreenRequest> TakeAndNextInternal()
UniquePtr<T> TakeAndNextInternal()
{
UniquePtr<FullscreenRequest> thisRequest(mCurrent);
FullscreenChange* thisChange = mCurrent;
MOZ_ASSERT(thisChange->Type() == T::kType);
mCurrent = mCurrent->removeAndGetNext();
return thisRequest;
return WrapUnique(static_cast<T*>(thisChange));
}
void SkipToNextMatch()
{
while (mCurrent) {
nsCOMPtr<nsIDocShellTreeItem>
docShell = mCurrent->Document()->GetDocShell();
if (!docShell) {
// Always automatically drop fullscreen requests which is from
// a document detached from the doc shell.
UniquePtr<FullscreenRequest> request = TakeAndNextInternal();
request->MayRejectPromise();
} else {
if (mCurrent->Type() == T::kType) {
nsCOMPtr<nsIDocShellTreeItem>
docShell = mCurrent->Document()->GetDocShell();
if (!docShell) {
// Always automatically drop fullscreen changes which are
// from a document detached from the doc shell.
UniquePtr<T> 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<nsIDocShellTreeItem> mRootShellForIteration;
};
private:
static LinkedList<FullscreenRequest> sList;
static LinkedList<FullscreenChange> sList;
};
/* static */ LinkedList<FullscreenRequest> PendingFullscreenRequestList::sList;
/* static */ LinkedList<FullscreenChange> 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<FullscreenRequest> iter(
aDoc, PendingFullscreenChangeList::eDocumentsWithSameRoot);
if (!iter.AtEnd()) {
return false;
}
@ -11411,7 +11415,7 @@ nsIDocument::RequestFullscreen(UniquePtr<FullscreenRequest> 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<FullscreenRequest> aRequest)
nsIDocument::HandlePendingFullscreenRequests(nsIDocument* aDoc)
{
bool handled = false;
PendingFullscreenRequestList::Iterator iter(
aDoc, PendingFullscreenRequestList::eDocumentsWithSameRoot);
PendingFullscreenChangeList::Iterator<FullscreenRequest> iter(
aDoc, PendingFullscreenChangeList::eDocumentsWithSameRoot);
while (!iter.AtEnd()) {
UniquePtr<FullscreenRequest> 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<FullscreenRequest> iter(
aDoc, PendingFullscreenChangeList::eInclusiveDescendants);
while (!iter.AtEnd()) {
UniquePtr<FullscreenRequest> request = iter.TakeAndNext();
request->MayRejectPromise();

Просмотреть файл

@ -126,7 +126,7 @@ class Encoding;
class ErrorResult;
class EventStates;
class EventListenerManager;
struct FullscreenRequest;
class FullscreenRequest;
class PendingAnimationTracker;
class ServoStyleSet;
template<typename> class OwningNonNull;