Bumping manifests a=b2g-bump
[gecko.git] / dom / base / nsINode.h
blobd38bfc04234c8b5bf2c2fbf7613e2bbe2f0cfd20
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/. */
6 #ifndef nsINode_h___
7 #define nsINode_h___
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 "mozilla/dom/NodeInfo.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"
25 // Including 'windows.h' will #define GetClassInfo to something else.
26 #ifdef XP_WIN
27 #ifdef GetClassInfo
28 #undef GetClassInfo
29 #endif
30 #endif
32 class nsAttrAndChildArray;
33 class nsChildContentList;
34 struct nsCSSSelectorList;
35 class nsDOMAttributeMap;
36 class nsIContent;
37 class nsIDocument;
38 class nsIDOMElement;
39 class nsIDOMNodeList;
40 class nsIEditor;
41 class nsIFrame;
42 class nsIMutationObserver;
43 class nsINodeList;
44 class nsIPresShell;
45 class nsIPrincipal;
46 class nsIURI;
47 class nsNodeSupportsWeakRefTearoff;
48 class nsNodeWeakReference;
49 class nsXPCClassInfo;
50 class nsDOMMutationObserver;
52 namespace mozilla {
53 class EventListenerManager;
54 namespace dom {
55 /**
56 * @return true if aChar is what the DOM spec defines as 'space character'.
57 * http://dom.spec.whatwg.org/#space-character
59 inline bool IsSpaceCharacter(char16_t aChar) {
60 return aChar == ' ' || aChar == '\t' || aChar == '\n' || aChar == '\r' ||
61 aChar == '\f';
63 inline bool IsSpaceCharacter(char aChar) {
64 return aChar == ' ' || aChar == '\t' || aChar == '\n' || aChar == '\r' ||
65 aChar == '\f';
67 struct BoxQuadOptions;
68 struct ConvertCoordinateOptions;
69 class DOMPoint;
70 class DOMQuad;
71 class DOMRectReadOnly;
72 class Element;
73 class EventHandlerNonNull;
74 class OnErrorEventHandlerNonNull;
75 template<typename T> class Optional;
76 class Text;
77 class TextOrElementOrDocument;
78 struct DOMPointInit;
79 } // namespace dom
80 } // namespace mozilla
82 #define NODE_FLAG_BIT(n_) \
83 (nsWrapperCache::FlagsType(1U) << (WRAPPER_CACHE_FLAGS_BITS_USED + (n_)))
85 enum {
86 // This bit will be set if the node has a listener manager.
87 NODE_HAS_LISTENERMANAGER = NODE_FLAG_BIT(0),
89 // Whether this node has had any properties set on it
90 NODE_HAS_PROPERTIES = NODE_FLAG_BIT(1),
92 // Whether this node is the root of an anonymous subtree. Note that this
93 // need not be a native anonymous subtree. Any anonymous subtree, including
94 // XBL-generated ones, will do. This flag is set-once: once a node has it,
95 // it must not be removed.
96 // NOTE: Should only be used on nsIContent nodes
97 NODE_IS_ANONYMOUS_ROOT = NODE_FLAG_BIT(2),
99 // Whether the node has some ancestor, possibly itself, that is native
100 // anonymous. This includes ancestors crossing XBL scopes, in cases when an
101 // XBL binding is attached to an element which has a native anonymous
102 // ancestor. This flag is set-once: once a node has it, it must not be
103 // removed.
104 // NOTE: Should only be used on nsIContent nodes
105 NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE = NODE_FLAG_BIT(3),
107 // Whether this node is the root of a native anonymous (from the perspective
108 // of its parent) subtree. This flag is set-once: once a node has it, it
109 // must not be removed.
110 // NOTE: Should only be used on nsIContent nodes
111 NODE_IS_NATIVE_ANONYMOUS_ROOT = NODE_FLAG_BIT(4),
113 // Forces the XBL code to treat this node as if it were
114 // in the document and therefore should get bindings attached.
115 NODE_FORCE_XBL_BINDINGS = NODE_FLAG_BIT(5),
117 // Whether a binding manager may have a pointer to this
118 NODE_MAY_BE_IN_BINDING_MNGR = NODE_FLAG_BIT(6),
120 NODE_IS_EDITABLE = NODE_FLAG_BIT(7),
122 // For all Element nodes, NODE_MAY_HAVE_CLASS is guaranteed to be set if the
123 // node in fact has a class, but may be set even if it doesn't.
124 NODE_MAY_HAVE_CLASS = NODE_FLAG_BIT(8),
126 // Whether the node participates in a shadow tree.
127 NODE_IS_IN_SHADOW_TREE = NODE_FLAG_BIT(9),
129 // Node has an :empty or :-moz-only-whitespace selector
130 NODE_HAS_EMPTY_SELECTOR = NODE_FLAG_BIT(10),
132 // A child of the node has a selector such that any insertion,
133 // removal, or appending of children requires restyling the parent.
134 NODE_HAS_SLOW_SELECTOR = NODE_FLAG_BIT(11),
136 // A child of the node has a :first-child, :-moz-first-node,
137 // :only-child, :last-child or :-moz-last-node selector.
138 NODE_HAS_EDGE_CHILD_SELECTOR = NODE_FLAG_BIT(12),
140 // A child of the node has a selector such that any insertion or
141 // removal of children requires restyling later siblings of that
142 // element. Additionally (in this manner it is stronger than
143 // NODE_HAS_SLOW_SELECTOR), if a child's style changes due to any
144 // other content tree changes (e.g., the child changes to or from
145 // matching :empty due to a grandchild insertion or removal), the
146 // child's later siblings must also be restyled.
147 NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS = NODE_FLAG_BIT(13),
149 NODE_ALL_SELECTOR_FLAGS = NODE_HAS_EMPTY_SELECTOR |
150 NODE_HAS_SLOW_SELECTOR |
151 NODE_HAS_EDGE_CHILD_SELECTOR |
152 NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS,
154 // This node needs to go through frame construction to get a frame (or
155 // undisplayed entry).
156 NODE_NEEDS_FRAME = NODE_FLAG_BIT(14),
158 // At least one descendant in the flattened tree has NODE_NEEDS_FRAME set.
159 // This should be set on every node on the flattened tree path between the
160 // node(s) with NODE_NEEDS_FRAME and the root content.
161 NODE_DESCENDANTS_NEED_FRAMES = NODE_FLAG_BIT(15),
163 // Set if the node has the accesskey attribute set.
164 NODE_HAS_ACCESSKEY = NODE_FLAG_BIT(16),
166 // Set if the node has right-to-left directionality
167 NODE_HAS_DIRECTION_RTL = NODE_FLAG_BIT(17),
169 // Set if the node has left-to-right directionality
170 NODE_HAS_DIRECTION_LTR = NODE_FLAG_BIT(18),
172 NODE_ALL_DIRECTION_FLAGS = NODE_HAS_DIRECTION_LTR |
173 NODE_HAS_DIRECTION_RTL,
175 NODE_CHROME_ONLY_ACCESS = NODE_FLAG_BIT(19),
177 NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS = NODE_FLAG_BIT(20),
179 // Remaining bits are node type specific.
180 NODE_TYPE_SPECIFIC_BITS_OFFSET = 21
183 // Make sure we have space for our bits
184 #define ASSERT_NODE_FLAGS_SPACE(n) \
185 static_assert(WRAPPER_CACHE_FLAGS_BITS_USED + (n) <= \
186 sizeof(nsWrapperCache::FlagsType) * 8, \
187 "Not enough space for our bits")
188 ASSERT_NODE_FLAGS_SPACE(NODE_TYPE_SPECIFIC_BITS_OFFSET);
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.
196 class nsMutationGuard {
197 public:
198 nsMutationGuard()
200 mStartingGeneration = sGeneration;
204 * Returns true if any unexpected mutations have occurred. You can pass in
205 * an 8-bit ignore count to ignore a number of expected mutations.
207 * We don't need to care about overflow because subtraction of uint64_t's is
208 * finding the difference between two elements of the group Z < 2^64. Once
209 * we know the difference between two elements we only need to check that is
210 * less than the given number of mutations to know less than that many
211 * mutations occured. Assuming constant 1ns mutations it would take 584
212 * years for sGeneration to fully wrap around so we can ignore a guard living
213 * through a full wrap around.
215 bool Mutated(uint8_t aIgnoreCount)
217 return (sGeneration - mStartingGeneration) > aIgnoreCount;
220 // This function should be called whenever a mutation that we want to keep
221 // track of happen. For now this is only done when children are added or
222 // removed, but we might do it for attribute changes too in the future.
223 static void DidMutate()
225 sGeneration++;
228 private:
229 // This is the value sGeneration had when the guard was constructed.
230 uint64_t mStartingGeneration;
232 // This value is incremented on every mutation, for the life of the process.
233 static uint64_t sGeneration;
236 // This should be used for any nsINode sub-class that has fields of its own
237 // that it needs to measure; any sub-class that doesn't use it will inherit
238 // SizeOfExcludingThis from its super-class. SizeOfIncludingThis() need not be
239 // defined, it is inherited from nsINode.
240 // This macro isn't actually specific to nodes, and bug 956400 will move it into MFBT.
241 #define NS_DECL_SIZEOF_EXCLUDING_THIS \
242 virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
244 // Categories of node properties
245 // 0 is global.
246 #define DOM_USER_DATA 1
247 #define SMIL_MAPPED_ATTR_ANIMVAL 2
249 // IID for the nsINode interface
250 #define NS_INODE_IID \
251 { 0x66972940, 0x1d1b, 0x4d15, \
252 { 0x93, 0x11, 0x96, 0x72, 0x84, 0x2e, 0xc7, 0x27 } }
255 * An internal interface that abstracts some DOMNode-related parts that both
256 * nsIContent and nsIDocument share. An instance of this interface has a list
257 * of nsIContent children and provides access to them.
259 class nsINode : public mozilla::dom::EventTarget
261 public:
262 typedef mozilla::dom::BoxQuadOptions BoxQuadOptions;
263 typedef mozilla::dom::ConvertCoordinateOptions ConvertCoordinateOptions;
264 typedef mozilla::dom::DOMPoint DOMPoint;
265 typedef mozilla::dom::DOMPointInit DOMPointInit;
266 typedef mozilla::dom::DOMQuad DOMQuad;
267 typedef mozilla::dom::DOMRectReadOnly DOMRectReadOnly;
268 typedef mozilla::dom::TextOrElementOrDocument TextOrElementOrDocument;
269 typedef mozilla::ErrorResult ErrorResult;
271 NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODE_IID)
273 // Among the sub-classes that inherit (directly or indirectly) from nsINode,
274 // measurement of the following members may be added later if DMD finds it is
275 // worthwhile:
276 // - nsGenericHTMLElement: mForm, mFieldSet
277 // - nsGenericHTMLFrameElement: mFrameLoader (bug 672539)
278 // - HTMLBodyElement: mContentStyleRule
279 // - HTMLDataListElement: mOptions
280 // - HTMLFieldSetElement: mElements, mDependentElements, mFirstLegend
281 // - HTMLFormElement: many!
282 // - HTMLFrameSetElement: mRowSpecs, mColSpecs
283 // - HTMLInputElement: mInputData, mFiles, mFileList, mStaticDocfileList
284 // - nsHTMLMapElement: mAreas
285 // - HTMLMediaElement: many!
286 // - nsHTMLOutputElement: mDefaultValue, mTokenList
287 // - nsHTMLRowElement: mCells
288 // - nsHTMLSelectElement: mOptions, mRestoreState
289 // - nsHTMLTableElement: mTBodies, mRows, mTableInheritedAttributes
290 // - nsHTMLTableSectionElement: mRows
291 // - nsHTMLTextAreaElement: mControllers, mState
293 // The following members don't need to be measured:
294 // - nsIContent: mPrimaryFrame, because it's non-owning and measured elsewhere
296 virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
298 // SizeOfIncludingThis doesn't need to be overridden by sub-classes because
299 // sub-classes of nsINode are guaranteed to be laid out in memory in such a
300 // way that |this| points to the start of the allocated object, even in
301 // methods of nsINode's sub-classes, and so |aMallocSizeOf(this)| is always
302 // safe to call no matter which object it was invoked on.
303 virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
304 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
307 friend class nsNodeUtils;
308 friend class nsNodeWeakReference;
309 friend class nsNodeSupportsWeakRefTearoff;
310 friend class nsAttrAndChildArray;
312 #ifdef MOZILLA_INTERNAL_API
313 explicit nsINode(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
314 : mNodeInfo(aNodeInfo),
315 mParent(nullptr),
316 mBoolFlags(0),
317 mNextSibling(nullptr),
318 mPreviousSibling(nullptr),
319 mFirstChild(nullptr),
320 mSubtreeRoot(this),
321 mSlots(nullptr)
324 #endif
326 virtual ~nsINode();
329 * Bit-flags to pass (or'ed together) to IsNodeOfType()
331 enum {
332 /** nsIContent nodes */
333 eCONTENT = 1 << 0,
334 /** nsIDocument nodes */
335 eDOCUMENT = 1 << 1,
336 /** nsIAttribute nodes */
337 eATTRIBUTE = 1 << 2,
338 /** text nodes */
339 eTEXT = 1 << 3,
340 /** xml processing instructions */
341 ePROCESSING_INSTRUCTION = 1 << 4,
342 /** comment nodes */
343 eCOMMENT = 1 << 5,
344 /** form control elements */
345 eHTML_FORM_CONTROL = 1 << 6,
346 /** document fragments */
347 eDOCUMENT_FRAGMENT = 1 << 7,
348 /** data nodes (comments, PIs, text). Nodes of this type always
349 returns a non-null value for nsIContent::GetText() */
350 eDATA_NODE = 1 << 8,
351 /** HTMLMediaElement */
352 eMEDIA = 1 << 9,
353 /** animation elements */
354 eANIMATION = 1 << 10,
355 /** filter elements that implement SVGFilterPrimitiveStandardAttributes */
356 eFILTER = 1 << 11
360 * API for doing a quick check if a content is of a given
361 * type, such as Text, Document, Comment ... Use this when you can instead of
362 * checking the tag.
364 * @param aFlags what types you want to test for (see above)
365 * @return whether the content matches ALL flags passed in
367 virtual bool IsNodeOfType(uint32_t aFlags) const = 0;
369 virtual JSObject* WrapObject(JSContext *aCx) MOZ_OVERRIDE;
372 * returns true if we are in priviliged code or
373 * layout.css.getBoxQuads.enabled == true.
375 static bool HasBoxQuadsSupport(JSContext* aCx, JSObject* /* unused */);
377 protected:
379 * WrapNode is called from WrapObject to actually wrap this node, WrapObject
380 * does some additional checks and fix-up that's common to all nodes. WrapNode
381 * should just call the DOM binding's Wrap function.
383 virtual JSObject* WrapNode(JSContext *aCx) = 0;
385 public:
386 mozilla::dom::ParentObject GetParentObject() const; // Implemented in nsIDocument.h
389 * Return the scope chain parent for this node, for use in things
390 * like event handler compilation. Returning null means to use the
391 * global object as the scope chain parent.
393 virtual nsINode* GetScopeChainParent() const;
396 * Return whether the node is an Element node
398 bool IsElement() const {
399 return GetBoolFlag(NodeIsElement);
403 * Return this node as an Element. Should only be used for nodes
404 * for which IsElement() is true. This is defined inline in Element.h.
406 mozilla::dom::Element* AsElement();
407 const mozilla::dom::Element* AsElement() const;
410 * Return this node as nsIContent. Should only be used for nodes for which
411 * IsContent() is true. This is defined inline in nsIContent.h.
413 nsIContent* AsContent();
414 const nsIContent* AsContent() const
416 return const_cast<nsINode*>(this)->AsContent();
420 * Return this node as Text if it is one, otherwise null. This is defined
421 * inline in Text.h.
423 mozilla::dom::Text* GetAsText();
424 const mozilla::dom::Text* GetAsText() const;
426 virtual nsIDOMNode* AsDOMNode() = 0;
429 * Return if this node has any children.
431 bool HasChildren() const { return !!mFirstChild; }
434 * Get the number of children
435 * @return the number of children
437 virtual uint32_t GetChildCount() const = 0;
440 * Get a child by index
441 * @param aIndex the index of the child to get
442 * @return the child, or null if index out of bounds
444 virtual nsIContent* GetChildAt(uint32_t aIndex) const = 0;
447 * Get a raw pointer to the child array. This should only be used if you
448 * plan to walk a bunch of the kids, promise to make sure that nothing ever
449 * mutates (no attribute changes, not DOM tree changes, no script execution,
450 * NOTHING), and will never ever peform an out-of-bounds access here. This
451 * method may return null if there are no children, or it may return a
452 * garbage pointer. In all cases the out param will be set to the number of
453 * children.
455 virtual nsIContent * const * GetChildArray(uint32_t* aChildCount) const = 0;
458 * Get the index of a child within this content
459 * @param aPossibleChild the child to get the index of.
460 * @return the index of the child, or -1 if not a child
462 * If the return value is not -1, then calling GetChildAt() with that value
463 * will return aPossibleChild.
465 virtual int32_t IndexOf(const nsINode* aPossibleChild) const = 0;
468 * Return the "owner document" of this node. Note that this is not the same
469 * as the DOM ownerDocument -- that's null for Document nodes, whereas for a
470 * nsIDocument GetOwnerDocument returns the document itself. For nsIContent
471 * implementations the two are the same.
473 nsIDocument *OwnerDoc() const
475 return mNodeInfo->GetDocument();
479 * Return the "owner document" of this node as an nsINode*. Implemented
480 * in nsIDocument.h.
482 nsINode *OwnerDocAsNode() const;
485 * Returns true if the content has an ancestor that is a document.
487 * @return whether this content is in a document tree
489 bool IsInUncomposedDoc() const
491 return GetBoolFlag(IsInDocument);
495 * @deprecated
497 bool IsInDoc() const
499 return IsInUncomposedDoc();
503 * Get the document that this content is currently in, if any. This will be
504 * null if the content has no ancestor that is a document.
506 * @return the current document
509 nsIDocument* GetUncomposedDoc() const
511 return IsInUncomposedDoc() ? OwnerDoc() : nullptr;
515 * @deprecated
517 nsIDocument *GetCurrentDoc() const
519 return GetUncomposedDoc();
523 * This method gets the current doc of the node hosting this content
524 * or the current doc of this content if it is not being hosted. This
525 * method walks through ShadowRoot boundaries until it reach the host
526 * that is located in the root of the "tree of trees" (see Shadow DOM
527 * spec) and returns the current doc for that host.
529 nsIDocument* GetComposedDoc() const
531 return IsInShadowTree() ?
532 GetComposedDocInternal() : GetUncomposedDoc();
536 * @deprecated
538 nsIDocument* GetCrossShadowCurrentDoc() const
540 return GetComposedDoc();
544 * Returns true if GetComposedDoc() would return a non-null value.
546 bool IsInComposedDoc() const
548 return IsInUncomposedDoc() || (IsInShadowTree() && GetComposedDocInternal());
552 * The values returned by this function are the ones defined for
553 * nsIDOMNode.nodeType
555 uint16_t NodeType() const
557 return mNodeInfo->NodeType();
559 const nsString& NodeName() const
561 return mNodeInfo->NodeName();
563 const nsString& LocalName() const
565 return mNodeInfo->LocalName();
569 * Get the tag for this element. This will always return a non-null atom
570 * pointer (as implied by the naming of the method). For elements this is
571 * the non-namespaced tag, and for other nodes it's something like "#text",
572 * "#comment", "#document", etc.
574 nsIAtom* Tag() const
576 return mNodeInfo->NameAtom();
580 * Insert a content node at a particular index. This method handles calling
581 * BindToTree on the child appropriately.
583 * @param aKid the content to insert
584 * @param aIndex the index it is being inserted at (the index it will have
585 * after it is inserted)
586 * @param aNotify whether to notify the document (current document for
587 * nsIContent, and |this| for nsIDocument) that the insert has
588 * occurred
590 * @throws NS_ERROR_DOM_HIERARCHY_REQUEST_ERR if one attempts to have more
591 * than one element node as a child of a document. Doing this will also
592 * assert -- you shouldn't be doing it! Check with
593 * nsIDocument::GetRootElement() first if you're not sure. Apart from this
594 * one constraint, this doesn't do any checking on whether aKid is a valid
595 * child of |this|.
597 * @throws NS_ERROR_OUT_OF_MEMORY in some cases (from BindToTree).
599 virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex,
600 bool aNotify) = 0;
603 * Append a content node to the end of the child list. This method handles
604 * calling BindToTree on the child appropriately.
606 * @param aKid the content to append
607 * @param aNotify whether to notify the document (current document for
608 * nsIContent, and |this| for nsIDocument) that the append has
609 * occurred
611 * @throws NS_ERROR_DOM_HIERARCHY_REQUEST_ERR if one attempts to have more
612 * than one element node as a child of a document. Doing this will also
613 * assert -- you shouldn't be doing it! Check with
614 * nsIDocument::GetRootElement() first if you're not sure. Apart from this
615 * one constraint, this doesn't do any checking on whether aKid is a valid
616 * child of |this|.
618 * @throws NS_ERROR_OUT_OF_MEMORY in some cases (from BindToTree).
620 nsresult AppendChildTo(nsIContent* aKid, bool aNotify)
622 return InsertChildAt(aKid, GetChildCount(), aNotify);
626 * Remove a child from this node. This method handles calling UnbindFromTree
627 * on the child appropriately.
629 * @param aIndex the index of the child to remove
630 * @param aNotify whether to notify the document (current document for
631 * nsIContent, and |this| for nsIDocument) that the remove has
632 * occurred
634 * Note: If there is no child at aIndex, this method will simply do nothing.
636 virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) = 0;
639 * Get a property associated with this node.
641 * @param aPropertyName name of property to get.
642 * @param aStatus out parameter for storing resulting status.
643 * Set to NS_PROPTABLE_PROP_NOT_THERE if the property
644 * is not set.
645 * @return the property. Null if the property is not set
646 * (though a null return value does not imply the
647 * property was not set, i.e. it can be set to null).
649 void* GetProperty(nsIAtom *aPropertyName,
650 nsresult *aStatus = nullptr) const
652 return GetProperty(0, aPropertyName, aStatus);
656 * Get a property associated with this node.
658 * @param aCategory category of property to get.
659 * @param aPropertyName name of property to get.
660 * @param aStatus out parameter for storing resulting status.
661 * Set to NS_PROPTABLE_PROP_NOT_THERE if the property
662 * is not set.
663 * @return the property. Null if the property is not set
664 * (though a null return value does not imply the
665 * property was not set, i.e. it can be set to null).
667 virtual void* GetProperty(uint16_t aCategory,
668 nsIAtom *aPropertyName,
669 nsresult *aStatus = nullptr) const;
672 * Set a property to be associated with this node. This will overwrite an
673 * existing value if one exists. The existing value is destroyed using the
674 * destructor function given when that value was set.
676 * @param aPropertyName name of property to set.
677 * @param aValue new value of property.
678 * @param aDtor destructor function to be used when this property
679 * is destroyed.
680 * @param aTransfer if true the property will not be deleted when the
681 * ownerDocument of the node changes, if false it
682 * will be deleted.
684 * @return NS_PROPTABLE_PROP_OVERWRITTEN (success value) if the property
685 * was already set
686 * @throws NS_ERROR_OUT_OF_MEMORY if that occurs
688 nsresult SetProperty(nsIAtom *aPropertyName,
689 void *aValue,
690 NSPropertyDtorFunc aDtor = nullptr,
691 bool aTransfer = false)
693 return SetProperty(0, aPropertyName, aValue, aDtor, aTransfer);
697 * Set a property to be associated with this node. This will overwrite an
698 * existing value if one exists. The existing value is destroyed using the
699 * destructor function given when that value was set.
701 * @param aCategory category of property to set.
702 * @param aPropertyName name of property to set.
703 * @param aValue new value of property.
704 * @param aDtor destructor function to be used when this property
705 * is destroyed.
706 * @param aTransfer if true the property will not be deleted when the
707 * ownerDocument of the node changes, if false it
708 * will be deleted.
709 * @param aOldValue [out] previous value of property.
711 * @return NS_PROPTABLE_PROP_OVERWRITTEN (success value) if the property
712 * was already set
713 * @throws NS_ERROR_OUT_OF_MEMORY if that occurs
715 virtual nsresult SetProperty(uint16_t aCategory,
716 nsIAtom *aPropertyName,
717 void *aValue,
718 NSPropertyDtorFunc aDtor = nullptr,
719 bool aTransfer = false,
720 void **aOldValue = nullptr);
723 * A generic destructor for property values allocated with new.
725 template<class T>
726 static void DeleteProperty(void *, nsIAtom *, void *aPropertyValue, void *)
728 delete static_cast<T *>(aPropertyValue);
732 * Destroys a property associated with this node. The value is destroyed
733 * using the destruction function given when that value was set.
735 * @param aPropertyName name of property to destroy.
737 void DeleteProperty(nsIAtom *aPropertyName)
739 DeleteProperty(0, aPropertyName);
743 * Destroys a property associated with this node. The value is destroyed
744 * using the destruction function given when that value was set.
746 * @param aCategory category of property to destroy.
747 * @param aPropertyName name of property to destroy.
749 virtual void DeleteProperty(uint16_t aCategory, nsIAtom *aPropertyName);
752 * Unset a property associated with this node. The value will not be
753 * destroyed but rather returned. It is the caller's responsibility to
754 * destroy the value after that point.
756 * @param aPropertyName name of property to unset.
757 * @param aStatus out parameter for storing resulting status.
758 * Set to NS_PROPTABLE_PROP_NOT_THERE if the property
759 * is not set.
760 * @return the property. Null if the property is not set
761 * (though a null return value does not imply the
762 * property was not set, i.e. it can be set to null).
764 void* UnsetProperty(nsIAtom *aPropertyName,
765 nsresult *aStatus = nullptr)
767 return UnsetProperty(0, aPropertyName, aStatus);
771 * Unset a property associated with this node. The value will not be
772 * destroyed but rather returned. It is the caller's responsibility to
773 * destroy the value after that point.
775 * @param aCategory category of property to unset.
776 * @param aPropertyName name of property to unset.
777 * @param aStatus out parameter for storing resulting status.
778 * Set to NS_PROPTABLE_PROP_NOT_THERE if the property
779 * is not set.
780 * @return the property. Null if the property is not set
781 * (though a null return value does not imply the
782 * property was not set, i.e. it can be set to null).
784 virtual void* UnsetProperty(uint16_t aCategory,
785 nsIAtom *aPropertyName,
786 nsresult *aStatus = nullptr);
788 bool HasProperties() const
790 return HasFlag(NODE_HAS_PROPERTIES);
794 * Return the principal of this node. This is guaranteed to never be a null
795 * pointer.
797 nsIPrincipal* NodePrincipal() const {
798 return mNodeInfo->NodeInfoManager()->DocumentPrincipal();
802 * Get the parent nsIContent for this node.
803 * @return the parent, or null if no parent or the parent is not an nsIContent
805 nsIContent* GetParent() const {
806 return MOZ_LIKELY(GetBoolFlag(ParentIsContent)) ?
807 reinterpret_cast<nsIContent*>(mParent) : nullptr;
811 * Get the parent nsINode for this node. This can be either an nsIContent,
812 * an nsIDocument or an nsIAttribute.
813 * @return the parent node
815 nsINode* GetParentNode() const
817 return mParent;
821 * Get the parent nsINode for this node if it is an Element.
822 * @return the parent node
824 mozilla::dom::Element* GetParentElement() const
826 return mParent && mParent->IsElement() ? mParent->AsElement() : nullptr;
830 * Get the parent Element of this node, traversing over a ShadowRoot
831 * to its host if necessary.
833 mozilla::dom::Element* GetParentElementCrossingShadowRoot() const;
836 * Get the root of the subtree this node belongs to. This never returns
837 * null. It may return 'this' (e.g. for document nodes, and nodes that
838 * are the roots of disconnected subtrees).
840 nsINode* SubtreeRoot() const;
843 * See nsIDOMEventTarget
845 NS_DECL_NSIDOMEVENTTARGET
847 virtual mozilla::EventListenerManager*
848 GetExistingListenerManager() const MOZ_OVERRIDE;
849 virtual mozilla::EventListenerManager*
850 GetOrCreateListenerManager() MOZ_OVERRIDE;
852 using mozilla::dom::EventTarget::RemoveEventListener;
853 using nsIDOMEventTarget::AddEventListener;
854 virtual void AddEventListener(const nsAString& aType,
855 mozilla::dom::EventListener* aListener,
856 bool aUseCapture,
857 const mozilla::dom::Nullable<bool>& aWantsUntrusted,
858 mozilla::ErrorResult& aRv) MOZ_OVERRIDE;
859 using nsIDOMEventTarget::AddSystemEventListener;
860 virtual nsIDOMWindow* GetOwnerGlobal() MOZ_OVERRIDE;
863 * Adds a mutation observer to be notified when this node, or any of its
864 * descendants, are modified. The node will hold a weak reference to the
865 * observer, which means that it is the responsibility of the observer to
866 * remove itself in case it dies before the node. If an observer is added
867 * while observers are being notified, it may also be notified. In general,
868 * adding observers while inside a notification is not a good idea. An
869 * observer that is already observing the node must not be added without
870 * being removed first.
872 void AddMutationObserver(nsIMutationObserver* aMutationObserver)
874 nsSlots* s = Slots();
875 NS_ASSERTION(s->mMutationObservers.IndexOf(aMutationObserver) ==
876 nsTArray<int>::NoIndex,
877 "Observer already in the list");
878 s->mMutationObservers.AppendElement(aMutationObserver);
882 * Same as above, but only adds the observer if its not observing
883 * the node already.
885 void AddMutationObserverUnlessExists(nsIMutationObserver* aMutationObserver)
887 nsSlots* s = Slots();
888 s->mMutationObservers.AppendElementUnlessExists(aMutationObserver);
892 * Removes a mutation observer.
894 void RemoveMutationObserver(nsIMutationObserver* aMutationObserver)
896 nsSlots* s = GetExistingSlots();
897 if (s) {
898 s->mMutationObservers.RemoveElement(aMutationObserver);
903 * Clones this node. This needs to be overriden by all node classes. aNodeInfo
904 * should be identical to this node's nodeInfo, except for the document which
905 * may be different. When cloning an element, all attributes of the element
906 * will be cloned. The children of the node will not be cloned.
908 * @param aNodeInfo the nodeinfo to use for the clone
909 * @param aResult the clone
911 virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const = 0;
913 // This class can be extended by subclasses that wish to store more
914 // information in the slots.
915 class nsSlots
917 public:
918 nsSlots()
919 : mChildNodes(nullptr),
920 mWeakReference(nullptr)
924 // If needed we could remove the vtable pointer this dtor causes by
925 // putting a DestroySlots function on nsINode
926 virtual ~nsSlots();
928 void Traverse(nsCycleCollectionTraversalCallback &cb);
929 void Unlink();
932 * A list of mutation observers
934 nsTObserverArray<nsIMutationObserver*> mMutationObservers;
937 * An object implementing nsIDOMNodeList for this content (childNodes)
938 * @see nsIDOMNodeList
939 * @see nsGenericHTMLElement::GetChildNodes
941 * MSVC 7 doesn't like this as an nsRefPtr
943 nsChildContentList* mChildNodes;
946 * Weak reference to this node
948 nsNodeWeakReference* mWeakReference;
952 * Functions for managing flags and slots
954 #ifdef DEBUG
955 nsSlots* DebugGetSlots()
957 return Slots();
959 #endif
961 void SetFlags(FlagsType aFlagsToSet)
963 NS_ASSERTION(!(aFlagsToSet & (NODE_IS_ANONYMOUS_ROOT |
964 NODE_IS_NATIVE_ANONYMOUS_ROOT |
965 NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE |
966 NODE_DESCENDANTS_NEED_FRAMES |
967 NODE_NEEDS_FRAME |
968 NODE_CHROME_ONLY_ACCESS)) ||
969 IsNodeOfType(eCONTENT),
970 "Flag only permitted on nsIContent nodes");
971 nsWrapperCache::SetFlags(aFlagsToSet);
974 void UnsetFlags(FlagsType aFlagsToUnset)
976 NS_ASSERTION(!(aFlagsToUnset &
977 (NODE_IS_ANONYMOUS_ROOT |
978 NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE |
979 NODE_IS_NATIVE_ANONYMOUS_ROOT)),
980 "Trying to unset write-only flags");
981 nsWrapperCache::UnsetFlags(aFlagsToUnset);
984 void SetEditableFlag(bool aEditable)
986 if (aEditable) {
987 SetFlags(NODE_IS_EDITABLE);
989 else {
990 UnsetFlags(NODE_IS_EDITABLE);
994 bool IsEditable() const
996 #ifdef MOZILLA_INTERNAL_API
997 return IsEditableInternal();
998 #else
999 return IsEditableExternal();
1000 #endif
1004 * Returns true if |this| or any of its ancestors is native anonymous.
1006 bool IsInNativeAnonymousSubtree() const
1008 #ifdef DEBUG
1009 if (HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE)) {
1010 return true;
1012 CheckNotNativeAnonymous();
1013 return false;
1014 #else
1015 return HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE);
1016 #endif
1019 bool IsInAnonymousSubtree() const;
1021 // Note: This asserts |IsInAnonymousSubtree()|.
1022 bool IsAnonymousContentInSVGUseSubtree() const;
1024 // True for native anonymous content and for XBL content if the binging
1025 // has chromeOnlyContent="true".
1026 bool ChromeOnlyAccess() const
1028 return HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE | NODE_CHROME_ONLY_ACCESS);
1031 bool IsInShadowTree() const
1033 return HasFlag(NODE_IS_IN_SHADOW_TREE);
1037 * Returns true if |this| node is the common ancestor of the start/end
1038 * nodes of a Range in a Selection or a descendant of such a common ancestor.
1039 * This node is definitely not selected when |false| is returned, but it may
1040 * or may not be selected when |true| is returned.
1042 bool IsSelectionDescendant() const
1044 return IsDescendantOfCommonAncestorForRangeInSelection() ||
1045 IsCommonAncestorForRangeInSelection();
1049 * Get the root content of an editor. So, this node must be a descendant of
1050 * an editor. Note that this should be only used for getting input or textarea
1051 * editor's root content. This method doesn't support HTML editors.
1053 nsIContent* GetTextEditorRootContent(nsIEditor** aEditor = nullptr);
1056 * Get the nearest selection root, ie. the node that will be selected if the
1057 * user does "Select All" while the focus is in this node. Note that if this
1058 * node is not in an editor, the result comes from the nsFrameSelection that
1059 * is related to aPresShell, so the result might not be the ancestor of this
1060 * node. Be aware that if this node and the computed selection limiter are
1061 * not in same subtree, this returns the root content of the closeset subtree.
1063 nsIContent* GetSelectionRootContent(nsIPresShell* aPresShell);
1065 virtual nsINodeList* ChildNodes();
1066 nsIContent* GetFirstChild() const { return mFirstChild; }
1067 nsIContent* GetLastChild() const
1069 uint32_t count;
1070 nsIContent* const* children = GetChildArray(&count);
1072 return count > 0 ? children[count - 1] : nullptr;
1076 * Implementation is in nsIDocument.h, because it needs to cast from
1077 * nsIDocument* to nsINode*.
1079 nsIDocument* GetOwnerDocument() const;
1081 void Normalize();
1084 * Get the base URI for any relative URIs within this piece of
1085 * content. Generally, this is the document's base URI, but certain
1086 * content carries a local base for backward compatibility, and XML
1087 * supports setting a per-node base URI.
1089 * @return the base URI
1091 virtual already_AddRefed<nsIURI> GetBaseURI(bool aTryUseXHRDocBaseURI = false) const = 0;
1092 already_AddRefed<nsIURI> GetBaseURIObject() const;
1095 * Facility for explicitly setting a base URI on a node.
1097 nsresult SetExplicitBaseURI(nsIURI* aURI);
1099 * The explicit base URI, if set, otherwise null
1101 protected:
1102 nsIURI* GetExplicitBaseURI() const {
1103 if (HasExplicitBaseURI()) {
1104 return static_cast<nsIURI*>(GetProperty(nsGkAtoms::baseURIProperty));
1106 return nullptr;
1109 public:
1110 void GetTextContent(nsAString& aTextContent,
1111 mozilla::ErrorResult& aError)
1113 GetTextContentInternal(aTextContent, aError);
1115 void SetTextContent(const nsAString& aTextContent,
1116 mozilla::ErrorResult& aError)
1118 SetTextContentInternal(aTextContent, aError);
1121 mozilla::dom::Element* QuerySelector(const nsAString& aSelector,
1122 mozilla::ErrorResult& aResult);
1123 already_AddRefed<nsINodeList> QuerySelectorAll(const nsAString& aSelector,
1124 mozilla::ErrorResult& aResult);
1126 nsresult QuerySelector(const nsAString& aSelector, nsIDOMElement **aReturn);
1127 nsresult QuerySelectorAll(const nsAString& aSelector, nsIDOMNodeList **aReturn);
1129 protected:
1130 // nsIDocument overrides this with its own (faster) version. This
1131 // should really only be called for elements and document fragments.
1132 mozilla::dom::Element* GetElementById(const nsAString& aId);
1134 public:
1136 * Associate an object aData to aKey on this node. If aData is null any
1137 * previously registered object associated to aKey on this node will
1138 * be removed.
1139 * Should only be used to implement the DOM Level 3 UserData API.
1141 * @param aKey the key to associate the object to
1142 * @param aData the object to associate to aKey on this node (may be null)
1143 * @param aResult [out] the previously registered object for aKey on this
1144 * node, if any
1145 * @return whether adding the object succeeded
1147 nsresult SetUserData(const nsAString& aKey, nsIVariant* aData,
1148 nsIVariant** aResult);
1151 * Get the UserData object registered for a Key on this node, if any.
1152 * Should only be used to implement the DOM Level 3 UserData API.
1154 * @param aKey the key to get UserData for
1155 * @return aResult the previously registered object for aKey on this node, if
1156 * any
1158 nsIVariant* GetUserData(const nsAString& aKey);
1160 nsresult GetUserData(const nsAString& aKey, nsIVariant** aResult)
1162 NS_IF_ADDREF(*aResult = GetUserData(aKey));
1164 return NS_OK;
1167 void LookupPrefix(const nsAString& aNamespace, nsAString& aResult);
1168 bool IsDefaultNamespace(const nsAString& aNamespaceURI)
1170 nsAutoString defaultNamespace;
1171 LookupNamespaceURI(EmptyString(), defaultNamespace);
1172 return aNamespaceURI.Equals(defaultNamespace);
1174 void LookupNamespaceURI(const nsAString& aNamespacePrefix,
1175 nsAString& aNamespaceURI);
1177 nsresult IsEqualNode(nsIDOMNode* aOther, bool* aReturn);
1179 nsIContent* GetNextSibling() const { return mNextSibling; }
1180 nsIContent* GetPreviousSibling() const { return mPreviousSibling; }
1183 * Get the next node in the pre-order tree traversal of the DOM. If
1184 * aRoot is non-null, then it must be an ancestor of |this|
1185 * (possibly equal to |this|) and only nodes that are descendants of
1186 * aRoot, not including aRoot itself, will be returned. Returns
1187 * null if there are no more nodes to traverse.
1189 nsIContent* GetNextNode(const nsINode* aRoot = nullptr) const
1191 return GetNextNodeImpl(aRoot, false);
1195 * Get the next node in the pre-order tree traversal of the DOM but ignoring
1196 * the children of this node. If aRoot is non-null, then it must be an
1197 * ancestor of |this| (possibly equal to |this|) and only nodes that are
1198 * descendants of aRoot, not including aRoot itself, will be returned.
1199 * Returns null if there are no more nodes to traverse.
1201 nsIContent* GetNextNonChildNode(const nsINode* aRoot = nullptr) const
1203 return GetNextNodeImpl(aRoot, true);
1207 * Returns true if 'this' is either document or element or
1208 * document fragment and aOther is a descendant in the same
1209 * anonymous tree.
1211 bool Contains(const nsINode* aOther) const;
1212 nsresult Contains(nsIDOMNode* aOther, bool* aReturn);
1214 bool UnoptimizableCCNode() const;
1216 private:
1218 nsIDocument* GetComposedDocInternal() const;
1220 nsIContent* GetNextNodeImpl(const nsINode* aRoot,
1221 const bool aSkipChildren) const
1223 // Can't use nsContentUtils::ContentIsDescendantOf here, since we
1224 // can't include it here.
1225 #ifdef DEBUG
1226 if (aRoot) {
1227 const nsINode* cur = this;
1228 for (; cur; cur = cur->GetParentNode())
1229 if (cur == aRoot) break;
1230 NS_ASSERTION(cur, "aRoot not an ancestor of |this|?");
1232 #endif
1233 if (!aSkipChildren) {
1234 nsIContent* kid = GetFirstChild();
1235 if (kid) {
1236 return kid;
1239 if (this == aRoot) {
1240 return nullptr;
1242 const nsINode* cur = this;
1243 while (1) {
1244 nsIContent* next = cur->GetNextSibling();
1245 if (next) {
1246 return next;
1248 nsINode* parent = cur->GetParentNode();
1249 if (parent == aRoot) {
1250 return nullptr;
1252 cur = parent;
1254 NS_NOTREACHED("How did we get here?");
1257 public:
1260 * Get the previous nsIContent in the pre-order tree traversal of the DOM. If
1261 * aRoot is non-null, then it must be an ancestor of |this|
1262 * (possibly equal to |this|) and only nsIContents that are descendants of
1263 * aRoot, including aRoot itself, will be returned. Returns
1264 * null if there are no more nsIContents to traverse.
1266 nsIContent* GetPreviousContent(const nsINode* aRoot = nullptr) const
1268 // Can't use nsContentUtils::ContentIsDescendantOf here, since we
1269 // can't include it here.
1270 #ifdef DEBUG
1271 if (aRoot) {
1272 const nsINode* cur = this;
1273 for (; cur; cur = cur->GetParentNode())
1274 if (cur == aRoot) break;
1275 NS_ASSERTION(cur, "aRoot not an ancestor of |this|?");
1277 #endif
1279 if (this == aRoot) {
1280 return nullptr;
1282 nsIContent* cur = this->GetParent();
1283 nsIContent* iter = this->GetPreviousSibling();
1284 while (iter) {
1285 cur = iter;
1286 iter = reinterpret_cast<nsINode*>(iter)->GetLastChild();
1288 return cur;
1292 * Boolean flags
1294 private:
1295 enum BooleanFlag {
1296 // Set if we're being used from -moz-element
1297 NodeHasRenderingObservers,
1298 // Set if our parent chain (including this node itself) terminates
1299 // in a document
1300 IsInDocument,
1301 // Set if mParent is an nsIContent
1302 ParentIsContent,
1303 // Set if this node is an Element
1304 NodeIsElement,
1305 // Set if the element has a non-empty id attribute. This can in rare
1306 // cases lie for nsXMLElement, such as when the node has been moved between
1307 // documents with different id mappings.
1308 ElementHasID,
1309 // Set if the element might have inline style.
1310 ElementMayHaveStyle,
1311 // Set if the element has a name attribute set.
1312 ElementHasName,
1313 // Set if the element might have a contenteditable attribute set.
1314 ElementMayHaveContentEditableAttr,
1315 // Set if the node is the common ancestor of the start/end nodes of a Range
1316 // that is in a Selection.
1317 NodeIsCommonAncestorForRangeInSelection,
1318 // Set if the node is a descendant of a node with the above bit set.
1319 NodeIsDescendantOfCommonAncestorForRangeInSelection,
1320 // Set if CanSkipInCC check has been done for this subtree root.
1321 NodeIsCCMarkedRoot,
1322 // Maybe set if this node is in black subtree.
1323 NodeIsCCBlackTree,
1324 // Maybe set if the node is a root of a subtree
1325 // which needs to be kept in the purple buffer.
1326 NodeIsPurpleRoot,
1327 // Set if the node has an explicit base URI stored
1328 NodeHasExplicitBaseURI,
1329 // Set if the element has some style states locked
1330 ElementHasLockedStyleStates,
1331 // Set if element has pointer locked
1332 ElementHasPointerLock,
1333 // Set if the node may have DOMMutationObserver attached to it.
1334 NodeMayHaveDOMMutationObserver,
1335 // Set if node is Content
1336 NodeIsContent,
1337 // Set if the node has animations or transitions
1338 ElementHasAnimations,
1339 // Set if node has a dir attribute with a valid value (ltr, rtl, or auto)
1340 NodeHasValidDirAttribute,
1341 // Set if node has a dir attribute with a fixed value (ltr or rtl, NOT auto)
1342 NodeHasFixedDir,
1343 // Set if the node has dir=auto and has a property pointing to the text
1344 // node that determines its direction
1345 NodeHasDirAutoSet,
1346 // Set if the node is a text node descendant of a node with dir=auto
1347 // and has a TextNodeDirectionalityMap property listing the elements whose
1348 // direction it determines.
1349 NodeHasTextNodeDirectionalityMap,
1350 // Set if the node has dir=auto.
1351 NodeHasDirAuto,
1352 // Set if a node in the node's parent chain has dir=auto.
1353 NodeAncestorHasDirAuto,
1354 // Set if the element is in the scope of a scoped style sheet; this flag is
1355 // only accurate for elements bound to a document
1356 ElementIsInStyleScope,
1357 // Set if the element is a scoped style sheet root
1358 ElementIsScopedStyleRoot,
1359 // Set if the node is handling a click.
1360 NodeHandlingClick,
1361 // Set if the node has had :hover selectors matched against it
1362 NodeHasRelevantHoverRules,
1363 // Set if the element has a parser insertion mode other than "in body",
1364 // per the HTML5 "Parse state" section.
1365 ElementHasWeirdParserInsertionMode,
1366 // Parser sets this flag if it has notified about the node.
1367 ParserHasNotified,
1368 // Guard value
1369 BooleanFlagCount
1372 void SetBoolFlag(BooleanFlag name, bool value) {
1373 static_assert(BooleanFlagCount <= 8*sizeof(mBoolFlags),
1374 "Too many boolean flags");
1375 mBoolFlags = (mBoolFlags & ~(1 << name)) | (value << name);
1378 void SetBoolFlag(BooleanFlag name) {
1379 static_assert(BooleanFlagCount <= 8*sizeof(mBoolFlags),
1380 "Too many boolean flags");
1381 mBoolFlags |= (1 << name);
1384 void ClearBoolFlag(BooleanFlag name) {
1385 static_assert(BooleanFlagCount <= 8*sizeof(mBoolFlags),
1386 "Too many boolean flags");
1387 mBoolFlags &= ~(1 << name);
1390 bool GetBoolFlag(BooleanFlag name) const {
1391 static_assert(BooleanFlagCount <= 8*sizeof(mBoolFlags),
1392 "Too many boolean flags");
1393 return mBoolFlags & (1 << name);
1396 public:
1397 bool HasRenderingObservers() const
1398 { return GetBoolFlag(NodeHasRenderingObservers); }
1399 void SetHasRenderingObservers(bool aValue)
1400 { SetBoolFlag(NodeHasRenderingObservers, aValue); }
1401 bool IsContent() const { return GetBoolFlag(NodeIsContent); }
1402 bool HasID() const { return GetBoolFlag(ElementHasID); }
1403 bool MayHaveStyle() const { return GetBoolFlag(ElementMayHaveStyle); }
1404 bool HasName() const { return GetBoolFlag(ElementHasName); }
1405 bool MayHaveContentEditableAttr() const
1406 { return GetBoolFlag(ElementMayHaveContentEditableAttr); }
1407 bool IsCommonAncestorForRangeInSelection() const
1408 { return GetBoolFlag(NodeIsCommonAncestorForRangeInSelection); }
1409 void SetCommonAncestorForRangeInSelection()
1410 { SetBoolFlag(NodeIsCommonAncestorForRangeInSelection); }
1411 void ClearCommonAncestorForRangeInSelection()
1412 { ClearBoolFlag(NodeIsCommonAncestorForRangeInSelection); }
1413 bool IsDescendantOfCommonAncestorForRangeInSelection() const
1414 { return GetBoolFlag(NodeIsDescendantOfCommonAncestorForRangeInSelection); }
1415 void SetDescendantOfCommonAncestorForRangeInSelection()
1416 { SetBoolFlag(NodeIsDescendantOfCommonAncestorForRangeInSelection); }
1417 void ClearDescendantOfCommonAncestorForRangeInSelection()
1418 { ClearBoolFlag(NodeIsDescendantOfCommonAncestorForRangeInSelection); }
1420 void SetCCMarkedRoot(bool aValue)
1421 { SetBoolFlag(NodeIsCCMarkedRoot, aValue); }
1422 bool CCMarkedRoot() const { return GetBoolFlag(NodeIsCCMarkedRoot); }
1423 void SetInCCBlackTree(bool aValue)
1424 { SetBoolFlag(NodeIsCCBlackTree, aValue); }
1425 bool InCCBlackTree() const { return GetBoolFlag(NodeIsCCBlackTree); }
1426 void SetIsPurpleRoot(bool aValue)
1427 { SetBoolFlag(NodeIsPurpleRoot, aValue); }
1428 bool IsPurpleRoot() const { return GetBoolFlag(NodeIsPurpleRoot); }
1429 bool MayHaveDOMMutationObserver()
1430 { return GetBoolFlag(NodeMayHaveDOMMutationObserver); }
1431 void SetMayHaveDOMMutationObserver()
1432 { SetBoolFlag(NodeMayHaveDOMMutationObserver, true); }
1433 bool HasListenerManager() { return HasFlag(NODE_HAS_LISTENERMANAGER); }
1434 bool HasPointerLock() const { return GetBoolFlag(ElementHasPointerLock); }
1435 void SetPointerLock() { SetBoolFlag(ElementHasPointerLock); }
1436 void ClearPointerLock() { ClearBoolFlag(ElementHasPointerLock); }
1437 bool MayHaveAnimations() { return GetBoolFlag(ElementHasAnimations); }
1438 void SetMayHaveAnimations() { SetBoolFlag(ElementHasAnimations); }
1439 void SetHasValidDir() { SetBoolFlag(NodeHasValidDirAttribute); }
1440 void ClearHasValidDir() { ClearBoolFlag(NodeHasValidDirAttribute); }
1441 bool HasValidDir() const { return GetBoolFlag(NodeHasValidDirAttribute); }
1442 void SetHasFixedDir() {
1443 MOZ_ASSERT(NodeType() != nsIDOMNode::TEXT_NODE,
1444 "SetHasFixedDir on text node");
1445 SetBoolFlag(NodeHasFixedDir);
1447 void ClearHasFixedDir() {
1448 MOZ_ASSERT(NodeType() != nsIDOMNode::TEXT_NODE,
1449 "ClearHasFixedDir on text node");
1450 ClearBoolFlag(NodeHasFixedDir);
1452 bool HasFixedDir() const { return GetBoolFlag(NodeHasFixedDir); }
1453 void SetHasDirAutoSet() {
1454 MOZ_ASSERT(NodeType() != nsIDOMNode::TEXT_NODE,
1455 "SetHasDirAutoSet on text node");
1456 SetBoolFlag(NodeHasDirAutoSet);
1458 void ClearHasDirAutoSet() {
1459 MOZ_ASSERT(NodeType() != nsIDOMNode::TEXT_NODE,
1460 "ClearHasDirAutoSet on text node");
1461 ClearBoolFlag(NodeHasDirAutoSet);
1463 bool HasDirAutoSet() const
1464 { return GetBoolFlag(NodeHasDirAutoSet); }
1465 void SetHasTextNodeDirectionalityMap() {
1466 MOZ_ASSERT(NodeType() == nsIDOMNode::TEXT_NODE,
1467 "SetHasTextNodeDirectionalityMap on non-text node");
1468 SetBoolFlag(NodeHasTextNodeDirectionalityMap);
1470 void ClearHasTextNodeDirectionalityMap() {
1471 MOZ_ASSERT(NodeType() == nsIDOMNode::TEXT_NODE,
1472 "ClearHasTextNodeDirectionalityMap on non-text node");
1473 ClearBoolFlag(NodeHasTextNodeDirectionalityMap);
1475 bool HasTextNodeDirectionalityMap() const
1476 { return GetBoolFlag(NodeHasTextNodeDirectionalityMap); }
1478 void SetHasDirAuto() { SetBoolFlag(NodeHasDirAuto); }
1479 void ClearHasDirAuto() { ClearBoolFlag(NodeHasDirAuto); }
1480 bool HasDirAuto() const { return GetBoolFlag(NodeHasDirAuto); }
1482 void SetAncestorHasDirAuto() { SetBoolFlag(NodeAncestorHasDirAuto); }
1483 void ClearAncestorHasDirAuto() { ClearBoolFlag(NodeAncestorHasDirAuto); }
1484 bool AncestorHasDirAuto() const { return GetBoolFlag(NodeAncestorHasDirAuto); }
1486 bool NodeOrAncestorHasDirAuto() const
1487 { return HasDirAuto() || AncestorHasDirAuto(); }
1489 void SetIsElementInStyleScope(bool aValue) {
1490 MOZ_ASSERT(IsElement(), "SetIsInStyleScope on a non-Element node");
1491 SetBoolFlag(ElementIsInStyleScope, aValue);
1493 void SetIsElementInStyleScope() {
1494 MOZ_ASSERT(IsElement(), "SetIsInStyleScope on a non-Element node");
1495 SetBoolFlag(ElementIsInStyleScope);
1497 void ClearIsElementInStyleScope() {
1498 MOZ_ASSERT(IsElement(), "ClearIsInStyleScope on a non-Element node");
1499 ClearBoolFlag(ElementIsInStyleScope);
1501 bool IsElementInStyleScope() const { return GetBoolFlag(ElementIsInStyleScope); }
1503 void SetIsScopedStyleRoot() { SetBoolFlag(ElementIsScopedStyleRoot); }
1504 void ClearIsScopedStyleRoot() { ClearBoolFlag(ElementIsScopedStyleRoot); }
1505 bool IsScopedStyleRoot() { return GetBoolFlag(ElementIsScopedStyleRoot); }
1506 bool HasRelevantHoverRules() const { return GetBoolFlag(NodeHasRelevantHoverRules); }
1507 void SetHasRelevantHoverRules() { SetBoolFlag(NodeHasRelevantHoverRules); }
1508 void SetParserHasNotified() { SetBoolFlag(ParserHasNotified); };
1509 bool HasParserNotified() { return GetBoolFlag(ParserHasNotified); }
1510 protected:
1511 void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); }
1512 void SetInDocument() { SetBoolFlag(IsInDocument); }
1513 void SetNodeIsContent() { SetBoolFlag(NodeIsContent); }
1514 void ClearInDocument() { ClearBoolFlag(IsInDocument); }
1515 void SetIsElement() { SetBoolFlag(NodeIsElement); }
1516 void SetHasID() { SetBoolFlag(ElementHasID); }
1517 void ClearHasID() { ClearBoolFlag(ElementHasID); }
1518 void SetMayHaveStyle() { SetBoolFlag(ElementMayHaveStyle); }
1519 void SetHasName() { SetBoolFlag(ElementHasName); }
1520 void ClearHasName() { ClearBoolFlag(ElementHasName); }
1521 void SetMayHaveContentEditableAttr()
1522 { SetBoolFlag(ElementMayHaveContentEditableAttr); }
1523 bool HasExplicitBaseURI() const { return GetBoolFlag(NodeHasExplicitBaseURI); }
1524 void SetHasExplicitBaseURI() { SetBoolFlag(NodeHasExplicitBaseURI); }
1525 void SetHasLockedStyleStates() { SetBoolFlag(ElementHasLockedStyleStates); }
1526 void ClearHasLockedStyleStates() { ClearBoolFlag(ElementHasLockedStyleStates); }
1527 bool HasLockedStyleStates() const
1528 { return GetBoolFlag(ElementHasLockedStyleStates); }
1529 void SetHasWeirdParserInsertionMode() { SetBoolFlag(ElementHasWeirdParserInsertionMode); }
1530 bool HasWeirdParserInsertionMode() const
1531 { return GetBoolFlag(ElementHasWeirdParserInsertionMode); }
1532 bool HandlingClick() const { return GetBoolFlag(NodeHandlingClick); }
1533 void SetHandlingClick() { SetBoolFlag(NodeHandlingClick); }
1534 void ClearHandlingClick() { ClearBoolFlag(NodeHandlingClick); }
1536 void SetSubtreeRootPointer(nsINode* aSubtreeRoot)
1538 NS_ASSERTION(aSubtreeRoot, "aSubtreeRoot can never be null!");
1539 NS_ASSERTION(!(IsNodeOfType(eCONTENT) && IsInDoc()) &&
1540 !IsInShadowTree(), "Shouldn't be here!");
1541 mSubtreeRoot = aSubtreeRoot;
1544 void ClearSubtreeRootPointer()
1546 mSubtreeRoot = nullptr;
1549 public:
1550 // Makes nsINode object to keep aObject alive.
1551 void BindObject(nsISupports* aObject);
1552 // After calling UnbindObject nsINode object doesn't keep
1553 // aObject alive anymore.
1554 void UnbindObject(nsISupports* aObject);
1556 void GetBoundMutationObservers(nsTArray<nsRefPtr<nsDOMMutationObserver> >& aResult);
1559 * Returns the length of this node, as specified at
1560 * <http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node-length>
1562 uint32_t Length() const;
1564 void GetNodeName(mozilla::dom::DOMString& aNodeName)
1566 const nsString& nodeName = NodeName();
1567 aNodeName.SetStringBuffer(nsStringBuffer::FromString(nodeName),
1568 nodeName.Length());
1570 void GetBaseURI(nsAString& aBaseURI) const;
1571 // Return the base URI for the document.
1572 // The returned value may differ if the document is loaded via XHR, and
1573 // when accessed from chrome privileged script and
1574 // from content privileged script for compatibility.
1575 void GetBaseURIFromJS(nsAString& aBaseURI) const;
1576 bool HasChildNodes() const
1578 return HasChildren();
1580 uint16_t CompareDocumentPosition(nsINode& aOther) const;
1581 void GetNodeValue(nsAString& aNodeValue)
1583 GetNodeValueInternal(aNodeValue);
1585 void SetNodeValue(const nsAString& aNodeValue,
1586 mozilla::ErrorResult& aError)
1588 SetNodeValueInternal(aNodeValue, aError);
1590 virtual void GetNodeValueInternal(nsAString& aNodeValue);
1591 virtual void SetNodeValueInternal(const nsAString& aNodeValue,
1592 mozilla::ErrorResult& aError)
1594 // The DOM spec says that when nodeValue is defined to be null "setting it
1595 // has no effect", so we don't throw an exception.
1597 nsINode* InsertBefore(nsINode& aNode, nsINode* aChild,
1598 mozilla::ErrorResult& aError)
1600 return ReplaceOrInsertBefore(false, &aNode, aChild, aError);
1602 nsINode* AppendChild(nsINode& aNode, mozilla::ErrorResult& aError)
1604 return InsertBefore(aNode, nullptr, aError);
1606 nsINode* ReplaceChild(nsINode& aNode, nsINode& aChild,
1607 mozilla::ErrorResult& aError)
1609 return ReplaceOrInsertBefore(true, &aNode, &aChild, aError);
1611 nsINode* RemoveChild(nsINode& aChild, mozilla::ErrorResult& aError);
1612 already_AddRefed<nsINode> CloneNode(bool aDeep, mozilla::ErrorResult& aError);
1613 bool IsEqualNode(nsINode* aNode);
1614 void GetNamespaceURI(nsAString& aNamespaceURI) const
1616 mNodeInfo->GetNamespaceURI(aNamespaceURI);
1618 #ifdef MOZILLA_INTERNAL_API
1619 void GetPrefix(nsAString& aPrefix)
1621 mNodeInfo->GetPrefix(aPrefix);
1623 #endif
1624 void GetLocalName(mozilla::dom::DOMString& aLocalName)
1626 const nsString& localName = LocalName();
1627 if (localName.IsVoid()) {
1628 aLocalName.SetNull();
1629 } else {
1630 aLocalName.SetStringBuffer(nsStringBuffer::FromString(localName),
1631 localName.Length());
1635 nsDOMAttributeMap* GetAttributes();
1636 void SetUserData(JSContext* aCx, const nsAString& aKey,
1637 JS::Handle<JS::Value> aData,
1638 JS::MutableHandle<JS::Value> aRetval,
1639 mozilla::ErrorResult& aError);
1640 void GetUserData(JSContext* aCx, const nsAString& aKey,
1641 JS::MutableHandle<JS::Value> aRetval,
1642 mozilla::ErrorResult& aError);
1644 // Helper method to remove this node from its parent. This is not exposed
1645 // through WebIDL.
1646 // Only call this if the node has a parent node.
1647 nsresult RemoveFromParent()
1649 nsINode* parent = GetParentNode();
1650 mozilla::ErrorResult rv;
1651 parent->RemoveChild(*this, rv);
1652 return rv.ErrorCode();
1655 // ChildNode methods
1656 mozilla::dom::Element* GetPreviousElementSibling() const;
1657 mozilla::dom::Element* GetNextElementSibling() const;
1659 * Remove this node from its parent, if any.
1661 void Remove();
1663 // ParentNode methods
1664 mozilla::dom::Element* GetFirstElementChild() const;
1665 mozilla::dom::Element* GetLastElementChild() const;
1667 void GetBoxQuads(const BoxQuadOptions& aOptions,
1668 nsTArray<nsRefPtr<DOMQuad> >& aResult,
1669 mozilla::ErrorResult& aRv);
1671 already_AddRefed<DOMQuad> ConvertQuadFromNode(DOMQuad& aQuad,
1672 const TextOrElementOrDocument& aFrom,
1673 const ConvertCoordinateOptions& aOptions,
1674 ErrorResult& aRv);
1675 already_AddRefed<DOMQuad> ConvertRectFromNode(DOMRectReadOnly& aRect,
1676 const TextOrElementOrDocument& aFrom,
1677 const ConvertCoordinateOptions& aOptions,
1678 ErrorResult& aRv);
1679 already_AddRefed<DOMPoint> ConvertPointFromNode(const DOMPointInit& aPoint,
1680 const TextOrElementOrDocument& aFrom,
1681 const ConvertCoordinateOptions& aOptions,
1682 ErrorResult& aRv);
1684 protected:
1686 // Override this function to create a custom slots class.
1687 // Must not return null.
1688 virtual nsINode::nsSlots* CreateSlots();
1690 bool HasSlots() const
1692 return mSlots != nullptr;
1695 nsSlots* GetExistingSlots() const
1697 return mSlots;
1700 nsSlots* Slots()
1702 if (!HasSlots()) {
1703 mSlots = CreateSlots();
1704 MOZ_ASSERT(mSlots);
1706 return GetExistingSlots();
1709 nsTObserverArray<nsIMutationObserver*> *GetMutationObservers()
1711 return HasSlots() ? &GetExistingSlots()->mMutationObservers : nullptr;
1714 bool IsEditableInternal() const;
1715 virtual bool IsEditableExternal() const
1717 return IsEditableInternal();
1720 virtual void GetTextContentInternal(nsAString& aTextContent,
1721 mozilla::ErrorResult& aError);
1722 virtual void SetTextContentInternal(const nsAString& aTextContent,
1723 mozilla::ErrorResult& aError)
1727 #ifdef DEBUG
1728 // Note: virtual so that IsInNativeAnonymousSubtree can be called accross
1729 // module boundaries.
1730 virtual void CheckNotNativeAnonymous() const;
1731 #endif
1733 // These are just used to implement nsIDOMNode using
1734 // NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER and for quickstubs.
1735 nsresult GetParentNode(nsIDOMNode** aParentNode);
1736 nsresult GetParentElement(nsIDOMElement** aParentElement);
1737 nsresult GetChildNodes(nsIDOMNodeList** aChildNodes);
1738 nsresult GetFirstChild(nsIDOMNode** aFirstChild);
1739 nsresult GetLastChild(nsIDOMNode** aLastChild);
1740 nsresult GetPreviousSibling(nsIDOMNode** aPrevSibling);
1741 nsresult GetNextSibling(nsIDOMNode** aNextSibling);
1742 nsresult GetOwnerDocument(nsIDOMDocument** aOwnerDocument);
1743 nsresult CompareDocumentPosition(nsIDOMNode* aOther,
1744 uint16_t* aReturn);
1746 nsresult ReplaceOrInsertBefore(bool aReplace, nsIDOMNode *aNewChild,
1747 nsIDOMNode *aRefChild, nsIDOMNode **aReturn);
1748 nsINode* ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
1749 nsINode* aRefChild,
1750 mozilla::ErrorResult& aError);
1751 nsresult RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn);
1754 * Returns the Element that should be used for resolving namespaces
1755 * on this node (ie the ownerElement for attributes, the documentElement for
1756 * documents, the node itself for elements and for other nodes the parentNode
1757 * if it is an element).
1759 virtual mozilla::dom::Element* GetNameSpaceElement() = 0;
1762 * Most of the implementation of the nsINode RemoveChildAt method.
1763 * Should only be called on document, element, and document fragment
1764 * nodes. The aChildArray passed in should be the one for |this|.
1766 * @param aIndex The index to remove at.
1767 * @param aNotify Whether to notify.
1768 * @param aKid The kid at aIndex. Must not be null.
1769 * @param aChildArray The child array to work with.
1770 * @param aMutationEvent whether to fire a mutation event for this removal.
1772 void doRemoveChildAt(uint32_t aIndex, bool aNotify, nsIContent* aKid,
1773 nsAttrAndChildArray& aChildArray);
1776 * Most of the implementation of the nsINode InsertChildAt method.
1777 * Should only be called on document, element, and document fragment
1778 * nodes. The aChildArray passed in should be the one for |this|.
1780 * @param aKid The child to insert.
1781 * @param aIndex The index to insert at.
1782 * @param aNotify Whether to notify.
1783 * @param aChildArray The child array to work with
1785 nsresult doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
1786 bool aNotify, nsAttrAndChildArray& aChildArray);
1789 * Parse the given selector string into an nsCSSSelectorList.
1791 * A null return value with a non-failing aRv means the string only
1792 * contained pseudo-element selectors.
1794 * A failing aRv means the string was not a valid selector.
1796 nsCSSSelectorList* ParseSelectorList(const nsAString& aSelectorString,
1797 mozilla::ErrorResult& aRv);
1799 public:
1800 /* Event stuff that documents and elements share. This needs to be
1801 NS_IMETHOD because some subclasses implement DOM methods with
1802 this exact name and signature and then the calling convention
1803 needs to match.
1805 Note that we include DOCUMENT_ONLY_EVENT events here so that we
1806 can forward all the document stuff to this implementation.
1808 #define EVENT(name_, id_, type_, struct_) \
1809 mozilla::dom::EventHandlerNonNull* GetOn##name_(); \
1810 void SetOn##name_(mozilla::dom::EventHandlerNonNull* listener);
1811 #define TOUCH_EVENT EVENT
1812 #define DOCUMENT_ONLY_EVENT EVENT
1813 #include "mozilla/EventNameList.h"
1814 #undef DOCUMENT_ONLY_EVENT
1815 #undef TOUCH_EVENT
1816 #undef EVENT
1818 protected:
1819 static bool Traverse(nsINode *tmp, nsCycleCollectionTraversalCallback &cb);
1820 static void Unlink(nsINode *tmp);
1822 nsRefPtr<mozilla::dom::NodeInfo> mNodeInfo;
1824 nsINode* mParent;
1826 private:
1827 // Boolean flags.
1828 uint32_t mBoolFlags;
1830 protected:
1831 nsIContent* mNextSibling;
1832 nsIContent* mPreviousSibling;
1833 nsIContent* mFirstChild;
1835 union {
1836 // Pointer to our primary frame. Might be null.
1837 nsIFrame* mPrimaryFrame;
1839 // Pointer to the root of our subtree. Might be null.
1840 nsINode* mSubtreeRoot;
1843 // Storage for more members that are usually not needed; allocated lazily.
1844 nsSlots* mSlots;
1847 inline nsIDOMNode* GetAsDOMNode(nsINode* aNode)
1849 return aNode ? aNode->AsDOMNode() : nullptr;
1852 // Useful inline function for getting a node given an nsIContent and an
1853 // nsIDocument. Returns the first argument cast to nsINode if it is non-null,
1854 // otherwise returns the second (which may be null). We use type variables
1855 // instead of nsIContent* and nsIDocument* because the actual types must be
1856 // known for the cast to work.
1857 template<class C, class D>
1858 inline nsINode* NODE_FROM(C& aContent, D& aDocument)
1860 if (aContent)
1861 return static_cast<nsINode*>(aContent);
1862 return static_cast<nsINode*>(aDocument);
1865 NS_DEFINE_STATIC_IID_ACCESSOR(nsINode, NS_INODE_IID)
1867 inline nsISupports*
1868 ToSupports(nsINode* aPointer)
1870 return aPointer;
1873 inline nsISupports*
1874 ToCanonicalSupports(nsINode* aPointer)
1876 return aPointer;
1879 #define NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER(...) \
1880 NS_IMETHOD GetNodeName(nsAString& aNodeName) __VA_ARGS__ MOZ_OVERRIDE \
1882 aNodeName = nsINode::NodeName(); \
1883 return NS_OK; \
1885 NS_IMETHOD GetNodeValue(nsAString& aNodeValue) __VA_ARGS__ MOZ_OVERRIDE \
1887 nsINode::GetNodeValue(aNodeValue); \
1888 return NS_OK; \
1890 NS_IMETHOD SetNodeValue(const nsAString& aNodeValue) __VA_ARGS__ MOZ_OVERRIDE \
1892 mozilla::ErrorResult rv; \
1893 nsINode::SetNodeValue(aNodeValue, rv); \
1894 return rv.ErrorCode(); \
1896 NS_IMETHOD GetNodeType(uint16_t* aNodeType) __VA_ARGS__ MOZ_OVERRIDE \
1898 *aNodeType = nsINode::NodeType(); \
1899 return NS_OK; \
1901 NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode) __VA_ARGS__ MOZ_OVERRIDE \
1903 return nsINode::GetParentNode(aParentNode); \
1905 NS_IMETHOD GetParentElement(nsIDOMElement** aParentElement) __VA_ARGS__ MOZ_OVERRIDE \
1907 return nsINode::GetParentElement(aParentElement); \
1909 NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes) __VA_ARGS__ MOZ_OVERRIDE \
1911 return nsINode::GetChildNodes(aChildNodes); \
1913 NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild) __VA_ARGS__ MOZ_OVERRIDE \
1915 return nsINode::GetFirstChild(aFirstChild); \
1917 NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild) __VA_ARGS__ MOZ_OVERRIDE \
1919 return nsINode::GetLastChild(aLastChild); \
1921 NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling) __VA_ARGS__ MOZ_OVERRIDE \
1923 return nsINode::GetPreviousSibling(aPreviousSibling); \
1925 NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling) __VA_ARGS__ MOZ_OVERRIDE \
1927 return nsINode::GetNextSibling(aNextSibling); \
1929 NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument) __VA_ARGS__ MOZ_OVERRIDE \
1931 return nsINode::GetOwnerDocument(aOwnerDocument); \
1933 NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aResult) __VA_ARGS__ MOZ_OVERRIDE \
1935 return ReplaceOrInsertBefore(false, aNewChild, aRefChild, aResult); \
1937 NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aResult) __VA_ARGS__ MOZ_OVERRIDE \
1939 return ReplaceOrInsertBefore(true, aNewChild, aOldChild, aResult); \
1941 NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aResult) __VA_ARGS__ MOZ_OVERRIDE \
1943 return nsINode::RemoveChild(aOldChild, aResult); \
1945 NS_IMETHOD AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aResult) __VA_ARGS__ MOZ_OVERRIDE \
1947 return InsertBefore(aNewChild, nullptr, aResult); \
1949 NS_IMETHOD HasChildNodes(bool* aResult) __VA_ARGS__ MOZ_OVERRIDE \
1951 *aResult = nsINode::HasChildNodes(); \
1952 return NS_OK; \
1954 NS_IMETHOD CloneNode(bool aDeep, uint8_t aArgc, nsIDOMNode** aResult) __VA_ARGS__ MOZ_OVERRIDE \
1956 if (aArgc == 0) { \
1957 aDeep = true; \
1959 mozilla::ErrorResult rv; \
1960 nsCOMPtr<nsINode> clone = nsINode::CloneNode(aDeep, rv); \
1961 if (rv.Failed()) { \
1962 return rv.ErrorCode(); \
1964 *aResult = clone.forget().take()->AsDOMNode(); \
1965 return NS_OK; \
1967 NS_IMETHOD Normalize() __VA_ARGS__ MOZ_OVERRIDE \
1969 nsINode::Normalize(); \
1970 return NS_OK; \
1972 NS_IMETHOD GetNamespaceURI(nsAString& aNamespaceURI) __VA_ARGS__ MOZ_OVERRIDE \
1974 nsINode::GetNamespaceURI(aNamespaceURI); \
1975 return NS_OK; \
1977 NS_IMETHOD GetPrefix(nsAString& aPrefix) __VA_ARGS__ MOZ_OVERRIDE \
1979 nsINode::GetPrefix(aPrefix); \
1980 return NS_OK; \
1982 NS_IMETHOD GetLocalName(nsAString& aLocalName) __VA_ARGS__ MOZ_OVERRIDE \
1984 aLocalName = nsINode::LocalName(); \
1985 return NS_OK; \
1987 NS_IMETHOD UnusedPlaceholder(bool* aResult) __VA_ARGS__ MOZ_OVERRIDE \
1989 *aResult = false; \
1990 return NS_OK; \
1992 NS_IMETHOD GetDOMBaseURI(nsAString& aBaseURI) __VA_ARGS__ MOZ_OVERRIDE \
1994 nsINode::GetBaseURI(aBaseURI); \
1995 return NS_OK; \
1997 NS_IMETHOD CompareDocumentPosition(nsIDOMNode* aOther, uint16_t* aResult) __VA_ARGS__ MOZ_OVERRIDE \
1999 return nsINode::CompareDocumentPosition(aOther, aResult); \
2001 NS_IMETHOD GetTextContent(nsAString& aTextContent) __VA_ARGS__ MOZ_OVERRIDE \
2003 mozilla::ErrorResult rv; \
2004 nsINode::GetTextContent(aTextContent, rv); \
2005 return rv.ErrorCode(); \
2007 NS_IMETHOD SetTextContent(const nsAString& aTextContent) __VA_ARGS__ MOZ_OVERRIDE \
2009 mozilla::ErrorResult rv; \
2010 nsINode::SetTextContent(aTextContent, rv); \
2011 return rv.ErrorCode(); \
2013 NS_IMETHOD LookupPrefix(const nsAString& aNamespaceURI, nsAString& aResult) __VA_ARGS__ MOZ_OVERRIDE \
2015 nsINode::LookupPrefix(aNamespaceURI, aResult); \
2016 return NS_OK; \
2018 NS_IMETHOD IsDefaultNamespace(const nsAString& aNamespaceURI, bool* aResult) __VA_ARGS__ MOZ_OVERRIDE \
2020 *aResult = nsINode::IsDefaultNamespace(aNamespaceURI); \
2021 return NS_OK; \
2023 NS_IMETHOD LookupNamespaceURI(const nsAString& aPrefix, nsAString& aResult) __VA_ARGS__ MOZ_OVERRIDE \
2025 nsINode::LookupNamespaceURI(aPrefix, aResult); \
2026 return NS_OK; \
2028 NS_IMETHOD IsEqualNode(nsIDOMNode* aArg, bool* aResult) __VA_ARGS__ MOZ_OVERRIDE \
2030 return nsINode::IsEqualNode(aArg, aResult); \
2032 NS_IMETHOD SetUserData(const nsAString& aKey, nsIVariant* aData, nsIVariant** aResult) __VA_ARGS__ MOZ_OVERRIDE \
2034 return nsINode::SetUserData(aKey, aData, aResult); \
2036 NS_IMETHOD GetUserData(const nsAString& aKey, nsIVariant** aResult) __VA_ARGS__ MOZ_OVERRIDE \
2038 return nsINode::GetUserData(aKey, aResult); \
2040 NS_IMETHOD Contains(nsIDOMNode* aOther, bool* aResult) __VA_ARGS__ MOZ_OVERRIDE \
2042 return nsINode::Contains(aOther, aResult); \
2045 #define NS_FORWARD_NSIDOMNODE_TO_NSINODE \
2046 NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER(MOZ_FINAL)
2048 #define NS_FORWARD_NSIDOMNODE_TO_NSINODE_OVERRIDABLE \
2049 NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER()
2051 #endif /* nsINode_h___ */