/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
template <typename NotifyObserver> staticinline nsINode* ForEachAncestorObserver(nsINode* aNode,
NotifyObserver& aFunc,
uint32_t aCallback) {
nsINode* last;
nsINode* node = aNode; do {
mozilla::SafeDoublyLinkedList<nsIMutationObserver>* observers =
node->GetMutationObservers(); if (observers) { for (auto iter = observers->begin(); iter != observers->end(); ++iter) { if (iter->IsCallbackEnabled(aCallback)) {
aFunc(&*iter);
}
}
}
last = node; if (!(node = node->GetParentNode())) { if (ShadowRoot* shadow = ShadowRoot::FromNode(last)) {
node = shadow->GetHost();
}
}
} while (node); return last;
}
// Whether to notify to the PresShell about a mutation. // For removals, the pres shell gets notified first, since it needs to operate // on the "old" DOM shape. enumclass NotifyPresShell { No, Before, After };
#ifdef DEBUG constbool wasConnected = aNode->IsInComposedDoc(); #endif if constexpr (aNotifyPresShell == NotifyPresShell::Before) { if (aNode->IsInComposedDoc()) {
NOTIFY_PRESSHELL(aNotify);
}
}
nsINode* last = ForEachAncestorObserver(aNode, aNotify, aCallback); // For non-removals, the pres shell gets notified last, since it needs to // operate on the "final" DOM shape. if constexpr (aNotifyPresShell == NotifyPresShell::After) { if (last == doc) {
NOTIFY_PRESSHELL(aNotify);
}
}
MOZ_ASSERT((last == doc) == wasConnected, "If we were connected we should notify all ancestors all the " "way to the document");
}
void MutationObservers::NotifyContentInserted(nsINode* aContainer,
nsIContent* aChild) {
MOZ_ASSERT(aContainer->IsContent() || aContainer->IsDocument(), "container must be an nsIContent or an Document");
aContainer->OwnerDoc()->Changed();
Notify(aContainer, NOTIFIER(ContentInserted, aChild),
nsIMutationObserver::kContentInserted);
}
void MutationObservers::NotifyContentWillBeRemoved(
nsINode* aContainer, nsIContent* aChild, const BatchRemovalState* aState) {
MOZ_ASSERT(aContainer->IsContent() || aContainer->IsDocument(), "container must be an nsIContent or an Document");
MOZ_ASSERT(aChild->GetParentNode() == aContainer, "We expect the parent link to be still around at this point");
aContainer->OwnerDoc()->Changed();
Notify<NotifyPresShell::Before>(
aContainer, NOTIFIER(ContentWillBeRemoved, aChild, aState),
nsIMutationObserver::kContentWillBeRemoved);
}
NonOwningAnimationTarget target = aAnimation->GetTargetForAnimation(); if (!target) { return;
}
// A pseudo element and its parent element use the same owner doc.
Document* doc = target.mElement->OwnerDoc(); if (doc->MayHaveAnimationObservers()) { // we use the its parent element as the subject in DOM Mutation Observer.
Element* elem = target.mElement; switch (aMutatedType) { case AnimationMutationType::Added:
IMPL_ANIMATION_NOTIFICATION(AnimationAdded, elem, (aAnimation)); break; case AnimationMutationType::Changed:
IMPL_ANIMATION_NOTIFICATION(AnimationChanged, elem, (aAnimation)); break; case AnimationMutationType::Removed:
IMPL_ANIMATION_NOTIFICATION(AnimationRemoved, elem, (aAnimation)); break; default:
MOZ_ASSERT_UNREACHABLE("unexpected mutation type");
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.