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