Backed out changeset b462e7b742d8 (bug 1908261) for causing multiple reftest failures...
[gecko.git] / dom / base / nsIMutationObserver.h
blobf092de41a5ab1338845a0af9280f72cdd997cf16
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 #ifndef nsIMutationObserver_h
8 #define nsIMutationObserver_h
10 #include "nsISupports.h"
12 #include "mozilla/Assertions.h"
13 #include "mozilla/DoublyLinkedList.h"
15 class nsAttrValue;
16 class nsAtom;
17 class nsIContent;
18 class nsINode;
19 struct BatchRemovalState;
21 namespace mozilla::dom {
22 class Element;
23 } // namespace mozilla::dom
25 #define NS_IMUTATION_OBSERVER_IID \
26 {0x6d674c17, 0x0fbc, 0x4633, {0x8f, 0x46, 0x73, 0x4e, 0x87, 0xeb, 0xf0, 0xc7}}
28 /**
29 * Information details about a characterdata change. Basically, we
30 * view all changes as replacements of a length of text at some offset
31 * with some other text (of possibly some other length).
33 struct CharacterDataChangeInfo {
34 /**
35 * True if this character data change is just an append.
37 bool mAppend;
39 /**
40 * The offset in the text where the change occurred.
42 uint32_t mChangeStart;
44 /**
45 * The offset such that mChangeEnd - mChangeStart is equal to the length of
46 * the text we removed. If this was a pure insert, append or a result of
47 * `splitText()` this is equal to mChangeStart.
49 uint32_t mChangeEnd;
51 uint32_t LengthOfRemovedText() const {
52 MOZ_ASSERT(mChangeStart <= mChangeEnd);
54 return mChangeEnd - mChangeStart;
57 /**
58 * The length of the text that was inserted in place of the removed text. If
59 * this was a pure text removal, this is 0.
61 uint32_t mReplaceLength;
63 /**
64 * The net result is that mChangeStart characters at the beginning of the
65 * text remained as they were. The next mChangeEnd - mChangeStart characters
66 * were removed, and mReplaceLength characters were inserted in their place.
67 * The text that used to begin at mChangeEnd now begins at
68 * mChangeStart + mReplaceLength.
71 struct MOZ_STACK_CLASS Details {
72 enum {
73 eMerge, // two text nodes are merged as a result of normalize()
74 eSplit // a text node is split as a result of splitText()
75 } mType;
76 /**
77 * For eMerge it's the text node that will be removed, for eSplit it's the
78 * new text node.
80 nsIContent* MOZ_NON_OWNING_REF mNextSibling;
83 /**
84 * Used for splitText() and normalize(), otherwise null.
86 Details* mDetails;
89 /**
90 * Mutation observer interface
92 * See nsINode::AddMutationObserver, nsINode::RemoveMutationObserver for how to
93 * attach or remove your observers. nsINode stores mutation observers using a
94 * mozilla::SafeDoublyLinkedList, which is a specialization of the
95 * DoublyLinkedList allowing for adding/removing elements while iterating.
96 * If a mutation observer is intended to be added to multiple nsINode instances,
97 * derive from nsMultiMutationObserver.
99 * WARNING: During these notifications, you are not allowed to perform
100 * any mutations to the current or any other document, or start a
101 * network load. If you need to perform such operations do that
102 * during the _last_ nsIDocumentObserver::EndUpdate notification. The
103 * exception for this is ParentChainChanged, where mutations should be
104 * done from an async event, as the notification might not be
105 * surrounded by BeginUpdate/EndUpdate calls.
107 class nsIMutationObserver
108 : public nsISupports,
109 mozilla::DoublyLinkedListElement<nsIMutationObserver> {
110 friend struct mozilla::GetDoublyLinkedListElement<nsIMutationObserver>;
112 public:
113 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMUTATION_OBSERVER_IID)
116 * Notification that the node value of a data node (text, cdata, pi, comment)
117 * will be changed.
119 * This notification is not sent when a piece of content is
120 * added/removed from the document (the other notifications are used
121 * for that).
123 * @param aContent The piece of content that changed. Is never null.
124 * @param aInfo The structure with information details about the change.
126 * @note Callers of this method might not hold a strong reference to the
127 * observer. The observer is responsible for making sure it stays
128 * alive for the duration of the call as needed. The observer may
129 * assume that this call will happen when there are script blockers on
130 * the stack.
132 virtual void CharacterDataWillChange(nsIContent* aContent,
133 const CharacterDataChangeInfo&) = 0;
136 * Notification that the node value of a data node (text, cdata, pi, comment)
137 * has changed.
139 * This notification is not sent when a piece of content is
140 * added/removed from the document (the other notifications are used
141 * for that).
143 * @param aContent The piece of content that changed. Is never null.
144 * @param aInfo The structure with information details about the change.
146 * @note Callers of this method might not hold a strong reference to the
147 * observer. The observer is responsible for making sure it stays
148 * alive for the duration of the call as needed. The observer may
149 * assume that this call will happen when there are script blockers on
150 * the stack.
152 virtual void CharacterDataChanged(nsIContent* aContent,
153 const CharacterDataChangeInfo&) = 0;
156 * Notification that an attribute of an element will change. This
157 * can happen before the BeginUpdate for the change and may not
158 * always be followed by an AttributeChanged (in particular, if the
159 * attribute doesn't actually change there will be no corresponding
160 * AttributeChanged).
162 * @param aContent The element whose attribute will change
163 * @param aNameSpaceID The namespace id of the changing attribute
164 * @param aAttribute The name of the changing attribute
165 * @param aModType Whether or not the attribute will be added, changed, or
166 * removed. The constants are defined in
167 * MutationEvent.webidl.
169 * @note Callers of this method might not hold a strong reference to the
170 * observer. The observer is responsible for making sure it stays
171 * alive for the duration of the call as needed. The observer may
172 * assume that this call will happen when there are script blockers on
173 * the stack.
175 virtual void AttributeWillChange(mozilla::dom::Element* aElement,
176 int32_t aNameSpaceID, nsAtom* aAttribute,
177 int32_t aModType) = 0;
180 * Notification that an attribute of an element has changed.
182 * @param aElement The element whose attribute changed
183 * @param aNameSpaceID The namespace id of the changed attribute
184 * @param aAttribute The name of the changed attribute
185 * @param aModType Whether or not the attribute was added, changed, or
186 * removed. The constants are defined in
187 * MutationEvent.webidl.
188 * @param aOldValue The old value, if either the old value or the new
189 * value are StoresOwnData() (or absent); null otherwise.
191 * @note Callers of this method might not hold a strong reference to the
192 * observer. The observer is responsible for making sure it stays
193 * alive for the duration of the call as needed. The observer may
194 * assume that this call will happen when there are script blockers on
195 * the stack.
197 virtual void AttributeChanged(mozilla::dom::Element* aElement,
198 int32_t aNameSpaceID, nsAtom* aAttribute,
199 int32_t aModType,
200 const nsAttrValue* aOldValue) = 0;
203 * Notification that an attribute of an element has been
204 * set to the value it already had.
206 * @param aElement The element whose attribute changed
207 * @param aNameSpaceID The namespace id of the changed attribute
208 * @param aAttribute The name of the changed attribute
210 virtual void AttributeSetToCurrentValue(mozilla::dom::Element* aElement,
211 int32_t aNameSpaceID,
212 nsAtom* aAttribute) {}
215 * Notification that one or more content nodes have been appended to the
216 * child list of another node in the tree.
218 * @param aFirstNewContent the first node appended.
220 * @note Callers of this method might not hold a strong reference to the
221 * observer. The observer is responsible for making sure it stays
222 * alive for the duration of the call as needed. The observer may
223 * assume that this call will happen when there are script blockers on
224 * the stack.
226 virtual void ContentAppended(nsIContent* aFirstNewContent) = 0;
229 * Notification that a content node has been inserted as child to another
230 * node in the tree.
232 * @param aChild The newly inserted child.
234 * @note Callers of this method might not hold a strong reference to the
235 * observer. The observer is responsible for making sure it stays
236 * alive for the duration of the call as needed. The observer may
237 * assume that this call will happen when there are script blockers on
238 * the stack.
240 virtual void ContentInserted(nsIContent* aChild) = 0;
243 * Notification that a content node is about to be removed from the child list
244 * of another node in the tree.
246 * @param aChild The child that will be removed.
247 * @param aState The state of our batch removal of all children, or null.
249 * @note Callers of this method might not hold a strong reference to the
250 * observer. The observer is responsible for making sure it stays
251 * alive for the duration of the call as needed. The observer may
252 * assume that this call will happen when there are script blockers on
253 * the stack.
255 virtual void ContentWillBeRemoved(nsIContent* aChild,
256 const BatchRemovalState*) = 0;
259 * The node is in the process of being destroyed. Calling QI on the node is
260 * not supported, however it is possible to get children and flags through
261 * nsINode as well as calling IsContent and casting to nsIContent to get
262 * attributes.
264 * NOTE: This notification is only called on observers registered directly
265 * on the node. This is because when the node is destroyed it can not have
266 * any ancestors. If you want to know when a descendant node is being
267 * removed from the observed node, use the ContentWillBeRemoved notification.
269 * @param aNode The node being destroyed.
271 * @note Callers of this method might not hold a strong reference to
272 * the observer. The observer is responsible for making sure it
273 * stays alive for the duration of the call as needed.
275 virtual void NodeWillBeDestroyed(nsINode* aNode) = 0;
278 * Notification that the node's parent chain has changed. This
279 * happens when either the node or one of its ancestors is inserted
280 * or removed as a child of another node.
282 * Note that when a node is inserted this notification is sent to
283 * all descendants of that node, since all such nodes have their
284 * parent chain changed.
286 * @param aContent The piece of content that had its parent changed.
288 * @note Callers of this method might not hold a strong reference to
289 * the observer. The observer is responsible for making sure it
290 * stays alive for the duration of the call as needed.
293 virtual void ParentChainChanged(nsIContent* aContent) = 0;
295 virtual void ARIAAttributeDefaultWillChange(mozilla::dom::Element* aElement,
296 nsAtom* aAttribute,
297 int32_t aModType) = 0;
298 virtual void ARIAAttributeDefaultChanged(mozilla::dom::Element* aElement,
299 nsAtom* aAttribute,
300 int32_t aModType) = 0;
302 enum : uint32_t {
303 kNone = 0,
304 kCharacterDataWillChange = 1 << 0,
305 kCharacterDataChanged = 1 << 1,
306 kAttributeWillChange = 1 << 2,
307 kAttributeChanged = 1 << 3,
308 kAttributeSetToCurrentValue = 1 << 4,
309 kContentAppended = 1 << 5,
310 kContentInserted = 1 << 6,
311 kContentWillBeRemoved = 1 << 7,
312 kNodeWillBeDestroyed = 1 << 8,
313 kParentChainChanged = 1 << 9,
314 kARIAAttributeDefaultWillChange = 1 << 10,
315 kARIAAttributeDefaultChanged = 1 << 11,
317 kBeginUpdate = 1 << 12,
318 kEndUpdate = 1 << 13,
319 kBeginLoad = 1 << 14,
320 kEndLoad = 1 << 15,
321 kElementStateChanged = 1 << 16,
323 kAnimationAdded = 1 << 17,
324 kAnimationChanged = 1 << 18,
325 kAnimationRemoved = 1 << 19,
327 kAll = 0xFFFFFFFF
330 void SetEnabledCallbacks(uint32_t aCallbacks) {
331 mEnabledCallbacks = aCallbacks;
334 bool IsCallbackEnabled(uint32_t aCallback) const {
335 return mEnabledCallbacks & aCallback;
338 private:
339 uint32_t mEnabledCallbacks = kAll;
342 NS_DEFINE_STATIC_IID_ACCESSOR(nsIMutationObserver, NS_IMUTATION_OBSERVER_IID)
344 #define NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATAWILLCHANGE \
345 virtual void CharacterDataWillChange( \
346 nsIContent* aContent, const CharacterDataChangeInfo& aInfo) override;
348 #define NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED \
349 virtual void CharacterDataChanged( \
350 nsIContent* aContent, const CharacterDataChangeInfo& aInfo) override;
352 #define NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE \
353 virtual void AttributeWillChange(mozilla::dom::Element* aElement, \
354 int32_t aNameSpaceID, nsAtom* aAttribute, \
355 int32_t aModType) override;
357 #define NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED \
358 virtual void AttributeChanged(mozilla::dom::Element* aElement, \
359 int32_t aNameSpaceID, nsAtom* aAttribute, \
360 int32_t aModType, \
361 const nsAttrValue* aOldValue) override;
363 #define NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED \
364 virtual void ContentAppended(nsIContent* aFirstNewContent) override;
366 #define NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED \
367 virtual void ContentInserted(nsIContent* aChild) override;
369 #define NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED \
370 virtual void ContentWillBeRemoved(nsIContent* aChild, \
371 const BatchRemovalState*) override;
373 #define NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED \
374 virtual void NodeWillBeDestroyed(nsINode* aNode) override;
376 #define NS_DECL_NSIMUTATIONOBSERVER_PARENTCHAINCHANGED \
377 virtual void ParentChainChanged(nsIContent* aContent) override;
379 #define NS_DECL_NSIMUTATIONOBSERVER_ARIAATTRIBUTEDEFAULTWILLCHANGE \
380 virtual void ARIAAttributeDefaultWillChange( \
381 mozilla::dom::Element* aElement, nsAtom* aAttribute, int32_t aModType) \
382 override;
384 #define NS_DECL_NSIMUTATIONOBSERVER_ARIAATTRIBUTEDEFAULTCHANGED \
385 virtual void ARIAAttributeDefaultChanged( \
386 mozilla::dom::Element* aElement, nsAtom* aAttribute, int32_t aModType) \
387 override;
389 #define NS_DECL_NSIMUTATIONOBSERVER \
390 NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATAWILLCHANGE \
391 NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED \
392 NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE \
393 NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED \
394 NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED \
395 NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED \
396 NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED \
397 NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED \
398 NS_DECL_NSIMUTATIONOBSERVER_PARENTCHAINCHANGED \
399 NS_DECL_NSIMUTATIONOBSERVER_ARIAATTRIBUTEDEFAULTWILLCHANGE \
400 NS_DECL_NSIMUTATIONOBSERVER_ARIAATTRIBUTEDEFAULTCHANGED
402 #define NS_IMPL_NSIMUTATIONOBSERVER_CORE_STUB(_class) \
403 void _class::NodeWillBeDestroyed(nsINode* aNode) {}
405 #define NS_IMPL_NSIMUTATIONOBSERVER_CONTENT(_class) \
406 void _class::CharacterDataWillChange( \
407 nsIContent* aContent, const CharacterDataChangeInfo& aInfo) {} \
408 void _class::CharacterDataChanged(nsIContent* aContent, \
409 const CharacterDataChangeInfo& aInfo) {} \
410 void _class::AttributeWillChange(mozilla::dom::Element* aElement, \
411 int32_t aNameSpaceID, nsAtom* aAttribute, \
412 int32_t aModType) {} \
413 void _class::AttributeChanged( \
414 mozilla::dom::Element* aElement, int32_t aNameSpaceID, \
415 nsAtom* aAttribute, int32_t aModType, const nsAttrValue* aOldValue) {} \
416 void _class::ContentAppended(nsIContent* aFirstNewContent) {} \
417 void _class::ContentInserted(nsIContent* aChild) {} \
418 void _class::ContentWillBeRemoved(nsIContent* aChild, \
419 const BatchRemovalState*) {} \
420 void _class::ParentChainChanged(nsIContent* aContent) {} \
421 void _class::ARIAAttributeDefaultWillChange( \
422 mozilla::dom::Element* aElement, nsAtom* aAttribute, int32_t aModType) { \
424 void _class::ARIAAttributeDefaultChanged( \
425 mozilla::dom::Element* aElement, nsAtom* aAttribute, int32_t aModType) { \
428 #endif /* nsIMutationObserver_h */