зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1420547: Notify the pres shell before everything else on removals. r=bz
This allows the flattened tree to have a reasonable state before content removals, allowing us to fix bugs like bug 1420533. This used to be also the old setup, but was changed in bug 382376, since the frame constructor used to reconstruct stuff synchronously. This used to break all sorts of stylo invariants, and I fixed this in bug 1389743, so now the order can be sane again. MozReview-Commit-ID: K2pTweGKSq0 --HG-- extra : rebase_source : e53b7314f39f9c1c2e87fbe202f64b06e4c64c57
This commit is contained in:
Родитель
bae0ffb7be
Коммит
2280023199
|
@ -42,40 +42,51 @@ using namespace mozilla;
|
|||
using namespace mozilla::dom;
|
||||
using mozilla::AutoJSContext;
|
||||
|
||||
enum class IsRemoveNotification
|
||||
{
|
||||
Yes,
|
||||
No,
|
||||
};
|
||||
|
||||
// This macro expects the ownerDocument of content_ to be in scope as
|
||||
// |nsIDocument* doc|
|
||||
#define IMPL_MUTATION_NOTIFICATION(func_, content_, params_) \
|
||||
PR_BEGIN_MACRO \
|
||||
bool needsEnterLeave = doc->MayHaveDOMMutationObservers(); \
|
||||
if (needsEnterLeave) { \
|
||||
nsDOMMutationObserver::EnterMutationHandling(); \
|
||||
} \
|
||||
nsINode* node = content_; \
|
||||
NS_ASSERTION(node->OwnerDoc() == doc, "Bogus document"); \
|
||||
doc->BindingManager()->func_ params_; \
|
||||
nsINode* last; \
|
||||
do { \
|
||||
nsINode::nsSlots* slots = node->GetExistingSlots(); \
|
||||
if (slots && !slots->mMutationObservers.IsEmpty()) { \
|
||||
NS_OBSERVER_AUTO_ARRAY_NOTIFY_OBSERVERS( \
|
||||
slots->mMutationObservers, nsIMutationObserver, 1, \
|
||||
func_, params_); \
|
||||
} \
|
||||
last = node; \
|
||||
if (ShadowRoot* shadow = ShadowRoot::FromNode(node)) { \
|
||||
node = shadow->GetHost(); \
|
||||
} else { \
|
||||
node = node->GetParentNode(); \
|
||||
} \
|
||||
} while (node); \
|
||||
if (last == doc) { \
|
||||
if (nsIPresShell* shell = doc->GetObservingShell()) { \
|
||||
shell->func_ params_; \
|
||||
} \
|
||||
} \
|
||||
if (needsEnterLeave) { \
|
||||
nsDOMMutationObserver::LeaveMutationHandling(); \
|
||||
} \
|
||||
#define IMPL_MUTATION_NOTIFICATION(func_, content_, params_, remove_) \
|
||||
PR_BEGIN_MACRO \
|
||||
bool needsEnterLeave = doc->MayHaveDOMMutationObservers(); \
|
||||
if (needsEnterLeave) { \
|
||||
nsDOMMutationObserver::EnterMutationHandling(); \
|
||||
} \
|
||||
nsINode* node = content_; \
|
||||
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; \
|
||||
do { \
|
||||
nsINode::nsSlots* slots = node->GetExistingSlots(); \
|
||||
if (slots && !slots->mMutationObservers.IsEmpty()) { \
|
||||
NS_OBSERVER_AUTO_ARRAY_NOTIFY_OBSERVERS( \
|
||||
slots->mMutationObservers, nsIMutationObserver, 1, \
|
||||
func_, params_); \
|
||||
} \
|
||||
last = node; \
|
||||
if (ShadowRoot* shadow = ShadowRoot::FromNode(node)) { \
|
||||
node = shadow->GetHost(); \
|
||||
} else { \
|
||||
node = node->GetParentNode(); \
|
||||
} \
|
||||
} while (node); \
|
||||
if (remove_ == IsRemoveNotification::No && last == doc) { \
|
||||
if (nsIPresShell* shell = doc->GetObservingShell()) { \
|
||||
shell->func_ params_; \
|
||||
} \
|
||||
} \
|
||||
if (needsEnterLeave) { \
|
||||
nsDOMMutationObserver::LeaveMutationHandling(); \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
#define IMPL_ANIMATION_NOTIFICATION(func_, content_, params_) \
|
||||
|
@ -110,7 +121,7 @@ nsNodeUtils::CharacterDataWillChange(nsIContent* aContent,
|
|||
{
|
||||
nsIDocument* doc = aContent->OwnerDoc();
|
||||
IMPL_MUTATION_NOTIFICATION(CharacterDataWillChange, aContent,
|
||||
(doc, aContent, aInfo));
|
||||
(doc, aContent, aInfo), IsRemoveNotification::No);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -119,7 +130,7 @@ nsNodeUtils::CharacterDataChanged(nsIContent* aContent,
|
|||
{
|
||||
nsIDocument* doc = aContent->OwnerDoc();
|
||||
IMPL_MUTATION_NOTIFICATION(CharacterDataChanged, aContent,
|
||||
(doc, aContent, aInfo));
|
||||
(doc, aContent, aInfo), IsRemoveNotification::No);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -132,7 +143,7 @@ nsNodeUtils::AttributeWillChange(Element* aElement,
|
|||
nsIDocument* doc = aElement->OwnerDoc();
|
||||
IMPL_MUTATION_NOTIFICATION(AttributeWillChange, aElement,
|
||||
(doc, aElement, aNameSpaceID, aAttribute,
|
||||
aModType, aNewValue));
|
||||
aModType, aNewValue), IsRemoveNotification::No);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -145,7 +156,7 @@ nsNodeUtils::AttributeChanged(Element* aElement,
|
|||
nsIDocument* doc = aElement->OwnerDoc();
|
||||
IMPL_MUTATION_NOTIFICATION(AttributeChanged, aElement,
|
||||
(doc, aElement, aNameSpaceID, aAttribute,
|
||||
aModType, aOldValue));
|
||||
aModType, aOldValue), IsRemoveNotification::No);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -155,7 +166,8 @@ nsNodeUtils::AttributeSetToCurrentValue(Element* aElement,
|
|||
{
|
||||
nsIDocument* doc = aElement->OwnerDoc();
|
||||
IMPL_MUTATION_NOTIFICATION(AttributeSetToCurrentValue, aElement,
|
||||
(doc, aElement, aNameSpaceID, aAttribute));
|
||||
(doc, aElement, aNameSpaceID, aAttribute),
|
||||
IsRemoveNotification::No);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -165,7 +177,8 @@ nsNodeUtils::ContentAppended(nsIContent* aContainer,
|
|||
nsIDocument* doc = aContainer->OwnerDoc();
|
||||
|
||||
IMPL_MUTATION_NOTIFICATION(ContentAppended, aContainer,
|
||||
(doc, aContainer, aFirstNewContent));
|
||||
(doc, aContainer, aFirstNewContent),
|
||||
IsRemoveNotification::No);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -174,7 +187,8 @@ nsNodeUtils::NativeAnonymousChildListChange(nsIContent* aContent,
|
|||
{
|
||||
nsIDocument* doc = aContent->OwnerDoc();
|
||||
IMPL_MUTATION_NOTIFICATION(NativeAnonymousChildListChange, aContent,
|
||||
(doc, aContent, aIsRemove));
|
||||
(doc, aContent, aIsRemove),
|
||||
IsRemoveNotification::No);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -196,7 +210,8 @@ nsNodeUtils::ContentInserted(nsINode* aContainer,
|
|||
}
|
||||
|
||||
IMPL_MUTATION_NOTIFICATION(ContentInserted, aContainer,
|
||||
(document, container, aChild));
|
||||
(document, container, aChild),
|
||||
IsRemoveNotification::No);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -219,7 +234,8 @@ nsNodeUtils::ContentRemoved(nsINode* aContainer,
|
|||
}
|
||||
|
||||
IMPL_MUTATION_NOTIFICATION(ContentRemoved, aContainer,
|
||||
(document, container, aChild, aPreviousSibling));
|
||||
(document, container, aChild, aPreviousSibling),
|
||||
IsRemoveNotification::Yes);
|
||||
}
|
||||
|
||||
Maybe<NonOwningAnimationTarget>
|
||||
|
|
Загрузка…
Ссылка в новой задаче