Bug 1852754: part 9) Add tests for dynamically loading <link rel="prefetch"> elements...
[gecko.git] / dom / base / nsIMutationObserver.h
blob71abf05925fe584f711ca859d093c0bc438be7ee
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;
20 namespace mozilla::dom {
21 class Element;
22 } // namespace mozilla::dom
24 #define NS_IMUTATION_OBSERVER_IID \
25 { \
26 0x6d674c17, 0x0fbc, 0x4633, { \
27 0x8f, 0x46, 0x73, 0x4e, 0x87, 0xeb, 0xf0, 0xc7 \
28 } \
31 /**
32 * Information details about a characterdata change. Basically, we
33 * view all changes as replacements of a length of text at some offset
34 * with some other text (of possibly some other length).
36 struct CharacterDataChangeInfo {
37 /**
38 * True if this character data change is just an append.
40 bool mAppend;
42 /**
43 * The offset in the text where the change occurred.
45 uint32_t mChangeStart;
47 /**
48 * The offset such that mChangeEnd - mChangeStart is equal to the length of
49 * the text we removed. If this was a pure insert, append or a result of
50 * `splitText()` this is equal to mChangeStart.
52 uint32_t mChangeEnd;
54 uint32_t LengthOfRemovedText() const {
55 MOZ_ASSERT(mChangeStart <= mChangeEnd);
57 return mChangeEnd - mChangeStart;
60 /**
61 * The length of the text that was inserted in place of the removed text. If
62 * this was a pure text removal, this is 0.
64 uint32_t mReplaceLength;
66 /**
67 * The net result is that mChangeStart characters at the beginning of the
68 * text remained as they were. The next mChangeEnd - mChangeStart characters
69 * were removed, and mReplaceLength characters were inserted in their place.
70 * The text that used to begin at mChangeEnd now begins at
71 * mChangeStart + mReplaceLength.
74 struct MOZ_STACK_CLASS Details {
75 enum {
76 eMerge, // two text nodes are merged as a result of normalize()
77 eSplit // a text node is split as a result of splitText()
78 } mType;
79 /**
80 * For eMerge it's the text node that will be removed, for eSplit it's the
81 * new text node.
83 nsIContent* MOZ_NON_OWNING_REF mNextSibling;
86 /**
87 * Used for splitText() and normalize(), otherwise null.
89 Details* mDetails;
92 /**
93 * Mutation observer interface
95 * See nsINode::AddMutationObserver, nsINode::RemoveMutationObserver for how to
96 * attach or remove your observers. nsINode stores mutation observers using a
97 * mozilla::SafeDoublyLinkedList, which is a specialization of the
98 * DoublyLinkedList allowing for adding/removing elements while iterating.
99 * If a mutation observer is intended to be added to multiple nsINode instances,
100 * derive from nsMultiMutationObserver.
102 * WARNING: During these notifications, you are not allowed to perform
103 * any mutations to the current or any other document, or start a
104 * network load. If you need to perform such operations do that
105 * during the _last_ nsIDocumentObserver::EndUpdate notification. The
106 * exception for this is ParentChainChanged, where mutations should be
107 * done from an async event, as the notification might not be
108 * surrounded by BeginUpdate/EndUpdate calls.
110 class nsIMutationObserver
111 : public nsISupports,
112 mozilla::DoublyLinkedListElement<nsIMutationObserver> {
113 friend struct mozilla::GetDoublyLinkedListElement<nsIMutationObserver>;
115 public:
116 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMUTATION_OBSERVER_IID)
119 * Notification that the node value of a data node (text, cdata, pi, comment)
120 * will be changed.
122 * This notification is not sent when a piece of content is
123 * added/removed from the document (the other notifications are used
124 * for that).
126 * @param aContent The piece of content that changed. Is never null.
127 * @param aInfo The structure with information details about the change.
129 * @note Callers of this method might not hold a strong reference to the
130 * observer. The observer is responsible for making sure it stays
131 * alive for the duration of the call as needed. The observer may
132 * assume that this call will happen when there are script blockers on
133 * the stack.
135 virtual void CharacterDataWillChange(nsIContent* aContent,
136 const CharacterDataChangeInfo&) = 0;
139 * Notification that the node value of a data node (text, cdata, pi, comment)
140 * has changed.
142 * This notification is not sent when a piece of content is
143 * added/removed from the document (the other notifications are used
144 * for that).
146 * @param aContent The piece of content that changed. Is never null.
147 * @param aInfo The structure with information details about the change.
149 * @note Callers of this method might not hold a strong reference to the
150 * observer. The observer is responsible for making sure it stays
151 * alive for the duration of the call as needed. The observer may
152 * assume that this call will happen when there are script blockers on
153 * the stack.
155 virtual void CharacterDataChanged(nsIContent* aContent,
156 const CharacterDataChangeInfo&) = 0;
159 * Notification that an attribute of an element will change. This
160 * can happen before the BeginUpdate for the change and may not
161 * always be followed by an AttributeChanged (in particular, if the
162 * attribute doesn't actually change there will be no corresponding
163 * AttributeChanged).
165 * @param aContent The element whose attribute will change
166 * @param aNameSpaceID The namespace id of the changing attribute
167 * @param aAttribute The name of the changing attribute
168 * @param aModType Whether or not the attribute will be added, changed, or
169 * removed. The constants are defined in
170 * MutationEvent.webidl.
172 * @note Callers of this method might not hold a strong reference to the
173 * observer. The observer is responsible for making sure it stays
174 * alive for the duration of the call as needed. The observer may
175 * assume that this call will happen when there are script blockers on
176 * the stack.
178 virtual void AttributeWillChange(mozilla::dom::Element* aElement,
179 int32_t aNameSpaceID, nsAtom* aAttribute,
180 int32_t aModType) = 0;
183 * Notification that an attribute of an element has changed.
185 * @param aElement The element whose attribute changed
186 * @param aNameSpaceID The namespace id of the changed attribute
187 * @param aAttribute The name of the changed attribute
188 * @param aModType Whether or not the attribute was added, changed, or
189 * removed. The constants are defined in
190 * MutationEvent.webidl.
191 * @param aOldValue The old value, if either the old value or the new
192 * value are StoresOwnData() (or absent); null otherwise.
194 * @note Callers of this method might not hold a strong reference to the
195 * observer. The observer is responsible for making sure it stays
196 * alive for the duration of the call as needed. The observer may
197 * assume that this call will happen when there are script blockers on
198 * the stack.
200 virtual void AttributeChanged(mozilla::dom::Element* aElement,
201 int32_t aNameSpaceID, nsAtom* aAttribute,
202 int32_t aModType,
203 const nsAttrValue* aOldValue) = 0;
206 * Notification that an attribute of an element has been
207 * set to the value it already had.
209 * @param aElement The element whose attribute changed
210 * @param aNameSpaceID The namespace id of the changed attribute
211 * @param aAttribute The name of the changed attribute
213 virtual void AttributeSetToCurrentValue(mozilla::dom::Element* aElement,
214 int32_t aNameSpaceID,
215 nsAtom* aAttribute) {}
218 * Notification that one or more content nodes have been appended to the
219 * child list of another node in the tree.
221 * @param aFirstNewContent the first node appended.
223 * @note Callers of this method might not hold a strong reference to the
224 * observer. The observer is responsible for making sure it stays
225 * alive for the duration of the call as needed. The observer may
226 * assume that this call will happen when there are script blockers on
227 * the stack.
229 virtual void ContentAppended(nsIContent* aFirstNewContent) = 0;
232 * Notification that a content node has been inserted as child to another
233 * node in the tree.
235 * @param aChild The newly inserted child.
237 * @note Callers of this method might not hold a strong reference to the
238 * observer. The observer is responsible for making sure it stays
239 * alive for the duration of the call as needed. The observer may
240 * assume that this call will happen when there are script blockers on
241 * the stack.
243 virtual void ContentInserted(nsIContent* aChild) = 0;
246 * Notification that a content node has been removed from the child list of
247 * another node in the tree.
249 * @param aChild The child that was removed.
250 * @param aPreviousSibling The previous sibling to the child that was removed.
251 * Can be null if there was no previous sibling.
253 * @note Callers of this method might not hold a strong reference to the
254 * observer. The observer is responsible for making sure it stays
255 * alive for the duration of the call as needed. The observer may
256 * assume that this call will happen when there are script blockers on
257 * the stack.
259 virtual void ContentRemoved(nsIContent* aChild,
260 nsIContent* aPreviousSibling) = 0;
263 * The node is in the process of being destroyed. Calling QI on the node is
264 * not supported, however it is possible to get children and flags through
265 * nsINode as well as calling IsContent and casting to nsIContent to get
266 * attributes.
268 * NOTE: This notification is only called on observers registered directly
269 * on the node. This is because when the node is destroyed it can not have
270 * any ancestors. If you want to know when a descendant node is being
271 * removed from the observed node, use the ContentRemoved notification.
273 * @param aNode The node being destroyed.
275 * @note Callers of this method might not hold a strong reference to
276 * the observer. The observer is responsible for making sure it
277 * stays alive for the duration of the call as needed.
279 virtual void NodeWillBeDestroyed(nsINode* aNode) = 0;
282 * Notification that the node's parent chain has changed. This
283 * happens when either the node or one of its ancestors is inserted
284 * or removed as a child of another node.
286 * Note that when a node is inserted this notification is sent to
287 * all descendants of that node, since all such nodes have their
288 * parent chain changed.
290 * @param aContent The piece of content that had its parent changed.
292 * @note Callers of this method might not hold a strong reference to
293 * the observer. The observer is responsible for making sure it
294 * stays alive for the duration of the call as needed.
297 virtual void ParentChainChanged(nsIContent* aContent) = 0;
299 virtual void ARIAAttributeDefaultWillChange(mozilla::dom::Element* aElement,
300 nsAtom* aAttribute,
301 int32_t aModType) = 0;
302 virtual void ARIAAttributeDefaultChanged(mozilla::dom::Element* aElement,
303 nsAtom* aAttribute,
304 int32_t aModType) = 0;
306 enum : uint32_t {
307 kNone = 0,
308 kCharacterDataWillChange = 1 << 0,
309 kCharacterDataChanged = 1 << 1,
310 kAttributeWillChange = 1 << 2,
311 kAttributeChanged = 1 << 3,
312 kAttributeSetToCurrentValue = 1 << 4,
313 kContentAppended = 1 << 5,
314 kContentInserted = 1 << 6,
315 kContentRemoved = 1 << 7,
316 kNodeWillBeDestroyed = 1 << 8,
317 kParentChainChanged = 1 << 9,
318 kARIAAttributeDefaultWillChange = 1 << 10,
319 kARIAAttributeDefaultChanged = 1 << 11,
321 kBeginUpdate = 1 << 12,
322 kEndUpdate = 1 << 13,
323 kBeginLoad = 1 << 14,
324 kEndLoad = 1 << 15,
325 kElementStateChanged = 1 << 16,
327 kAnimationAdded = 1 << 17,
328 kAnimationChanged = 1 << 18,
329 kAnimationRemoved = 1 << 19,
331 kAll = 0xFFFFFFFF
334 void SetEnabledCallbacks(uint32_t aCallbacks) {
335 mEnabledCallbacks = aCallbacks;
338 bool IsCallbackEnabled(uint32_t aCallback) const {
339 return mEnabledCallbacks & aCallback;
342 private:
343 uint32_t mEnabledCallbacks = kAll;
346 NS_DEFINE_STATIC_IID_ACCESSOR(nsIMutationObserver, NS_IMUTATION_OBSERVER_IID)
348 #define NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATAWILLCHANGE \
349 virtual void CharacterDataWillChange( \
350 nsIContent* aContent, const CharacterDataChangeInfo& aInfo) override;
352 #define NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED \
353 virtual void CharacterDataChanged( \
354 nsIContent* aContent, const CharacterDataChangeInfo& aInfo) override;
356 #define NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE \
357 virtual void AttributeWillChange(mozilla::dom::Element* aElement, \
358 int32_t aNameSpaceID, nsAtom* aAttribute, \
359 int32_t aModType) override;
361 #define NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED \
362 virtual void AttributeChanged(mozilla::dom::Element* aElement, \
363 int32_t aNameSpaceID, nsAtom* aAttribute, \
364 int32_t aModType, \
365 const nsAttrValue* aOldValue) override;
367 #define NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED \
368 virtual void ContentAppended(nsIContent* aFirstNewContent) override;
370 #define NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED \
371 virtual void ContentInserted(nsIContent* aChild) override;
373 #define NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED \
374 virtual void ContentRemoved(nsIContent* aChild, \
375 nsIContent* aPreviousSibling) override;
377 #define NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED \
378 virtual void NodeWillBeDestroyed(nsINode* aNode) override;
380 #define NS_DECL_NSIMUTATIONOBSERVER_PARENTCHAINCHANGED \
381 virtual void ParentChainChanged(nsIContent* aContent) override;
383 #define NS_DECL_NSIMUTATIONOBSERVER_ARIAATTRIBUTEDEFAULTWILLCHANGE \
384 virtual void ARIAAttributeDefaultWillChange( \
385 mozilla::dom::Element* aElement, nsAtom* aAttribute, int32_t aModType) \
386 override;
388 #define NS_DECL_NSIMUTATIONOBSERVER_ARIAATTRIBUTEDEFAULTCHANGED \
389 virtual void ARIAAttributeDefaultChanged( \
390 mozilla::dom::Element* aElement, nsAtom* aAttribute, int32_t aModType) \
391 override;
393 #define NS_DECL_NSIMUTATIONOBSERVER \
394 NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATAWILLCHANGE \
395 NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED \
396 NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE \
397 NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED \
398 NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED \
399 NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED \
400 NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED \
401 NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED \
402 NS_DECL_NSIMUTATIONOBSERVER_PARENTCHAINCHANGED \
403 NS_DECL_NSIMUTATIONOBSERVER_ARIAATTRIBUTEDEFAULTWILLCHANGE \
404 NS_DECL_NSIMUTATIONOBSERVER_ARIAATTRIBUTEDEFAULTCHANGED
406 #define NS_IMPL_NSIMUTATIONOBSERVER_CORE_STUB(_class) \
407 void _class::NodeWillBeDestroyed(nsINode* aNode) {}
409 #define NS_IMPL_NSIMUTATIONOBSERVER_CONTENT(_class) \
410 void _class::CharacterDataWillChange( \
411 nsIContent* aContent, const CharacterDataChangeInfo& aInfo) {} \
412 void _class::CharacterDataChanged(nsIContent* aContent, \
413 const CharacterDataChangeInfo& aInfo) {} \
414 void _class::AttributeWillChange(mozilla::dom::Element* aElement, \
415 int32_t aNameSpaceID, nsAtom* aAttribute, \
416 int32_t aModType) {} \
417 void _class::AttributeChanged( \
418 mozilla::dom::Element* aElement, int32_t aNameSpaceID, \
419 nsAtom* aAttribute, int32_t aModType, const nsAttrValue* aOldValue) {} \
420 void _class::ContentAppended(nsIContent* aFirstNewContent) {} \
421 void _class::ContentInserted(nsIContent* aChild) {} \
422 void _class::ContentRemoved(nsIContent* aChild, \
423 nsIContent* aPreviousSibling) {} \
424 void _class::ParentChainChanged(nsIContent* aContent) {} \
425 void _class::ARIAAttributeDefaultWillChange( \
426 mozilla::dom::Element* aElement, nsAtom* aAttribute, int32_t aModType) { \
428 void _class::ARIAAttributeDefaultChanged( \
429 mozilla::dom::Element* aElement, nsAtom* aAttribute, int32_t aModType) { \
432 #endif /* nsIMutationObserver_h */