|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #ifndef nsINode_h___ |
|
7 #define nsINode_h___ |
|
8 |
|
9 #include "mozilla/Likely.h" |
|
10 #include "nsCOMPtr.h" // for member, local |
|
11 #include "nsGkAtoms.h" // for nsGkAtoms::baseURIProperty |
|
12 #include "nsIDOMNode.h" |
|
13 #include "nsINodeInfo.h" // member (in nsCOMPtr) |
|
14 #include "nsIVariant.h" // for use in GetUserData() |
|
15 #include "nsNodeInfoManager.h" // for use in NodePrincipal() |
|
16 #include "nsPropertyTable.h" // for typedefs |
|
17 #include "nsTObserverArray.h" // for member |
|
18 #include "mozilla/ErrorResult.h" |
|
19 #include "mozilla/MemoryReporting.h" |
|
20 #include "mozilla/dom/EventTarget.h" // for base class |
|
21 #include "js/TypeDecls.h" // for Handle, Value, JSObject, JSContext |
|
22 #include "mozilla/dom/DOMString.h" |
|
23 #include "mozilla/dom/BindingDeclarations.h" |
|
24 |
|
25 // Including 'windows.h' will #define GetClassInfo to something else. |
|
26 #ifdef XP_WIN |
|
27 #ifdef GetClassInfo |
|
28 #undef GetClassInfo |
|
29 #endif |
|
30 #endif |
|
31 |
|
32 class nsAttrAndChildArray; |
|
33 class nsChildContentList; |
|
34 class nsCSSSelectorList; |
|
35 class nsDOMAttributeMap; |
|
36 class nsIContent; |
|
37 class nsIDocument; |
|
38 class nsIDOMElement; |
|
39 class nsIDOMNodeList; |
|
40 class nsIDOMUserDataHandler; |
|
41 class nsIEditor; |
|
42 class nsIFrame; |
|
43 class nsIMutationObserver; |
|
44 class nsINodeList; |
|
45 class nsIPresShell; |
|
46 class nsIPrincipal; |
|
47 class nsIURI; |
|
48 class nsNodeSupportsWeakRefTearoff; |
|
49 class nsNodeWeakReference; |
|
50 class nsXPCClassInfo; |
|
51 class nsDOMMutationObserver; |
|
52 |
|
53 namespace mozilla { |
|
54 class EventListenerManager; |
|
55 namespace dom { |
|
56 /** |
|
57 * @return true if aChar is what the DOM spec defines as 'space character'. |
|
58 * http://dom.spec.whatwg.org/#space-character |
|
59 */ |
|
60 inline bool IsSpaceCharacter(char16_t aChar) { |
|
61 return aChar == ' ' || aChar == '\t' || aChar == '\n' || aChar == '\r' || |
|
62 aChar == '\f'; |
|
63 } |
|
64 inline bool IsSpaceCharacter(char aChar) { |
|
65 return aChar == ' ' || aChar == '\t' || aChar == '\n' || aChar == '\r' || |
|
66 aChar == '\f'; |
|
67 } |
|
68 struct BoxQuadOptions; |
|
69 struct ConvertCoordinateOptions; |
|
70 class DOMPoint; |
|
71 class DOMQuad; |
|
72 class DOMRectReadOnly; |
|
73 class Element; |
|
74 class EventHandlerNonNull; |
|
75 class OnErrorEventHandlerNonNull; |
|
76 template<typename T> class Optional; |
|
77 class TextOrElementOrDocument; |
|
78 struct DOMPointInit; |
|
79 } // namespace dom |
|
80 } // namespace mozilla |
|
81 |
|
82 #define NODE_FLAG_BIT(n_) (1U << (WRAPPER_CACHE_FLAGS_BITS_USED + (n_))) |
|
83 |
|
84 enum { |
|
85 // This bit will be set if the node has a listener manager. |
|
86 NODE_HAS_LISTENERMANAGER = NODE_FLAG_BIT(0), |
|
87 |
|
88 // Whether this node has had any properties set on it |
|
89 NODE_HAS_PROPERTIES = NODE_FLAG_BIT(1), |
|
90 |
|
91 // Whether this node is the root of an anonymous subtree. Note that this |
|
92 // need not be a native anonymous subtree. Any anonymous subtree, including |
|
93 // XBL-generated ones, will do. This flag is set-once: once a node has it, |
|
94 // it must not be removed. |
|
95 // NOTE: Should only be used on nsIContent nodes |
|
96 NODE_IS_ANONYMOUS_ROOT = NODE_FLAG_BIT(2), |
|
97 |
|
98 // Whether the node has some ancestor, possibly itself, that is native |
|
99 // anonymous. This includes ancestors crossing XBL scopes, in cases when an |
|
100 // XBL binding is attached to an element which has a native anonymous |
|
101 // ancestor. This flag is set-once: once a node has it, it must not be |
|
102 // removed. |
|
103 // NOTE: Should only be used on nsIContent nodes |
|
104 NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE = NODE_FLAG_BIT(3), |
|
105 |
|
106 // Whether this node is the root of a native anonymous (from the perspective |
|
107 // of its parent) subtree. This flag is set-once: once a node has it, it |
|
108 // must not be removed. |
|
109 // NOTE: Should only be used on nsIContent nodes |
|
110 NODE_IS_NATIVE_ANONYMOUS_ROOT = NODE_FLAG_BIT(4), |
|
111 |
|
112 // Forces the XBL code to treat this node as if it were |
|
113 // in the document and therefore should get bindings attached. |
|
114 NODE_FORCE_XBL_BINDINGS = NODE_FLAG_BIT(5), |
|
115 |
|
116 // Whether a binding manager may have a pointer to this |
|
117 NODE_MAY_BE_IN_BINDING_MNGR = NODE_FLAG_BIT(6), |
|
118 |
|
119 NODE_IS_EDITABLE = NODE_FLAG_BIT(7), |
|
120 |
|
121 // For all Element nodes, NODE_MAY_HAVE_CLASS is guaranteed to be set if the |
|
122 // node in fact has a class, but may be set even if it doesn't. |
|
123 NODE_MAY_HAVE_CLASS = NODE_FLAG_BIT(8), |
|
124 |
|
125 // Whether the node participates in a shadow tree. |
|
126 NODE_IS_IN_SHADOW_TREE = NODE_FLAG_BIT(9), |
|
127 |
|
128 // Node has an :empty or :-moz-only-whitespace selector |
|
129 NODE_HAS_EMPTY_SELECTOR = NODE_FLAG_BIT(10), |
|
130 |
|
131 // A child of the node has a selector such that any insertion, |
|
132 // removal, or appending of children requires restyling the parent. |
|
133 NODE_HAS_SLOW_SELECTOR = NODE_FLAG_BIT(11), |
|
134 |
|
135 // A child of the node has a :first-child, :-moz-first-node, |
|
136 // :only-child, :last-child or :-moz-last-node selector. |
|
137 NODE_HAS_EDGE_CHILD_SELECTOR = NODE_FLAG_BIT(12), |
|
138 |
|
139 // A child of the node has a selector such that any insertion or |
|
140 // removal of children requires restyling later siblings of that |
|
141 // element. Additionally (in this manner it is stronger than |
|
142 // NODE_HAS_SLOW_SELECTOR), if a child's style changes due to any |
|
143 // other content tree changes (e.g., the child changes to or from |
|
144 // matching :empty due to a grandchild insertion or removal), the |
|
145 // child's later siblings must also be restyled. |
|
146 NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS = NODE_FLAG_BIT(13), |
|
147 |
|
148 NODE_ALL_SELECTOR_FLAGS = NODE_HAS_EMPTY_SELECTOR | |
|
149 NODE_HAS_SLOW_SELECTOR | |
|
150 NODE_HAS_EDGE_CHILD_SELECTOR | |
|
151 NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS, |
|
152 |
|
153 NODE_ATTACH_BINDING_ON_POSTCREATE = NODE_FLAG_BIT(14), |
|
154 |
|
155 // This node needs to go through frame construction to get a frame (or |
|
156 // undisplayed entry). |
|
157 NODE_NEEDS_FRAME = NODE_FLAG_BIT(15), |
|
158 |
|
159 // At least one descendant in the flattened tree has NODE_NEEDS_FRAME set. |
|
160 // This should be set on every node on the flattened tree path between the |
|
161 // node(s) with NODE_NEEDS_FRAME and the root content. |
|
162 NODE_DESCENDANTS_NEED_FRAMES = NODE_FLAG_BIT(16), |
|
163 |
|
164 // Set if the node has the accesskey attribute set. |
|
165 NODE_HAS_ACCESSKEY = NODE_FLAG_BIT(17), |
|
166 |
|
167 // Set if the node has right-to-left directionality |
|
168 NODE_HAS_DIRECTION_RTL = NODE_FLAG_BIT(18), |
|
169 |
|
170 // Set if the node has left-to-right directionality |
|
171 NODE_HAS_DIRECTION_LTR = NODE_FLAG_BIT(19), |
|
172 |
|
173 NODE_ALL_DIRECTION_FLAGS = NODE_HAS_DIRECTION_LTR | |
|
174 NODE_HAS_DIRECTION_RTL, |
|
175 |
|
176 NODE_CHROME_ONLY_ACCESS = NODE_FLAG_BIT(20), |
|
177 |
|
178 NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS = NODE_FLAG_BIT(21), |
|
179 |
|
180 // Remaining bits are node type specific. |
|
181 NODE_TYPE_SPECIFIC_BITS_OFFSET = 22 |
|
182 }; |
|
183 |
|
184 // Make sure we have space for our bits |
|
185 #define ASSERT_NODE_FLAGS_SPACE(n) \ |
|
186 static_assert(WRAPPER_CACHE_FLAGS_BITS_USED + (n) <= 32, \ |
|
187 "Not enough space for our bits") |
|
188 ASSERT_NODE_FLAGS_SPACE(NODE_TYPE_SPECIFIC_BITS_OFFSET); |
|
189 |
|
190 /** |
|
191 * Class used to detect unexpected mutations. To use the class create an |
|
192 * nsMutationGuard on the stack before unexpected mutations could occur. |
|
193 * You can then at any time call Mutated to check if any unexpected mutations |
|
194 * have occurred. |
|
195 * |
|
196 * When a guard is instantiated sMutationCount is set to 300. It is then |
|
197 * decremented by every mutation (capped at 0). This means that we can only |
|
198 * detect 300 mutations during the lifetime of a single guard, however that |
|
199 * should be more then we ever care about as we usually only care if more then |
|
200 * one mutation has occurred. |
|
201 * |
|
202 * When the guard goes out of scope it will adjust sMutationCount so that over |
|
203 * the lifetime of the guard the guard itself has not affected sMutationCount, |
|
204 * while mutations that happened while the guard was alive still will. This |
|
205 * allows a guard to be instantiated even if there is another guard higher up |
|
206 * on the callstack watching for mutations. |
|
207 * |
|
208 * The only thing that has to be avoided is for an outer guard to be used |
|
209 * while an inner guard is alive. This can be avoided by only ever |
|
210 * instantiating a single guard per scope and only using the guard in the |
|
211 * current scope. |
|
212 */ |
|
213 class nsMutationGuard { |
|
214 public: |
|
215 nsMutationGuard() |
|
216 { |
|
217 mDelta = eMaxMutations - sMutationCount; |
|
218 sMutationCount = eMaxMutations; |
|
219 } |
|
220 ~nsMutationGuard() |
|
221 { |
|
222 sMutationCount = |
|
223 mDelta > sMutationCount ? 0 : sMutationCount - mDelta; |
|
224 } |
|
225 |
|
226 /** |
|
227 * Returns true if any unexpected mutations have occurred. You can pass in |
|
228 * an 8-bit ignore count to ignore a number of expected mutations. |
|
229 */ |
|
230 bool Mutated(uint8_t aIgnoreCount) |
|
231 { |
|
232 return sMutationCount < static_cast<uint32_t>(eMaxMutations - aIgnoreCount); |
|
233 } |
|
234 |
|
235 // This function should be called whenever a mutation that we want to keep |
|
236 // track of happen. For now this is only done when children are added or |
|
237 // removed, but we might do it for attribute changes too in the future. |
|
238 static void DidMutate() |
|
239 { |
|
240 if (sMutationCount) { |
|
241 --sMutationCount; |
|
242 } |
|
243 } |
|
244 |
|
245 private: |
|
246 // mDelta is the amount sMutationCount was adjusted when the guard was |
|
247 // initialized. It is needed so that we can undo that adjustment once |
|
248 // the guard dies. |
|
249 uint32_t mDelta; |
|
250 |
|
251 // The value 300 is not important, as long as it is bigger then anything |
|
252 // ever passed to Mutated(). |
|
253 enum { eMaxMutations = 300 }; |
|
254 |
|
255 |
|
256 // sMutationCount is a global mutation counter which is decreased by one at |
|
257 // every mutation. It is capped at 0 to avoid wrapping. |
|
258 // Its value is always between 0 and 300, inclusive. |
|
259 static uint32_t sMutationCount; |
|
260 }; |
|
261 |
|
262 // This should be used for any nsINode sub-class that has fields of its own |
|
263 // that it needs to measure; any sub-class that doesn't use it will inherit |
|
264 // SizeOfExcludingThis from its super-class. SizeOfIncludingThis() need not be |
|
265 // defined, it is inherited from nsINode. |
|
266 // This macro isn't actually specific to nodes, and bug 956400 will move it into MFBT. |
|
267 #define NS_DECL_SIZEOF_EXCLUDING_THIS \ |
|
268 virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; |
|
269 |
|
270 // Categories of node properties |
|
271 // 0 is global. |
|
272 #define DOM_USER_DATA 1 |
|
273 #define DOM_USER_DATA_HANDLER 2 |
|
274 #define SMIL_MAPPED_ATTR_ANIMVAL 3 |
|
275 |
|
276 // IID for the nsINode interface |
|
277 #define NS_INODE_IID \ |
|
278 { 0x77a62cd0, 0xb34f, 0x42cb, \ |
|
279 { 0x94, 0x52, 0xae, 0xb2, 0x4d, 0x93, 0x2c, 0xb4 } } |
|
280 |
|
281 /** |
|
282 * An internal interface that abstracts some DOMNode-related parts that both |
|
283 * nsIContent and nsIDocument share. An instance of this interface has a list |
|
284 * of nsIContent children and provides access to them. |
|
285 */ |
|
286 class nsINode : public mozilla::dom::EventTarget |
|
287 { |
|
288 public: |
|
289 typedef mozilla::dom::BoxQuadOptions BoxQuadOptions; |
|
290 typedef mozilla::dom::ConvertCoordinateOptions ConvertCoordinateOptions; |
|
291 typedef mozilla::dom::DOMPoint DOMPoint; |
|
292 typedef mozilla::dom::DOMPointInit DOMPointInit; |
|
293 typedef mozilla::dom::DOMQuad DOMQuad; |
|
294 typedef mozilla::dom::DOMRectReadOnly DOMRectReadOnly; |
|
295 typedef mozilla::dom::TextOrElementOrDocument TextOrElementOrDocument; |
|
296 typedef mozilla::ErrorResult ErrorResult; |
|
297 |
|
298 NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODE_IID) |
|
299 |
|
300 // Among the sub-classes that inherit (directly or indirectly) from nsINode, |
|
301 // measurement of the following members may be added later if DMD finds it is |
|
302 // worthwhile: |
|
303 // - nsGenericHTMLElement: mForm, mFieldSet |
|
304 // - nsGenericHTMLFrameElement: mFrameLoader (bug 672539) |
|
305 // - HTMLBodyElement: mContentStyleRule |
|
306 // - HTMLDataListElement: mOptions |
|
307 // - HTMLFieldSetElement: mElements, mDependentElements, mFirstLegend |
|
308 // - HTMLFormElement: many! |
|
309 // - HTMLFrameSetElement: mRowSpecs, mColSpecs |
|
310 // - HTMLInputElement: mInputData, mFiles, mFileList, mStaticDocfileList |
|
311 // - nsHTMLMapElement: mAreas |
|
312 // - HTMLMediaElement: many! |
|
313 // - nsHTMLOutputElement: mDefaultValue, mTokenList |
|
314 // - nsHTMLRowElement: mCells |
|
315 // - nsHTMLSelectElement: mOptions, mRestoreState |
|
316 // - nsHTMLTableElement: mTBodies, mRows, mTableInheritedAttributes |
|
317 // - nsHTMLTableSectionElement: mRows |
|
318 // - nsHTMLTextAreaElement: mControllers, mState |
|
319 // |
|
320 // The following members don't need to be measured: |
|
321 // - nsIContent: mPrimaryFrame, because it's non-owning and measured elsewhere |
|
322 // |
|
323 NS_DECL_SIZEOF_EXCLUDING_THIS |
|
324 |
|
325 // SizeOfIncludingThis doesn't need to be overridden by sub-classes because |
|
326 // sub-classes of nsINode are guaranteed to be laid out in memory in such a |
|
327 // way that |this| points to the start of the allocated object, even in |
|
328 // methods of nsINode's sub-classes, and so |aMallocSizeOf(this)| is always |
|
329 // safe to call no matter which object it was invoked on. |
|
330 virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { |
|
331 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); |
|
332 } |
|
333 |
|
334 friend class nsNodeUtils; |
|
335 friend class nsNodeWeakReference; |
|
336 friend class nsNodeSupportsWeakRefTearoff; |
|
337 friend class nsAttrAndChildArray; |
|
338 |
|
339 #ifdef MOZILLA_INTERNAL_API |
|
340 nsINode(already_AddRefed<nsINodeInfo>& aNodeInfo) |
|
341 : mNodeInfo(aNodeInfo), |
|
342 mParent(nullptr), |
|
343 mBoolFlags(0), |
|
344 mNextSibling(nullptr), |
|
345 mPreviousSibling(nullptr), |
|
346 mFirstChild(nullptr), |
|
347 mSubtreeRoot(MOZ_THIS_IN_INITIALIZER_LIST()), |
|
348 mSlots(nullptr) |
|
349 { |
|
350 SetIsDOMBinding(); |
|
351 } |
|
352 #endif |
|
353 |
|
354 virtual ~nsINode(); |
|
355 |
|
356 /** |
|
357 * Bit-flags to pass (or'ed together) to IsNodeOfType() |
|
358 */ |
|
359 enum { |
|
360 /** nsIContent nodes */ |
|
361 eCONTENT = 1 << 0, |
|
362 /** nsIDocument nodes */ |
|
363 eDOCUMENT = 1 << 1, |
|
364 /** nsIAttribute nodes */ |
|
365 eATTRIBUTE = 1 << 2, |
|
366 /** text nodes */ |
|
367 eTEXT = 1 << 3, |
|
368 /** xml processing instructions */ |
|
369 ePROCESSING_INSTRUCTION = 1 << 4, |
|
370 /** comment nodes */ |
|
371 eCOMMENT = 1 << 5, |
|
372 /** form control elements */ |
|
373 eHTML_FORM_CONTROL = 1 << 6, |
|
374 /** document fragments */ |
|
375 eDOCUMENT_FRAGMENT = 1 << 7, |
|
376 /** data nodes (comments, PIs, text). Nodes of this type always |
|
377 returns a non-null value for nsIContent::GetText() */ |
|
378 eDATA_NODE = 1 << 8, |
|
379 /** HTMLMediaElement */ |
|
380 eMEDIA = 1 << 9, |
|
381 /** animation elements */ |
|
382 eANIMATION = 1 << 10, |
|
383 /** filter elements that implement SVGFilterPrimitiveStandardAttributes */ |
|
384 eFILTER = 1 << 11 |
|
385 }; |
|
386 |
|
387 /** |
|
388 * API for doing a quick check if a content is of a given |
|
389 * type, such as Text, Document, Comment ... Use this when you can instead of |
|
390 * checking the tag. |
|
391 * |
|
392 * @param aFlags what types you want to test for (see above) |
|
393 * @return whether the content matches ALL flags passed in |
|
394 */ |
|
395 virtual bool IsNodeOfType(uint32_t aFlags) const = 0; |
|
396 |
|
397 virtual JSObject* WrapObject(JSContext *aCx) MOZ_OVERRIDE; |
|
398 |
|
399 protected: |
|
400 /** |
|
401 * WrapNode is called from WrapObject to actually wrap this node, WrapObject |
|
402 * does some additional checks and fix-up that's common to all nodes. WrapNode |
|
403 * should just call the DOM binding's Wrap function. |
|
404 */ |
|
405 virtual JSObject* WrapNode(JSContext *aCx) |
|
406 { |
|
407 MOZ_ASSERT(!IsDOMBinding(), "Someone forgot to override WrapNode"); |
|
408 return nullptr; |
|
409 } |
|
410 |
|
411 // Subclasses that wish to override the parent behavior should return the |
|
412 // result of GetParentObjectIntenral, which handles the XBL scope stuff. |
|
413 // |
|
414 mozilla::dom::ParentObject GetParentObjectInternal(nsINode* aNativeParent) const { |
|
415 mozilla::dom::ParentObject p(aNativeParent); |
|
416 // Note that mUseXBLScope is a no-op for chrome, and other places where we |
|
417 // don't use XBL scopes. |
|
418 p.mUseXBLScope = IsInAnonymousSubtree() && !IsAnonymousContentInSVGUseSubtree(); |
|
419 return p; |
|
420 } |
|
421 |
|
422 public: |
|
423 mozilla::dom::ParentObject GetParentObject() const; // Implemented in nsIDocument.h |
|
424 |
|
425 /** |
|
426 * Return whether the node is an Element node |
|
427 */ |
|
428 bool IsElement() const { |
|
429 return GetBoolFlag(NodeIsElement); |
|
430 } |
|
431 |
|
432 /** |
|
433 * Return this node as an Element. Should only be used for nodes |
|
434 * for which IsElement() is true. This is defined inline in Element.h. |
|
435 */ |
|
436 mozilla::dom::Element* AsElement(); |
|
437 const mozilla::dom::Element* AsElement() const; |
|
438 |
|
439 /** |
|
440 * Return this node as nsIContent. Should only be used for nodes for which |
|
441 * IsContent() is true. This is defined inline in nsIContent.h. |
|
442 */ |
|
443 nsIContent* AsContent(); |
|
444 const nsIContent* AsContent() const |
|
445 { |
|
446 return const_cast<nsINode*>(this)->AsContent(); |
|
447 } |
|
448 |
|
449 virtual nsIDOMNode* AsDOMNode() = 0; |
|
450 |
|
451 /** |
|
452 * Return if this node has any children. |
|
453 */ |
|
454 bool HasChildren() const { return !!mFirstChild; } |
|
455 |
|
456 /** |
|
457 * Get the number of children |
|
458 * @return the number of children |
|
459 */ |
|
460 virtual uint32_t GetChildCount() const = 0; |
|
461 |
|
462 /** |
|
463 * Get a child by index |
|
464 * @param aIndex the index of the child to get |
|
465 * @return the child, or null if index out of bounds |
|
466 */ |
|
467 virtual nsIContent* GetChildAt(uint32_t aIndex) const = 0; |
|
468 |
|
469 /** |
|
470 * Get a raw pointer to the child array. This should only be used if you |
|
471 * plan to walk a bunch of the kids, promise to make sure that nothing ever |
|
472 * mutates (no attribute changes, not DOM tree changes, no script execution, |
|
473 * NOTHING), and will never ever peform an out-of-bounds access here. This |
|
474 * method may return null if there are no children, or it may return a |
|
475 * garbage pointer. In all cases the out param will be set to the number of |
|
476 * children. |
|
477 */ |
|
478 virtual nsIContent * const * GetChildArray(uint32_t* aChildCount) const = 0; |
|
479 |
|
480 /** |
|
481 * Get the index of a child within this content |
|
482 * @param aPossibleChild the child to get the index of. |
|
483 * @return the index of the child, or -1 if not a child |
|
484 * |
|
485 * If the return value is not -1, then calling GetChildAt() with that value |
|
486 * will return aPossibleChild. |
|
487 */ |
|
488 virtual int32_t IndexOf(const nsINode* aPossibleChild) const = 0; |
|
489 |
|
490 /** |
|
491 * Return the "owner document" of this node. Note that this is not the same |
|
492 * as the DOM ownerDocument -- that's null for Document nodes, whereas for a |
|
493 * nsIDocument GetOwnerDocument returns the document itself. For nsIContent |
|
494 * implementations the two are the same. |
|
495 */ |
|
496 nsIDocument *OwnerDoc() const |
|
497 { |
|
498 return mNodeInfo->GetDocument(); |
|
499 } |
|
500 |
|
501 /** |
|
502 * Return the "owner document" of this node as an nsINode*. Implemented |
|
503 * in nsIDocument.h. |
|
504 */ |
|
505 nsINode *OwnerDocAsNode() const; |
|
506 |
|
507 /** |
|
508 * Returns true if the content has an ancestor that is a document. |
|
509 * |
|
510 * @return whether this content is in a document tree |
|
511 */ |
|
512 bool IsInDoc() const |
|
513 { |
|
514 return GetBoolFlag(IsInDocument); |
|
515 } |
|
516 |
|
517 /** |
|
518 * Get the document that this content is currently in, if any. This will be |
|
519 * null if the content has no ancestor that is a document. |
|
520 * |
|
521 * @return the current document |
|
522 */ |
|
523 nsIDocument *GetCurrentDoc() const |
|
524 { |
|
525 return IsInDoc() ? OwnerDoc() : nullptr; |
|
526 } |
|
527 |
|
528 /** |
|
529 * The values returned by this function are the ones defined for |
|
530 * nsIDOMNode.nodeType |
|
531 */ |
|
532 uint16_t NodeType() const |
|
533 { |
|
534 return mNodeInfo->NodeType(); |
|
535 } |
|
536 const nsString& NodeName() const |
|
537 { |
|
538 return mNodeInfo->NodeName(); |
|
539 } |
|
540 const nsString& LocalName() const |
|
541 { |
|
542 return mNodeInfo->LocalName(); |
|
543 } |
|
544 |
|
545 /** |
|
546 * Get the tag for this element. This will always return a non-null atom |
|
547 * pointer (as implied by the naming of the method). For elements this is |
|
548 * the non-namespaced tag, and for other nodes it's something like "#text", |
|
549 * "#comment", "#document", etc. |
|
550 */ |
|
551 nsIAtom* Tag() const |
|
552 { |
|
553 return mNodeInfo->NameAtom(); |
|
554 } |
|
555 |
|
556 /** |
|
557 * Insert a content node at a particular index. This method handles calling |
|
558 * BindToTree on the child appropriately. |
|
559 * |
|
560 * @param aKid the content to insert |
|
561 * @param aIndex the index it is being inserted at (the index it will have |
|
562 * after it is inserted) |
|
563 * @param aNotify whether to notify the document (current document for |
|
564 * nsIContent, and |this| for nsIDocument) that the insert has |
|
565 * occurred |
|
566 * |
|
567 * @throws NS_ERROR_DOM_HIERARCHY_REQUEST_ERR if one attempts to have more |
|
568 * than one element node as a child of a document. Doing this will also |
|
569 * assert -- you shouldn't be doing it! Check with |
|
570 * nsIDocument::GetRootElement() first if you're not sure. Apart from this |
|
571 * one constraint, this doesn't do any checking on whether aKid is a valid |
|
572 * child of |this|. |
|
573 * |
|
574 * @throws NS_ERROR_OUT_OF_MEMORY in some cases (from BindToTree). |
|
575 */ |
|
576 virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex, |
|
577 bool aNotify) = 0; |
|
578 |
|
579 /** |
|
580 * Append a content node to the end of the child list. This method handles |
|
581 * calling BindToTree on the child appropriately. |
|
582 * |
|
583 * @param aKid the content to append |
|
584 * @param aNotify whether to notify the document (current document for |
|
585 * nsIContent, and |this| for nsIDocument) that the append has |
|
586 * occurred |
|
587 * |
|
588 * @throws NS_ERROR_DOM_HIERARCHY_REQUEST_ERR if one attempts to have more |
|
589 * than one element node as a child of a document. Doing this will also |
|
590 * assert -- you shouldn't be doing it! Check with |
|
591 * nsIDocument::GetRootElement() first if you're not sure. Apart from this |
|
592 * one constraint, this doesn't do any checking on whether aKid is a valid |
|
593 * child of |this|. |
|
594 * |
|
595 * @throws NS_ERROR_OUT_OF_MEMORY in some cases (from BindToTree). |
|
596 */ |
|
597 nsresult AppendChildTo(nsIContent* aKid, bool aNotify) |
|
598 { |
|
599 return InsertChildAt(aKid, GetChildCount(), aNotify); |
|
600 } |
|
601 |
|
602 /** |
|
603 * Remove a child from this node. This method handles calling UnbindFromTree |
|
604 * on the child appropriately. |
|
605 * |
|
606 * @param aIndex the index of the child to remove |
|
607 * @param aNotify whether to notify the document (current document for |
|
608 * nsIContent, and |this| for nsIDocument) that the remove has |
|
609 * occurred |
|
610 * |
|
611 * Note: If there is no child at aIndex, this method will simply do nothing. |
|
612 */ |
|
613 virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) = 0; |
|
614 |
|
615 /** |
|
616 * Get a property associated with this node. |
|
617 * |
|
618 * @param aPropertyName name of property to get. |
|
619 * @param aStatus out parameter for storing resulting status. |
|
620 * Set to NS_PROPTABLE_PROP_NOT_THERE if the property |
|
621 * is not set. |
|
622 * @return the property. Null if the property is not set |
|
623 * (though a null return value does not imply the |
|
624 * property was not set, i.e. it can be set to null). |
|
625 */ |
|
626 void* GetProperty(nsIAtom *aPropertyName, |
|
627 nsresult *aStatus = nullptr) const |
|
628 { |
|
629 return GetProperty(0, aPropertyName, aStatus); |
|
630 } |
|
631 |
|
632 /** |
|
633 * Get a property associated with this node. |
|
634 * |
|
635 * @param aCategory category of property to get. |
|
636 * @param aPropertyName name of property to get. |
|
637 * @param aStatus out parameter for storing resulting status. |
|
638 * Set to NS_PROPTABLE_PROP_NOT_THERE if the property |
|
639 * is not set. |
|
640 * @return the property. Null if the property is not set |
|
641 * (though a null return value does not imply the |
|
642 * property was not set, i.e. it can be set to null). |
|
643 */ |
|
644 virtual void* GetProperty(uint16_t aCategory, |
|
645 nsIAtom *aPropertyName, |
|
646 nsresult *aStatus = nullptr) const; |
|
647 |
|
648 /** |
|
649 * Set a property to be associated with this node. This will overwrite an |
|
650 * existing value if one exists. The existing value is destroyed using the |
|
651 * destructor function given when that value was set. |
|
652 * |
|
653 * @param aPropertyName name of property to set. |
|
654 * @param aValue new value of property. |
|
655 * @param aDtor destructor function to be used when this property |
|
656 * is destroyed. |
|
657 * @param aTransfer if true the property will not be deleted when the |
|
658 * ownerDocument of the node changes, if false it |
|
659 * will be deleted. |
|
660 * |
|
661 * @return NS_PROPTABLE_PROP_OVERWRITTEN (success value) if the property |
|
662 * was already set |
|
663 * @throws NS_ERROR_OUT_OF_MEMORY if that occurs |
|
664 */ |
|
665 nsresult SetProperty(nsIAtom *aPropertyName, |
|
666 void *aValue, |
|
667 NSPropertyDtorFunc aDtor = nullptr, |
|
668 bool aTransfer = false) |
|
669 { |
|
670 return SetProperty(0, aPropertyName, aValue, aDtor, aTransfer); |
|
671 } |
|
672 |
|
673 /** |
|
674 * Set a property to be associated with this node. This will overwrite an |
|
675 * existing value if one exists. The existing value is destroyed using the |
|
676 * destructor function given when that value was set. |
|
677 * |
|
678 * @param aCategory category of property to set. |
|
679 * @param aPropertyName name of property to set. |
|
680 * @param aValue new value of property. |
|
681 * @param aDtor destructor function to be used when this property |
|
682 * is destroyed. |
|
683 * @param aTransfer if true the property will not be deleted when the |
|
684 * ownerDocument of the node changes, if false it |
|
685 * will be deleted. |
|
686 * @param aOldValue [out] previous value of property. |
|
687 * |
|
688 * @return NS_PROPTABLE_PROP_OVERWRITTEN (success value) if the property |
|
689 * was already set |
|
690 * @throws NS_ERROR_OUT_OF_MEMORY if that occurs |
|
691 */ |
|
692 virtual nsresult SetProperty(uint16_t aCategory, |
|
693 nsIAtom *aPropertyName, |
|
694 void *aValue, |
|
695 NSPropertyDtorFunc aDtor = nullptr, |
|
696 bool aTransfer = false, |
|
697 void **aOldValue = nullptr); |
|
698 |
|
699 /** |
|
700 * A generic destructor for property values allocated with new. |
|
701 */ |
|
702 template<class T> |
|
703 static void DeleteProperty(void *, nsIAtom *, void *aPropertyValue, void *) |
|
704 { |
|
705 delete static_cast<T *>(aPropertyValue); |
|
706 } |
|
707 |
|
708 /** |
|
709 * Destroys a property associated with this node. The value is destroyed |
|
710 * using the destruction function given when that value was set. |
|
711 * |
|
712 * @param aPropertyName name of property to destroy. |
|
713 */ |
|
714 void DeleteProperty(nsIAtom *aPropertyName) |
|
715 { |
|
716 DeleteProperty(0, aPropertyName); |
|
717 } |
|
718 |
|
719 /** |
|
720 * Destroys a property associated with this node. The value is destroyed |
|
721 * using the destruction function given when that value was set. |
|
722 * |
|
723 * @param aCategory category of property to destroy. |
|
724 * @param aPropertyName name of property to destroy. |
|
725 */ |
|
726 virtual void DeleteProperty(uint16_t aCategory, nsIAtom *aPropertyName); |
|
727 |
|
728 /** |
|
729 * Unset a property associated with this node. The value will not be |
|
730 * destroyed but rather returned. It is the caller's responsibility to |
|
731 * destroy the value after that point. |
|
732 * |
|
733 * @param aPropertyName name of property to unset. |
|
734 * @param aStatus out parameter for storing resulting status. |
|
735 * Set to NS_PROPTABLE_PROP_NOT_THERE if the property |
|
736 * is not set. |
|
737 * @return the property. Null if the property is not set |
|
738 * (though a null return value does not imply the |
|
739 * property was not set, i.e. it can be set to null). |
|
740 */ |
|
741 void* UnsetProperty(nsIAtom *aPropertyName, |
|
742 nsresult *aStatus = nullptr) |
|
743 { |
|
744 return UnsetProperty(0, aPropertyName, aStatus); |
|
745 } |
|
746 |
|
747 /** |
|
748 * Unset a property associated with this node. The value will not be |
|
749 * destroyed but rather returned. It is the caller's responsibility to |
|
750 * destroy the value after that point. |
|
751 * |
|
752 * @param aCategory category of property to unset. |
|
753 * @param aPropertyName name of property to unset. |
|
754 * @param aStatus out parameter for storing resulting status. |
|
755 * Set to NS_PROPTABLE_PROP_NOT_THERE if the property |
|
756 * is not set. |
|
757 * @return the property. Null if the property is not set |
|
758 * (though a null return value does not imply the |
|
759 * property was not set, i.e. it can be set to null). |
|
760 */ |
|
761 virtual void* UnsetProperty(uint16_t aCategory, |
|
762 nsIAtom *aPropertyName, |
|
763 nsresult *aStatus = nullptr); |
|
764 |
|
765 bool HasProperties() const |
|
766 { |
|
767 return HasFlag(NODE_HAS_PROPERTIES); |
|
768 } |
|
769 |
|
770 /** |
|
771 * Return the principal of this node. This is guaranteed to never be a null |
|
772 * pointer. |
|
773 */ |
|
774 nsIPrincipal* NodePrincipal() const { |
|
775 return mNodeInfo->NodeInfoManager()->DocumentPrincipal(); |
|
776 } |
|
777 |
|
778 /** |
|
779 * Get the parent nsIContent for this node. |
|
780 * @return the parent, or null if no parent or the parent is not an nsIContent |
|
781 */ |
|
782 nsIContent* GetParent() const { |
|
783 return MOZ_LIKELY(GetBoolFlag(ParentIsContent)) ? |
|
784 reinterpret_cast<nsIContent*>(mParent) : nullptr; |
|
785 } |
|
786 |
|
787 /** |
|
788 * Get the parent nsINode for this node. This can be either an nsIContent, |
|
789 * an nsIDocument or an nsIAttribute. |
|
790 * @return the parent node |
|
791 */ |
|
792 nsINode* GetParentNode() const |
|
793 { |
|
794 return mParent; |
|
795 } |
|
796 |
|
797 /** |
|
798 * Get the parent nsINode for this node if it is an Element. |
|
799 * @return the parent node |
|
800 */ |
|
801 mozilla::dom::Element* GetParentElement() const |
|
802 { |
|
803 return mParent && mParent->IsElement() ? mParent->AsElement() : nullptr; |
|
804 } |
|
805 |
|
806 /** |
|
807 * Get the root of the subtree this node belongs to. This never returns |
|
808 * null. It may return 'this' (e.g. for document nodes, and nodes that |
|
809 * are the roots of disconnected subtrees). |
|
810 */ |
|
811 nsINode* SubtreeRoot() const |
|
812 { |
|
813 // There are three cases of interest here. nsINodes that are really: |
|
814 // 1. nsIDocument nodes - Are always in the document. |
|
815 // 2. nsIContent nodes - Are either in the document, or mSubtreeRoot |
|
816 // is updated in BindToTree/UnbindFromTree. |
|
817 // 3. nsIAttribute nodes - Are never in the document, and mSubtreeRoot |
|
818 // is always 'this' (as set in nsINode's ctor). |
|
819 nsINode* node = IsInDoc() ? OwnerDocAsNode() : mSubtreeRoot; |
|
820 NS_ASSERTION(node, "Should always have a node here!"); |
|
821 #ifdef DEBUG |
|
822 { |
|
823 const nsINode* slowNode = this; |
|
824 const nsINode* iter = slowNode; |
|
825 while ((iter = iter->GetParentNode())) { |
|
826 slowNode = iter; |
|
827 } |
|
828 |
|
829 NS_ASSERTION(slowNode == node, "These should always be in sync!"); |
|
830 } |
|
831 #endif |
|
832 return node; |
|
833 } |
|
834 |
|
835 /** |
|
836 * See nsIDOMEventTarget |
|
837 */ |
|
838 NS_DECL_NSIDOMEVENTTARGET |
|
839 |
|
840 virtual mozilla::EventListenerManager* |
|
841 GetExistingListenerManager() const MOZ_OVERRIDE; |
|
842 virtual mozilla::EventListenerManager* |
|
843 GetOrCreateListenerManager() MOZ_OVERRIDE; |
|
844 |
|
845 using mozilla::dom::EventTarget::RemoveEventListener; |
|
846 using nsIDOMEventTarget::AddEventListener; |
|
847 virtual void AddEventListener(const nsAString& aType, |
|
848 mozilla::dom::EventListener* aListener, |
|
849 bool aUseCapture, |
|
850 const mozilla::dom::Nullable<bool>& aWantsUntrusted, |
|
851 mozilla::ErrorResult& aRv) MOZ_OVERRIDE; |
|
852 using nsIDOMEventTarget::AddSystemEventListener; |
|
853 virtual nsIDOMWindow* GetOwnerGlobal() MOZ_OVERRIDE; |
|
854 |
|
855 /** |
|
856 * Adds a mutation observer to be notified when this node, or any of its |
|
857 * descendants, are modified. The node will hold a weak reference to the |
|
858 * observer, which means that it is the responsibility of the observer to |
|
859 * remove itself in case it dies before the node. If an observer is added |
|
860 * while observers are being notified, it may also be notified. In general, |
|
861 * adding observers while inside a notification is not a good idea. An |
|
862 * observer that is already observing the node must not be added without |
|
863 * being removed first. |
|
864 */ |
|
865 void AddMutationObserver(nsIMutationObserver* aMutationObserver) |
|
866 { |
|
867 nsSlots* s = Slots(); |
|
868 NS_ASSERTION(s->mMutationObservers.IndexOf(aMutationObserver) == |
|
869 nsTArray<int>::NoIndex, |
|
870 "Observer already in the list"); |
|
871 s->mMutationObservers.AppendElement(aMutationObserver); |
|
872 } |
|
873 |
|
874 /** |
|
875 * Same as above, but only adds the observer if its not observing |
|
876 * the node already. |
|
877 */ |
|
878 void AddMutationObserverUnlessExists(nsIMutationObserver* aMutationObserver) |
|
879 { |
|
880 nsSlots* s = Slots(); |
|
881 s->mMutationObservers.AppendElementUnlessExists(aMutationObserver); |
|
882 } |
|
883 |
|
884 /** |
|
885 * Removes a mutation observer. |
|
886 */ |
|
887 void RemoveMutationObserver(nsIMutationObserver* aMutationObserver) |
|
888 { |
|
889 nsSlots* s = GetExistingSlots(); |
|
890 if (s) { |
|
891 s->mMutationObservers.RemoveElement(aMutationObserver); |
|
892 } |
|
893 } |
|
894 |
|
895 /** |
|
896 * Clones this node. This needs to be overriden by all node classes. aNodeInfo |
|
897 * should be identical to this node's nodeInfo, except for the document which |
|
898 * may be different. When cloning an element, all attributes of the element |
|
899 * will be cloned. The children of the node will not be cloned. |
|
900 * |
|
901 * @param aNodeInfo the nodeinfo to use for the clone |
|
902 * @param aResult the clone |
|
903 */ |
|
904 virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const = 0; |
|
905 |
|
906 // This class can be extended by subclasses that wish to store more |
|
907 // information in the slots. |
|
908 class nsSlots |
|
909 { |
|
910 public: |
|
911 nsSlots() |
|
912 : mChildNodes(nullptr), |
|
913 mWeakReference(nullptr) |
|
914 { |
|
915 } |
|
916 |
|
917 // If needed we could remove the vtable pointer this dtor causes by |
|
918 // putting a DestroySlots function on nsINode |
|
919 virtual ~nsSlots(); |
|
920 |
|
921 void Traverse(nsCycleCollectionTraversalCallback &cb); |
|
922 void Unlink(); |
|
923 |
|
924 /** |
|
925 * A list of mutation observers |
|
926 */ |
|
927 nsTObserverArray<nsIMutationObserver*> mMutationObservers; |
|
928 |
|
929 /** |
|
930 * An object implementing nsIDOMNodeList for this content (childNodes) |
|
931 * @see nsIDOMNodeList |
|
932 * @see nsGenericHTMLElement::GetChildNodes |
|
933 * |
|
934 * MSVC 7 doesn't like this as an nsRefPtr |
|
935 */ |
|
936 nsChildContentList* mChildNodes; |
|
937 |
|
938 /** |
|
939 * Weak reference to this node |
|
940 */ |
|
941 nsNodeWeakReference* mWeakReference; |
|
942 }; |
|
943 |
|
944 /** |
|
945 * Functions for managing flags and slots |
|
946 */ |
|
947 #ifdef DEBUG |
|
948 nsSlots* DebugGetSlots() |
|
949 { |
|
950 return Slots(); |
|
951 } |
|
952 #endif |
|
953 |
|
954 void SetFlags(uint32_t aFlagsToSet) |
|
955 { |
|
956 NS_ASSERTION(!(aFlagsToSet & (NODE_IS_ANONYMOUS_ROOT | |
|
957 NODE_IS_NATIVE_ANONYMOUS_ROOT | |
|
958 NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE | |
|
959 NODE_ATTACH_BINDING_ON_POSTCREATE | |
|
960 NODE_DESCENDANTS_NEED_FRAMES | |
|
961 NODE_NEEDS_FRAME | |
|
962 NODE_CHROME_ONLY_ACCESS)) || |
|
963 IsNodeOfType(eCONTENT), |
|
964 "Flag only permitted on nsIContent nodes"); |
|
965 nsWrapperCache::SetFlags(aFlagsToSet); |
|
966 } |
|
967 |
|
968 void UnsetFlags(uint32_t aFlagsToUnset) |
|
969 { |
|
970 NS_ASSERTION(!(aFlagsToUnset & |
|
971 (NODE_IS_ANONYMOUS_ROOT | |
|
972 NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE | |
|
973 NODE_IS_NATIVE_ANONYMOUS_ROOT)), |
|
974 "Trying to unset write-only flags"); |
|
975 nsWrapperCache::UnsetFlags(aFlagsToUnset); |
|
976 } |
|
977 |
|
978 void SetEditableFlag(bool aEditable) |
|
979 { |
|
980 if (aEditable) { |
|
981 SetFlags(NODE_IS_EDITABLE); |
|
982 } |
|
983 else { |
|
984 UnsetFlags(NODE_IS_EDITABLE); |
|
985 } |
|
986 } |
|
987 |
|
988 bool IsEditable() const |
|
989 { |
|
990 #ifdef MOZILLA_INTERNAL_API |
|
991 return IsEditableInternal(); |
|
992 #else |
|
993 return IsEditableExternal(); |
|
994 #endif |
|
995 } |
|
996 |
|
997 /** |
|
998 * Returns true if |this| or any of its ancestors is native anonymous. |
|
999 */ |
|
1000 bool IsInNativeAnonymousSubtree() const |
|
1001 { |
|
1002 #ifdef DEBUG |
|
1003 if (HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE)) { |
|
1004 return true; |
|
1005 } |
|
1006 CheckNotNativeAnonymous(); |
|
1007 return false; |
|
1008 #else |
|
1009 return HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE); |
|
1010 #endif |
|
1011 } |
|
1012 |
|
1013 bool IsInAnonymousSubtree() const; |
|
1014 |
|
1015 // Note: This asserts |IsInAnonymousSubtree()|. |
|
1016 bool IsAnonymousContentInSVGUseSubtree() const; |
|
1017 |
|
1018 // True for native anonymous content and for XBL content if the binging |
|
1019 // has chromeOnlyContent="true". |
|
1020 bool ChromeOnlyAccess() const |
|
1021 { |
|
1022 return HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE | NODE_CHROME_ONLY_ACCESS); |
|
1023 } |
|
1024 |
|
1025 /** |
|
1026 * Returns true if |this| node is the common ancestor of the start/end |
|
1027 * nodes of a Range in a Selection or a descendant of such a common ancestor. |
|
1028 * This node is definitely not selected when |false| is returned, but it may |
|
1029 * or may not be selected when |true| is returned. |
|
1030 */ |
|
1031 bool IsSelectionDescendant() const |
|
1032 { |
|
1033 return IsDescendantOfCommonAncestorForRangeInSelection() || |
|
1034 IsCommonAncestorForRangeInSelection(); |
|
1035 } |
|
1036 |
|
1037 /** |
|
1038 * Get the root content of an editor. So, this node must be a descendant of |
|
1039 * an editor. Note that this should be only used for getting input or textarea |
|
1040 * editor's root content. This method doesn't support HTML editors. |
|
1041 */ |
|
1042 nsIContent* GetTextEditorRootContent(nsIEditor** aEditor = nullptr); |
|
1043 |
|
1044 /** |
|
1045 * Get the nearest selection root, ie. the node that will be selected if the |
|
1046 * user does "Select All" while the focus is in this node. Note that if this |
|
1047 * node is not in an editor, the result comes from the nsFrameSelection that |
|
1048 * is related to aPresShell, so the result might not be the ancestor of this |
|
1049 * node. Be aware that if this node and the computed selection limiter are |
|
1050 * not in same subtree, this returns the root content of the closeset subtree. |
|
1051 */ |
|
1052 nsIContent* GetSelectionRootContent(nsIPresShell* aPresShell); |
|
1053 |
|
1054 virtual nsINodeList* ChildNodes(); |
|
1055 nsIContent* GetFirstChild() const { return mFirstChild; } |
|
1056 nsIContent* GetLastChild() const |
|
1057 { |
|
1058 uint32_t count; |
|
1059 nsIContent* const* children = GetChildArray(&count); |
|
1060 |
|
1061 return count > 0 ? children[count - 1] : nullptr; |
|
1062 } |
|
1063 |
|
1064 /** |
|
1065 * Implementation is in nsIDocument.h, because it needs to cast from |
|
1066 * nsIDocument* to nsINode*. |
|
1067 */ |
|
1068 nsIDocument* GetOwnerDocument() const; |
|
1069 |
|
1070 void Normalize(); |
|
1071 |
|
1072 /** |
|
1073 * Get the base URI for any relative URIs within this piece of |
|
1074 * content. Generally, this is the document's base URI, but certain |
|
1075 * content carries a local base for backward compatibility, and XML |
|
1076 * supports setting a per-node base URI. |
|
1077 * |
|
1078 * @return the base URI |
|
1079 */ |
|
1080 virtual already_AddRefed<nsIURI> GetBaseURI(bool aTryUseXHRDocBaseURI = false) const = 0; |
|
1081 already_AddRefed<nsIURI> GetBaseURIObject() const; |
|
1082 |
|
1083 /** |
|
1084 * Facility for explicitly setting a base URI on a node. |
|
1085 */ |
|
1086 nsresult SetExplicitBaseURI(nsIURI* aURI); |
|
1087 /** |
|
1088 * The explicit base URI, if set, otherwise null |
|
1089 */ |
|
1090 protected: |
|
1091 nsIURI* GetExplicitBaseURI() const { |
|
1092 if (HasExplicitBaseURI()) { |
|
1093 return static_cast<nsIURI*>(GetProperty(nsGkAtoms::baseURIProperty)); |
|
1094 } |
|
1095 return nullptr; |
|
1096 } |
|
1097 |
|
1098 public: |
|
1099 void GetTextContent(nsAString& aTextContent) |
|
1100 { |
|
1101 GetTextContentInternal(aTextContent); |
|
1102 } |
|
1103 void SetTextContent(const nsAString& aTextContent, |
|
1104 mozilla::ErrorResult& aError) |
|
1105 { |
|
1106 SetTextContentInternal(aTextContent, aError); |
|
1107 } |
|
1108 |
|
1109 mozilla::dom::Element* QuerySelector(const nsAString& aSelector, |
|
1110 mozilla::ErrorResult& aResult); |
|
1111 already_AddRefed<nsINodeList> QuerySelectorAll(const nsAString& aSelector, |
|
1112 mozilla::ErrorResult& aResult); |
|
1113 |
|
1114 nsresult QuerySelector(const nsAString& aSelector, nsIDOMElement **aReturn); |
|
1115 nsresult QuerySelectorAll(const nsAString& aSelector, nsIDOMNodeList **aReturn); |
|
1116 |
|
1117 protected: |
|
1118 // nsIDocument overrides this with its own (faster) version. This |
|
1119 // should really only be called for elements and document fragments. |
|
1120 mozilla::dom::Element* GetElementById(const nsAString& aId); |
|
1121 |
|
1122 public: |
|
1123 /** |
|
1124 * Associate an object aData to aKey on this node. If aData is null any |
|
1125 * previously registered object and UserDataHandler associated to aKey on |
|
1126 * this node will be removed. |
|
1127 * Should only be used to implement the DOM Level 3 UserData API. |
|
1128 * |
|
1129 * @param aKey the key to associate the object to |
|
1130 * @param aData the object to associate to aKey on this node (may be null) |
|
1131 * @param aHandler the UserDataHandler to call when the node is |
|
1132 * cloned/deleted/imported/renamed (may be null) |
|
1133 * @param aResult [out] the previously registered object for aKey on this |
|
1134 * node, if any |
|
1135 * @return whether adding the object and UserDataHandler succeeded |
|
1136 */ |
|
1137 nsresult SetUserData(const nsAString& aKey, nsIVariant* aData, |
|
1138 nsIDOMUserDataHandler* aHandler, nsIVariant** aResult); |
|
1139 |
|
1140 /** |
|
1141 * Get the UserData object registered for a Key on this node, if any. |
|
1142 * Should only be used to implement the DOM Level 3 UserData API. |
|
1143 * |
|
1144 * @param aKey the key to get UserData for |
|
1145 * @return aResult the previously registered object for aKey on this node, if |
|
1146 * any |
|
1147 */ |
|
1148 nsIVariant* GetUserData(const nsAString& aKey); |
|
1149 |
|
1150 nsresult GetUserData(const nsAString& aKey, nsIVariant** aResult) |
|
1151 { |
|
1152 NS_IF_ADDREF(*aResult = GetUserData(aKey)); |
|
1153 |
|
1154 return NS_OK; |
|
1155 } |
|
1156 |
|
1157 void LookupPrefix(const nsAString& aNamespace, nsAString& aResult); |
|
1158 bool IsDefaultNamespace(const nsAString& aNamespaceURI) |
|
1159 { |
|
1160 nsAutoString defaultNamespace; |
|
1161 LookupNamespaceURI(EmptyString(), defaultNamespace); |
|
1162 return aNamespaceURI.Equals(defaultNamespace); |
|
1163 } |
|
1164 void LookupNamespaceURI(const nsAString& aNamespacePrefix, |
|
1165 nsAString& aNamespaceURI); |
|
1166 |
|
1167 nsresult IsEqualNode(nsIDOMNode* aOther, bool* aReturn); |
|
1168 |
|
1169 nsIContent* GetNextSibling() const { return mNextSibling; } |
|
1170 nsIContent* GetPreviousSibling() const { return mPreviousSibling; } |
|
1171 |
|
1172 /** |
|
1173 * Get the next node in the pre-order tree traversal of the DOM. If |
|
1174 * aRoot is non-null, then it must be an ancestor of |this| |
|
1175 * (possibly equal to |this|) and only nodes that are descendants of |
|
1176 * aRoot, not including aRoot itself, will be returned. Returns |
|
1177 * null if there are no more nodes to traverse. |
|
1178 */ |
|
1179 nsIContent* GetNextNode(const nsINode* aRoot = nullptr) const |
|
1180 { |
|
1181 return GetNextNodeImpl(aRoot, false); |
|
1182 } |
|
1183 |
|
1184 /** |
|
1185 * Get the next node in the pre-order tree traversal of the DOM but ignoring |
|
1186 * the children of this node. If aRoot is non-null, then it must be an |
|
1187 * ancestor of |this| (possibly equal to |this|) and only nodes that are |
|
1188 * descendants of aRoot, not including aRoot itself, will be returned. |
|
1189 * Returns null if there are no more nodes to traverse. |
|
1190 */ |
|
1191 nsIContent* GetNextNonChildNode(const nsINode* aRoot = nullptr) const |
|
1192 { |
|
1193 return GetNextNodeImpl(aRoot, true); |
|
1194 } |
|
1195 |
|
1196 /** |
|
1197 * Returns true if 'this' is either document or element or |
|
1198 * document fragment and aOther is a descendant in the same |
|
1199 * anonymous tree. |
|
1200 */ |
|
1201 bool Contains(const nsINode* aOther) const; |
|
1202 nsresult Contains(nsIDOMNode* aOther, bool* aReturn); |
|
1203 |
|
1204 bool UnoptimizableCCNode() const; |
|
1205 |
|
1206 private: |
|
1207 |
|
1208 nsIContent* GetNextNodeImpl(const nsINode* aRoot, |
|
1209 const bool aSkipChildren) const |
|
1210 { |
|
1211 // Can't use nsContentUtils::ContentIsDescendantOf here, since we |
|
1212 // can't include it here. |
|
1213 #ifdef DEBUG |
|
1214 if (aRoot) { |
|
1215 const nsINode* cur = this; |
|
1216 for (; cur; cur = cur->GetParentNode()) |
|
1217 if (cur == aRoot) break; |
|
1218 NS_ASSERTION(cur, "aRoot not an ancestor of |this|?"); |
|
1219 } |
|
1220 #endif |
|
1221 if (!aSkipChildren) { |
|
1222 nsIContent* kid = GetFirstChild(); |
|
1223 if (kid) { |
|
1224 return kid; |
|
1225 } |
|
1226 } |
|
1227 if (this == aRoot) { |
|
1228 return nullptr; |
|
1229 } |
|
1230 const nsINode* cur = this; |
|
1231 while (1) { |
|
1232 nsIContent* next = cur->GetNextSibling(); |
|
1233 if (next) { |
|
1234 return next; |
|
1235 } |
|
1236 nsINode* parent = cur->GetParentNode(); |
|
1237 if (parent == aRoot) { |
|
1238 return nullptr; |
|
1239 } |
|
1240 cur = parent; |
|
1241 } |
|
1242 NS_NOTREACHED("How did we get here?"); |
|
1243 } |
|
1244 |
|
1245 public: |
|
1246 |
|
1247 /** |
|
1248 * Get the previous nsIContent in the pre-order tree traversal of the DOM. If |
|
1249 * aRoot is non-null, then it must be an ancestor of |this| |
|
1250 * (possibly equal to |this|) and only nsIContents that are descendants of |
|
1251 * aRoot, including aRoot itself, will be returned. Returns |
|
1252 * null if there are no more nsIContents to traverse. |
|
1253 */ |
|
1254 nsIContent* GetPreviousContent(const nsINode* aRoot = nullptr) const |
|
1255 { |
|
1256 // Can't use nsContentUtils::ContentIsDescendantOf here, since we |
|
1257 // can't include it here. |
|
1258 #ifdef DEBUG |
|
1259 if (aRoot) { |
|
1260 const nsINode* cur = this; |
|
1261 for (; cur; cur = cur->GetParentNode()) |
|
1262 if (cur == aRoot) break; |
|
1263 NS_ASSERTION(cur, "aRoot not an ancestor of |this|?"); |
|
1264 } |
|
1265 #endif |
|
1266 |
|
1267 if (this == aRoot) { |
|
1268 return nullptr; |
|
1269 } |
|
1270 nsIContent* cur = this->GetParent(); |
|
1271 nsIContent* iter = this->GetPreviousSibling(); |
|
1272 while (iter) { |
|
1273 cur = iter; |
|
1274 iter = reinterpret_cast<nsINode*>(iter)->GetLastChild(); |
|
1275 } |
|
1276 return cur; |
|
1277 } |
|
1278 |
|
1279 /** |
|
1280 * Boolean flags |
|
1281 */ |
|
1282 private: |
|
1283 enum BooleanFlag { |
|
1284 // Set if we're being used from -moz-element |
|
1285 NodeHasRenderingObservers, |
|
1286 // Set if our parent chain (including this node itself) terminates |
|
1287 // in a document |
|
1288 IsInDocument, |
|
1289 // Set if mParent is an nsIContent |
|
1290 ParentIsContent, |
|
1291 // Set if this node is an Element |
|
1292 NodeIsElement, |
|
1293 // Set if the element has a non-empty id attribute. This can in rare |
|
1294 // cases lie for nsXMLElement, such as when the node has been moved between |
|
1295 // documents with different id mappings. |
|
1296 ElementHasID, |
|
1297 // Set if the element might have inline style. |
|
1298 ElementMayHaveStyle, |
|
1299 // Set if the element has a name attribute set. |
|
1300 ElementHasName, |
|
1301 // Set if the element might have a contenteditable attribute set. |
|
1302 ElementMayHaveContentEditableAttr, |
|
1303 // Set if the node is the common ancestor of the start/end nodes of a Range |
|
1304 // that is in a Selection. |
|
1305 NodeIsCommonAncestorForRangeInSelection, |
|
1306 // Set if the node is a descendant of a node with the above bit set. |
|
1307 NodeIsDescendantOfCommonAncestorForRangeInSelection, |
|
1308 // Set if CanSkipInCC check has been done for this subtree root. |
|
1309 NodeIsCCMarkedRoot, |
|
1310 // Maybe set if this node is in black subtree. |
|
1311 NodeIsCCBlackTree, |
|
1312 // Maybe set if the node is a root of a subtree |
|
1313 // which needs to be kept in the purple buffer. |
|
1314 NodeIsPurpleRoot, |
|
1315 // Set if the node has an explicit base URI stored |
|
1316 NodeHasExplicitBaseURI, |
|
1317 // Set if the element has some style states locked |
|
1318 ElementHasLockedStyleStates, |
|
1319 // Set if element has pointer locked |
|
1320 ElementHasPointerLock, |
|
1321 // Set if the node may have DOMMutationObserver attached to it. |
|
1322 NodeMayHaveDOMMutationObserver, |
|
1323 // Set if node is Content |
|
1324 NodeIsContent, |
|
1325 // Set if the node has animations or transitions |
|
1326 ElementHasAnimations, |
|
1327 // Set if node has a dir attribute with a valid value (ltr, rtl, or auto) |
|
1328 NodeHasValidDirAttribute, |
|
1329 // Set if node has a dir attribute with a fixed value (ltr or rtl, NOT auto) |
|
1330 NodeHasFixedDir, |
|
1331 // Set if the node has dir=auto and has a property pointing to the text |
|
1332 // node that determines its direction |
|
1333 NodeHasDirAutoSet, |
|
1334 // Set if the node is a text node descendant of a node with dir=auto |
|
1335 // and has a TextNodeDirectionalityMap property listing the elements whose |
|
1336 // direction it determines. |
|
1337 NodeHasTextNodeDirectionalityMap, |
|
1338 // Set if the node has dir=auto. |
|
1339 NodeHasDirAuto, |
|
1340 // Set if a node in the node's parent chain has dir=auto. |
|
1341 NodeAncestorHasDirAuto, |
|
1342 // Set if the element is in the scope of a scoped style sheet; this flag is |
|
1343 // only accurate for elements bound to a document |
|
1344 ElementIsInStyleScope, |
|
1345 // Set if the element is a scoped style sheet root |
|
1346 ElementIsScopedStyleRoot, |
|
1347 // Set if the node is handling a click. |
|
1348 NodeHandlingClick, |
|
1349 // Set if the node has had :hover selectors matched against it |
|
1350 NodeHasRelevantHoverRules, |
|
1351 // Set if the element has a parser insertion mode other than "in body", |
|
1352 // per the HTML5 "Parse state" section. |
|
1353 ElementHasWeirdParserInsertionMode, |
|
1354 // Guard value |
|
1355 BooleanFlagCount |
|
1356 }; |
|
1357 |
|
1358 void SetBoolFlag(BooleanFlag name, bool value) { |
|
1359 static_assert(BooleanFlagCount <= 8*sizeof(mBoolFlags), |
|
1360 "Too many boolean flags"); |
|
1361 mBoolFlags = (mBoolFlags & ~(1 << name)) | (value << name); |
|
1362 } |
|
1363 |
|
1364 void SetBoolFlag(BooleanFlag name) { |
|
1365 static_assert(BooleanFlagCount <= 8*sizeof(mBoolFlags), |
|
1366 "Too many boolean flags"); |
|
1367 mBoolFlags |= (1 << name); |
|
1368 } |
|
1369 |
|
1370 void ClearBoolFlag(BooleanFlag name) { |
|
1371 static_assert(BooleanFlagCount <= 8*sizeof(mBoolFlags), |
|
1372 "Too many boolean flags"); |
|
1373 mBoolFlags &= ~(1 << name); |
|
1374 } |
|
1375 |
|
1376 bool GetBoolFlag(BooleanFlag name) const { |
|
1377 static_assert(BooleanFlagCount <= 8*sizeof(mBoolFlags), |
|
1378 "Too many boolean flags"); |
|
1379 return mBoolFlags & (1 << name); |
|
1380 } |
|
1381 |
|
1382 public: |
|
1383 bool HasRenderingObservers() const |
|
1384 { return GetBoolFlag(NodeHasRenderingObservers); } |
|
1385 void SetHasRenderingObservers(bool aValue) |
|
1386 { SetBoolFlag(NodeHasRenderingObservers, aValue); } |
|
1387 bool IsContent() const { return GetBoolFlag(NodeIsContent); } |
|
1388 bool HasID() const { return GetBoolFlag(ElementHasID); } |
|
1389 bool MayHaveStyle() const { return GetBoolFlag(ElementMayHaveStyle); } |
|
1390 bool HasName() const { return GetBoolFlag(ElementHasName); } |
|
1391 bool MayHaveContentEditableAttr() const |
|
1392 { return GetBoolFlag(ElementMayHaveContentEditableAttr); } |
|
1393 bool IsCommonAncestorForRangeInSelection() const |
|
1394 { return GetBoolFlag(NodeIsCommonAncestorForRangeInSelection); } |
|
1395 void SetCommonAncestorForRangeInSelection() |
|
1396 { SetBoolFlag(NodeIsCommonAncestorForRangeInSelection); } |
|
1397 void ClearCommonAncestorForRangeInSelection() |
|
1398 { ClearBoolFlag(NodeIsCommonAncestorForRangeInSelection); } |
|
1399 bool IsDescendantOfCommonAncestorForRangeInSelection() const |
|
1400 { return GetBoolFlag(NodeIsDescendantOfCommonAncestorForRangeInSelection); } |
|
1401 void SetDescendantOfCommonAncestorForRangeInSelection() |
|
1402 { SetBoolFlag(NodeIsDescendantOfCommonAncestorForRangeInSelection); } |
|
1403 void ClearDescendantOfCommonAncestorForRangeInSelection() |
|
1404 { ClearBoolFlag(NodeIsDescendantOfCommonAncestorForRangeInSelection); } |
|
1405 |
|
1406 void SetCCMarkedRoot(bool aValue) |
|
1407 { SetBoolFlag(NodeIsCCMarkedRoot, aValue); } |
|
1408 bool CCMarkedRoot() const { return GetBoolFlag(NodeIsCCMarkedRoot); } |
|
1409 void SetInCCBlackTree(bool aValue) |
|
1410 { SetBoolFlag(NodeIsCCBlackTree, aValue); } |
|
1411 bool InCCBlackTree() const { return GetBoolFlag(NodeIsCCBlackTree); } |
|
1412 void SetIsPurpleRoot(bool aValue) |
|
1413 { SetBoolFlag(NodeIsPurpleRoot, aValue); } |
|
1414 bool IsPurpleRoot() const { return GetBoolFlag(NodeIsPurpleRoot); } |
|
1415 bool MayHaveDOMMutationObserver() |
|
1416 { return GetBoolFlag(NodeMayHaveDOMMutationObserver); } |
|
1417 void SetMayHaveDOMMutationObserver() |
|
1418 { SetBoolFlag(NodeMayHaveDOMMutationObserver, true); } |
|
1419 bool HasListenerManager() { return HasFlag(NODE_HAS_LISTENERMANAGER); } |
|
1420 bool HasPointerLock() const { return GetBoolFlag(ElementHasPointerLock); } |
|
1421 void SetPointerLock() { SetBoolFlag(ElementHasPointerLock); } |
|
1422 void ClearPointerLock() { ClearBoolFlag(ElementHasPointerLock); } |
|
1423 bool MayHaveAnimations() { return GetBoolFlag(ElementHasAnimations); } |
|
1424 void SetMayHaveAnimations() { SetBoolFlag(ElementHasAnimations); } |
|
1425 void SetHasValidDir() { SetBoolFlag(NodeHasValidDirAttribute); } |
|
1426 void ClearHasValidDir() { ClearBoolFlag(NodeHasValidDirAttribute); } |
|
1427 bool HasValidDir() const { return GetBoolFlag(NodeHasValidDirAttribute); } |
|
1428 void SetHasFixedDir() { |
|
1429 MOZ_ASSERT(NodeType() != nsIDOMNode::TEXT_NODE, |
|
1430 "SetHasFixedDir on text node"); |
|
1431 SetBoolFlag(NodeHasFixedDir); |
|
1432 } |
|
1433 void ClearHasFixedDir() { |
|
1434 MOZ_ASSERT(NodeType() != nsIDOMNode::TEXT_NODE, |
|
1435 "ClearHasFixedDir on text node"); |
|
1436 ClearBoolFlag(NodeHasFixedDir); |
|
1437 } |
|
1438 bool HasFixedDir() const { return GetBoolFlag(NodeHasFixedDir); } |
|
1439 void SetHasDirAutoSet() { |
|
1440 MOZ_ASSERT(NodeType() != nsIDOMNode::TEXT_NODE, |
|
1441 "SetHasDirAutoSet on text node"); |
|
1442 SetBoolFlag(NodeHasDirAutoSet); |
|
1443 } |
|
1444 void ClearHasDirAutoSet() { |
|
1445 MOZ_ASSERT(NodeType() != nsIDOMNode::TEXT_NODE, |
|
1446 "ClearHasDirAutoSet on text node"); |
|
1447 ClearBoolFlag(NodeHasDirAutoSet); |
|
1448 } |
|
1449 bool HasDirAutoSet() const |
|
1450 { return GetBoolFlag(NodeHasDirAutoSet); } |
|
1451 void SetHasTextNodeDirectionalityMap() { |
|
1452 MOZ_ASSERT(NodeType() == nsIDOMNode::TEXT_NODE, |
|
1453 "SetHasTextNodeDirectionalityMap on non-text node"); |
|
1454 SetBoolFlag(NodeHasTextNodeDirectionalityMap); |
|
1455 } |
|
1456 void ClearHasTextNodeDirectionalityMap() { |
|
1457 MOZ_ASSERT(NodeType() == nsIDOMNode::TEXT_NODE, |
|
1458 "ClearHasTextNodeDirectionalityMap on non-text node"); |
|
1459 ClearBoolFlag(NodeHasTextNodeDirectionalityMap); |
|
1460 } |
|
1461 bool HasTextNodeDirectionalityMap() const |
|
1462 { return GetBoolFlag(NodeHasTextNodeDirectionalityMap); } |
|
1463 |
|
1464 void SetHasDirAuto() { SetBoolFlag(NodeHasDirAuto); } |
|
1465 void ClearHasDirAuto() { ClearBoolFlag(NodeHasDirAuto); } |
|
1466 bool HasDirAuto() const { return GetBoolFlag(NodeHasDirAuto); } |
|
1467 |
|
1468 void SetAncestorHasDirAuto() { SetBoolFlag(NodeAncestorHasDirAuto); } |
|
1469 void ClearAncestorHasDirAuto() { ClearBoolFlag(NodeAncestorHasDirAuto); } |
|
1470 bool AncestorHasDirAuto() const { return GetBoolFlag(NodeAncestorHasDirAuto); } |
|
1471 |
|
1472 bool NodeOrAncestorHasDirAuto() const |
|
1473 { return HasDirAuto() || AncestorHasDirAuto(); } |
|
1474 |
|
1475 void SetIsElementInStyleScope(bool aValue) { |
|
1476 MOZ_ASSERT(IsElement(), "SetIsInStyleScope on a non-Element node"); |
|
1477 SetBoolFlag(ElementIsInStyleScope, aValue); |
|
1478 } |
|
1479 void SetIsElementInStyleScope() { |
|
1480 MOZ_ASSERT(IsElement(), "SetIsInStyleScope on a non-Element node"); |
|
1481 SetBoolFlag(ElementIsInStyleScope); |
|
1482 } |
|
1483 void ClearIsElementInStyleScope() { |
|
1484 MOZ_ASSERT(IsElement(), "ClearIsInStyleScope on a non-Element node"); |
|
1485 ClearBoolFlag(ElementIsInStyleScope); |
|
1486 } |
|
1487 bool IsElementInStyleScope() const { return GetBoolFlag(ElementIsInStyleScope); } |
|
1488 |
|
1489 void SetIsScopedStyleRoot() { SetBoolFlag(ElementIsScopedStyleRoot); } |
|
1490 void ClearIsScopedStyleRoot() { ClearBoolFlag(ElementIsScopedStyleRoot); } |
|
1491 bool IsScopedStyleRoot() { return GetBoolFlag(ElementIsScopedStyleRoot); } |
|
1492 bool HasRelevantHoverRules() const { return GetBoolFlag(NodeHasRelevantHoverRules); } |
|
1493 void SetHasRelevantHoverRules() { SetBoolFlag(NodeHasRelevantHoverRules); } |
|
1494 protected: |
|
1495 void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); } |
|
1496 void SetInDocument() { SetBoolFlag(IsInDocument); } |
|
1497 void SetNodeIsContent() { SetBoolFlag(NodeIsContent); } |
|
1498 void ClearInDocument() { ClearBoolFlag(IsInDocument); } |
|
1499 void SetIsElement() { SetBoolFlag(NodeIsElement); } |
|
1500 void SetHasID() { SetBoolFlag(ElementHasID); } |
|
1501 void ClearHasID() { ClearBoolFlag(ElementHasID); } |
|
1502 void SetMayHaveStyle() { SetBoolFlag(ElementMayHaveStyle); } |
|
1503 void SetHasName() { SetBoolFlag(ElementHasName); } |
|
1504 void ClearHasName() { ClearBoolFlag(ElementHasName); } |
|
1505 void SetMayHaveContentEditableAttr() |
|
1506 { SetBoolFlag(ElementMayHaveContentEditableAttr); } |
|
1507 bool HasExplicitBaseURI() const { return GetBoolFlag(NodeHasExplicitBaseURI); } |
|
1508 void SetHasExplicitBaseURI() { SetBoolFlag(NodeHasExplicitBaseURI); } |
|
1509 void SetHasLockedStyleStates() { SetBoolFlag(ElementHasLockedStyleStates); } |
|
1510 void ClearHasLockedStyleStates() { ClearBoolFlag(ElementHasLockedStyleStates); } |
|
1511 bool HasLockedStyleStates() const |
|
1512 { return GetBoolFlag(ElementHasLockedStyleStates); } |
|
1513 void SetHasWeirdParserInsertionMode() { SetBoolFlag(ElementHasWeirdParserInsertionMode); } |
|
1514 bool HasWeirdParserInsertionMode() const |
|
1515 { return GetBoolFlag(ElementHasWeirdParserInsertionMode); } |
|
1516 bool HandlingClick() const { return GetBoolFlag(NodeHandlingClick); } |
|
1517 void SetHandlingClick() { SetBoolFlag(NodeHandlingClick); } |
|
1518 void ClearHandlingClick() { ClearBoolFlag(NodeHandlingClick); } |
|
1519 |
|
1520 void SetSubtreeRootPointer(nsINode* aSubtreeRoot) |
|
1521 { |
|
1522 NS_ASSERTION(aSubtreeRoot, "aSubtreeRoot can never be null!"); |
|
1523 NS_ASSERTION(!(IsNodeOfType(eCONTENT) && IsInDoc()), "Shouldn't be here!"); |
|
1524 mSubtreeRoot = aSubtreeRoot; |
|
1525 } |
|
1526 |
|
1527 void ClearSubtreeRootPointer() |
|
1528 { |
|
1529 mSubtreeRoot = nullptr; |
|
1530 } |
|
1531 |
|
1532 public: |
|
1533 // Makes nsINode object to keep aObject alive. |
|
1534 void BindObject(nsISupports* aObject); |
|
1535 // After calling UnbindObject nsINode object doesn't keep |
|
1536 // aObject alive anymore. |
|
1537 void UnbindObject(nsISupports* aObject); |
|
1538 |
|
1539 void GetBoundMutationObservers(nsTArray<nsRefPtr<nsDOMMutationObserver> >& aResult); |
|
1540 |
|
1541 /** |
|
1542 * Returns the length of this node, as specified at |
|
1543 * <http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node-length> |
|
1544 */ |
|
1545 uint32_t Length() const; |
|
1546 |
|
1547 void GetNodeName(mozilla::dom::DOMString& aNodeName) |
|
1548 { |
|
1549 const nsString& nodeName = NodeName(); |
|
1550 aNodeName.SetStringBuffer(nsStringBuffer::FromString(nodeName), |
|
1551 nodeName.Length()); |
|
1552 } |
|
1553 void GetBaseURI(nsAString& aBaseURI) const; |
|
1554 // Return the base URI for the document. |
|
1555 // The returned value may differ if the document is loaded via XHR, and |
|
1556 // when accessed from chrome privileged script and |
|
1557 // from content privileged script for compatibility. |
|
1558 void GetBaseURIFromJS(nsAString& aBaseURI) const; |
|
1559 bool HasChildNodes() const |
|
1560 { |
|
1561 return HasChildren(); |
|
1562 } |
|
1563 uint16_t CompareDocumentPosition(nsINode& aOther) const; |
|
1564 void GetNodeValue(nsAString& aNodeValue) |
|
1565 { |
|
1566 GetNodeValueInternal(aNodeValue); |
|
1567 } |
|
1568 void SetNodeValue(const nsAString& aNodeValue, |
|
1569 mozilla::ErrorResult& aError) |
|
1570 { |
|
1571 SetNodeValueInternal(aNodeValue, aError); |
|
1572 } |
|
1573 virtual void GetNodeValueInternal(nsAString& aNodeValue); |
|
1574 virtual void SetNodeValueInternal(const nsAString& aNodeValue, |
|
1575 mozilla::ErrorResult& aError) |
|
1576 { |
|
1577 // The DOM spec says that when nodeValue is defined to be null "setting it |
|
1578 // has no effect", so we don't throw an exception. |
|
1579 } |
|
1580 nsINode* InsertBefore(nsINode& aNode, nsINode* aChild, |
|
1581 mozilla::ErrorResult& aError) |
|
1582 { |
|
1583 return ReplaceOrInsertBefore(false, &aNode, aChild, aError); |
|
1584 } |
|
1585 nsINode* AppendChild(nsINode& aNode, mozilla::ErrorResult& aError) |
|
1586 { |
|
1587 return InsertBefore(aNode, nullptr, aError); |
|
1588 } |
|
1589 nsINode* ReplaceChild(nsINode& aNode, nsINode& aChild, |
|
1590 mozilla::ErrorResult& aError) |
|
1591 { |
|
1592 return ReplaceOrInsertBefore(true, &aNode, &aChild, aError); |
|
1593 } |
|
1594 nsINode* RemoveChild(nsINode& aChild, mozilla::ErrorResult& aError); |
|
1595 already_AddRefed<nsINode> CloneNode(bool aDeep, mozilla::ErrorResult& aError); |
|
1596 bool IsEqualNode(nsINode* aNode); |
|
1597 void GetNamespaceURI(nsAString& aNamespaceURI) const |
|
1598 { |
|
1599 mNodeInfo->GetNamespaceURI(aNamespaceURI); |
|
1600 } |
|
1601 #ifdef MOZILLA_INTERNAL_API |
|
1602 void GetPrefix(nsAString& aPrefix) |
|
1603 { |
|
1604 mNodeInfo->GetPrefix(aPrefix); |
|
1605 } |
|
1606 #endif |
|
1607 void GetLocalName(mozilla::dom::DOMString& aLocalName) |
|
1608 { |
|
1609 const nsString& localName = LocalName(); |
|
1610 if (localName.IsVoid()) { |
|
1611 aLocalName.SetNull(); |
|
1612 } else { |
|
1613 aLocalName.SetStringBuffer(nsStringBuffer::FromString(localName), |
|
1614 localName.Length()); |
|
1615 } |
|
1616 } |
|
1617 // HasAttributes is defined inline in Element.h. |
|
1618 bool HasAttributes() const; |
|
1619 nsDOMAttributeMap* GetAttributes(); |
|
1620 void SetUserData(JSContext* aCx, const nsAString& aKey, |
|
1621 JS::Handle<JS::Value> aData, |
|
1622 nsIDOMUserDataHandler* aHandler, |
|
1623 JS::MutableHandle<JS::Value> aRetval, |
|
1624 mozilla::ErrorResult& aError); |
|
1625 void GetUserData(JSContext* aCx, const nsAString& aKey, |
|
1626 JS::MutableHandle<JS::Value> aRetval, |
|
1627 mozilla::ErrorResult& aError); |
|
1628 |
|
1629 // Helper method to remove this node from its parent. This is not exposed |
|
1630 // through WebIDL. |
|
1631 // Only call this if the node has a parent node. |
|
1632 nsresult RemoveFromParent() |
|
1633 { |
|
1634 nsINode* parent = GetParentNode(); |
|
1635 mozilla::ErrorResult rv; |
|
1636 parent->RemoveChild(*this, rv); |
|
1637 return rv.ErrorCode(); |
|
1638 } |
|
1639 |
|
1640 // ChildNode methods |
|
1641 mozilla::dom::Element* GetPreviousElementSibling() const; |
|
1642 mozilla::dom::Element* GetNextElementSibling() const; |
|
1643 /** |
|
1644 * Remove this node from its parent, if any. |
|
1645 */ |
|
1646 void Remove(); |
|
1647 |
|
1648 // ParentNode methods |
|
1649 mozilla::dom::Element* GetFirstElementChild() const; |
|
1650 mozilla::dom::Element* GetLastElementChild() const; |
|
1651 |
|
1652 void GetBoxQuads(const BoxQuadOptions& aOptions, |
|
1653 nsTArray<nsRefPtr<DOMQuad> >& aResult, |
|
1654 mozilla::ErrorResult& aRv); |
|
1655 |
|
1656 already_AddRefed<DOMQuad> ConvertQuadFromNode(DOMQuad& aQuad, |
|
1657 const TextOrElementOrDocument& aFrom, |
|
1658 const ConvertCoordinateOptions& aOptions, |
|
1659 ErrorResult& aRv); |
|
1660 already_AddRefed<DOMQuad> ConvertRectFromNode(DOMRectReadOnly& aRect, |
|
1661 const TextOrElementOrDocument& aFrom, |
|
1662 const ConvertCoordinateOptions& aOptions, |
|
1663 ErrorResult& aRv); |
|
1664 already_AddRefed<DOMPoint> ConvertPointFromNode(const DOMPointInit& aPoint, |
|
1665 const TextOrElementOrDocument& aFrom, |
|
1666 const ConvertCoordinateOptions& aOptions, |
|
1667 ErrorResult& aRv); |
|
1668 |
|
1669 protected: |
|
1670 |
|
1671 // Override this function to create a custom slots class. |
|
1672 // Must not return null. |
|
1673 virtual nsINode::nsSlots* CreateSlots(); |
|
1674 |
|
1675 bool HasSlots() const |
|
1676 { |
|
1677 return mSlots != nullptr; |
|
1678 } |
|
1679 |
|
1680 nsSlots* GetExistingSlots() const |
|
1681 { |
|
1682 return mSlots; |
|
1683 } |
|
1684 |
|
1685 nsSlots* Slots() |
|
1686 { |
|
1687 if (!HasSlots()) { |
|
1688 mSlots = CreateSlots(); |
|
1689 MOZ_ASSERT(mSlots); |
|
1690 } |
|
1691 return GetExistingSlots(); |
|
1692 } |
|
1693 |
|
1694 nsTObserverArray<nsIMutationObserver*> *GetMutationObservers() |
|
1695 { |
|
1696 return HasSlots() ? &GetExistingSlots()->mMutationObservers : nullptr; |
|
1697 } |
|
1698 |
|
1699 bool IsEditableInternal() const; |
|
1700 virtual bool IsEditableExternal() const |
|
1701 { |
|
1702 return IsEditableInternal(); |
|
1703 } |
|
1704 |
|
1705 virtual void GetTextContentInternal(nsAString& aTextContent); |
|
1706 virtual void SetTextContentInternal(const nsAString& aTextContent, |
|
1707 mozilla::ErrorResult& aError) |
|
1708 { |
|
1709 } |
|
1710 |
|
1711 #ifdef DEBUG |
|
1712 // Note: virtual so that IsInNativeAnonymousSubtree can be called accross |
|
1713 // module boundaries. |
|
1714 virtual void CheckNotNativeAnonymous() const; |
|
1715 #endif |
|
1716 |
|
1717 // These are just used to implement nsIDOMNode using |
|
1718 // NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER and for quickstubs. |
|
1719 nsresult GetParentNode(nsIDOMNode** aParentNode); |
|
1720 nsresult GetParentElement(nsIDOMElement** aParentElement); |
|
1721 nsresult GetChildNodes(nsIDOMNodeList** aChildNodes); |
|
1722 nsresult GetFirstChild(nsIDOMNode** aFirstChild); |
|
1723 nsresult GetLastChild(nsIDOMNode** aLastChild); |
|
1724 nsresult GetPreviousSibling(nsIDOMNode** aPrevSibling); |
|
1725 nsresult GetNextSibling(nsIDOMNode** aNextSibling); |
|
1726 nsresult GetOwnerDocument(nsIDOMDocument** aOwnerDocument); |
|
1727 nsresult CompareDocumentPosition(nsIDOMNode* aOther, |
|
1728 uint16_t* aReturn); |
|
1729 |
|
1730 nsresult ReplaceOrInsertBefore(bool aReplace, nsIDOMNode *aNewChild, |
|
1731 nsIDOMNode *aRefChild, nsIDOMNode **aReturn); |
|
1732 nsINode* ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild, |
|
1733 nsINode* aRefChild, |
|
1734 mozilla::ErrorResult& aError); |
|
1735 nsresult RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn); |
|
1736 |
|
1737 /** |
|
1738 * Returns the Element that should be used for resolving namespaces |
|
1739 * on this node (ie the ownerElement for attributes, the documentElement for |
|
1740 * documents, the node itself for elements and for other nodes the parentNode |
|
1741 * if it is an element). |
|
1742 */ |
|
1743 virtual mozilla::dom::Element* GetNameSpaceElement() = 0; |
|
1744 |
|
1745 /** |
|
1746 * Most of the implementation of the nsINode RemoveChildAt method. |
|
1747 * Should only be called on document, element, and document fragment |
|
1748 * nodes. The aChildArray passed in should be the one for |this|. |
|
1749 * |
|
1750 * @param aIndex The index to remove at. |
|
1751 * @param aNotify Whether to notify. |
|
1752 * @param aKid The kid at aIndex. Must not be null. |
|
1753 * @param aChildArray The child array to work with. |
|
1754 * @param aMutationEvent whether to fire a mutation event for this removal. |
|
1755 */ |
|
1756 void doRemoveChildAt(uint32_t aIndex, bool aNotify, nsIContent* aKid, |
|
1757 nsAttrAndChildArray& aChildArray); |
|
1758 |
|
1759 /** |
|
1760 * Most of the implementation of the nsINode InsertChildAt method. |
|
1761 * Should only be called on document, element, and document fragment |
|
1762 * nodes. The aChildArray passed in should be the one for |this|. |
|
1763 * |
|
1764 * @param aKid The child to insert. |
|
1765 * @param aIndex The index to insert at. |
|
1766 * @param aNotify Whether to notify. |
|
1767 * @param aChildArray The child array to work with |
|
1768 */ |
|
1769 nsresult doInsertChildAt(nsIContent* aKid, uint32_t aIndex, |
|
1770 bool aNotify, nsAttrAndChildArray& aChildArray); |
|
1771 |
|
1772 /** |
|
1773 * Parse the given selector string into an nsCSSSelectorList. |
|
1774 * |
|
1775 * A null return value with a non-failing aRv means the string only |
|
1776 * contained pseudo-element selectors. |
|
1777 * |
|
1778 * A failing aRv means the string was not a valid selector. |
|
1779 */ |
|
1780 nsCSSSelectorList* ParseSelectorList(const nsAString& aSelectorString, |
|
1781 mozilla::ErrorResult& aRv); |
|
1782 |
|
1783 public: |
|
1784 /* Event stuff that documents and elements share. This needs to be |
|
1785 NS_IMETHOD because some subclasses implement DOM methods with |
|
1786 this exact name and signature and then the calling convention |
|
1787 needs to match. |
|
1788 |
|
1789 Note that we include DOCUMENT_ONLY_EVENT events here so that we |
|
1790 can forward all the document stuff to this implementation. |
|
1791 */ |
|
1792 #define EVENT(name_, id_, type_, struct_) \ |
|
1793 mozilla::dom::EventHandlerNonNull* GetOn##name_(); \ |
|
1794 void SetOn##name_(mozilla::dom::EventHandlerNonNull* listener); |
|
1795 #define TOUCH_EVENT EVENT |
|
1796 #define DOCUMENT_ONLY_EVENT EVENT |
|
1797 #include "mozilla/EventNameList.h" |
|
1798 #undef DOCUMENT_ONLY_EVENT |
|
1799 #undef TOUCH_EVENT |
|
1800 #undef EVENT |
|
1801 |
|
1802 protected: |
|
1803 static bool Traverse(nsINode *tmp, nsCycleCollectionTraversalCallback &cb); |
|
1804 static void Unlink(nsINode *tmp); |
|
1805 |
|
1806 nsCOMPtr<nsINodeInfo> mNodeInfo; |
|
1807 |
|
1808 nsINode* mParent; |
|
1809 |
|
1810 private: |
|
1811 // Boolean flags. |
|
1812 uint32_t mBoolFlags; |
|
1813 |
|
1814 protected: |
|
1815 nsIContent* mNextSibling; |
|
1816 nsIContent* mPreviousSibling; |
|
1817 nsIContent* mFirstChild; |
|
1818 |
|
1819 union { |
|
1820 // Pointer to our primary frame. Might be null. |
|
1821 nsIFrame* mPrimaryFrame; |
|
1822 |
|
1823 // Pointer to the root of our subtree. Might be null. |
|
1824 nsINode* mSubtreeRoot; |
|
1825 }; |
|
1826 |
|
1827 // Storage for more members that are usually not needed; allocated lazily. |
|
1828 nsSlots* mSlots; |
|
1829 }; |
|
1830 |
|
1831 // Useful inline function for getting a node given an nsIContent and an |
|
1832 // nsIDocument. Returns the first argument cast to nsINode if it is non-null, |
|
1833 // otherwise returns the second (which may be null). We use type variables |
|
1834 // instead of nsIContent* and nsIDocument* because the actual types must be |
|
1835 // known for the cast to work. |
|
1836 template<class C, class D> |
|
1837 inline nsINode* NODE_FROM(C& aContent, D& aDocument) |
|
1838 { |
|
1839 if (aContent) |
|
1840 return static_cast<nsINode*>(aContent); |
|
1841 return static_cast<nsINode*>(aDocument); |
|
1842 } |
|
1843 |
|
1844 NS_DEFINE_STATIC_IID_ACCESSOR(nsINode, NS_INODE_IID) |
|
1845 |
|
1846 inline nsISupports* |
|
1847 ToSupports(nsINode* aPointer) |
|
1848 { |
|
1849 return aPointer; |
|
1850 } |
|
1851 |
|
1852 inline nsISupports* |
|
1853 ToCanonicalSupports(nsINode* aPointer) |
|
1854 { |
|
1855 return aPointer; |
|
1856 } |
|
1857 |
|
1858 #define NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER(...) \ |
|
1859 NS_IMETHOD GetNodeName(nsAString& aNodeName) __VA_ARGS__ \ |
|
1860 { \ |
|
1861 aNodeName = nsINode::NodeName(); \ |
|
1862 return NS_OK; \ |
|
1863 } \ |
|
1864 NS_IMETHOD GetNodeValue(nsAString& aNodeValue) __VA_ARGS__ \ |
|
1865 { \ |
|
1866 nsINode::GetNodeValue(aNodeValue); \ |
|
1867 return NS_OK; \ |
|
1868 } \ |
|
1869 NS_IMETHOD SetNodeValue(const nsAString& aNodeValue) __VA_ARGS__ \ |
|
1870 { \ |
|
1871 mozilla::ErrorResult rv; \ |
|
1872 nsINode::SetNodeValue(aNodeValue, rv); \ |
|
1873 return rv.ErrorCode(); \ |
|
1874 } \ |
|
1875 NS_IMETHOD GetNodeType(uint16_t* aNodeType) __VA_ARGS__ \ |
|
1876 { \ |
|
1877 *aNodeType = nsINode::NodeType(); \ |
|
1878 return NS_OK; \ |
|
1879 } \ |
|
1880 NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode) __VA_ARGS__ \ |
|
1881 { \ |
|
1882 return nsINode::GetParentNode(aParentNode); \ |
|
1883 } \ |
|
1884 NS_IMETHOD GetParentElement(nsIDOMElement** aParentElement) __VA_ARGS__ \ |
|
1885 { \ |
|
1886 return nsINode::GetParentElement(aParentElement); \ |
|
1887 } \ |
|
1888 NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes) __VA_ARGS__ \ |
|
1889 { \ |
|
1890 return nsINode::GetChildNodes(aChildNodes); \ |
|
1891 } \ |
|
1892 NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild) __VA_ARGS__ \ |
|
1893 { \ |
|
1894 return nsINode::GetFirstChild(aFirstChild); \ |
|
1895 } \ |
|
1896 NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild) __VA_ARGS__ \ |
|
1897 { \ |
|
1898 return nsINode::GetLastChild(aLastChild); \ |
|
1899 } \ |
|
1900 NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling) __VA_ARGS__ \ |
|
1901 { \ |
|
1902 return nsINode::GetPreviousSibling(aPreviousSibling); \ |
|
1903 } \ |
|
1904 NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling) __VA_ARGS__ \ |
|
1905 { \ |
|
1906 return nsINode::GetNextSibling(aNextSibling); \ |
|
1907 } \ |
|
1908 NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument) __VA_ARGS__ \ |
|
1909 { \ |
|
1910 return nsINode::GetOwnerDocument(aOwnerDocument); \ |
|
1911 } \ |
|
1912 NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aResult) __VA_ARGS__ \ |
|
1913 { \ |
|
1914 return ReplaceOrInsertBefore(false, aNewChild, aRefChild, aResult); \ |
|
1915 } \ |
|
1916 NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aResult) __VA_ARGS__ \ |
|
1917 { \ |
|
1918 return ReplaceOrInsertBefore(true, aNewChild, aOldChild, aResult); \ |
|
1919 } \ |
|
1920 NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aResult) __VA_ARGS__ \ |
|
1921 { \ |
|
1922 return nsINode::RemoveChild(aOldChild, aResult); \ |
|
1923 } \ |
|
1924 NS_IMETHOD AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aResult) __VA_ARGS__ \ |
|
1925 { \ |
|
1926 return InsertBefore(aNewChild, nullptr, aResult); \ |
|
1927 } \ |
|
1928 NS_IMETHOD HasChildNodes(bool* aResult) __VA_ARGS__ \ |
|
1929 { \ |
|
1930 *aResult = nsINode::HasChildNodes(); \ |
|
1931 return NS_OK; \ |
|
1932 } \ |
|
1933 NS_IMETHOD CloneNode(bool aDeep, uint8_t aArgc, nsIDOMNode** aResult) __VA_ARGS__ \ |
|
1934 { \ |
|
1935 if (aArgc == 0) { \ |
|
1936 aDeep = true; \ |
|
1937 } \ |
|
1938 mozilla::ErrorResult rv; \ |
|
1939 nsCOMPtr<nsINode> clone = nsINode::CloneNode(aDeep, rv); \ |
|
1940 if (rv.Failed()) { \ |
|
1941 return rv.ErrorCode(); \ |
|
1942 } \ |
|
1943 *aResult = clone.forget().take()->AsDOMNode(); \ |
|
1944 return NS_OK; \ |
|
1945 } \ |
|
1946 NS_IMETHOD Normalize() __VA_ARGS__ \ |
|
1947 { \ |
|
1948 nsINode::Normalize(); \ |
|
1949 return NS_OK; \ |
|
1950 } \ |
|
1951 NS_IMETHOD GetNamespaceURI(nsAString& aNamespaceURI) __VA_ARGS__ \ |
|
1952 { \ |
|
1953 nsINode::GetNamespaceURI(aNamespaceURI); \ |
|
1954 return NS_OK; \ |
|
1955 } \ |
|
1956 NS_IMETHOD GetPrefix(nsAString& aPrefix) __VA_ARGS__ \ |
|
1957 { \ |
|
1958 nsINode::GetPrefix(aPrefix); \ |
|
1959 return NS_OK; \ |
|
1960 } \ |
|
1961 NS_IMETHOD GetLocalName(nsAString& aLocalName) __VA_ARGS__ \ |
|
1962 { \ |
|
1963 aLocalName = nsINode::LocalName(); \ |
|
1964 return NS_OK; \ |
|
1965 } \ |
|
1966 using nsINode::HasAttributes; \ |
|
1967 NS_IMETHOD HasAttributes(bool* aResult) __VA_ARGS__ \ |
|
1968 { \ |
|
1969 *aResult = nsINode::HasAttributes(); \ |
|
1970 return NS_OK; \ |
|
1971 } \ |
|
1972 NS_IMETHOD GetDOMBaseURI(nsAString& aBaseURI) __VA_ARGS__ \ |
|
1973 { \ |
|
1974 nsINode::GetBaseURI(aBaseURI); \ |
|
1975 return NS_OK; \ |
|
1976 } \ |
|
1977 NS_IMETHOD CompareDocumentPosition(nsIDOMNode* aOther, uint16_t* aResult) __VA_ARGS__ \ |
|
1978 { \ |
|
1979 return nsINode::CompareDocumentPosition(aOther, aResult); \ |
|
1980 } \ |
|
1981 NS_IMETHOD GetTextContent(nsAString& aTextContent) __VA_ARGS__ \ |
|
1982 { \ |
|
1983 nsINode::GetTextContent(aTextContent); \ |
|
1984 return NS_OK; \ |
|
1985 } \ |
|
1986 NS_IMETHOD SetTextContent(const nsAString& aTextContent) __VA_ARGS__ \ |
|
1987 { \ |
|
1988 mozilla::ErrorResult rv; \ |
|
1989 nsINode::SetTextContent(aTextContent, rv); \ |
|
1990 return rv.ErrorCode(); \ |
|
1991 } \ |
|
1992 NS_IMETHOD LookupPrefix(const nsAString& aNamespaceURI, nsAString& aResult) __VA_ARGS__ \ |
|
1993 { \ |
|
1994 nsINode::LookupPrefix(aNamespaceURI, aResult); \ |
|
1995 return NS_OK; \ |
|
1996 } \ |
|
1997 NS_IMETHOD IsDefaultNamespace(const nsAString& aNamespaceURI, bool* aResult) __VA_ARGS__ \ |
|
1998 { \ |
|
1999 *aResult = nsINode::IsDefaultNamespace(aNamespaceURI); \ |
|
2000 return NS_OK; \ |
|
2001 } \ |
|
2002 NS_IMETHOD LookupNamespaceURI(const nsAString& aPrefix, nsAString& aResult) __VA_ARGS__ \ |
|
2003 { \ |
|
2004 nsINode::LookupNamespaceURI(aPrefix, aResult); \ |
|
2005 return NS_OK; \ |
|
2006 } \ |
|
2007 NS_IMETHOD IsEqualNode(nsIDOMNode* aArg, bool* aResult) __VA_ARGS__ \ |
|
2008 { \ |
|
2009 return nsINode::IsEqualNode(aArg, aResult); \ |
|
2010 } \ |
|
2011 NS_IMETHOD SetUserData(const nsAString& aKey, nsIVariant* aData, nsIDOMUserDataHandler* aHandler, nsIVariant** aResult) __VA_ARGS__ \ |
|
2012 { \ |
|
2013 return nsINode::SetUserData(aKey, aData, aHandler, aResult); \ |
|
2014 } \ |
|
2015 NS_IMETHOD GetUserData(const nsAString& aKey, nsIVariant** aResult) __VA_ARGS__ \ |
|
2016 { \ |
|
2017 return nsINode::GetUserData(aKey, aResult); \ |
|
2018 } \ |
|
2019 NS_IMETHOD Contains(nsIDOMNode* aOther, bool* aResult) __VA_ARGS__ \ |
|
2020 { \ |
|
2021 return nsINode::Contains(aOther, aResult); \ |
|
2022 } |
|
2023 |
|
2024 #define NS_FORWARD_NSIDOMNODE_TO_NSINODE \ |
|
2025 NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER(MOZ_FINAL) |
|
2026 |
|
2027 #define NS_FORWARD_NSIDOMNODE_TO_NSINODE_OVERRIDABLE \ |
|
2028 NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER() |
|
2029 |
|
2030 #endif /* nsINode_h___ */ |