Bug 1892041 - Part 1: Update test262 features. r=spidermonkey-reviewers,dminor
[gecko.git] / dom / base / nsStubMutationObserver.cpp
blobfcd8a8fdc576798821b3f893620ad31bd64a200c
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /*
8 * nsStubMutationObserver is an implementation of the nsIMutationObserver
9 * interface (except for the methods on nsISupports) that is intended to be
10 * used as a base class within the content/layout library. All methods do
11 * nothing.
14 #include "nsStubMutationObserver.h"
15 #include "mozilla/RefCountType.h"
16 #include "nsISupports.h"
17 #include "nsINode.h"
19 /******************************************************************************
20 * nsStubMutationObserver
21 *****************************************************************************/
23 NS_IMPL_NSIMUTATIONOBSERVER_CORE_STUB(nsStubMutationObserver)
24 NS_IMPL_NSIMUTATIONOBSERVER_CONTENT(nsStubMutationObserver)
26 /******************************************************************************
27 * MutationObserverWrapper
28 *****************************************************************************/
30 /**
31 * @brief Wrapper class for a mutation observer that observes multiple nodes.
33 * This wrapper implements all methods of the nsIMutationObserver interface
34 * and forwards all calls to its owner, which is an instance of
35 * nsMultiMutationObserver.
37 * This class holds a reference to the owner and AddRefs/Releases its owner
38 * as well to ensure lifetime.
40 class MutationObserverWrapper final : public nsIMutationObserver {
41 public:
42 NS_DECL_ISUPPORTS
44 explicit MutationObserverWrapper(nsMultiMutationObserver* aOwner)
45 : mOwner(aOwner) {}
47 void CharacterDataWillChange(nsIContent* aContent,
48 const CharacterDataChangeInfo& aInfo) override {
49 MOZ_ASSERT(mOwner);
50 mOwner->CharacterDataWillChange(aContent, aInfo);
53 void CharacterDataChanged(nsIContent* aContent,
54 const CharacterDataChangeInfo& aInfo) override {
55 MOZ_ASSERT(mOwner);
56 mOwner->CharacterDataChanged(aContent, aInfo);
59 void AttributeWillChange(mozilla::dom::Element* aElement,
60 int32_t aNameSpaceID, nsAtom* aAttribute,
61 int32_t aModType) override {
62 MOZ_ASSERT(mOwner);
63 mOwner->AttributeWillChange(aElement, aNameSpaceID, aAttribute, aModType);
66 void AttributeChanged(mozilla::dom::Element* aElement, int32_t aNameSpaceID,
67 nsAtom* aAttribute, int32_t aModType,
68 const nsAttrValue* aOldValue) override {
69 MOZ_ASSERT(mOwner);
70 mOwner->AttributeChanged(aElement, aNameSpaceID, aAttribute, aModType,
71 aOldValue);
74 void AttributeSetToCurrentValue(mozilla::dom::Element* aElement,
75 int32_t aNameSpaceID,
76 nsAtom* aAttribute) override {
77 MOZ_ASSERT(mOwner);
78 mOwner->AttributeSetToCurrentValue(aElement, aNameSpaceID, aAttribute);
81 void ContentAppended(nsIContent* aFirstNewContent) override {
82 MOZ_ASSERT(mOwner);
83 mOwner->ContentAppended(aFirstNewContent);
86 void ContentInserted(nsIContent* aChild) override {
87 MOZ_ASSERT(mOwner);
88 mOwner->ContentInserted(aChild);
91 void ContentRemoved(nsIContent* aChild,
92 nsIContent* aPreviousSibling) override {
93 MOZ_ASSERT(mOwner);
94 mOwner->ContentRemoved(aChild, aPreviousSibling);
97 void NodeWillBeDestroyed(nsINode* aNode) override {
98 MOZ_ASSERT(mOwner);
99 AddRefWrapper();
100 RefPtr<nsMultiMutationObserver> owner = mOwner;
101 owner->NodeWillBeDestroyed(aNode);
102 owner->RemoveMutationObserverFromNode(aNode);
103 mOwner = nullptr;
104 ReleaseWrapper();
107 void ParentChainChanged(nsIContent* aContent) override {
108 MOZ_ASSERT(mOwner);
109 mOwner->ParentChainChanged(aContent);
112 void ARIAAttributeDefaultWillChange(mozilla::dom::Element* aElement,
113 nsAtom* aAttribute,
114 int32_t aModType) override {
115 MOZ_ASSERT(mOwner);
116 mOwner->ARIAAttributeDefaultWillChange(aElement, aAttribute, aModType);
119 void ARIAAttributeDefaultChanged(mozilla::dom::Element* aElement,
120 nsAtom* aAttribute,
121 int32_t aModType) override {
122 MOZ_ASSERT(mOwner);
123 mOwner->ARIAAttributeDefaultChanged(aElement, aAttribute, aModType);
126 MozExternalRefCountType AddRefWrapper() {
127 nsrefcnt count = ++mRefCnt;
128 NS_LOG_ADDREF(this, count, "MutationObserverWrapper", sizeof(*this));
129 return count;
132 MozExternalRefCountType ReleaseWrapper() {
133 --mRefCnt;
134 NS_LOG_RELEASE(this, mRefCnt, "MutationObserverWrapper");
135 if (mRefCnt == 0) {
136 mRefCnt = 1;
137 delete this;
138 return MozExternalRefCountType(0);
140 return mRefCnt;
143 private:
144 ~MutationObserverWrapper() = default;
145 nsMultiMutationObserver* mOwner{nullptr};
148 NS_IMPL_QUERY_INTERFACE(MutationObserverWrapper, nsIMutationObserver);
150 MozExternalRefCountType MutationObserverWrapper::AddRef() {
151 MOZ_ASSERT(mOwner);
152 AddRefWrapper();
153 mOwner->AddRef();
154 return mRefCnt;
157 MozExternalRefCountType MutationObserverWrapper::Release() {
158 MOZ_ASSERT(mOwner);
159 mOwner->Release();
160 return ReleaseWrapper();
163 /******************************************************************************
164 * nsMultiMutationObserver
165 *****************************************************************************/
167 void nsMultiMutationObserver::AddMutationObserverToNode(nsINode* aNode) {
168 if (!aNode) {
169 return;
171 if (mWrapperForNode.Contains(aNode)) {
172 return;
174 auto* newWrapper = new MutationObserverWrapper{this};
175 newWrapper->AddRefWrapper();
176 mWrapperForNode.InsertOrUpdate(aNode, newWrapper);
177 aNode->AddMutationObserver(newWrapper);
180 void nsMultiMutationObserver::RemoveMutationObserverFromNode(nsINode* aNode) {
181 if (!aNode) {
182 return;
185 if (auto obs = mWrapperForNode.MaybeGet(aNode); obs.isSome()) {
186 aNode->RemoveMutationObserver(*obs);
187 mWrapperForNode.Remove(aNode);
188 (*obs)->ReleaseWrapper();
192 bool nsMultiMutationObserver::ContainsNode(const nsINode* aNode) const {
193 return mWrapperForNode.Contains(const_cast<nsINode*>(aNode));
196 /******************************************************************************
197 * nsStubMultiMutationObserver
198 *****************************************************************************/
200 NS_IMPL_NSIMUTATIONOBSERVER_CORE_STUB(nsStubMultiMutationObserver)
201 NS_IMPL_NSIMUTATIONOBSERVER_CONTENT(nsStubMultiMutationObserver)