Line data Source code
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/. */
6 :
7 : #ifndef nsIMutationObserver_h
8 : #define nsIMutationObserver_h
9 :
10 : #include "nsISupports.h"
11 :
12 : class nsAttrValue;
13 : class nsIAtom;
14 : class nsIContent;
15 : class nsIDocument;
16 : class nsINode;
17 :
18 : namespace mozilla {
19 : namespace dom {
20 : class Element;
21 : } // namespace dom
22 : } // namespace mozilla
23 :
24 : #define NS_IMUTATION_OBSERVER_IID \
25 : { 0x6d674c17, 0x0fbc, 0x4633, \
26 : { 0x8f, 0x46, 0x73, 0x4e, 0x87, 0xeb, 0xf0, 0xc7 } }
27 :
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).
32 : */
33 : struct CharacterDataChangeInfo
34 : {
35 : /**
36 : * True if this character data change is just an append.
37 : */
38 : bool mAppend;
39 :
40 : /**
41 : * The offset in the text where the change occurred.
42 : */
43 : uint32_t mChangeStart;
44 :
45 : /**
46 : * The offset such that mChangeEnd - mChangeStart is equal to the length of
47 : * the text we removed. If this was a pure insert or append, this is equal to
48 : * mChangeStart.
49 : */
50 : uint32_t mChangeEnd;
51 :
52 : /**
53 : * The length of the text that was inserted in place of the removed text. If
54 : * this was a pure text removal, this is 0.
55 : */
56 : uint32_t mReplaceLength;
57 :
58 : /**
59 : * The net result is that mChangeStart characters at the beginning of the
60 : * text remained as they were. The next mChangeEnd - mChangeStart characters
61 : * were removed, and mReplaceLength characters were inserted in their place.
62 : * The text that used to begin at mChangeEnd now begins at
63 : * mChangeStart + mReplaceLength.
64 : */
65 :
66 : struct MOZ_STACK_CLASS Details {
67 : enum {
68 : eMerge, // two text nodes are merged as a result of normalize()
69 : eSplit // a text node is split as a result of splitText()
70 : } mType;
71 : /**
72 : * For eMerge it's the text node that will be removed, for eSplit it's the
73 : * new text node.
74 : */
75 : nsIContent* MOZ_NON_OWNING_REF mNextSibling;
76 : };
77 :
78 : /**
79 : * Used for splitText() and normalize(), otherwise null.
80 : */
81 : Details* mDetails;
82 : };
83 :
84 : /**
85 : * Mutation observer interface
86 : *
87 : * See nsINode::AddMutationObserver, nsINode::RemoveMutationObserver for how to
88 : * attach or remove your observers.
89 : *
90 : * WARNING: During these notifications, you are not allowed to perform
91 : * any mutations to the current or any other document, or start a
92 : * network load. If you need to perform such operations do that
93 : * during the _last_ nsIDocumentObserver::EndUpdate notification. The
94 : * expection for this is ParentChainChanged, where mutations should be
95 : * done from an async event, as the notification might not be
96 : * surrounded by BeginUpdate/EndUpdate calls.
97 : */
98 290 : class nsIMutationObserver : public nsISupports
99 : {
100 : public:
101 : NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMUTATION_OBSERVER_IID)
102 :
103 : /**
104 : * Notification that the node value of a data node (text, cdata, pi, comment)
105 : * will be changed.
106 : *
107 : * This notification is not sent when a piece of content is
108 : * added/removed from the document (the other notifications are used
109 : * for that).
110 : *
111 : * @param aDocument The owner-document of aContent. Can be null.
112 : * @param aContent The piece of content that changed. Is never null.
113 : * @param aInfo The structure with information details about the change.
114 : *
115 : * @note Callers of this method might not hold a strong reference to the
116 : * observer. The observer is responsible for making sure it stays
117 : * alive for the duration of the call as needed. The observer may
118 : * assume that this call will happen when there are script blockers on
119 : * the stack.
120 : */
121 : virtual void CharacterDataWillChange(nsIDocument *aDocument,
122 : nsIContent* aContent,
123 : CharacterDataChangeInfo* aInfo) = 0;
124 :
125 : /**
126 : * Notification that the node value of a data node (text, cdata, pi, comment)
127 : * has changed.
128 : *
129 : * This notification is not sent when a piece of content is
130 : * added/removed from the document (the other notifications are used
131 : * for that).
132 : *
133 : * @param aDocument The owner-document of aContent. Can be null.
134 : * @param aContent The piece of content that changed. Is never null.
135 : * @param aInfo The structure with information details about the change.
136 : *
137 : * @note Callers of this method might not hold a strong reference to the
138 : * observer. The observer is responsible for making sure it stays
139 : * alive for the duration of the call as needed. The observer may
140 : * assume that this call will happen when there are script blockers on
141 : * the stack.
142 : */
143 : virtual void CharacterDataChanged(nsIDocument *aDocument,
144 : nsIContent* aContent,
145 : CharacterDataChangeInfo* aInfo) = 0;
146 :
147 : /**
148 : * Notification that an attribute of an element will change. This
149 : * can happen before the BeginUpdate for the change and may not
150 : * always be followed by an AttributeChanged (in particular, if the
151 : * attribute doesn't actually change there will be no corresponding
152 : * AttributeChanged).
153 : *
154 : * @param aDocument The owner-document of aContent. Can be null.
155 : * @param aContent The element whose attribute will change
156 : * @param aNameSpaceID The namespace id of the changing attribute
157 : * @param aAttribute The name of the changing attribute
158 : * @param aModType Whether or not the attribute will be added, changed, or
159 : * removed. The constants are defined in
160 : * nsIDOMMutationEvent.h.
161 : * @param aNewValue The new value, IF it has been preparsed by
162 : * BeforeSetAttr, otherwise null.
163 : *
164 : * @note Callers of this method might not hold a strong reference to the
165 : * observer. The observer is responsible for making sure it stays
166 : * alive for the duration of the call as needed. The observer may
167 : * assume that this call will happen when there are script blockers on
168 : * the stack.
169 : */
170 : virtual void AttributeWillChange(nsIDocument* aDocument,
171 : mozilla::dom::Element* aElement,
172 : int32_t aNameSpaceID,
173 : nsIAtom* aAttribute,
174 : int32_t aModType,
175 : const nsAttrValue* aNewValue) = 0;
176 :
177 : /**
178 : * Notification that an attribute of an element has changed.
179 : *
180 : * @param aDocument The owner-document of aContent. Can be null.
181 : * @param aElement The element whose attribute changed
182 : * @param aNameSpaceID The namespace id of the changed attribute
183 : * @param aAttribute The name of the changed attribute
184 : * @param aModType Whether or not the attribute was added, changed, or
185 : * removed. The constants are defined in
186 : * nsIDOMMutationEvent.h.
187 : * @param aOldValue The old value, if either the old value or the new
188 : * value are StoresOwnData() (or absent); null otherwise.
189 : *
190 : * @note Callers of this method might not hold a strong reference to the
191 : * observer. The observer is responsible for making sure it stays
192 : * alive for the duration of the call as needed. The observer may
193 : * assume that this call will happen when there are script blockers on
194 : * the stack.
195 : */
196 : virtual void AttributeChanged(nsIDocument* aDocument,
197 : mozilla::dom::Element* aElement,
198 : int32_t aNameSpaceID,
199 : nsIAtom* aAttribute,
200 : int32_t aModType,
201 : const nsAttrValue* aOldValue) = 0;
202 :
203 : /**
204 : * Notification that the root of a native anonymous has been added
205 : * or removed.
206 : *
207 : * @param aDocument Owner doc of aContent
208 : * @param aContent Anonymous node that's been added or removed
209 : * @param aIsRemove True if it's a removal, false if an addition
210 : */
211 0 : virtual void NativeAnonymousChildListChange(nsIDocument* aDocument,
212 : nsIContent* aContent,
213 0 : bool aIsRemove) {}
214 :
215 : /**
216 : * Notification that an attribute of an element has been
217 : * set to the value it already had.
218 : *
219 : * @param aDocument The owner-document of aContent.
220 : * @param aElement The element whose attribute changed
221 : * @param aNameSpaceID The namespace id of the changed attribute
222 : * @param aAttribute The name of the changed attribute
223 : */
224 355 : virtual void AttributeSetToCurrentValue(nsIDocument* aDocument,
225 : mozilla::dom::Element* aElement,
226 : int32_t aNameSpaceID,
227 355 : nsIAtom* aAttribute) {}
228 :
229 : /**
230 : * Notification that one or more content nodes have been appended to the
231 : * child list of another node in the tree.
232 : *
233 : * @param aDocument The owner-document of aContent. Can be null.
234 : * @param aContainer The container that had new children appended. Is never
235 : * null.
236 : * @param aFirstNewContent the node at aIndexInContainer in aContainer.
237 : * @param aNewIndexInContainer the index in the container of the first
238 : * new child
239 : *
240 : * @note Callers of this method might not hold a strong reference to the
241 : * observer. The observer is responsible for making sure it stays
242 : * alive for the duration of the call as needed. The observer may
243 : * assume that this call will happen when there are script blockers on
244 : * the stack.
245 : */
246 : virtual void ContentAppended(nsIDocument *aDocument,
247 : nsIContent* aContainer,
248 : nsIContent* aFirstNewContent,
249 : int32_t aNewIndexInContainer) = 0;
250 :
251 : /**
252 : * Notification that a content node has been inserted as child to another
253 : * node in the tree.
254 : *
255 : * @param aDocument The owner-document of aContent, or, when aContainer
256 : * is null, the container that had the child inserted.
257 : * Can be null.
258 : * @param aContainer The container that had new a child inserted. Can be
259 : * null to indicate that the child was inserted into
260 : * aDocument
261 : * @param aChild The newly inserted child.
262 : * @param aIndexInContainer The index in the container of the new child.
263 : *
264 : * @note Callers of this method might not hold a strong reference to the
265 : * observer. The observer is responsible for making sure it stays
266 : * alive for the duration of the call as needed. The observer may
267 : * assume that this call will happen when there are script blockers on
268 : * the stack.
269 : */
270 : virtual void ContentInserted(nsIDocument *aDocument,
271 : nsIContent* aContainer,
272 : nsIContent* aChild,
273 : int32_t aIndexInContainer) = 0;
274 :
275 : /**
276 : * Notification that a content node has been removed from the child list of
277 : * another node in the tree.
278 : *
279 : * @param aDocument The owner-document of aContent, or, when aContainer
280 : * is null, the container that had the child removed.
281 : * Can be null.
282 : * @param aContainer The container that had new a child removed. Can be
283 : * null to indicate that the child was removed from
284 : * aDocument.
285 : * @param aChild The child that was removed.
286 : * @param aIndexInContainer The index in the container which the child used
287 : * to have.
288 : * @param aPreviousSibling The previous sibling to the child that was removed.
289 : * Can be null if there was no previous sibling.
290 : *
291 : * @note Callers of this method might not hold a strong reference to the
292 : * observer. The observer is responsible for making sure it stays
293 : * alive for the duration of the call as needed. The observer may
294 : * assume that this call will happen when there are script blockers on
295 : * the stack.
296 : */
297 : virtual void ContentRemoved(nsIDocument *aDocument,
298 : nsIContent* aContainer,
299 : nsIContent* aChild,
300 : int32_t aIndexInContainer,
301 : nsIContent* aPreviousSibling) = 0;
302 :
303 : /**
304 : * The node is in the process of being destroyed. Calling QI on the node is
305 : * not supported, however it is possible to get children and flags through
306 : * nsINode as well as calling IsNodeOfType(eCONTENT) and casting to
307 : * nsIContent to get attributes.
308 : *
309 : * NOTE: This notification is only called on observers registered directly
310 : * on the node. This is because when the node is destroyed it can not have
311 : * any ancestors. If you want to know when a descendant node is being
312 : * removed from the observed node, use the ContentRemoved notification.
313 : *
314 : * @param aNode The node being destroyed.
315 : *
316 : * @note Callers of this method might not hold a strong reference to
317 : * the observer. The observer is responsible for making sure it
318 : * stays alive for the duration of the call as needed.
319 : */
320 : virtual void NodeWillBeDestroyed(const nsINode *aNode) = 0;
321 :
322 : /**
323 : * Notification that the node's parent chain has changed. This
324 : * happens when either the node or one of its ancestors is inserted
325 : * or removed as a child of another node.
326 : *
327 : * Note that when a node is inserted this notification is sent to
328 : * all descendants of that node, since all such nodes have their
329 : * parent chain changed.
330 : *
331 : * @param aContent The piece of content that had its parent changed.
332 : *
333 : * @note Callers of this method might not hold a strong reference to
334 : * the observer. The observer is responsible for making sure it
335 : * stays alive for the duration of the call as needed.
336 : */
337 :
338 : virtual void ParentChainChanged(nsIContent *aContent) = 0;
339 : };
340 :
341 : NS_DEFINE_STATIC_IID_ACCESSOR(nsIMutationObserver, NS_IMUTATION_OBSERVER_IID)
342 :
343 : #define NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATAWILLCHANGE \
344 : virtual void CharacterDataWillChange(nsIDocument* aDocument, \
345 : nsIContent* aContent, \
346 : CharacterDataChangeInfo* aInfo) override;
347 :
348 : #define NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED \
349 : virtual void CharacterDataChanged(nsIDocument* aDocument, \
350 : nsIContent* aContent, \
351 : CharacterDataChangeInfo* aInfo) override;
352 :
353 : #define NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE \
354 : virtual void AttributeWillChange(nsIDocument* aDocument, \
355 : mozilla::dom::Element* aElement, \
356 : int32_t aNameSpaceID, \
357 : nsIAtom* aAttribute, \
358 : int32_t aModType, \
359 : const nsAttrValue* aNewValue) override;
360 :
361 : #define NS_DECL_NSIMUTATIONOBSERVER_NATIVEANONYMOUSCHILDLISTCHANGE \
362 : virtual void NativeAnonymousChildListChange(nsIDocument* aDocument, \
363 : nsIContent* aContent, \
364 : bool aIsRemove) override;
365 :
366 : #define NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED \
367 : virtual void AttributeChanged(nsIDocument* aDocument, \
368 : mozilla::dom::Element* aElement, \
369 : int32_t aNameSpaceID, \
370 : nsIAtom* aAttribute, \
371 : int32_t aModType, \
372 : const nsAttrValue* aOldValue) override;
373 :
374 : #define NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED \
375 : virtual void ContentAppended(nsIDocument* aDocument, \
376 : nsIContent* aContainer, \
377 : nsIContent* aFirstNewContent, \
378 : int32_t aNewIndexInContainer) override;
379 :
380 : #define NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED \
381 : virtual void ContentInserted(nsIDocument* aDocument, \
382 : nsIContent* aContainer, \
383 : nsIContent* aChild, \
384 : int32_t aIndexInContainer) override;
385 :
386 : #define NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED \
387 : virtual void ContentRemoved(nsIDocument* aDocument, \
388 : nsIContent* aContainer, \
389 : nsIContent* aChild, \
390 : int32_t aIndexInContainer, \
391 : nsIContent* aPreviousSibling) override;
392 :
393 : #define NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED \
394 : virtual void NodeWillBeDestroyed(const nsINode* aNode) override;
395 :
396 : #define NS_DECL_NSIMUTATIONOBSERVER_PARENTCHAINCHANGED \
397 : virtual void ParentChainChanged(nsIContent *aContent) override;
398 :
399 : #define NS_DECL_NSIMUTATIONOBSERVER \
400 : NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATAWILLCHANGE \
401 : NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED \
402 : NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE \
403 : NS_DECL_NSIMUTATIONOBSERVER_NATIVEANONYMOUSCHILDLISTCHANGE \
404 : NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED \
405 : NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED \
406 : NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED \
407 : NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED \
408 : NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED \
409 : NS_DECL_NSIMUTATIONOBSERVER_PARENTCHAINCHANGED
410 :
411 : #define NS_IMPL_NSIMUTATIONOBSERVER_CORE_STUB(_class) \
412 : void \
413 : _class::NodeWillBeDestroyed(const nsINode* aNode) \
414 : { \
415 : }
416 :
417 : #define NS_IMPL_NSIMUTATIONOBSERVER_CONTENT(_class) \
418 : void \
419 : _class::CharacterDataWillChange(nsIDocument* aDocument, \
420 : nsIContent* aContent, \
421 : CharacterDataChangeInfo* aInfo) \
422 : { \
423 : } \
424 : void \
425 : _class::CharacterDataChanged(nsIDocument* aDocument, \
426 : nsIContent* aContent, \
427 : CharacterDataChangeInfo* aInfo) \
428 : { \
429 : } \
430 : void \
431 : _class::AttributeWillChange(nsIDocument* aDocument, \
432 : mozilla::dom::Element* aElement, \
433 : int32_t aNameSpaceID, \
434 : nsIAtom* aAttribute, \
435 : int32_t aModType, \
436 : const nsAttrValue* aNewValue) \
437 : { \
438 : } \
439 : void \
440 : _class::NativeAnonymousChildListChange(nsIDocument* aDocument, \
441 : nsIContent* aContent, \
442 : bool aIsRemove) \
443 : { \
444 : } \
445 : void \
446 : _class::AttributeChanged(nsIDocument* aDocument, \
447 : mozilla::dom::Element* aElement, \
448 : int32_t aNameSpaceID, \
449 : nsIAtom* aAttribute, \
450 : int32_t aModType, \
451 : const nsAttrValue* aOldValue) \
452 : { \
453 : } \
454 : void \
455 : _class::ContentAppended(nsIDocument* aDocument, \
456 : nsIContent* aContainer, \
457 : nsIContent* aFirstNewContent, \
458 : int32_t aNewIndexInContainer) \
459 : { \
460 : } \
461 : void \
462 : _class::ContentInserted(nsIDocument* aDocument, \
463 : nsIContent* aContainer, \
464 : nsIContent* aChild, \
465 : int32_t aIndexInContainer) \
466 : { \
467 : } \
468 : void \
469 : _class::ContentRemoved(nsIDocument* aDocument, \
470 : nsIContent* aContainer, \
471 : nsIContent* aChild, \
472 : int32_t aIndexInContainer, \
473 : nsIContent* aPreviousSibling) \
474 : { \
475 : } \
476 : void \
477 : _class::ParentChainChanged(nsIContent *aContent) \
478 : { \
479 : }
480 :
481 :
482 : #endif /* nsIMutationObserver_h */
|