Bug 1624829 - Use FunctionRef for various Enumerate* callbacks. r=edgar

This avoids a bunch of ugly casts and void pointers, without much overhead
(unlike std::function or such).

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Emilio Cobos Álvarez 2020-03-26 12:44:47 +00:00
parent d83a7f3703
commit fcff6b1a69
14 changed files with 398 additions and 536 deletions

View File

@ -760,8 +760,7 @@ Document* ExternalResourceMap::RequestResource(
return nullptr;
}
void ExternalResourceMap::EnumerateResources(SubDocEnumFunc aCallback,
void* aData) {
void ExternalResourceMap::EnumerateResources(SubDocEnumFunc aCallback) {
nsTArray<RefPtr<Document>> docs(mMap.Count());
for (const auto& entry : mMap) {
if (Document* doc = entry.GetData()->mDocument) {
@ -770,7 +769,7 @@ void ExternalResourceMap::EnumerateResources(SubDocEnumFunc aCallback,
}
for (auto& doc : docs) {
if (aCallback(*doc, aData) == CallState::Stop) {
if (aCallback(*doc) == CallState::Stop) {
return;
}
}
@ -6830,44 +6829,40 @@ void Document::SetScopeObject(nsIGlobalObject* aGlobal) {
}
}
static void CheckIfContainsEMEContent(nsISupports* aSupports,
void* aContainsEME) {
nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
if (auto mediaElem = HTMLMediaElement::FromNodeOrNull(content)) {
bool* contains = static_cast<bool*>(aContainsEME);
if (mediaElem->GetMediaKeys()) {
*contains = true;
}
}
}
bool Document::ContainsEMEContent() {
bool containsEME = false;
EnumerateActivityObservers(CheckIfContainsEMEContent,
static_cast<void*>(&containsEME));
return containsEME;
}
static void CheckIfContainsMSEContent(nsISupports* aSupports,
void* aContainsMSE) {
nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
if (auto mediaElem = HTMLMediaElement::FromNodeOrNull(content)) {
bool* contains = static_cast<bool*>(aContainsMSE);
RefPtr<MediaSource> ms = mediaElem->GetMozMediaSourceObject();
if (ms) {
*contains = true;
auto check = [&containsEME](nsISupports* aSupports) {
nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
if (auto* mediaElem = HTMLMediaElement::FromNodeOrNull(content)) {
if (mediaElem->GetMediaKeys()) {
containsEME = true;
}
}
}
};
EnumerateActivityObservers(check);
return containsEME;
}
bool Document::ContainsMSEContent() {
bool containsMSE = false;
EnumerateActivityObservers(CheckIfContainsMSEContent,
static_cast<void*>(&containsMSE));
auto check = [&containsMSE](nsISupports* aSupports) {
nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
if (auto* mediaElem = HTMLMediaElement::FromNodeOrNull(content)) {
RefPtr<MediaSource> ms = mediaElem->GetMozMediaSourceObject();
if (ms) {
containsMSE = true;
}
}
};
EnumerateActivityObservers(check);
return containsMSE;
}
static void NotifyActivityChanged(nsISupports* aSupports, void* aUnused) {
static void NotifyActivityChanged(nsISupports* aSupports) {
nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
if (auto mediaElem = HTMLMediaElement::FromNodeOrNull(content)) {
mediaElem->NotifyOwnerDocumentActivityChanged();
@ -6919,7 +6914,7 @@ void Document::SetContainer(nsDocShell* aContainer) {
mInChromeDocShell =
aContainer && aContainer->GetBrowsingContext()->IsChrome();
EnumerateActivityObservers(NotifyActivityChanged, nullptr);
EnumerateActivityObservers(NotifyActivityChanged);
// IsTopLevelWindowInactive depends on the docshell, so
// update the cached value now that it's available.
@ -7064,7 +7059,7 @@ void Document::SetScriptGlobalObject(
// call, the document becomes not hidden. At the time, MediaDecoder needs
// to know it and needs to start updating decoding.
if (oldState != mVisibilityState) {
EnumerateActivityObservers(NotifyActivityChanged, nullptr);
EnumerateActivityObservers(NotifyActivityChanged);
}
// The global in the template contents owner document should be the same.
@ -8629,9 +8624,8 @@ Document* Document::RequestExternalResource(
aURI, aReferrerInfo, aRequestingNode, this, aPendingLoad);
}
void Document::EnumerateExternalResources(SubDocEnumFunc aCallback,
void* aData) {
mExternalResourceMap.EnumerateResources(aCallback, aData);
void Document::EnumerateExternalResources(SubDocEnumFunc aCallback) {
mExternalResourceMap.EnumerateResources(aCallback);
}
SMILAnimationController* Document::GetAnimationController() {
@ -10096,12 +10090,12 @@ void Document::FlushExternalResources(FlushType aType) {
return;
}
EnumerateExternalResources(
[](Document& aDoc, void* aData) -> CallState {
aDoc.FlushPendingNotifications(*static_cast<FlushType*>(aData));
return CallState::Continue;
},
&aType);
auto flush = [aType](Document& aDoc) {
aDoc.FlushPendingNotifications(aType);
return CallState::Continue;
};
EnumerateExternalResources(flush);
}
void Document::SetXMLDeclaration(const char16_t* aVersion,
@ -10326,7 +10320,7 @@ void Document::Sanitize() {
}
}
void Document::EnumerateSubDocuments(SubDocEnumFunc aCallback, void* aData) {
void Document::EnumerateSubDocuments(SubDocEnumFunc aCallback) {
if (!mSubDocuments) {
return;
}
@ -10341,7 +10335,7 @@ void Document::EnumerateSubDocuments(SubDocEnumFunc aCallback, void* aData) {
}
}
for (auto& subdoc : subdocs) {
if (aCallback(*subdoc, aData) == CallState::Stop) {
if (aCallback(*subdoc) == CallState::Stop) {
break;
}
}
@ -10597,7 +10591,7 @@ void Document::RemovedFromDocShell() {
if (mRemovedFromDocShell) return;
mRemovedFromDocShell = true;
EnumerateActivityObservers(NotifyActivityChanged, nullptr);
EnumerateActivityObservers(NotifyActivityChanged);
for (nsIContent* child = GetFirstChild(); child;
child = child->GetNextSibling()) {
@ -10823,12 +10817,6 @@ void Document::DispatchPageTransition(EventTarget* aDispatchTarget,
nullptr);
}
static CallState NotifyPageShow(Document& aDocument, void* aData) {
const bool* aPersistedPtr = static_cast<const bool*>(aData);
aDocument.OnPageShow(*aPersistedPtr, nullptr);
return CallState::Continue;
}
void Document::OnPageShow(bool aPersisted, EventTarget* aDispatchStartTarget,
bool aOnlySystemGroup) {
const bool inFrameLoaderSwap = !!aDispatchStartTarget;
@ -10862,8 +10850,13 @@ void Document::OnPageShow(bool aPersisted, EventTarget* aDispatchStartTarget,
UpdateVisibilityState();
}
EnumerateActivityObservers(NotifyActivityChanged, nullptr);
EnumerateExternalResources(NotifyPageShow, &aPersisted);
EnumerateActivityObservers(NotifyActivityChanged);
auto notifyExternal = [aPersisted](Document& aExternalResource) {
aExternalResource.OnPageShow(aPersisted, nullptr);
return CallState::Continue;
};
EnumerateExternalResources(notifyExternal);
if (mAnimationController) {
mAnimationController->OnPageShow();
@ -10889,12 +10882,6 @@ void Document::OnPageShow(bool aPersisted, EventTarget* aDispatchStartTarget,
}
}
static CallState NotifyPageHide(Document& aDocument, void* aData) {
const bool* aPersistedPtr = static_cast<const bool*>(aData);
aDocument.OnPageHide(*aPersistedPtr, nullptr);
return CallState::Continue;
}
static void DispatchFullscreenChange(Document& aDocument, nsINode* aTarget) {
if (nsPresContext* presContext = aDocument.GetPresContext()) {
auto pendingEvent = MakeUnique<PendingFullscreenEvent>(
@ -10973,8 +10960,12 @@ void Document::OnPageHide(bool aPersisted, EventTarget* aDispatchStartTarget,
UpdateVisibilityState();
}
EnumerateExternalResources(NotifyPageHide, &aPersisted);
EnumerateActivityObservers(NotifyActivityChanged, nullptr);
auto notifyExternal = [aPersisted](Document& aExternalResource) {
aExternalResource.OnPageHide(aPersisted, nullptr);
return CallState::Continue;
};
EnumerateExternalResources(notifyExternal);
EnumerateActivityObservers(NotifyActivityChanged);
ClearPendingFullscreenRequests(this);
if (FullscreenStackTop()) {
@ -11305,12 +11296,6 @@ void Document::GetReadyState(nsAString& aReadyState) const {
}
}
static CallState SuppressEventHandlingInDocument(Document& aDocument,
void* aData) {
aDocument.SuppressEventHandling(*static_cast<uint32_t*>(aData));
return CallState::Continue;
}
void Document::SuppressEventHandling(uint32_t aIncrease) {
mEventsSuppressed += aIncrease;
UpdateFrameRequestCallbackSchedulingState();
@ -11318,7 +11303,12 @@ void Document::SuppressEventHandling(uint32_t aIncrease) {
ScriptLoader()->AddExecuteBlocker();
}
EnumerateSubDocuments(SuppressEventHandlingInDocument, &aIncrease);
auto suppressInSubDoc = [aIncrease](Document& aSubDoc) {
aSubDoc.SuppressEventHandling(aIncrease);
return CallState::Continue;
};
EnumerateSubDocuments(suppressInSubDoc);
}
static void FireOrClearDelayedEvents(nsTArray<nsCOMPtr<Document>>& aDocuments,
@ -11628,23 +11618,22 @@ class nsDelayedEventDispatcher : public Runnable {
nsTArray<nsCOMPtr<Document>> mDocuments;
};
static CallState GetAndUnsuppressSubDocuments(Document& aDocument,
void* aData) {
static void GetAndUnsuppressSubDocuments(Document& aDocument, nsTArray<nsCOMPtr<Document>>& aDocuments) {
if (aDocument.EventHandlingSuppressed() > 0) {
aDocument.DecreaseEventSuppression();
aDocument.ScriptLoader()->RemoveExecuteBlocker();
}
auto* docs = static_cast<nsTArray<nsCOMPtr<Document>>*>(aData);
docs->AppendElement(&aDocument);
aDocument.EnumerateSubDocuments(GetAndUnsuppressSubDocuments, aData);
return CallState::Continue;
aDocuments.AppendElement(&aDocument);
auto recurse = [&aDocuments](Document& aSubDoc) {
GetAndUnsuppressSubDocuments(aSubDoc, aDocuments);
return CallState::Continue;
};
aDocument.EnumerateSubDocuments(recurse);
}
void Document::UnsuppressEventHandlingAndFireEvents(bool aFireEvents) {
nsTArray<nsCOMPtr<Document>> documents;
GetAndUnsuppressSubDocuments(*this, &documents);
GetAndUnsuppressSubDocuments(*this, documents);
if (aFireEvents) {
MOZ_RELEASE_ASSERT(NS_IsMainThread());
@ -11705,13 +11694,11 @@ void Document::FireOrClearPostMessageEvents(bool aFireEvents) {
void Document::SetSuppressedEventListener(EventListener* aListener) {
mSuppressedEventListener = aListener;
EnumerateSubDocuments(
[](Document& aDocument, void* aData) {
aDocument.SetSuppressedEventListener(
static_cast<EventListener*>(aData));
return CallState::Continue;
},
aListener);
auto setOnSubDocs = [&](Document& aDocument) {
aDocument.SetSuppressedEventListener(aListener);
return CallState::Continue;
};
EnumerateSubDocuments(setOnSubDocs);
}
nsISupports* Document::GetCurrentContentSink() {
@ -11970,7 +11957,7 @@ bool Document::UnregisterActivityObserver(nsISupports* aSupports) {
}
void Document::EnumerateActivityObservers(
ActivityObserverEnumerator aEnumerator, void* aData) {
ActivityObserverEnumerator aEnumerator) {
if (!mActivityObservers) {
return;
}
@ -11981,7 +11968,7 @@ void Document::EnumerateActivityObservers(
}
for (auto& observer : observers) {
aEnumerator(observer.get(), aData);
aEnumerator(observer.get());
}
}
@ -12262,20 +12249,16 @@ mozilla::dom::ImageTracker* Document::ImageTracker() {
return mImageTracker;
}
static CallState AllSubDocumentPluginEnum(Document& aDocument, void* userArg) {
nsTArray<nsIObjectLoadingContent*>* plugins =
reinterpret_cast<nsTArray<nsIObjectLoadingContent*>*>(userArg);
MOZ_ASSERT(plugins);
aDocument.GetPlugins(*plugins);
return CallState::Continue;
}
void Document::GetPlugins(nsTArray<nsIObjectLoadingContent*>& aPlugins) {
aPlugins.SetCapacity(aPlugins.Length() + mPlugins.Count());
for (auto iter = mPlugins.ConstIter(); !iter.Done(); iter.Next()) {
aPlugins.AppendElement(iter.Get()->GetKey());
}
EnumerateSubDocuments(AllSubDocumentPluginEnum, &aPlugins);
auto recurse = [&aPlugins] (Document& aSubDoc) {
aSubDoc.GetPlugins(aPlugins);
return CallState::Continue;
};
EnumerateSubDocuments(recurse);
}
void Document::ScheduleSVGUseElementShadowTreeUpdate(
@ -13063,17 +13046,16 @@ void Document::AsyncExitFullscreen(Document* aDoc) {
}
}
static CallState CountFullscreenSubDocuments(Document& aDoc, void* aData) {
if (aDoc.FullscreenStackTop()) {
uint32_t* count = static_cast<uint32_t*>(aData);
(*count)++;
}
return CallState::Continue;
}
static uint32_t CountFullscreenSubDocuments(Document& aDoc) {
uint32_t count = 0;
aDoc.EnumerateSubDocuments(CountFullscreenSubDocuments, &count);
// FIXME(emilio): Should this be recursive and dig into our nested subdocs?
auto subDoc = [&count](Document& aSubDoc) {
if (aSubDoc.FullscreenStackTop()) {
count++;
}
return CallState::Continue;
};
aDoc.EnumerateSubDocuments(subDoc);
return count;
}
@ -13086,49 +13068,40 @@ bool Document::IsFullscreenLeaf() {
return CountFullscreenSubDocuments(*this) == 0;
}
static bool GetFullscreenLeaf(Document& aDoc, void* aData) {
static Document* GetFullscreenLeaf(Document& aDoc) {
if (aDoc.IsFullscreenLeaf()) {
Document** result = static_cast<Document**>(aData);
*result = &aDoc;
return false;
return &aDoc;
}
if (aDoc.FullscreenStackTop()) {
aDoc.EnumerateSubDocuments(
[](Document& aDocument, void* aData) {
return GetFullscreenLeaf(aDocument, aData) ? CallState::Continue
: CallState::Stop;
},
aData);
if (!aDoc.FullscreenStackTop()) {
return nullptr;
}
return true;
Document* leaf = nullptr;
auto recurse = [&leaf](Document& aSubDoc) {
leaf = GetFullscreenLeaf(aSubDoc);
return leaf ? CallState::Stop : CallState::Continue;
};
aDoc.EnumerateSubDocuments(recurse);
return leaf;
}
static Document* GetFullscreenLeaf(Document* aDoc) {
Document* leaf = nullptr;
GetFullscreenLeaf(*aDoc, &leaf);
if (leaf) {
if (Document* leaf = GetFullscreenLeaf(*aDoc)) {
return leaf;
}
// Otherwise we could be either in a non-fullscreen doc tree, or we're
// below the fullscreen doc. Start the search from the root.
Document* root = nsContentUtils::GetRootDocument(aDoc);
// Check that the root is actually fullscreen so we don't waste time walking
// around its descendants.
if (!root->FullscreenStackTop()) {
return nullptr;
}
GetFullscreenLeaf(*root, &leaf);
return leaf;
return GetFullscreenLeaf(*root);
}
static CallState ResetFullscreen(Document& aDocument, void* aData) {
static CallState ResetFullscreen(Document& aDocument) {
if (Element* fsElement = aDocument.FullscreenStackTop()) {
NS_ASSERTION(CountFullscreenSubDocuments(aDocument) <= 1,
"Should have at most 1 fullscreen subdocument.");
aDocument.CleanupFullscreenState();
NS_ASSERTION(!aDocument.FullscreenStackTop(), "Should reset fullscreen");
DispatchFullscreenChange(aDocument, fsElement);
aDocument.EnumerateSubDocuments(ResetFullscreen, nullptr);
aDocument.EnumerateSubDocuments(ResetFullscreen);
}
return CallState::Continue;
}
@ -13198,7 +13171,7 @@ void Document::ExitFullscreenInDocTree(Document* aMaybeNotARootDoc) {
Document* fullscreenLeaf = GetFullscreenLeaf(root);
// Walk the tree of fullscreen documents, and reset their fullscreen state.
ResetFullscreen(*root, nullptr);
ResetFullscreen(*root);
NS_ASSERTION(!root->FullscreenStackTop(),
"Fullscreen root should no longer be a fullscreen doc...");
@ -14123,7 +14096,7 @@ void Document::UpdateVisibilityState() {
nsContentUtils::DispatchTrustedEvent(this, ToSupports(this),
NS_LITERAL_STRING("visibilitychange"),
CanBubble::eYes, Cancelable::eNo);
EnumerateActivityObservers(NotifyActivityChanged, nullptr);
EnumerateActivityObservers(NotifyActivityChanged);
}
if (mVisibilityState == dom::VisibilityState::Visible) {
@ -14595,12 +14568,10 @@ void Document::ReportUseCounters() {
if (Document* doc = GetLatestStaticClone()) {
doc->ReportUseCounters();
}
EnumerateExternalResources(
[](Document& aDoc, void*) -> CallState {
aDoc.ReportUseCounters();
return CallState::Continue;
},
nullptr);
EnumerateExternalResources([](Document& aDoc) {
aDoc.ReportUseCounters();
return CallState::Continue;
});
}
PropagateUseCountersToPage();
@ -14770,15 +14741,12 @@ DOMIntersectionObserver& Document::EnsureLazyLoadImageObserver() {
return *mLazyLoadImageObserver;
}
static CallState NotifyLayerManagerRecreatedCallback(Document& aDocument,
void*) {
aDocument.NotifyLayerManagerRecreated();
return CallState::Continue;
}
void Document::NotifyLayerManagerRecreated() {
EnumerateActivityObservers(NotifyActivityChanged, nullptr);
EnumerateSubDocuments(NotifyLayerManagerRecreatedCallback, nullptr);
EnumerateActivityObservers(NotifyActivityChanged);
EnumerateSubDocuments([] (Document& aSubDoc) {
aSubDoc.NotifyLayerManagerRecreated();
return CallState::Continue;
});
}
XPathEvaluator* Document::XPathEvaluator() {
@ -14863,15 +14831,17 @@ already_AddRefed<Element> Document::CreateHTMLElement(nsAtom* aTag) {
return element.forget();
}
static CallState MarkDocumentTreeToBeInSyncOperation(Document& aDoc,
void* aData) {
auto* documents = static_cast<nsTArray<nsCOMPtr<Document>>*>(aData);
static CallState MarkDocumentTreeToBeInSyncOperation(
Document& aDoc, nsTArray<RefPtr<Document>>& aDocuments) {
aDoc.SetIsInSyncOperation(true);
if (nsCOMPtr<nsPIDOMWindowInner> window = aDoc.GetInnerWindow()) {
window->TimeoutManager().BeginSyncOperation();
}
documents->AppendElement(&aDoc);
aDoc.EnumerateSubDocuments(MarkDocumentTreeToBeInSyncOperation, aData);
aDocuments.AppendElement(&aDoc);
auto recurse = [&aDocuments](Document& aSubDoc) {
return MarkDocumentTreeToBeInSyncOperation(aSubDoc, aDocuments);
};
aDoc.EnumerateSubDocuments(recurse);
return CallState::Continue;
}
@ -14886,7 +14856,7 @@ nsAutoSyncOperation::nsAutoSyncOperation(Document* aDoc) {
if (nsPIDOMWindowOuter* win = aDoc->GetWindow()) {
if (nsCOMPtr<nsPIDOMWindowOuter> top = win->GetInProcessTop()) {
if (RefPtr<Document> doc = top->GetExtantDoc()) {
MarkDocumentTreeToBeInSyncOperation(*doc, &mDocuments);
MarkDocumentTreeToBeInSyncOperation(*doc, mDocuments);
}
}
}

View File

@ -9,7 +9,7 @@
#include "mozilla/EventStates.h" // for EventStates
#include "mozilla/FlushType.h" // for enum
#include "mozilla/MozPromise.h" // for MozPromise
#include "mozilla/Saturate.h" // for SaturateUint32
#include "mozilla/FunctionRef.h" // for FunctionRef
#include "nsAutoPtr.h" // for member
#include "nsCOMArray.h" // for member
#include "nsCompatibility.h" // for member
@ -296,7 +296,7 @@ class DocHeaderData {
};
class ExternalResourceMap {
typedef CallState (*SubDocEnumFunc)(Document& aDocument, void* aData);
using SubDocEnumFunc = FunctionRef<CallState(Document&)>;
public:
/**
@ -339,7 +339,7 @@ class ExternalResourceMap {
* Enumerate the resource documents. See
* Document::EnumerateExternalResources.
*/
void EnumerateResources(SubDocEnumFunc aCallback, void* aData);
void EnumerateResources(SubDocEnumFunc aCallback);
/**
* Traverse ourselves for cycle-collection
@ -2276,8 +2276,8 @@ class Document : public nsINode,
* enumerating, or CallState::Stop to stop. This will never get passed a null
* aDocument.
*/
typedef CallState (*SubDocEnumFunc)(Document&, void* aData);
void EnumerateSubDocuments(SubDocEnumFunc aCallback, void* aData);
using SubDocEnumFunc = FunctionRef<CallState(Document&)>;
void EnumerateSubDocuments(SubDocEnumFunc aCallback);
/**
* Collect all the descendant documents for which |aCalback| returns true.
@ -2590,7 +2590,7 @@ class Document : public nsINode,
* enumerating, or CallState::Stop to stop. This callback will never get
* passed a null aDocument.
*/
void EnumerateExternalResources(SubDocEnumFunc aCallback, void* aData);
void EnumerateExternalResources(SubDocEnumFunc aCallback);
dom::ExternalResourceMap& ExternalResourceMap() {
return mExternalResourceMap;
@ -2658,9 +2658,8 @@ class Document : public nsINode,
void RegisterActivityObserver(nsISupports* aSupports);
bool UnregisterActivityObserver(nsISupports* aSupports);
// Enumerate all the observers in mActivityObservers by the aEnumerator.
typedef void (*ActivityObserverEnumerator)(nsISupports*, void*);
void EnumerateActivityObservers(ActivityObserverEnumerator aEnumerator,
void* aData);
using ActivityObserverEnumerator = FunctionRef<void(nsISupports*)>;
void EnumerateActivityObservers(ActivityObserverEnumerator aEnumerator);
// Indicates whether mAnimationController has been (lazily) initialized.
// If this returns true, we're promising that GetAnimationController()

View File

@ -6665,8 +6665,8 @@ void nsGlobalWindowOuter::ActivateOrDeactivate(bool aActivate) {
}
}
static CallState NotifyDocumentTree(Document& aDocument, void*) {
aDocument.EnumerateSubDocuments(NotifyDocumentTree, nullptr);
static CallState NotifyDocumentTree(Document& aDocument) {
aDocument.EnumerateSubDocuments(NotifyDocumentTree);
aDocument.UpdateDocumentStates(NS_DOCUMENT_STATE_WINDOW_INACTIVE, true);
return CallState::Continue;
}
@ -6674,7 +6674,7 @@ static CallState NotifyDocumentTree(Document& aDocument, void*) {
void nsGlobalWindowOuter::SetActive(bool aActive) {
nsPIDOMWindowOuter::SetActive(aActive);
if (mDoc) {
NotifyDocumentTree(*mDoc, nullptr);
NotifyDocumentTree(*mDoc);
}
}

View File

@ -6408,7 +6408,7 @@ nsIFrame* PresShell::EventHandler::GetNearestFrameContainingPresShell(
return frame;
}
static CallState FlushThrottledStyles(Document& aDocument, void* aData) {
static CallState FlushThrottledStyles(Document& aDocument) {
PresShell* presShell = aDocument.GetPresShell();
if (presShell && presShell->IsVisible()) {
if (nsPresContext* presContext = presShell->GetPresContext()) {
@ -6416,7 +6416,7 @@ static CallState FlushThrottledStyles(Document& aDocument, void* aData) {
}
}
aDocument.EnumerateSubDocuments(FlushThrottledStyles, nullptr);
aDocument.EnumerateSubDocuments(FlushThrottledStyles);
return CallState::Continue;
}
@ -7336,7 +7336,7 @@ nsIFrame* PresShell::EventHandler::MaybeFlushThrottledStyles(
AutoWeakFrame weakFrameForPresShell(aFrameForPresShell);
{ // scope for scriptBlocker.
nsAutoScriptBlocker scriptBlocker;
FlushThrottledStyles(*rootDocument, nullptr);
FlushThrottledStyles(*rootDocument);
}
if (weakFrameForPresShell.IsAlive()) {
@ -8959,14 +8959,13 @@ nsresult PresShell::RemoveOverrideStyleSheet(StyleSheet* aSheet) {
return NS_OK;
}
static void FreezeElement(nsISupports* aSupports, void* /* unused */) {
nsCOMPtr<nsIObjectLoadingContent> olc(do_QueryInterface(aSupports));
if (olc) {
static void FreezeElement(nsISupports* aSupports) {
if (nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(aSupports)) {
olc->StopPluginInstance();
}
}
static CallState FreezeSubDocument(Document& aDocument, void*) {
static CallState FreezeSubDocument(Document& aDocument) {
if (PresShell* presShell = aDocument.GetPresShell()) {
presShell->Freeze();
}
@ -8978,7 +8977,7 @@ void PresShell::Freeze() {
MaybeReleaseCapturingContent();
mDocument->EnumerateActivityObservers(FreezeElement, nullptr);
mDocument->EnumerateActivityObservers(FreezeElement);
if (mCaret) {
SetCaretEnabled(false);
@ -8987,7 +8986,7 @@ void PresShell::Freeze() {
mPaintingSuppressed = true;
if (mDocument) {
mDocument->EnumerateSubDocuments(FreezeSubDocument, nullptr);
mDocument->EnumerateSubDocuments(FreezeSubDocument);
}
nsPresContext* presContext = GetPresContext();
@ -9029,20 +9028,6 @@ void PresShell::FireOrClearDelayedEvents(bool aFireEvents) {
}
}
static void ThawElement(nsISupports* aSupports, void* aShell) {
nsCOMPtr<nsIObjectLoadingContent> olc(do_QueryInterface(aSupports));
if (olc) {
olc->AsyncStartPluginInstance();
}
}
static CallState ThawSubDocument(Document& aDocument, void* aData) {
if (PresShell* presShell = aDocument.GetPresShell()) {
presShell->Thaw();
}
return CallState::Continue;
}
void PresShell::Thaw() {
nsPresContext* presContext = GetPresContext();
if (presContext &&
@ -9050,10 +9035,19 @@ void PresShell::Thaw() {
presContext->RefreshDriver()->Thaw();
}
mDocument->EnumerateActivityObservers(ThawElement, this);
mDocument->EnumerateActivityObservers([](nsISupports* aSupports) {
if (nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(aSupports)) {
olc->AsyncStartPluginInstance();
}
});
if (mDocument) {
mDocument->EnumerateSubDocuments(ThawSubDocument, nullptr);
mDocument->EnumerateSubDocuments([](Document& aSubDoc) {
if (PresShell* presShell = aSubDoc.GetPresShell()) {
presShell->Thaw();
}
return CallState::Continue;
});
}
// Get the activeness of our presshell, as this might have changed
@ -10528,25 +10522,14 @@ void PresShell::QueryIsActive() {
}
}
// Helper for propagating mIsActive changes to external resources
static CallState SetExternalResourceIsActive(Document& aDocument,
void* aClosure) {
if (PresShell* presShell = aDocument.GetPresShell()) {
presShell->SetIsActive(*static_cast<bool*>(aClosure));
}
return CallState::Continue;
}
static void SetPluginIsActive(nsISupports* aSupports, void* aClosure) {
static void SetPluginIsActive(nsISupports* aSupports, bool aIsActive) {
nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
if (!content) {
return;
}
nsIFrame* frame = content->GetPrimaryFrame();
nsIObjectFrame* objectFrame = do_QueryFrame(frame);
if (objectFrame) {
objectFrame->SetIsDocumentActive(*static_cast<bool*>(aClosure));
if (nsIObjectFrame* objectFrame = do_QueryFrame(content->GetPrimaryFrame())) {
objectFrame->SetIsDocumentActive(aIsActive);
}
}
@ -10565,10 +10548,22 @@ nsresult PresShell::SetIsActive(bool aIsActive) {
presContext->RefreshDriver()->SetThrottled(!mIsActive);
}
// Propagate state-change to my resource documents' PresShells
mDocument->EnumerateExternalResources(SetExternalResourceIsActive,
&aIsActive);
mDocument->EnumerateActivityObservers(SetPluginIsActive, &aIsActive);
{
// Propagate state-change to my resource documents' PresShells
auto recurse = [aIsActive](Document& aResourceDoc) {
if (PresShell* presShell = aResourceDoc.GetPresShell()) {
presShell->SetIsActive(aIsActive);
}
return CallState::Continue;
};
mDocument->EnumerateExternalResources(recurse);
}
{
auto visitPlugin = [aIsActive](nsISupports* aSupports) {
SetPluginIsActive(aSupports, aIsActive);
};
mDocument->EnumerateActivityObservers(visitPlugin);
}
nsresult rv = UpdateImageLockingState();
#ifdef ACCESSIBILITY
if (aIsActive) {
@ -11304,18 +11299,16 @@ PresShell::EventHandler::HandlingTimeAccumulator::~HandlingTimeAccumulator() {
}
}
static CallState EndPaintHelper(Document& aDocument, void* aData) {
if (PresShell* presShell = aDocument.GetPresShell()) {
presShell->EndPaint();
}
return CallState::Continue;
}
void PresShell::EndPaint() {
ClearPendingVisualScrollUpdate();
if (mDocument) {
mDocument->EnumerateSubDocuments(EndPaintHelper, nullptr);
mDocument->EnumerateSubDocuments([](Document& aSubDoc) {
if (PresShell* presShell = aSubDoc.GetPresShell()) {
presShell->EndPaint();
}
return CallState::Continue;
});
}
}

View File

@ -306,10 +306,10 @@ class nsDocumentViewer final : public nsIContentViewer,
NS_DECL_NSIWEBBROWSERPRINT
#endif
typedef void (*CallChildFunc)(nsDocumentViewer* aViewer, void* aClosure);
void CallChildren(CallChildFunc aFunc, void* aClosure);
using CallChildFunc = FunctionRef<void(nsDocumentViewer*)>;
void CallChildren(CallChildFunc aFunc);
typedef void (*PresContextFunc)(nsPresContext*, void* aClosure);
using PresContextFunc = FunctionRef<void(nsPresContext*)>;
/**
* Calls a `CallChildFunc` on all children, a `PresContextFunc`
* on all external documents' pres contexts of our document, and then
@ -321,8 +321,7 @@ class nsDocumentViewer final : public nsIContentViewer,
*
* FIXME(emilio): Better name for this appreciated.
*/
void PropagateToPresContextsHelper(CallChildFunc, PresContextFunc,
void* aClosure);
void PropagateToPresContextsHelper(CallChildFunc, PresContextFunc);
// nsIDocumentViewerPrint Printing Methods
NS_DECL_NSIDOCUMENTVIEWERPRINT
@ -509,10 +508,20 @@ class AutoPrintEventDispatcher {
}
private:
static CallState CollectDocuments(Document& aDoc,
nsTArray<nsCOMPtr<Document>>& aDocs) {
aDocs.AppendElement(&aDoc);
auto recurse = [&aDocs](Document& aSubDoc) {
return CollectDocuments(aSubDoc, aDocs);
};
aDoc.EnumerateSubDocuments(recurse);
return CallState::Continue;
}
void DispatchEventToWindowTree(const nsAString& aEvent) {
nsTArray<nsCOMPtr<Document>> targets;
if (mTop) {
CollectDocuments(*mTop, &targets);
CollectDocuments(*mTop, targets);
}
for (nsCOMPtr<Document>& doc : targets) {
nsContentUtils::DispatchTrustedEvent(doc, doc->GetWindow(), aEvent,
@ -521,13 +530,6 @@ class AutoPrintEventDispatcher {
}
}
static CallState CollectDocuments(Document& aDocument, void* aData) {
static_cast<nsTArray<nsCOMPtr<Document>>*>(aData)->AppendElement(
&aDocument);
aDocument.EnumerateSubDocuments(CollectDocuments, aData);
return CallState::Continue;
}
nsCOMPtr<Document> mTop;
};
@ -2666,51 +2668,41 @@ NS_IMETHODIMP nsDocumentViewer::SetCommandNode(nsINode* aNode) {
}
void nsDocumentViewer::PropagateToPresContextsHelper(CallChildFunc aChildFunc,
PresContextFunc aPcFunc,
void* aClosure) {
CallChildren(aChildFunc, aClosure);
PresContextFunc aPcFunc) {
CallChildren(aChildFunc);
{
struct ResourceDocClosure {
PresContextFunc mFunc;
void* mParentClosure;
} resourceDocClosure{aPcFunc, aClosure};
if (mDocument) {
mDocument->EnumerateExternalResources(
[](Document& aDoc, void* aClosure) -> CallState {
auto* closure = static_cast<ResourceDocClosure*>(aClosure);
if (nsPresContext* pc = aDoc.GetPresContext()) {
closure->mFunc(pc, closure->mParentClosure);
}
return CallState::Continue;
},
&resourceDocClosure);
}
if (mDocument) {
auto resourceDoc = [aPcFunc](Document& aResourceDoc) {
if (nsPresContext* pc = aResourceDoc.GetPresContext()) {
aPcFunc(pc);
}
return CallState::Continue;
};
mDocument->EnumerateExternalResources(resourceDoc);
}
if (mPresContext) {
aPcFunc(mPresContext, aClosure);
aPcFunc(mPresContext);
}
}
void nsDocumentViewer::CallChildren(CallChildFunc aFunc, void* aClosure) {
void nsDocumentViewer::CallChildren(CallChildFunc aFunc) {
nsCOMPtr<nsIDocShell> docShell(mContainer);
if (docShell) {
int32_t i;
int32_t n;
docShell->GetInProcessChildCount(&n);
for (i = 0; i < n; i++) {
nsCOMPtr<nsIDocShellTreeItem> child;
docShell->GetInProcessChildAt(i, getter_AddRefs(child));
nsCOMPtr<nsIDocShell> childAsShell(do_QueryInterface(child));
NS_ASSERTION(childAsShell, "null child in docshell");
if (childAsShell) {
nsCOMPtr<nsIContentViewer> childCV;
childAsShell->GetContentViewer(getter_AddRefs(childCV));
if (childCV) {
(*aFunc)(static_cast<nsDocumentViewer*>(childCV.get()), aClosure);
}
if (!docShell) {
return;
}
int32_t n = 0;
docShell->GetInProcessChildCount(&n);
for (int32_t i = 0; i < n; i++) {
nsCOMPtr<nsIDocShellTreeItem> child;
docShell->GetInProcessChildAt(i, getter_AddRefs(child));
nsCOMPtr<nsIDocShell> childAsShell(do_QueryInterface(child));
NS_ASSERTION(childAsShell, "null child in docshell");
if (childAsShell) {
nsCOMPtr<nsIContentViewer> childCV;
childAsShell->GetContentViewer(getter_AddRefs(childCV));
if (childCV) {
aFunc(static_cast<nsDocumentViewer*>(childCV.get()));
}
}
}
@ -2730,14 +2722,13 @@ nsDocumentViewer::SetTextZoom(float aTextZoom) {
bool textZoomChange = (mTextZoom != aTextZoom);
mTextZoom = aTextZoom;
PropagateToPresContextsHelper(
[](nsDocumentViewer* aChild, void* aClosure) {
aChild->SetTextZoom(*static_cast<float*>(aClosure));
},
[](nsPresContext* aPc, void* aClosure) {
aPc->SetTextZoom(*static_cast<float*>(aClosure));
},
&aTextZoom);
auto childFn = [aTextZoom](nsDocumentViewer* aChild) {
aChild->SetTextZoom(aTextZoom);
};
auto presContextFn = [aTextZoom](nsPresContext* aPc) {
aPc->SetTextZoom(aTextZoom);
};
PropagateToPresContextsHelper(childFn, presContextFn);
// Dispatch TextZoomChange event only if text zoom value has changed.
if (textZoomChange) {
@ -2811,14 +2802,13 @@ nsDocumentViewer::SetFullZoom(float aFullZoom) {
mPageZoom = aFullZoom;
PropagateToPresContextsHelper(
[](nsDocumentViewer* aChild, void* aClosure) {
aChild->SetFullZoom(*static_cast<float*>(aClosure));
},
[](nsPresContext* aPc, void* aClosure) {
aPc->SetFullZoom(*static_cast<float*>(aClosure));
},
&aFullZoom);
auto childFn = [aFullZoom](nsDocumentViewer* aChild) {
aChild->SetFullZoom(aFullZoom);
};
auto presContextFn = [aFullZoom](nsPresContext* aPc) {
aPc->SetFullZoom(aFullZoom);
};
PropagateToPresContextsHelper(childFn, presContextFn);
// Dispatch FullZoomChange event only if fullzoom value really has changed.
if (fullZoomChange) {
@ -2873,15 +2863,13 @@ nsDocumentViewer::SetOverrideDPPX(float aDPPX) {
mOverrideDPPX = aDPPX;
PropagateToPresContextsHelper(
[](nsDocumentViewer* aChild, void* aClosure) {
aChild->SetOverrideDPPX(*static_cast<float*>(aClosure));
},
[](nsPresContext* aPc, void* aClosure) {
aPc->SetOverrideDPPX(*static_cast<float*>(aClosure));
},
&aDPPX);
auto childFn = [aDPPX](nsDocumentViewer* aChild) {
aChild->SetOverrideDPPX(aDPPX);
};
auto presContextFn = [aDPPX](nsPresContext* aPc) {
aPc->SetOverrideDPPX(aDPPX);
};
PropagateToPresContextsHelper(childFn, presContextFn);
return NS_OK;
}
@ -2900,11 +2888,11 @@ nsDocumentViewer::SetAuthorStyleDisabled(bool aStyleDisabled) {
mPresShell->SetAuthorStyleDisabled(aStyleDisabled);
}
CallChildren(
[](nsDocumentViewer* aChild, void* aClosure) {
aChild->SetAuthorStyleDisabled(*static_cast<bool*>(aClosure));
},
&aStyleDisabled);
auto children = [aStyleDisabled](nsDocumentViewer* aChild) {
aChild->SetAuthorStyleDisabled(aStyleDisabled);
};
CallChildren(children);
return NS_OK;
}
@ -2919,14 +2907,13 @@ nsDocumentViewer::GetAuthorStyleDisabled(bool* aStyleDisabled) {
}
void nsDocumentViewer::EmulateMediumInternal(nsAtom* aMedia) {
PropagateToPresContextsHelper(
[](nsDocumentViewer* aChild, void* aClosure) {
aChild->EmulateMediumInternal(static_cast<nsAtom*>(aClosure));
},
[](nsPresContext* aPc, void* aClosure) {
aPc->EmulateMedium(static_cast<nsAtom*>(aClosure));
},
aMedia);
auto childFn = [&](nsDocumentViewer* aChild) {
aChild->EmulateMediumInternal(aMedia);
};
auto presContextFn = [&](nsPresContext* aPc) {
aPc->EmulateMedium(aMedia);
};
PropagateToPresContextsHelper(childFn, presContextFn);
}
NS_IMETHODIMP
@ -2969,16 +2956,13 @@ nsDocumentViewer::EmulatePrefersColorScheme(PrefersColorScheme aScheme) {
void nsDocumentViewer::EmulatePrefersColorSchemeInternal(
const ColorSchemeOverride& aOverride) {
PropagateToPresContextsHelper(
[](nsDocumentViewer* aChild, void* aClosure) {
aChild->EmulatePrefersColorSchemeInternal(
*static_cast<const ColorSchemeOverride*>(aClosure));
},
[](nsPresContext* aPc, void* aClosure) {
aPc->SetOverridePrefersColorScheme(
*static_cast<const ColorSchemeOverride*>(aClosure));
},
const_cast<ColorSchemeOverride*>(&aOverride));
auto childFn = [&aOverride](nsDocumentViewer* aChild) {
aChild->EmulatePrefersColorSchemeInternal(aOverride);
};
auto presContextFn = [&aOverride](nsPresContext* aPc) {
aPc->SetOverridePrefersColorScheme(aOverride);
};
PropagateToPresContextsHelper(childFn, presContextFn);
}
NS_IMETHODIMP nsDocumentViewer::GetForceCharacterSet(
@ -2996,12 +2980,6 @@ NS_IMETHODIMP nsDocumentViewer::GetForceCharacterSet(
NS_IMETHODIMP_(const Encoding*)
nsDocumentViewer::GetForceCharset() { return mForceCharacterSet; }
static void SetChildForceCharacterSet(nsDocumentViewer* aChild,
void* aClosure) {
auto encoding = static_cast<const Encoding*>(aClosure);
aChild->SetForceCharset(encoding);
}
NS_IMETHODIMP
nsDocumentViewer::SetForceCharacterSet(const nsACString& aForceCharacterSet) {
// The empty string means no hint.
@ -3020,8 +2998,11 @@ nsDocumentViewer::SetForceCharacterSet(const nsACString& aForceCharacterSet) {
NS_IMETHODIMP_(void)
nsDocumentViewer::SetForceCharset(const Encoding* aEncoding) {
mForceCharacterSet = aEncoding;
auto childFn = [aEncoding](nsDocumentViewer* aChild) {
aChild->SetForceCharset(aEncoding);
};
// now set the force char set on all children of mContainer
CallChildren(SetChildForceCharacterSet, (void*)aEncoding);
CallChildren(childFn);
}
NS_IMETHODIMP nsDocumentViewer::GetHintCharacterSet(
@ -3050,30 +3031,21 @@ nsDocumentViewer::GetHintCharset() {
NS_IMETHODIMP nsDocumentViewer::GetHintCharacterSetSource(
int32_t* aHintCharacterSetSource) {
NS_ENSURE_ARG_POINTER(aHintCharacterSetSource);
*aHintCharacterSetSource = mHintCharsetSource;
return NS_OK;
}
static void SetChildHintCharacterSetSource(nsDocumentViewer* aChild,
void* aClosure) {
aChild->SetHintCharacterSetSource(NS_PTR_TO_INT32(aClosure));
}
NS_IMETHODIMP
nsDocumentViewer::SetHintCharacterSetSource(int32_t aHintCharacterSetSource) {
mHintCharsetSource = aHintCharacterSetSource;
// now set the hint char set source on all children of mContainer
CallChildren(SetChildHintCharacterSetSource,
NS_INT32_TO_PTR(aHintCharacterSetSource));
auto childFn = [aHintCharacterSetSource](nsDocumentViewer* aChild) {
aChild->SetHintCharacterSetSource(aHintCharacterSetSource);
};
// now set the force char set on all children of mContainer
CallChildren(childFn);
return NS_OK;
}
static void SetChildHintCharacterSet(nsDocumentViewer* aChild, void* aClosure) {
auto encoding = static_cast<const Encoding*>(aClosure);
aChild->SetHintCharset(encoding);
}
NS_IMETHODIMP
nsDocumentViewer::SetHintCharacterSet(const nsACString& aHintCharacterSet) {
// The empty string means no hint.
@ -3092,27 +3064,26 @@ nsDocumentViewer::SetHintCharacterSet(const nsACString& aHintCharacterSet) {
NS_IMETHODIMP_(void)
nsDocumentViewer::SetHintCharset(const Encoding* aEncoding) {
mHintCharset = aEncoding;
// now set the hint char set on all children of mContainer
CallChildren(SetChildHintCharacterSet, (void*)aEncoding);
}
static void AppendChildSubtree(nsDocumentViewer* aChild, void* aClosure) {
nsTArray<nsCOMPtr<nsIContentViewer>>& array =
*static_cast<nsTArray<nsCOMPtr<nsIContentViewer>>*>(aClosure);
aChild->AppendSubtree(array);
auto childFn = [aEncoding](nsDocumentViewer* aChild) {
aChild->SetHintCharset(aEncoding);
};
// now set the force char set on all children of mContainer
CallChildren(childFn);
}
NS_IMETHODIMP nsDocumentViewer::AppendSubtree(
nsTArray<nsCOMPtr<nsIContentViewer>>& aArray) {
aArray.AppendElement(this);
CallChildren(AppendChildSubtree, &aArray);
auto childFn = [&aArray](nsDocumentViewer* aChild) {
aChild->AppendSubtree(aArray);
};
CallChildren(childFn);
return NS_OK;
}
NS_IMETHODIMP
nsDocumentViewer::PausePainting() {
CallChildren([](nsDocumentViewer* aChild, void*) { aChild->PausePainting(); },
nullptr);
CallChildren([](nsDocumentViewer* aChild) { aChild->PausePainting(); });
if (PresShell* presShell = GetPresShell()) {
presShell->PausePainting();
@ -3123,9 +3094,7 @@ nsDocumentViewer::PausePainting() {
NS_IMETHODIMP
nsDocumentViewer::ResumePainting() {
CallChildren(
[](nsDocumentViewer* aChild, void*) { aChild->ResumePainting(); },
nullptr);
CallChildren([](nsDocumentViewer* aChild) { aChild->ResumePainting(); });
if (PresShell* presShell = GetPresShell()) {
presShell->ResumePainting();

View File

@ -1395,20 +1395,6 @@ void nsPresContext::UIResolutionChangedSync() {
}
}
/* static */
CallState nsPresContext::UIResolutionChangedSubdocumentCallback(
dom::Document& aDocument, void* aData) {
if (nsPresContext* pc = aDocument.GetPresContext()) {
// For subdocuments, we want to apply the parent's scale, because there
// are cases where the subdoc's device context is connected to a widget
// that has an out-of-date resolution (it's on a different screen, but
// currently hidden, and will not be updated until shown): bug 1249279.
double scale = *static_cast<double*>(aData);
pc->UIResolutionChangedInternalScale(scale);
}
return CallState::Continue;
}
static void NotifyTabUIResolutionChanged(nsIRemoteTab* aTab, void* aArg) {
aTab->NotifyResolutionChanged();
}
@ -1439,8 +1425,17 @@ void nsPresContext::UIResolutionChangedInternalScale(double aScale) {
NotifyChildrenUIResolutionChanged(window);
}
mDocument->EnumerateSubDocuments(UIResolutionChangedSubdocumentCallback,
&aScale);
auto recurse = [aScale](dom::Document& aSubDoc) {
if (nsPresContext* pc = aSubDoc.GetPresContext()) {
// For subdocuments, we want to apply the parent's scale, because there
// are cases where the subdoc's device context is connected to a widget
// that has an out-of-date resolution (it's on a different screen, but
// currently hidden, and will not be updated until shown): bug 1249279.
pc->UIResolutionChangedInternalScale(aScale);
}
return CallState::Continue;
};
mDocument->EnumerateSubDocuments(recurse);
}
void nsPresContext::EmulateMedium(nsAtom* aMediaType) {
@ -1503,15 +1498,6 @@ void nsPresContext::PostRebuildAllStyleDataEvent(
RestyleManager()->RebuildAllStyleData(aExtraHint, aRestyleHint);
}
static CallState MediaFeatureValuesChangedAllDocumentsCallback(
Document& aDocument, void* aChange) {
auto* change = static_cast<const MediaFeatureChange*>(aChange);
if (nsPresContext* pc = aDocument.GetPresContext()) {
pc->MediaFeatureValuesChangedAllDocuments(*change);
}
return CallState::Continue;
}
void nsPresContext::MediaFeatureValuesChangedAllDocuments(
const MediaFeatureChange& aChange) {
// Handle the media feature value change in this document.
@ -1522,9 +1508,13 @@ void nsPresContext::MediaFeatureValuesChangedAllDocuments(
mDocument->ImageTracker()->MediaFeatureValuesChangedAllDocuments(aChange);
// And then into any subdocuments.
mDocument->EnumerateSubDocuments(
MediaFeatureValuesChangedAllDocumentsCallback,
const_cast<MediaFeatureChange*>(&aChange));
auto recurse = [&aChange](dom::Document& aSubDoc) {
if (nsPresContext* pc = aSubDoc.GetPresContext()) {
pc->MediaFeatureValuesChangedAllDocuments(aChange);
}
return CallState::Continue;
};
mDocument->EnumerateSubDocuments(recurse);
}
void nsPresContext::FlushPendingMediaFeatureValuesChanged() {
@ -1811,19 +1801,6 @@ void nsPresContext::FireDOMPaintEvent(
static_cast<Event*>(event), this, nullptr);
}
static CallState MayHavePaintEventListenerSubdocumentCallback(
Document& aDocument, void* aData) {
bool* result = static_cast<bool*>(aData);
if (nsPresContext* pc = aDocument.GetPresContext()) {
*result = pc->MayHavePaintEventListenerInSubDocument();
// If we found a paint event listener, then we can stop enumerating
// sub documents.
return !*result ? CallState::Continue : CallState::Stop;
}
return CallState::Continue;
}
static bool MayHavePaintEventListener(nsPIDOMWindowInner* aInnerWindow) {
if (!aInnerWindow) return false;
if (aInnerWindow->HasPaintEventListeners()) return true;
@ -1872,8 +1849,17 @@ bool nsPresContext::MayHavePaintEventListenerInSubDocument() {
}
bool result = false;
mDocument->EnumerateSubDocuments(MayHavePaintEventListenerSubdocumentCallback,
&result);
auto recurse = [&result](dom::Document& aSubDoc) {
if (nsPresContext* pc = aSubDoc.GetPresContext()) {
if (pc->MayHavePaintEventListenerInSubDocument()) {
result = true;
return CallState::Stop;
}
}
return CallState::Continue;
};
mDocument->EnumerateSubDocuments(recurse);
return result;
}
@ -1977,30 +1963,6 @@ void nsPresContext::ClearNotifySubDocInvalidationData(
aContainer->SetUserData(&gNotifySubDocInvalidationData, nullptr);
}
struct NotifyDidPaintSubdocumentCallbackClosure {
TransactionId mTransactionId;
const mozilla::TimeStamp& mTimeStamp;
};
/* static */
CallState nsPresContext::NotifyDidPaintSubdocumentCallback(
dom::Document& aDocument, void* aData) {
auto* closure = static_cast<NotifyDidPaintSubdocumentCallbackClosure*>(aData);
if (nsPresContext* pc = aDocument.GetPresContext()) {
pc->NotifyDidPaintForSubtree(closure->mTransactionId, closure->mTimeStamp);
}
return CallState::Continue;
}
/* static */
CallState nsPresContext::NotifyRevokingDidPaintSubdocumentCallback(
dom::Document& aDocument, void* aData) {
auto* closure = static_cast<NotifyDidPaintSubdocumentCallbackClosure*>(aData);
if (nsPresContext* pc = aDocument.GetPresContext()) {
pc->NotifyRevokingDidPaint(closure->mTransactionId);
}
return CallState::Continue;
}
class DelayedFireDOMPaintEvent : public Runnable {
public:
DelayedFireDOMPaintEvent(
@ -2064,10 +2026,13 @@ void nsPresContext::NotifyRevokingDidPaint(TransactionId aTransactionId) {
transaction->mIsWaitingForPreviousTransaction = true;
}
NotifyDidPaintSubdocumentCallbackClosure closure = {aTransactionId,
mozilla::TimeStamp()};
mDocument->EnumerateSubDocuments(
nsPresContext::NotifyRevokingDidPaintSubdocumentCallback, &closure);
auto recurse = [&aTransactionId](dom::Document& aSubDoc) {
if (nsPresContext* pc = aSubDoc.GetPresContext()) {
pc->NotifyRevokingDidPaint(aTransactionId);
}
return CallState::Continue;
};
mDocument->EnumerateSubDocuments(recurse);
}
void nsPresContext::NotifyDidPaintForSubtree(
@ -2131,10 +2096,13 @@ void nsPresContext::NotifyDidPaintForSubtree(
nsContentUtils::AddScriptRunner(ev);
}
NotifyDidPaintSubdocumentCallbackClosure closure = {aTransactionId,
aTimeStamp};
mDocument->EnumerateSubDocuments(
nsPresContext::NotifyDidPaintSubdocumentCallback, &closure);
auto recurse = [&aTransactionId, &aTimeStamp](dom::Document& aSubDoc) {
if (nsPresContext* pc = aSubDoc.GetPresContext()) {
pc->NotifyDidPaintForSubtree(aTransactionId, aTimeStamp);
}
return CallState::Continue;
};
mDocument->EnumerateSubDocuments(recurse);
}
already_AddRefed<nsITimer> nsPresContext::CreateTimer(

View File

@ -1070,12 +1070,6 @@ class nsPresContext : public nsISupports,
// (otherwise get it from the widget)
void UIResolutionChangedInternalScale(double aScale);
// aData here is a pointer to a double that holds the CSS to device-pixel
// scale factor from the parent, which will be applied to the subdocument's
// device context instead of retrieving a scale from the widget.
static mozilla::CallState UIResolutionChangedSubdocumentCallback(
mozilla::dom::Document&, void* aData);
void SetImgAnimations(nsIContent* aParent, uint16_t aMode);
void SetSMILAnimations(mozilla::dom::Document* aDoc, uint16_t aNewMode,
uint16_t aOldMode);
@ -1090,11 +1084,6 @@ class nsPresContext : public nsISupports,
void UpdateCharSet(NotNull<const Encoding*> aCharSet);
static mozilla::CallState NotifyDidPaintSubdocumentCallback(
mozilla::dom::Document&, void* aData);
static mozilla::CallState NotifyRevokingDidPaintSubdocumentCallback(
mozilla::dom::Document&, void* aData);
public:
// Used by the PresShell to force a reflow when some aspect of font info
// has been updated, potentially affecting font selection and layout.

View File

@ -1820,12 +1820,13 @@ void nsRefreshDriver::CancelIdleRunnable(nsIRunnable* aRunnable) {
}
}
static CallState ReduceAnimations(Document& aDocument, void* aData) {
if (aDocument.GetPresContext() &&
aDocument.GetPresContext()->EffectCompositor()->NeedsReducing()) {
aDocument.GetPresContext()->EffectCompositor()->ReduceAnimations();
static CallState ReduceAnimations(Document& aDocument) {
if (nsPresContext* pc = aDocument.GetPresContext()) {
if (pc->EffectCompositor()->NeedsReducing()) {
pc->EffectCompositor()->ReduceAnimations();
}
}
aDocument.EnumerateSubDocuments(ReduceAnimations, nullptr);
aDocument.EnumerateSubDocuments(ReduceAnimations);
return CallState::Continue;
}
@ -2005,7 +2006,7 @@ void nsRefreshDriver::Tick(VsyncId aId, TimeStamp aNowTime) {
// https://drafts.csswg.org/web-animations-1/#update-animations-and-send-events
if (i == 1) {
nsAutoMicroTask mt;
ReduceAnimations(*mPresContext->Document(), nullptr);
ReduceAnimations(*mPresContext->Document());
}
// Check if running the microtask checkpoint caused the pres context to

View File

@ -1631,7 +1631,7 @@ nsIObjectFrame* nsPluginFrame::GetNextObjectFrame(nsPresContext* aPresContext,
}
/*static*/
void nsPluginFrame::BeginSwapDocShells(nsISupports* aSupports, void*) {
void nsPluginFrame::BeginSwapDocShells(nsISupports* aSupports) {
MOZ_ASSERT(aSupports, "null parameter");
nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
if (!content) {
@ -1650,7 +1650,7 @@ void nsPluginFrame::BeginSwapDocShells(nsISupports* aSupports, void*) {
}
/*static*/
void nsPluginFrame::EndSwapDocShells(nsISupports* aSupports, void*) {
void nsPluginFrame::EndSwapDocShells(nsISupports* aSupports) {
MOZ_ASSERT(aSupports, "null parameter");
nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
if (!content) {

View File

@ -183,12 +183,12 @@ class nsPluginFrame final : public nsFrame,
* There will be a call to EndSwapDocShells after we were moved to the
* new view tree.
*/
static void BeginSwapDocShells(nsISupports* aSupports, void*);
static void BeginSwapDocShells(nsISupports* aSupports);
/**
* If aSupports has a nsPluginFrame, then set it up after a DocShell swap.
* @see nsSubDocumentFrame::EndSwapDocShells.
*/
static void EndSwapDocShells(nsISupports* aSupports, void*);
static void EndSwapDocShells(nsISupports* aSupports);
nsIWidget* GetWidget() override {
if (!mInnerView) {

View File

@ -1002,7 +1002,7 @@ static void DestroyDisplayItemDataForFrames(nsIFrame* aFrame) {
}
}
static CallState BeginSwapDocShellsForDocument(Document& aDocument, void*) {
static CallState BeginSwapDocShellsForDocument(Document& aDocument) {
if (PresShell* presShell = aDocument.GetPresShell()) {
// Disable painting while the views are detached, see bug 946929.
presShell->SetNeverPainting(true);
@ -1011,9 +1011,8 @@ static CallState BeginSwapDocShellsForDocument(Document& aDocument, void*) {
::DestroyDisplayItemDataForFrames(rootFrame);
}
}
aDocument.EnumerateActivityObservers(nsPluginFrame::BeginSwapDocShells,
nullptr);
aDocument.EnumerateSubDocuments(BeginSwapDocShellsForDocument, nullptr);
aDocument.EnumerateActivityObservers(nsPluginFrame::BeginSwapDocShells);
aDocument.EnumerateSubDocuments(BeginSwapDocShellsForDocument);
return CallState::Continue;
}
@ -1022,7 +1021,7 @@ static nsView* BeginSwapDocShellsForViews(nsView* aSibling) {
nsView* removedViews = nullptr;
while (aSibling) {
if (Document* doc = ::GetDocumentFromView(aSibling)) {
::BeginSwapDocShellsForDocument(*doc, nullptr);
::BeginSwapDocShellsForDocument(*doc);
}
nsView* next = aSibling->GetNextSibling();
aSibling->GetViewManager()->RemoveChild(aSibling);
@ -1075,7 +1074,7 @@ nsresult nsSubDocumentFrame::BeginSwapDocShells(nsIFrame* aOther) {
return NS_OK;
}
static CallState EndSwapDocShellsForDocument(Document& aDocument, void*) {
static CallState EndSwapDocShellsForDocument(Document& aDocument) {
// Our docshell and view trees have been updated for the new hierarchy.
// Now also update all nsDeviceContext::mWidget to that of the
// container view in the new hierarchy.
@ -1096,16 +1095,15 @@ static CallState EndSwapDocShellsForDocument(Document& aDocument, void*) {
}
}
aDocument.EnumerateActivityObservers(nsPluginFrame::EndSwapDocShells,
nullptr);
aDocument.EnumerateSubDocuments(EndSwapDocShellsForDocument, nullptr);
aDocument.EnumerateActivityObservers(nsPluginFrame::EndSwapDocShells);
aDocument.EnumerateSubDocuments(EndSwapDocShellsForDocument);
return CallState::Continue;
}
static void EndSwapDocShellsForViews(nsView* aSibling) {
for (; aSibling; aSibling = aSibling->GetNextSibling()) {
if (Document* doc = ::GetDocumentFromView(aSibling)) {
::EndSwapDocShellsForDocument(*doc, nullptr);
::EndSwapDocShellsForDocument(*doc);
}
nsIFrame* frame = aSibling->GetFrame();
if (frame) {

View File

@ -844,43 +844,6 @@ bool RetainedDisplayListBuilder::MergeDisplayLists(
return merge.mResultIsModified;
}
static void TakeAndAddModifiedAndFramesWithPropsFromRootFrame(
nsDisplayListBuilder* aBuilder, nsTArray<nsIFrame*>* aModifiedFrames,
nsTArray<nsIFrame*>* aFramesWithProps, nsIFrame* aRootFrame) {
MOZ_ASSERT(aRootFrame);
RetainedDisplayListData* data = GetRetainedDisplayListData(aRootFrame);
if (!data) {
return;
}
for (auto it = data->Iterator(); !it.Done(); it.Next()) {
nsIFrame* frame = it.Key();
const RetainedDisplayListData::FrameFlags& flags = it.Data();
if (flags & RetainedDisplayListData::FrameFlags::Modified) {
aModifiedFrames->AppendElement(frame);
}
if (flags & RetainedDisplayListData::FrameFlags::HasProps) {
aFramesWithProps->AppendElement(frame);
}
if (flags & RetainedDisplayListData::FrameFlags::HadWillChange) {
aBuilder->RemoveFromWillChangeBudgets(frame);
}
}
data->Clear();
}
struct CbData {
nsDisplayListBuilder* builder;
nsTArray<nsIFrame*>* modifiedFrames;
nsTArray<nsIFrame*>* framesWithProps;
};
static nsIFrame* GetRootFrameForPainting(nsDisplayListBuilder* aBuilder,
Document& aDocument) {
// Although this is the actual subdocument, it might not be
@ -922,20 +885,41 @@ static nsIFrame* GetRootFrameForPainting(nsDisplayListBuilder* aBuilder,
return presShell ? presShell->GetRootFrame() : nullptr;
}
static CallState SubDocEnumCb(Document& aDocument, void* aData) {
MOZ_ASSERT(aData);
static void TakeAndAddModifiedAndFramesWithPropsFromRootFrame(
nsDisplayListBuilder* aBuilder, nsTArray<nsIFrame*>* aModifiedFrames,
nsTArray<nsIFrame*>* aFramesWithProps, nsIFrame* aRootFrame,
Document& aDoc) {
MOZ_ASSERT(aRootFrame);
auto* data = static_cast<CbData*>(aData);
if (RetainedDisplayListData* data = GetRetainedDisplayListData(aRootFrame)) {
for (auto it = data->Iterator(); !it.Done(); it.Next()) {
nsIFrame* frame = it.Key();
const RetainedDisplayListData::FrameFlags& flags = it.Data();
if (nsIFrame* rootFrame = GetRootFrameForPainting(data->builder, aDocument)) {
TakeAndAddModifiedAndFramesWithPropsFromRootFrame(
data->builder, data->modifiedFrames, data->framesWithProps, rootFrame);
if (flags & RetainedDisplayListData::FrameFlags::Modified) {
aModifiedFrames->AppendElement(frame);
}
if (Document* innerDoc = rootFrame->PresShell()->GetDocument()) {
innerDoc->EnumerateSubDocuments(SubDocEnumCb, aData);
if (flags & RetainedDisplayListData::FrameFlags::HasProps) {
aFramesWithProps->AppendElement(frame);
}
if (flags & RetainedDisplayListData::FrameFlags::HadWillChange) {
aBuilder->RemoveFromWillChangeBudgets(frame);
}
}
data->Clear();
}
return CallState::Continue;
auto recurse = [&](Document& aSubDoc) {
if (nsIFrame* rootFrame = GetRootFrameForPainting(aBuilder, aSubDoc)) {
TakeAndAddModifiedAndFramesWithPropsFromRootFrame(
aBuilder, aModifiedFrames, aFramesWithProps, rootFrame, aSubDoc);
}
return CallState::Continue;
};
aDoc.EnumerateSubDocuments(recurse);
}
static void GetModifiedAndFramesWithProps(
@ -944,12 +928,9 @@ static void GetModifiedAndFramesWithProps(
nsIFrame* rootFrame = aBuilder->RootReferenceFrame();
MOZ_ASSERT(rootFrame);
Document* rootDoc = rootFrame->PresContext()->Document();
TakeAndAddModifiedAndFramesWithPropsFromRootFrame(
aBuilder, aOutModifiedFrames, aOutFramesWithProps, rootFrame);
Document* rootdoc = rootFrame->PresContext()->Document();
CbData data = {aBuilder, aOutModifiedFrames, aOutFramesWithProps};
rootdoc->EnumerateSubDocuments(SubDocEnumCb, &data);
aBuilder, aOutModifiedFrames, aOutFramesWithProps, rootFrame, *rootDoc);
}
// ComputeRebuildRegion debugging

View File

@ -2786,29 +2786,24 @@ bool nsDisplayList::ComputeVisibilityForSublist(
return anyVisible;
}
static CallState TriggerPendingAnimationsOnSubDocuments(Document& aDoc,
void* aReadyTime) {
static void TriggerPendingAnimations(Document& aDoc,
const TimeStamp& aReadyTime) {
MOZ_ASSERT(!aReadyTime.IsNull(),
"Animation ready time is not set. Perhaps we're using a layer"
" manager that doesn't update it");
if (PendingAnimationTracker* tracker = aDoc.GetPendingAnimationTracker()) {
PresShell* presShell = aDoc.GetPresShell();
// If paint-suppression is in effect then we haven't finished painting
// this document yet so we shouldn't start animations
if (!presShell || !presShell->IsPaintingSuppressed()) {
const TimeStamp& readyTime = *static_cast<TimeStamp*>(aReadyTime);
tracker->TriggerPendingAnimationsOnNextTick(readyTime);
tracker->TriggerPendingAnimationsOnNextTick(aReadyTime);
}
}
aDoc.EnumerateSubDocuments(TriggerPendingAnimationsOnSubDocuments,
aReadyTime);
return CallState::Continue;
}
static void TriggerPendingAnimations(Document& aDocument,
const TimeStamp& aReadyTime) {
MOZ_ASSERT(!aReadyTime.IsNull(),
"Animation ready time is not set. Perhaps we're using a layer"
" manager that doesn't update it");
TriggerPendingAnimationsOnSubDocuments(aDocument,
const_cast<TimeStamp*>(&aReadyTime));
auto recurse = [&aReadyTime](Document& aDoc) {
TriggerPendingAnimations(aDoc, aReadyTime);
return CallState::Continue;
};
aDoc.EnumerateSubDocuments(recurse);
}
LayerManager* nsDisplayListBuilder::GetWidgetLayerManager(nsView** aView) {

View File

@ -490,31 +490,34 @@ static nsresult EnsureSettingsHasPrinterNameSet(
#endif
}
static CallState DocHasPrintCallbackCanvas(Document& aDoc, void* aData) {
static bool DocHasPrintCallbackCanvas(Document& aDoc) {
Element* root = aDoc.GetRootElement();
if (!root) {
return CallState::Continue;
return false;
}
// FIXME(emilio): This doesn't account for shadow dom and it's unnecessarily
// inefficient. Though I guess it doesn't really matter.
RefPtr<nsContentList> canvases =
NS_GetContentList(root, kNameSpaceID_XHTML, NS_LITERAL_STRING("canvas"));
uint32_t canvasCount = canvases->Length(true);
for (uint32_t i = 0; i < canvasCount; ++i) {
HTMLCanvasElement* canvas =
HTMLCanvasElement::FromNodeOrNull(canvases->Item(i, false));
auto* canvas = HTMLCanvasElement::FromNodeOrNull(canvases->Item(i, false));
if (canvas && canvas->GetMozPrintCallback()) {
// This subdocument has a print callback. Set result and return false to
// stop iteration.
*static_cast<bool*>(aData) = true;
return CallState::Stop;
return true;
}
}
return CallState::Continue;
}
static bool AnySubdocHasPrintCallbackCanvas(Document& aDoc) {
bool result = false;
aDoc.EnumerateSubDocuments(DocHasPrintCallbackCanvas,
static_cast<void*>(&result));
auto checkSubDoc = [&result](Document& aSubDoc) {
if (DocHasPrintCallbackCanvas(aSubDoc)) {
result = true;
return CallState::Stop;
}
return CallState::Continue;
};
aDoc.EnumerateSubDocuments(checkSubDoc);
return result;
}
@ -587,11 +590,7 @@ nsresult nsPrintJob::Initialize(nsIDocumentViewerPrint* aDocViewerPrint,
}
}
bool hasMozPrintCallback = false;
DocHasPrintCallbackCanvas(*aOriginalDoc,
static_cast<void*>(&hasMozPrintCallback));
mHasMozPrintCallback =
hasMozPrintCallback || AnySubdocHasPrintCallbackCanvas(*aOriginalDoc);
mHasMozPrintCallback = DocHasPrintCallbackCanvas(*aOriginalDoc);
return NS_OK;
}