зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
f398a3ed0e
Коммит
93d16f9841
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче