Bug 1420547: Add assertions for the assumptions we're making. r?bz
MozReview-Commit-ID: 8CVtclXLgzH
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -43,25 +43,33 @@ using namespace mozilla::dom;
using mozilla::AutoJSContext;
enum class IsRemoveNotification
{
Yes,
No,
};
+#ifdef DEBUG
+#define COMPOSED_DOC_DECL \
+ const bool wasInComposedDoc = !!node->GetComposedDoc();
+#else
+#define COMPOSED_DOC_DECL
+#endif
+
// This macro expects the ownerDocument of content_ to be in scope as
// |nsIDocument* doc|
#define IMPL_MUTATION_NOTIFICATION(func_, content_, params_, remove_) \
PR_BEGIN_MACRO \
bool needsEnterLeave = doc->MayHaveDOMMutationObservers(); \
if (needsEnterLeave) { \
nsDOMMutationObserver::EnterMutationHandling(); \
} \
nsINode* node = content_; \
+ COMPOSED_DOC_DECL \
NS_ASSERTION(node->OwnerDoc() == doc, "Bogus document"); \
if (remove_ == IsRemoveNotification::Yes && node->GetComposedDoc()) { \
if (nsIPresShell* shell = doc->GetObservingShell()) { \
shell->func_ params_; \
} \
} \
doc->BindingManager()->func_ params_; \
nsINode* last; \
@@ -74,16 +82,22 @@ enum class IsRemoveNotification
} \
last = node; \
if (ShadowRoot* shadow = ShadowRoot::FromNode(node)) { \
node = shadow->GetHost(); \
} else { \
node = node->GetParentNode(); \
} \
} while (node); \
+ /* Whitelist NativeAnonymousChildListChange removal notifications from \
+ * the assertion since it runs from UnbindFromTree, and thus we don't \
+ * reach the document, but doesn't matter. */ \
+ MOZ_ASSERT((last == doc) == wasInComposedDoc || \
+ (remove_ == IsRemoveNotification::Yes && \
+ !strcmp(#func_, "NativeAnonymousChildListChange"))); \
if (remove_ == IsRemoveNotification::No && last == doc) { \
if (nsIPresShell* shell = doc->GetObservingShell()) { \
shell->func_ params_; \
} \
} \
if (needsEnterLeave) { \
nsDOMMutationObserver::LeaveMutationHandling(); \
} \
@@ -181,19 +195,21 @@ nsNodeUtils::ContentAppended(nsIContent*
IsRemoveNotification::No);
}
void
nsNodeUtils::NativeAnonymousChildListChange(nsIContent* aContent,
bool aIsRemove)
{
nsIDocument* doc = aContent->OwnerDoc();
+ auto isRemove = aIsRemove
+ ? IsRemoveNotification::Yes : IsRemoveNotification::No;
IMPL_MUTATION_NOTIFICATION(NativeAnonymousChildListChange, aContent,
(doc, aContent, aIsRemove),
- IsRemoveNotification::No);
+ isRemove);
}
void
nsNodeUtils::ContentInserted(nsINode* aContainer,
nsIContent* aChild)
{
NS_PRECONDITION(aContainer->IsContent() ||
aContainer->IsNodeOfType(nsINode::eDOCUMENT),