Bug 1433336 - Add nsIDocument::CollectDescendantDocument(). r?smaug
In contrast to nsIDocument::EnumerateSubDocuments(), this new function is
supposed to work with the callback function which does not mutate any state
in the document, and also this function checks all descendant documents even
if there is a descendant that the callback function returns false.
MozReview-Commit-ID: 4f6zD29qQD2
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -8599,16 +8599,37 @@ nsDocument::EnumerateSubDocuments(nsSubD
}
for (auto subdoc : subdocs) {
if (!aCallback(subdoc, aData)) {
break;
}
}
}
+void
+nsDocument::CollectDescendantDocuments(
+ nsTArray<nsCOMPtr<nsIDocument>>& aDescendants,
+ nsDocTestFunc aCallback) const
+{
+ if (!mSubDocuments) {
+ return;
+ }
+
+ for (auto iter = mSubDocuments->Iter(); !iter.Done(); iter.Next()) {
+ auto entry = static_cast<SubDocMapEntry*>(iter.Get());
+ const nsIDocument* subdoc = entry->mSubDocument;
+ if (subdoc) {
+ if (aCallback(subdoc)) {
+ aDescendants.AppendElement(entry->mSubDocument);
+ }
+ subdoc->CollectDescendantDocuments(aDescendants, aCallback);
+ }
+ }
+}
+
#ifdef DEBUG_bryner
#define DEBUG_PAGE_CACHE
#endif
bool
nsDocument::CanSavePresentation(nsIRequest *aNewRequest)
{
if (EventHandlingSuppressed()) {
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -673,16 +673,19 @@ public:
nsAtom* aPrefix,
int32_t aNamespaceID,
const nsAString* aIs = nullptr) override;
virtual void Sanitize() override;
virtual void EnumerateSubDocuments(nsSubDocEnumFunc aCallback,
void *aData) override;
+ virtual void CollectDescendantDocuments(
+ nsTArray<nsCOMPtr<nsIDocument>>& aDescendants,
+ nsDocTestFunc aCallback) const override;
virtual bool CanSavePresentation(nsIRequest *aNewRequest) override;
virtual void Destroy() override;
virtual void RemovedFromDocShell() override;
virtual already_AddRefed<nsILayoutHistoryState> GetLayoutHistoryState() const override;
virtual void BlockOnload() override;
virtual void UnblockOnload(bool aFireSync) override;
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -1912,16 +1912,25 @@ public:
* The enumerator callback should return true to continue enumerating, or
* false to stop. This will never get passed a null aDocument.
*/
typedef bool (*nsSubDocEnumFunc)(nsIDocument *aDocument, void *aData);
virtual void EnumerateSubDocuments(nsSubDocEnumFunc aCallback,
void *aData) = 0;
/**
+ * Collect all the descendant documents for which |aCalback| returns true.
+ * The callback function must not mutate any state for the given document.
+ */
+ typedef bool (*nsDocTestFunc)(const nsIDocument* aDocument);
+ virtual void CollectDescendantDocuments(
+ nsTArray<nsCOMPtr<nsIDocument>>& aDescendants,
+ nsDocTestFunc aCallback) const = 0;
+
+ /**
* Check whether it is safe to cache the presentation of this document
* and all of its subdocuments. This method checks the following conditions
* recursively:
* - Some document types, such as plugin documents, cannot be safely cached.
* - If there are any pending requests, we don't allow the presentation
* to be cached. Ideally these requests would be suspended and resumed,
* but that is difficult in some cases, such as XMLHttpRequest.
* - If there are any beforeunload or unload listeners, we must fire them