/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//* vim: set ts=8 sts=2 et sw=2 tw=80: *//* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */#ifndef nsINode_h___#define nsINode_h___#include"mozilla/Likely.h"#include"nsCOMPtr.h" // for member, local#include"nsGkAtoms.h" // for nsGkAtoms::baseURIProperty#include"nsIDOMNode.h"#include"mozilla/dom/NodeInfo.h" // member (in nsCOMPtr)#include"nsIVariant.h" // for use in GetUserData()#include"nsNodeInfoManager.h" // for use in NodePrincipal()#include"nsPropertyTable.h" // for typedefs#include"nsTObserverArray.h" // for member#include"mozilla/ErrorResult.h"#include"mozilla/MemoryReporting.h"#include"mozilla/dom/EventTarget.h" // for base class#include"js/TypeDecls.h" // for Handle, Value, JSObject, JSContext#include"mozilla/dom/DOMString.h"#include"mozilla/dom/BindingDeclarations.h"#include<iosfwd>// Including 'windows.h' will #define GetClassInfo to something else.#ifdef XP_WIN#ifdef GetClassInfo#undef GetClassInfo#endif#endifclassnsAttrAndChildArray;classnsChildContentList;structnsCSSSelectorList;classnsDOMAttributeMap;classnsIAnimationObserver;classnsIContent;classnsIDocument;classnsIDOMElement;classnsIDOMNodeList;classnsIEditor;classnsIFrame;classnsIMutationObserver;classnsINode;classnsINodeList;classnsIPresShell;classnsIPrincipal;classnsIURI;classnsNodeSupportsWeakRefTearoff;classnsNodeWeakReference;classnsDOMMutationObserver;namespacemozilla{classEventListenerManager;namespacedom{/** * @return true if aChar is what the DOM spec defines as 'space character'. * http://dom.spec.whatwg.org/#space-character */inlineboolIsSpaceCharacter(char16_taChar){returnaChar==' '||aChar=='\t'||aChar=='\n'||aChar=='\r'||aChar=='\f';}inlineboolIsSpaceCharacter(charaChar){returnaChar==' '||aChar=='\t'||aChar=='\n'||aChar=='\r'||aChar=='\f';}structBoxQuadOptions;structConvertCoordinateOptions;classDOMPoint;classDOMQuad;classDOMRectReadOnly;classElement;classEventHandlerNonNull;template<typenameT>classOptional;classText;classTextOrElementOrDocument;structDOMPointInit;}// namespace dom}// namespace mozilla#define NODE_FLAG_BIT(n_) \ (nsWrapperCache::FlagsType(1U) << (WRAPPER_CACHE_FLAGS_BITS_USED + (n_)))enum{// This bit will be set if the node has a listener manager.NODE_HAS_LISTENERMANAGER=NODE_FLAG_BIT(0),// Whether this node has had any properties set on itNODE_HAS_PROPERTIES=NODE_FLAG_BIT(1),// Whether this node is the root of an anonymous subtree. Note that this// need not be a native anonymous subtree. Any anonymous subtree, including// XBL-generated ones, will do. This flag is set-once: once a node has it,// it must not be removed.// NOTE: Should only be used on nsIContent nodesNODE_IS_ANONYMOUS_ROOT=NODE_FLAG_BIT(2),// Whether the node has some ancestor, possibly itself, that is native// anonymous. This includes ancestors crossing XBL scopes, in cases when an// XBL binding is attached to an element which has a native anonymous// ancestor. This flag is set-once: once a node has it, it must not be// removed.// NOTE: Should only be used on nsIContent nodesNODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE=NODE_FLAG_BIT(3),// Whether this node is the root of a native anonymous (from the perspective// of its parent) subtree. This flag is set-once: once a node has it, it// must not be removed.// NOTE: Should only be used on nsIContent nodesNODE_IS_NATIVE_ANONYMOUS_ROOT=NODE_FLAG_BIT(4),// Forces the XBL code to treat this node as if it were// in the document and therefore should get bindings attached.NODE_FORCE_XBL_BINDINGS=NODE_FLAG_BIT(5),// Whether a binding manager may have a pointer to thisNODE_MAY_BE_IN_BINDING_MNGR=NODE_FLAG_BIT(6),NODE_IS_EDITABLE=NODE_FLAG_BIT(7),// For all Element nodes, NODE_MAY_HAVE_CLASS is guaranteed to be set if the// node in fact has a class, but may be set even if it doesn't.NODE_MAY_HAVE_CLASS=NODE_FLAG_BIT(8),// Whether the node participates in a shadow tree.NODE_IS_IN_SHADOW_TREE=NODE_FLAG_BIT(9),// Node has an :empty or :-moz-only-whitespace selectorNODE_HAS_EMPTY_SELECTOR=NODE_FLAG_BIT(10),// A child of the node has a selector such that any insertion,// removal, or appending of children requires restyling the parent.NODE_HAS_SLOW_SELECTOR=NODE_FLAG_BIT(11),// A child of the node has a :first-child, :-moz-first-node,// :only-child, :last-child or :-moz-last-node selector.NODE_HAS_EDGE_CHILD_SELECTOR=NODE_FLAG_BIT(12),// A child of the node has a selector such that any insertion or// removal of children requires restyling later siblings of that// element. Additionally (in this manner it is stronger than// NODE_HAS_SLOW_SELECTOR), if a child's style changes due to any// other content tree changes (e.g., the child changes to or from// matching :empty due to a grandchild insertion or removal), the// child's later siblings must also be restyled.NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS=NODE_FLAG_BIT(13),NODE_ALL_SELECTOR_FLAGS=NODE_HAS_EMPTY_SELECTOR|NODE_HAS_SLOW_SELECTOR|NODE_HAS_EDGE_CHILD_SELECTOR|NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS,// This node needs to go through frame construction to get a frame (or// undisplayed entry).NODE_NEEDS_FRAME=NODE_FLAG_BIT(14),// At least one descendant in the flattened tree has NODE_NEEDS_FRAME set.// This should be set on every node on the flattened tree path between the// node(s) with NODE_NEEDS_FRAME and the root content.NODE_DESCENDANTS_NEED_FRAMES=NODE_FLAG_BIT(15),// Set if the node has the accesskey attribute set.NODE_HAS_ACCESSKEY=NODE_FLAG_BIT(16),// Set if the node has right-to-left directionalityNODE_HAS_DIRECTION_RTL=NODE_FLAG_BIT(17),// Set if the node has left-to-right directionalityNODE_HAS_DIRECTION_LTR=NODE_FLAG_BIT(18),NODE_ALL_DIRECTION_FLAGS=NODE_HAS_DIRECTION_LTR|NODE_HAS_DIRECTION_RTL,NODE_CHROME_ONLY_ACCESS=NODE_FLAG_BIT(19),NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS=NODE_FLAG_BIT(20),// Remaining bits are node type specific.NODE_TYPE_SPECIFIC_BITS_OFFSET=21};// Make sure we have space for our bits#define ASSERT_NODE_FLAGS_SPACE(n) \ static_assert(WRAPPER_CACHE_FLAGS_BITS_USED + (n) <= \ sizeof(nsWrapperCache::FlagsType) * 8, \ "Not enough space for our bits")ASSERT_NODE_FLAGS_SPACE(NODE_TYPE_SPECIFIC_BITS_OFFSET);/** * Class used to detect unexpected mutations. To use the class create an * nsMutationGuard on the stack before unexpected mutations could occur. * You can then at any time call Mutated to check if any unexpected mutations * have occurred. */classnsMutationGuard{public:nsMutationGuard(){mStartingGeneration=sGeneration;}/** * Returns true if any unexpected mutations have occurred. You can pass in * an 8-bit ignore count to ignore a number of expected mutations. * * We don't need to care about overflow because subtraction of uint64_t's is * finding the difference between two elements of the group Z < 2^64. Once * we know the difference between two elements we only need to check that is * less than the given number of mutations to know less than that many * mutations occured. Assuming constant 1ns mutations it would take 584 * years for sGeneration to fully wrap around so we can ignore a guard living * through a full wrap around. */boolMutated(uint8_taIgnoreCount){return(sGeneration-mStartingGeneration)>aIgnoreCount;}// This function should be called whenever a mutation that we want to keep// track of happen. For now this is only done when children are added or// removed, but we might do it for attribute changes too in the future.staticvoidDidMutate(){sGeneration++;}private:// This is the value sGeneration had when the guard was constructed.uint64_tmStartingGeneration;// This value is incremented on every mutation, for the life of the process.staticuint64_tsGeneration;};// This should be used for any nsINode sub-class that has fields of its own// that it needs to measure; any sub-class that doesn't use it will inherit// SizeOfExcludingThis from its super-class. SizeOfIncludingThis() need not be// defined, it is inherited from nsINode.// This macro isn't actually specific to nodes, and bug 956400 will move it into MFBT.#define NS_DECL_SIZEOF_EXCLUDING_THIS \ virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;// Categories of node properties// 0 is global.#define DOM_USER_DATA 1#define SMIL_MAPPED_ATTR_ANIMVAL 2// IID for the nsINode interface#define NS_INODE_IID \{ 0x70ba4547, 0x7699, 0x44fc, \ { 0xb3, 0x20, 0x52, 0xdb, 0xe3, 0xd1, 0xf9, 0x0a } }/** * An internal interface that abstracts some DOMNode-related parts that both * nsIContent and nsIDocument share. An instance of this interface has a list * of nsIContent children and provides access to them. */classnsINode:publicmozilla::dom::EventTarget{public:typedefmozilla::dom::BoxQuadOptionsBoxQuadOptions;typedefmozilla::dom::ConvertCoordinateOptionsConvertCoordinateOptions;typedefmozilla::dom::DOMPointDOMPoint;typedefmozilla::dom::DOMPointInitDOMPointInit;typedefmozilla::dom::DOMQuadDOMQuad;typedefmozilla::dom::DOMRectReadOnlyDOMRectReadOnly;typedefmozilla::dom::TextOrElementOrDocumentTextOrElementOrDocument;typedefmozilla::ErrorResultErrorResult;NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODE_IID)// Among the sub-classes that inherit (directly or indirectly) from nsINode,// measurement of the following members may be added later if DMD finds it is// worthwhile:// - nsGenericHTMLElement: mForm, mFieldSet// - nsGenericHTMLFrameElement: mFrameLoader (bug 672539)// - HTMLBodyElement: mContentStyleRule// - HTMLDataListElement: mOptions// - HTMLFieldSetElement: mElements, mDependentElements, mFirstLegend// - HTMLFormElement: many!// - HTMLFrameSetElement: mRowSpecs, mColSpecs// - HTMLInputElement: mInputData, mFiles, mFileList, mStaticDocfileList// - nsHTMLMapElement: mAreas// - HTMLMediaElement: many!// - nsHTMLOutputElement: mDefaultValue, mTokenList// - nsHTMLRowElement: mCells// - nsHTMLSelectElement: mOptions, mRestoreState// - nsHTMLTableElement: mTBodies, mRows, mTableInheritedAttributes// - nsHTMLTableSectionElement: mRows// - nsHTMLTextAreaElement: mControllers, mState//// The following members don't need to be measured:// - nsIContent: mPrimaryFrame, because it's non-owning and measured elsewhere//virtualsize_tSizeOfExcludingThis(mozilla::MallocSizeOfaMallocSizeOf)const;// SizeOfIncludingThis doesn't need to be overridden by sub-classes because// sub-classes of nsINode are guaranteed to be laid out in memory in such a// way that |this| points to the start of the allocated object, even in// methods of nsINode's sub-classes, and so |aMallocSizeOf(this)| is always// safe to call no matter which object it was invoked on.virtualsize_tSizeOfIncludingThis(mozilla::MallocSizeOfaMallocSizeOf)const{returnaMallocSizeOf(this)+SizeOfExcludingThis(aMallocSizeOf);}friendclassnsNodeUtils;friendclassnsNodeWeakReference;friendclassnsNodeSupportsWeakRefTearoff;friendclassnsAttrAndChildArray;#ifdef MOZILLA_INTERNAL_APIexplicitnsINode(already_AddRefed<mozilla::dom::NodeInfo>&aNodeInfo):mNodeInfo(aNodeInfo),mParent(nullptr),mBoolFlags(0),mNextSibling(nullptr),mPreviousSibling(nullptr),mFirstChild(nullptr),mSubtreeRoot(this),mSlots(nullptr){}#endifvirtual~nsINode();/** * Bit-flags to pass (or'ed together) to IsNodeOfType() */enum{/** nsIContent nodes */eCONTENT=1<<0,/** nsIDocument nodes */eDOCUMENT=1<<1,/** nsIAttribute nodes */eATTRIBUTE=1<<2,/** text nodes */eTEXT=1<<3,/** xml processing instructions */ePROCESSING_INSTRUCTION=1<<4,/** comment nodes */eCOMMENT=1<<5,/** form control elements */eHTML_FORM_CONTROL=1<<6,/** document fragments */eDOCUMENT_FRAGMENT=1<<7,/** data nodes (comments, PIs, text). Nodes of this type always returns a non-null value for nsIContent::GetText() */eDATA_NODE=1<<8,/** HTMLMediaElement */eMEDIA=1<<9,/** animation elements */eANIMATION=1<<10,/** filter elements that implement SVGFilterPrimitiveStandardAttributes */eFILTER=1<<11};/** * API for doing a quick check if a content is of a given * type, such as Text, Document, Comment ... Use this when you can instead of * checking the tag. * * @param aFlags what types you want to test for (see above) * @return whether the content matches ALL flags passed in */virtualboolIsNodeOfType(uint32_taFlags)const=0;virtualJSObject*WrapObject(JSContext*aCx,JS::Handle<JSObject*>aGivenProto)override;/** * returns true if we are in priviliged code or * layout.css.getBoxQuads.enabled == true. */staticboolHasBoxQuadsSupport(JSContext*aCx,JSObject*/* unused */);protected:/** * WrapNode is called from WrapObject to actually wrap this node, WrapObject * does some additional checks and fix-up that's common to all nodes. WrapNode * should just call the DOM binding's Wrap function. * * aGivenProto is the prototype to use (or null if the default one should be * used) and should just be passed directly on to the DOM binding's Wrap * function. */virtualJSObject*WrapNode(JSContext*aCx,JS::Handle<JSObject*>aGivenProto)=0;public:mozilla::dom::ParentObjectGetParentObject()const;// Implemented in nsIDocument.h/** * Return the scope chain parent for this node, for use in things * like event handler compilation. Returning null means to use the * global object as the scope chain parent. */virtualnsINode*GetScopeChainParent()const;/** * Return whether the node is an Element node */boolIsElement()const{returnGetBoolFlag(NodeIsElement);}/** * Return this node as an Element. Should only be used for nodes * for which IsElement() is true. This is defined inline in Element.h. */mozilla::dom::Element*AsElement();constmozilla::dom::Element*AsElement()const;/** * Return this node as nsIContent. Should only be used for nodes for which * IsContent() is true. This is defined inline in nsIContent.h. */nsIContent*AsContent();constnsIContent*AsContent()const{returnconst_cast<nsINode*>(this)->AsContent();}/** * Return this node as Text if it is one, otherwise null. This is defined * inline in Text.h. */mozilla::dom::Text*GetAsText();constmozilla::dom::Text*GetAsText()const;virtualnsIDOMNode*AsDOMNode()=0;/** * Return if this node has any children. */boolHasChildren()const{return!!mFirstChild;}/** * Get the number of children * @return the number of children */virtualuint32_tGetChildCount()const=0;/** * Get a child by index * @param aIndex the index of the child to get * @return the child, or null if index out of bounds */virtualnsIContent*GetChildAt(uint32_taIndex)const=0;/** * Get a raw pointer to the child array. This should only be used if you * plan to walk a bunch of the kids, promise to make sure that nothing ever * mutates (no attribute changes, not DOM tree changes, no script execution, * NOTHING), and will never ever peform an out-of-bounds access here. This * method may return null if there are no children, or it may return a * garbage pointer. In all cases the out param will be set to the number of * children. */virtualnsIContent*const*GetChildArray(uint32_t*aChildCount)const=0;/** * Get the index of a child within this content * @param aPossibleChild the child to get the index of. * @return the index of the child, or -1 if not a child * * If the return value is not -1, then calling GetChildAt() with that value * will return aPossibleChild. */virtualint32_tIndexOf(constnsINode*aPossibleChild)const=0;/** * Returns the "node document" of this node. * * https://dom.spec.whatwg.org/#concept-node-document * * Note that in the case that this node is a document node this method * will return |this|. That is different to the Node.ownerDocument DOM * attribute (implemented by nsINode::GetOwnerDocument) which is specified to * be null in that case: * * https://dom.spec.whatwg.org/#dom-node-ownerdocument * * For all other cases GetOwnerDoc and GetOwnerDocument behave identically. */nsIDocument*OwnerDoc()const{returnmNodeInfo->GetDocument();}/** * Return the "owner document" of this node as an nsINode*. Implemented * in nsIDocument.h. */nsINode*OwnerDocAsNode()const;/** * Returns true if the content has an ancestor that is a document. * * @return whether this content is in a document tree */boolIsInUncomposedDoc()const{returnGetBoolFlag(IsInDocument);}/** * @deprecated */boolIsInDoc()const{returnIsInUncomposedDoc();}/** * Get the document that this content is currently in, if any. This will be * null if the content has no ancestor that is a document. * * @return the current document */nsIDocument*GetUncomposedDoc()const{returnIsInUncomposedDoc()?OwnerDoc():nullptr;}/** * @deprecated */nsIDocument*GetCurrentDoc()const{returnGetUncomposedDoc();}/** * This method returns the owner doc if the node is in the * composed document (as defined in the Shadow DOM spec), otherwise * it returns null. */nsIDocument*GetComposedDoc()const{returnIsInShadowTree()?GetComposedDocInternal():GetUncomposedDoc();}/** * @deprecated */nsIDocument*GetCrossShadowCurrentDoc()const{returnGetComposedDoc();}/** * Returns true if GetComposedDoc() would return a non-null value. */boolIsInComposedDoc()const{returnIsInUncomposedDoc()||(IsInShadowTree()&&GetComposedDocInternal());}/** * The values returned by this function are the ones defined for * nsIDOMNode.nodeType */uint16_tNodeType()const{returnmNodeInfo->NodeType();}constnsString&NodeName()const{returnmNodeInfo->NodeName();}constnsString&LocalName()const{returnmNodeInfo->LocalName();}/** * Get the NodeInfo for this element * @return the nodes node info */inlinemozilla::dom::NodeInfo*NodeInfo()const{returnmNodeInfo;}inlineboolIsInNamespace(int32_taNamespace)const{returnmNodeInfo->NamespaceID()==aNamespace;}/** * Print a debugger friendly descriptor of this element. This will describe * the position of this element in the document. */friendstd::ostream&operator<<(std::ostream&aStream,constnsINode&aNode);protected:// These 2 methods are useful for the recursive templates IsHTMLElement,// IsSVGElement, etc.inlineboolIsNodeInternal()const{returnfalse;}template<typenameFirst,typename...Args>inlineboolIsNodeInternal(FirstaFirst,Args...aArgs)const{returnmNodeInfo->Equals(aFirst)||IsNodeInternal(aArgs...);}public:inlineboolIsHTMLElement()const{returnIsElement()&&IsInNamespace(kNameSpaceID_XHTML);}inlineboolIsHTMLElement(nsIAtom*aTag)const{returnIsElement()&&mNodeInfo->Equals(aTag,kNameSpaceID_XHTML);}template<typenameFirst,typename...Args>inlineboolIsAnyOfHTMLElements(FirstaFirst,Args...aArgs)const{returnIsHTMLElement()&&IsNodeInternal(aFirst,aArgs...);}inlineboolIsSVGElement()const{returnIsElement()&&IsInNamespace(kNameSpaceID_SVG);}inlineboolIsSVGElement(nsIAtom*aTag)const{returnIsElement()&&mNodeInfo->Equals(aTag,kNameSpaceID_SVG);}template<typenameFirst,typename...Args>inlineboolIsAnyOfSVGElements(FirstaFirst,Args...aArgs)const{returnIsSVGElement()&&IsNodeInternal(aFirst,aArgs...);}inlineboolIsXULElement()const{returnIsElement()&&IsInNamespace(kNameSpaceID_XUL);}inlineboolIsXULElement(nsIAtom*aTag)const{returnIsElement()&&mNodeInfo->Equals(aTag,kNameSpaceID_XUL);}template<typenameFirst,typename...Args>inlineboolIsAnyOfXULElements(FirstaFirst,Args...aArgs)const{returnIsXULElement()&&IsNodeInternal(aFirst,aArgs...);}inlineboolIsMathMLElement()const{returnIsElement()&&IsInNamespace(kNameSpaceID_MathML);}inlineboolIsMathMLElement(nsIAtom*aTag)const{returnIsElement()&&mNodeInfo->Equals(aTag,kNameSpaceID_MathML);}template<typenameFirst,typename...Args>inlineboolIsAnyOfMathMLElements(FirstaFirst,Args...aArgs)const{returnIsMathMLElement()&&IsNodeInternal(aFirst,aArgs...);}/** * Insert a content node at a particular index. This method handles calling * BindToTree on the child appropriately. * * @param aKid the content to insert * @param aIndex the index it is being inserted at (the index it will have * after it is inserted) * @param aNotify whether to notify the document (current document for * nsIContent, and |this| for nsIDocument) that the insert has * occurred * * @throws NS_ERROR_DOM_HIERARCHY_REQUEST_ERR if one attempts to have more * than one element node as a child of a document. Doing this will also * assert -- you shouldn't be doing it! Check with * nsIDocument::GetRootElement() first if you're not sure. Apart from this * one constraint, this doesn't do any checking on whether aKid is a valid * child of |this|. * * @throws NS_ERROR_OUT_OF_MEMORY in some cases (from BindToTree). */virtualnsresultInsertChildAt(nsIContent*aKid,uint32_taIndex,boolaNotify)=0;/** * Append a content node to the end of the child list. This method handles * calling BindToTree on the child appropriately. * * @param aKid the content to append * @param aNotify whether to notify the document (current document for * nsIContent, and |this| for nsIDocument) that the append has * occurred * * @throws NS_ERROR_DOM_HIERARCHY_REQUEST_ERR if one attempts to have more * than one element node as a child of a document. Doing this will also * assert -- you shouldn't be doing it! Check with * nsIDocument::GetRootElement() first if you're not sure. Apart from this * one constraint, this doesn't do any checking on whether aKid is a valid * child of |this|. * * @throws NS_ERROR_OUT_OF_MEMORY in some cases (from BindToTree). */nsresultAppendChildTo(nsIContent*aKid,boolaNotify){returnInsertChildAt(aKid,GetChildCount(),aNotify);}/** * Remove a child from this node. This method handles calling UnbindFromTree * on the child appropriately. * * @param aIndex the index of the child to remove * @param aNotify whether to notify the document (current document for * nsIContent, and |this| for nsIDocument) that the remove has * occurred * * Note: If there is no child at aIndex, this method will simply do nothing. */virtualvoidRemoveChildAt(uint32_taIndex,boolaNotify)=0;/** * Get a property associated with this node. * * @param aPropertyName name of property to get. * @param aStatus out parameter for storing resulting status. * Set to NS_PROPTABLE_PROP_NOT_THERE if the property * is not set. * @return the property. Null if the property is not set * (though a null return value does not imply the * property was not set, i.e. it can be set to null). */void*GetProperty(nsIAtom*aPropertyName,nsresult*aStatus=nullptr)const{returnGetProperty(0,aPropertyName,aStatus);}/** * Get a property associated with this node. * * @param aCategory category of property to get. * @param aPropertyName name of property to get. * @param aStatus out parameter for storing resulting status. * Set to NS_PROPTABLE_PROP_NOT_THERE if the property * is not set. * @return the property. Null if the property is not set * (though a null return value does not imply the * property was not set, i.e. it can be set to null). */virtualvoid*GetProperty(uint16_taCategory,nsIAtom*aPropertyName,nsresult*aStatus=nullptr)const;/** * Set a property to be associated with this node. This will overwrite an * existing value if one exists. The existing value is destroyed using the * destructor function given when that value was set. * * @param aPropertyName name of property to set. * @param aValue new value of property. * @param aDtor destructor function to be used when this property * is destroyed. * @param aTransfer if true the property will not be deleted when the * ownerDocument of the node changes, if false it * will be deleted. * * @return NS_PROPTABLE_PROP_OVERWRITTEN (success value) if the property * was already set * @throws NS_ERROR_OUT_OF_MEMORY if that occurs */nsresultSetProperty(nsIAtom*aPropertyName,void*aValue,NSPropertyDtorFuncaDtor=nullptr,boolaTransfer=false){returnSetProperty(0,aPropertyName,aValue,aDtor,aTransfer);}/** * Set a property to be associated with this node. This will overwrite an * existing value if one exists. The existing value is destroyed using the * destructor function given when that value was set. * * @param aCategory category of property to set. * @param aPropertyName name of property to set. * @param aValue new value of property. * @param aDtor destructor function to be used when this property * is destroyed. * @param aTransfer if true the property will not be deleted when the * ownerDocument of the node changes, if false it * will be deleted. * @param aOldValue [out] previous value of property. * * @return NS_PROPTABLE_PROP_OVERWRITTEN (success value) if the property * was already set * @throws NS_ERROR_OUT_OF_MEMORY if that occurs */virtualnsresultSetProperty(uint16_taCategory,nsIAtom*aPropertyName,void*aValue,NSPropertyDtorFuncaDtor=nullptr,boolaTransfer=false,void**aOldValue=nullptr);/** * A generic destructor for property values allocated with new. */template<classT>staticvoidDeleteProperty(void*,nsIAtom*,void*aPropertyValue,void*){deletestatic_cast<T*>(aPropertyValue);}/** * Destroys a property associated with this node. The value is destroyed * using the destruction function given when that value was set. * * @param aPropertyName name of property to destroy. */voidDeleteProperty(nsIAtom*aPropertyName){DeleteProperty(0,aPropertyName);}/** * Destroys a property associated with this node. The value is destroyed * using the destruction function given when that value was set. * * @param aCategory category of property to destroy. * @param aPropertyName name of property to destroy. */virtualvoidDeleteProperty(uint16_taCategory,nsIAtom*aPropertyName);/** * Unset a property associated with this node. The value will not be * destroyed but rather returned. It is the caller's responsibility to * destroy the value after that point. * * @param aPropertyName name of property to unset. * @param aStatus out parameter for storing resulting status. * Set to NS_PROPTABLE_PROP_NOT_THERE if the property * is not set. * @return the property. Null if the property is not set * (though a null return value does not imply the * property was not set, i.e. it can be set to null). */void*UnsetProperty(nsIAtom*aPropertyName,nsresult*aStatus=nullptr){returnUnsetProperty(0,aPropertyName,aStatus);}/** * Unset a property associated with this node. The value will not be * destroyed but rather returned. It is the caller's responsibility to * destroy the value after that point. * * @param aCategory category of property to unset. * @param aPropertyName name of property to unset. * @param aStatus out parameter for storing resulting status. * Set to NS_PROPTABLE_PROP_NOT_THERE if the property * is not set. * @return the property. Null if the property is not set * (though a null return value does not imply the * property was not set, i.e. it can be set to null). */virtualvoid*UnsetProperty(uint16_taCategory,nsIAtom*aPropertyName,nsresult*aStatus=nullptr);boolHasProperties()const{returnHasFlag(NODE_HAS_PROPERTIES);}/** * Return the principal of this node. This is guaranteed to never be a null * pointer. */nsIPrincipal*NodePrincipal()const{returnmNodeInfo->NodeInfoManager()->DocumentPrincipal();}/** * Get the parent nsIContent for this node. * @return the parent, or null if no parent or the parent is not an nsIContent */nsIContent*GetParent()const{returnMOZ_LIKELY(GetBoolFlag(ParentIsContent))?reinterpret_cast<nsIContent*>(mParent):nullptr;}/** * Get the parent nsINode for this node. This can be either an nsIContent, * an nsIDocument or an nsIAttribute. * @return the parent node */nsINode*GetParentNode()const{returnmParent;}/** * Get the parent nsINode for this node if it is an Element. * @return the parent node */mozilla::dom::Element*GetParentElement()const{returnmParent&&mParent->IsElement()?mParent->AsElement():nullptr;}/** * Get the parent Element of this node, traversing over a ShadowRoot * to its host if necessary. */mozilla::dom::Element*GetParentElementCrossingShadowRoot()const;/** * Get the root of the subtree this node belongs to. This never returns * null. It may return 'this' (e.g. for document nodes, and nodes that * are the roots of disconnected subtrees). */nsINode*SubtreeRoot()const;/** * See nsIDOMEventTarget */NS_DECL_NSIDOMEVENTTARGETvirtualmozilla::EventListenerManager*GetExistingListenerManager()constoverride;virtualmozilla::EventListenerManager*GetOrCreateListenerManager()override;usingmozilla::dom::EventTarget::RemoveEventListener;usingnsIDOMEventTarget::AddEventListener;virtualvoidAddEventListener(constnsAString&aType,mozilla::dom::EventListener*aListener,boolaUseCapture,constmozilla::dom::Nullable<bool>&aWantsUntrusted,mozilla::ErrorResult&aRv)override;usingnsIDOMEventTarget::AddSystemEventListener;virtualboolHasApzAwareListeners()constoverride;virtualnsPIDOMWindowOuter*GetOwnerGlobalForBindings()override;virtualnsIGlobalObject*GetOwnerGlobal()constoverride;/** * Adds a mutation observer to be notified when this node, or any of its * descendants, are modified. The node will hold a weak reference to the * observer, which means that it is the responsibility of the observer to * remove itself in case it dies before the node. If an observer is added * while observers are being notified, it may also be notified. In general, * adding observers while inside a notification is not a good idea. An * observer that is already observing the node must not be added without * being removed first. * * For mutation observers that implement nsIAnimationObserver, use * AddAnimationObserver instead. */voidAddMutationObserver(nsIMutationObserver*aMutationObserver){nsSlots*s=Slots();NS_ASSERTION(s->mMutationObservers.IndexOf(aMutationObserver)==nsTArray<int>::NoIndex,"Observer already in the list");s->mMutationObservers.AppendElement(aMutationObserver);}/** * Same as above, but only adds the observer if its not observing * the node already. * * For mutation observers that implement nsIAnimationObserver, use * AddAnimationObserverUnlessExists instead. */voidAddMutationObserverUnlessExists(nsIMutationObserver*aMutationObserver){nsSlots*s=Slots();s->mMutationObservers.AppendElementUnlessExists(aMutationObserver);}/** * Same as AddMutationObserver, but for nsIAnimationObservers. This * additionally records on the document that animation observers have * been registered, which is used to determine whether notifications * must be fired when animations are added, removed or changed. */voidAddAnimationObserver(nsIAnimationObserver*aAnimationObserver);/** * Same as above, but only adds the observer if its not observing * the node already. */voidAddAnimationObserverUnlessExists(nsIAnimationObserver*aAnimationObserver);/** * Removes a mutation observer. */voidRemoveMutationObserver(nsIMutationObserver*aMutationObserver){nsSlots*s=GetExistingSlots();if(s){s->mMutationObservers.RemoveElement(aMutationObserver);}}/** * Clones this node. This needs to be overriden by all node classes. aNodeInfo * should be identical to this node's nodeInfo, except for the document which * may be different. When cloning an element, all attributes of the element * will be cloned. The children of the node will not be cloned. * * @param aNodeInfo the nodeinfo to use for the clone * @param aResult the clone */virtualnsresultClone(mozilla::dom::NodeInfo*aNodeInfo,nsINode**aResult)const=0;// This class can be extended by subclasses that wish to store more// information in the slots.classnsSlots{public:nsSlots();// If needed we could remove the vtable pointer this dtor causes by// putting a DestroySlots function on nsINodevirtual~nsSlots();voidTraverse(nsCycleCollectionTraversalCallback&cb);voidUnlink();/** * A list of mutation observers */nsTObserverArray<nsIMutationObserver*>mMutationObservers;/** * An object implementing nsIDOMNodeList for this content (childNodes) * @see nsIDOMNodeList * @see nsGenericHTMLElement::GetChildNodes */RefPtr<nsChildContentList>mChildNodes;/** * Weak reference to this node. This is cleared by the destructor of * nsNodeWeakReference. */nsNodeWeakReference*MOZ_NON_OWNING_REFmWeakReference;/** * Number of descendant nodes in the uncomposed document that have been * explicitly set as editable. */uint32_tmEditableDescendantCount;};/** * Functions for managing flags and slots */#ifdef DEBUGnsSlots*DebugGetSlots(){returnSlots();}#endifvoidSetFlags(FlagsTypeaFlagsToSet){NS_ASSERTION(!(aFlagsToSet&(NODE_IS_ANONYMOUS_ROOT|NODE_IS_NATIVE_ANONYMOUS_ROOT|NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE|NODE_DESCENDANTS_NEED_FRAMES|NODE_NEEDS_FRAME|NODE_CHROME_ONLY_ACCESS))||IsNodeOfType(eCONTENT),"Flag only permitted on nsIContent nodes");nsWrapperCache::SetFlags(aFlagsToSet);}voidUnsetFlags(FlagsTypeaFlagsToUnset){NS_ASSERTION(!(aFlagsToUnset&(NODE_IS_ANONYMOUS_ROOT|NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE|NODE_IS_NATIVE_ANONYMOUS_ROOT)),"Trying to unset write-only flags");nsWrapperCache::UnsetFlags(aFlagsToUnset);}voidChangeEditableDescendantCount(int32_taDelta);/** * Returns the count of descendant nodes in the uncomposed * document that are explicitly set as editable. */uint32_tEditableDescendantCount();/** * Sets the editable descendant count to 0. The editable * descendant count only counts explicitly editable nodes * that are in the uncomposed document so this method * should be called when nodes are are removed from it. */voidResetEditableDescendantCount();voidSetEditableFlag(boolaEditable){if(aEditable){SetFlags(NODE_IS_EDITABLE);}else{UnsetFlags(NODE_IS_EDITABLE);}}boolIsEditable()const{#ifdef MOZILLA_INTERNAL_APIreturnIsEditableInternal();#elsereturnIsEditableExternal();#endif}/** * Returns true if |this| or any of its ancestors is native anonymous. */boolIsInNativeAnonymousSubtree()const{#ifdef DEBUGif(HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE)){returntrue;}CheckNotNativeAnonymous();returnfalse;#elsereturnHasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE);#endif}boolIsInAnonymousSubtree()const;// Note: This asserts |IsInAnonymousSubtree()|.boolIsAnonymousContentInSVGUseSubtree()const;// True for native anonymous content and for XBL content if the binding// has chromeOnlyContent="true".boolChromeOnlyAccess()const{returnHasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE|NODE_CHROME_ONLY_ACCESS);}boolIsInShadowTree()const{returnHasFlag(NODE_IS_IN_SHADOW_TREE);}/** * Returns true if |this| node is the common ancestor of the start/end * nodes of a Range in a Selection or a descendant of such a common ancestor. * This node is definitely not selected when |false| is returned, but it may * or may not be selected when |true| is returned. */boolIsSelectionDescendant()const{returnIsDescendantOfCommonAncestorForRangeInSelection()||IsCommonAncestorForRangeInSelection();}/** * Get the root content of an editor. So, this node must be a descendant of * an editor. Note that this should be only used for getting input or textarea * editor's root content. This method doesn't support HTML editors. */nsIContent*GetTextEditorRootContent(nsIEditor**aEditor=nullptr);/** * Get the nearest selection root, ie. the node that will be selected if the * user does "Select All" while the focus is in this node. Note that if this * node is not in an editor, the result comes from the nsFrameSelection that * is related to aPresShell, so the result might not be the ancestor of this * node. Be aware that if this node and the computed selection limiter are * not in same subtree, this returns the root content of the closeset subtree. */nsIContent*GetSelectionRootContent(nsIPresShell*aPresShell);virtualnsINodeList*ChildNodes();nsIContent*GetFirstChild()const{returnmFirstChild;}nsIContent*GetLastChild()const{uint32_tcount;nsIContent*const*children=GetChildArray(&count);returncount>0?children[count-1]:nullptr;}/** * Implementation is in nsIDocument.h, because it needs to cast from * nsIDocument* to nsINode*. */nsIDocument*GetOwnerDocument()const;voidNormalize();/** * Get the base URI for any relative URIs within this piece of * content. Generally, this is the document's base URI, but certain * content carries a local base for backward compatibility, and XML * supports setting a per-node base URI. * * @return the base URI */virtualalready_AddRefed<nsIURI>GetBaseURI(boolaTryUseXHRDocBaseURI=false)const=0;already_AddRefed<nsIURI>GetBaseURIObject()const;/** * Facility for explicitly setting a base URI on a node. */nsresultSetExplicitBaseURI(nsIURI*aURI);/** * The explicit base URI, if set, otherwise null */protected:nsIURI*GetExplicitBaseURI()const{if(HasExplicitBaseURI()){returnstatic_cast<nsIURI*>(GetProperty(nsGkAtoms::baseURIProperty));}returnnullptr;}public:voidGetTextContent(nsAString&aTextContent,mozilla::ErrorResult&aError){GetTextContentInternal(aTextContent,aError);}voidSetTextContent(constnsAString&aTextContent,mozilla::ErrorResult&aError){SetTextContentInternal(aTextContent,aError);}mozilla::dom::Element*QuerySelector(constnsAString&aSelector,mozilla::ErrorResult&aResult);already_AddRefed<nsINodeList>QuerySelectorAll(constnsAString&aSelector,mozilla::ErrorResult&aResult);nsresultQuerySelector(constnsAString&aSelector,nsIDOMElement**aReturn);nsresultQuerySelectorAll(constnsAString&aSelector,nsIDOMNodeList**aReturn);protected:// nsIDocument overrides this with its own (faster) version. This// should really only be called for elements and document fragments.mozilla::dom::Element*GetElementById(constnsAString&aId);public:/** * Associate an object aData to aKey on this node. If aData is null any * previously registered object associated to aKey on this node will * be removed. * Should only be used to implement the DOM Level 3 UserData API. * * @param aKey the key to associate the object to * @param aData the object to associate to aKey on this node (may be null) * @param aResult [out] the previously registered object for aKey on this * node, if any * @return whether adding the object succeeded */nsresultSetUserData(constnsAString&aKey,nsIVariant*aData,nsIVariant**aResult);/** * Get the UserData object registered for a Key on this node, if any. * Should only be used to implement the DOM Level 3 UserData API. * * @param aKey the key to get UserData for * @return aResult the previously registered object for aKey on this node, if * any */nsIVariant*GetUserData(constnsAString&aKey);nsresultGetUserData(constnsAString&aKey,nsIVariant**aResult){NS_IF_ADDREF(*aResult=GetUserData(aKey));returnNS_OK;}voidLookupPrefix(constnsAString&aNamespace,nsAString&aResult);boolIsDefaultNamespace(constnsAString&aNamespaceURI){nsAutoStringdefaultNamespace;LookupNamespaceURI(EmptyString(),defaultNamespace);returnaNamespaceURI.Equals(defaultNamespace);}voidLookupNamespaceURI(constnsAString&aNamespacePrefix,nsAString&aNamespaceURI);nsresultIsEqualNode(nsIDOMNode*aOther,bool*aReturn);nsIContent*GetNextSibling()const{returnmNextSibling;}nsIContent*GetPreviousSibling()const{returnmPreviousSibling;}/** * Get the next node in the pre-order tree traversal of the DOM. If * aRoot is non-null, then it must be an ancestor of |this| * (possibly equal to |this|) and only nodes that are descendants of * aRoot, not including aRoot itself, will be returned. Returns * null if there are no more nodes to traverse. */nsIContent*GetNextNode(constnsINode*aRoot=nullptr)const{returnGetNextNodeImpl(aRoot,false);}/** * Get the next node in the pre-order tree traversal of the DOM but ignoring * the children of this node. If aRoot is non-null, then it must be an * ancestor of |this| (possibly equal to |this|) and only nodes that are * descendants of aRoot, not including aRoot itself, will be returned. * Returns null if there are no more nodes to traverse. */nsIContent*GetNextNonChildNode(constnsINode*aRoot=nullptr)const{returnGetNextNodeImpl(aRoot,true);}/** * Returns true if 'this' is either document or element or * document fragment and aOther is a descendant in the same * anonymous tree. */boolContains(constnsINode*aOther)const;nsresultContains(nsIDOMNode*aOther,bool*aReturn);boolUnoptimizableCCNode()const;private:nsIDocument*GetComposedDocInternal()const;nsIContent*GetNextNodeImpl(constnsINode*aRoot,constboolaSkipChildren)const{// Can't use nsContentUtils::ContentIsDescendantOf here, since we// can't include it here.#ifdef DEBUGif(aRoot){constnsINode*cur=this;for(;cur;cur=cur->GetParentNode())if(cur==aRoot)break;NS_ASSERTION(cur,"aRoot not an ancestor of |this|?");}#endifif(!aSkipChildren){nsIContent*kid=GetFirstChild();if(kid){returnkid;}}if(this==aRoot){returnnullptr;}constnsINode*cur=this;while(1){nsIContent*next=cur->GetNextSibling();if(next){returnnext;}nsINode*parent=cur->GetParentNode();if(parent==aRoot){returnnullptr;}cur=parent;}NS_NOTREACHED("How did we get here?");}public:/** * Get the previous nsIContent in the pre-order tree traversal of the DOM. If * aRoot is non-null, then it must be an ancestor of |this| * (possibly equal to |this|) and only nsIContents that are descendants of * aRoot, including aRoot itself, will be returned. Returns * null if there are no more nsIContents to traverse. */nsIContent*GetPreviousContent(constnsINode*aRoot=nullptr)const{// Can't use nsContentUtils::ContentIsDescendantOf here, since we// can't include it here.#ifdef DEBUGif(aRoot){constnsINode*cur=this;for(;cur;cur=cur->GetParentNode())if(cur==aRoot)break;NS_ASSERTION(cur,"aRoot not an ancestor of |this|?");}#endifif(this==aRoot){returnnullptr;}nsIContent*cur=this->GetParent();nsIContent*iter=this->GetPreviousSibling();while(iter){cur=iter;iter=reinterpret_cast<nsINode*>(iter)->GetLastChild();}returncur;}/** * Boolean flags */private:enumBooleanFlag{// Set if we're being used from -moz-elementNodeHasRenderingObservers,// Set if our parent chain (including this node itself) terminates// in a documentIsInDocument,// Set if mParent is an nsIContentParentIsContent,// Set if this node is an ElementNodeIsElement,// Set if the element has a non-empty id attribute. This can in rare// cases lie for nsXMLElement, such as when the node has been moved between// documents with different id mappings.ElementHasID,// Set if the element might have inline style.ElementMayHaveStyle,// Set if the element has a name attribute set.ElementHasName,// Set if the element might have a contenteditable attribute set.ElementMayHaveContentEditableAttr,// Set if the node is the common ancestor of the start/end nodes of a Range// that is in a Selection.NodeIsCommonAncestorForRangeInSelection,// Set if the node is a descendant of a node with the above bit set.NodeIsDescendantOfCommonAncestorForRangeInSelection,// Set if CanSkipInCC check has been done for this subtree root.NodeIsCCMarkedRoot,// Maybe set if this node is in black subtree.NodeIsCCBlackTree,// Maybe set if the node is a root of a subtree // which needs to be kept in the purple buffer.NodeIsPurpleRoot,// Set if the node has an explicit base URI storedNodeHasExplicitBaseURI,// Set if the element has some style states lockedElementHasLockedStyleStates,// Set if element has pointer lockedElementHasPointerLock,// Set if the node may have DOMMutationObserver attached to it.NodeMayHaveDOMMutationObserver,// Set if node is ContentNodeIsContent,// Set if the node has animations or transitionsElementHasAnimations,// Set if node has a dir attribute with a valid value (ltr, rtl, or auto)NodeHasValidDirAttribute,// Set if node has a dir attribute with a fixed value (ltr or rtl, NOT auto)NodeHasFixedDir,// Set if the node has dir=auto and has a property pointing to the text// node that determines its directionNodeHasDirAutoSet,// Set if the node is a text node descendant of a node with dir=auto// and has a TextNodeDirectionalityMap property listing the elements whose// direction it determines.NodeHasTextNodeDirectionalityMap,// Set if the node has dir=auto.NodeHasDirAuto,// Set if a node in the node's parent chain has dir=auto.NodeAncestorHasDirAuto,// Set if the element is in the scope of a scoped style sheet; this flag is// only accurate for elements bound to a documentElementIsInStyleScope,// Set if the element is a scoped style sheet rootElementIsScopedStyleRoot,// Set if the node is handling a click.NodeHandlingClick,// Set if the node has had :hover selectors matched against itNodeHasRelevantHoverRules,// Set if the element has a parser insertion mode other than "in body",// per the HTML5 "Parse state" section.ElementHasWeirdParserInsertionMode,// Parser sets this flag if it has notified about the node.ParserHasNotified,// EventListenerManager sets this flag in case we have apz aware listeners.MayHaveApzAwareListeners,// Guard valueBooleanFlagCount};voidSetBoolFlag(BooleanFlagname,boolvalue){static_assert(BooleanFlagCount<=8*sizeof(mBoolFlags),"Too many boolean flags");mBoolFlags=(mBoolFlags&~(1<<name))|(value<<name);}voidSetBoolFlag(BooleanFlagname){static_assert(BooleanFlagCount<=8*sizeof(mBoolFlags),"Too many boolean flags");mBoolFlags|=(1<<name);}voidClearBoolFlag(BooleanFlagname){static_assert(BooleanFlagCount<=8*sizeof(mBoolFlags),"Too many boolean flags");mBoolFlags&=~(1<<name);}boolGetBoolFlag(BooleanFlagname)const{static_assert(BooleanFlagCount<=8*sizeof(mBoolFlags),"Too many boolean flags");returnmBoolFlags&(1<<name);}public:boolHasRenderingObservers()const{returnGetBoolFlag(NodeHasRenderingObservers);}voidSetHasRenderingObservers(boolaValue){SetBoolFlag(NodeHasRenderingObservers,aValue);}boolIsContent()const{returnGetBoolFlag(NodeIsContent);}boolHasID()const{returnGetBoolFlag(ElementHasID);}boolMayHaveStyle()const{returnGetBoolFlag(ElementMayHaveStyle);}boolHasName()const{returnGetBoolFlag(ElementHasName);}boolMayHaveContentEditableAttr()const{returnGetBoolFlag(ElementMayHaveContentEditableAttr);}boolIsCommonAncestorForRangeInSelection()const{returnGetBoolFlag(NodeIsCommonAncestorForRangeInSelection);}voidSetCommonAncestorForRangeInSelection(){SetBoolFlag(NodeIsCommonAncestorForRangeInSelection);}voidClearCommonAncestorForRangeInSelection(){ClearBoolFlag(NodeIsCommonAncestorForRangeInSelection);}boolIsDescendantOfCommonAncestorForRangeInSelection()const{returnGetBoolFlag(NodeIsDescendantOfCommonAncestorForRangeInSelection);}voidSetDescendantOfCommonAncestorForRangeInSelection(){SetBoolFlag(NodeIsDescendantOfCommonAncestorForRangeInSelection);}voidClearDescendantOfCommonAncestorForRangeInSelection(){ClearBoolFlag(NodeIsDescendantOfCommonAncestorForRangeInSelection);}voidSetCCMarkedRoot(boolaValue){SetBoolFlag(NodeIsCCMarkedRoot,aValue);}boolCCMarkedRoot()const{returnGetBoolFlag(NodeIsCCMarkedRoot);}voidSetInCCBlackTree(boolaValue){SetBoolFlag(NodeIsCCBlackTree,aValue);}boolInCCBlackTree()const{returnGetBoolFlag(NodeIsCCBlackTree);}voidSetIsPurpleRoot(boolaValue){SetBoolFlag(NodeIsPurpleRoot,aValue);}boolIsPurpleRoot()const{returnGetBoolFlag(NodeIsPurpleRoot);}boolMayHaveDOMMutationObserver(){returnGetBoolFlag(NodeMayHaveDOMMutationObserver);}voidSetMayHaveDOMMutationObserver(){SetBoolFlag(NodeMayHaveDOMMutationObserver,true);}boolHasListenerManager(){returnHasFlag(NODE_HAS_LISTENERMANAGER);}boolHasPointerLock()const{returnGetBoolFlag(ElementHasPointerLock);}voidSetPointerLock(){SetBoolFlag(ElementHasPointerLock);}voidClearPointerLock(){ClearBoolFlag(ElementHasPointerLock);}boolMayHaveAnimations(){returnGetBoolFlag(ElementHasAnimations);}voidSetMayHaveAnimations(){SetBoolFlag(ElementHasAnimations);}voidSetHasValidDir(){SetBoolFlag(NodeHasValidDirAttribute);}voidClearHasValidDir(){ClearBoolFlag(NodeHasValidDirAttribute);}boolHasValidDir()const{returnGetBoolFlag(NodeHasValidDirAttribute);}voidSetHasFixedDir(){MOZ_ASSERT(NodeType()!=nsIDOMNode::TEXT_NODE,"SetHasFixedDir on text node");SetBoolFlag(NodeHasFixedDir);}voidClearHasFixedDir(){MOZ_ASSERT(NodeType()!=nsIDOMNode::TEXT_NODE,"ClearHasFixedDir on text node");ClearBoolFlag(NodeHasFixedDir);}boolHasFixedDir()const{returnGetBoolFlag(NodeHasFixedDir);}voidSetHasDirAutoSet(){MOZ_ASSERT(NodeType()!=nsIDOMNode::TEXT_NODE,"SetHasDirAutoSet on text node");SetBoolFlag(NodeHasDirAutoSet);}voidClearHasDirAutoSet(){MOZ_ASSERT(NodeType()!=nsIDOMNode::TEXT_NODE,"ClearHasDirAutoSet on text node");ClearBoolFlag(NodeHasDirAutoSet);}boolHasDirAutoSet()const{returnGetBoolFlag(NodeHasDirAutoSet);}voidSetHasTextNodeDirectionalityMap(){MOZ_ASSERT(NodeType()==nsIDOMNode::TEXT_NODE,"SetHasTextNodeDirectionalityMap on non-text node");SetBoolFlag(NodeHasTextNodeDirectionalityMap);}voidClearHasTextNodeDirectionalityMap(){MOZ_ASSERT(NodeType()==nsIDOMNode::TEXT_NODE,"ClearHasTextNodeDirectionalityMap on non-text node");ClearBoolFlag(NodeHasTextNodeDirectionalityMap);}boolHasTextNodeDirectionalityMap()const{returnGetBoolFlag(NodeHasTextNodeDirectionalityMap);}voidSetHasDirAuto(){SetBoolFlag(NodeHasDirAuto);}voidClearHasDirAuto(){ClearBoolFlag(NodeHasDirAuto);}boolHasDirAuto()const{returnGetBoolFlag(NodeHasDirAuto);}voidSetAncestorHasDirAuto(){SetBoolFlag(NodeAncestorHasDirAuto);}voidClearAncestorHasDirAuto(){ClearBoolFlag(NodeAncestorHasDirAuto);}boolAncestorHasDirAuto()const{returnGetBoolFlag(NodeAncestorHasDirAuto);}boolNodeOrAncestorHasDirAuto()const{returnHasDirAuto()||AncestorHasDirAuto();}voidSetIsElementInStyleScope(boolaValue){MOZ_ASSERT(IsElement(),"SetIsInStyleScope on a non-Element node");SetBoolFlag(ElementIsInStyleScope,aValue);}voidSetIsElementInStyleScope(){MOZ_ASSERT(IsElement(),"SetIsInStyleScope on a non-Element node");SetBoolFlag(ElementIsInStyleScope);}voidClearIsElementInStyleScope(){MOZ_ASSERT(IsElement(),"ClearIsInStyleScope on a non-Element node");ClearBoolFlag(ElementIsInStyleScope);}boolIsElementInStyleScope()const{returnGetBoolFlag(ElementIsInStyleScope);}voidSetIsScopedStyleRoot(){SetBoolFlag(ElementIsScopedStyleRoot);}voidClearIsScopedStyleRoot(){ClearBoolFlag(ElementIsScopedStyleRoot);}boolIsScopedStyleRoot(){returnGetBoolFlag(ElementIsScopedStyleRoot);}boolHasRelevantHoverRules()const{returnGetBoolFlag(NodeHasRelevantHoverRules);}voidSetHasRelevantHoverRules(){SetBoolFlag(NodeHasRelevantHoverRules);}voidSetParserHasNotified(){SetBoolFlag(ParserHasNotified);};boolHasParserNotified(){returnGetBoolFlag(ParserHasNotified);}voidSetMayHaveApzAwareListeners(){SetBoolFlag(MayHaveApzAwareListeners);}boolNodeMayHaveApzAwareListeners()const{returnGetBoolFlag(MayHaveApzAwareListeners);}protected:voidSetParentIsContent(boolaValue){SetBoolFlag(ParentIsContent,aValue);}voidSetInDocument(){SetBoolFlag(IsInDocument);}voidSetNodeIsContent(){SetBoolFlag(NodeIsContent);}voidClearInDocument(){ClearBoolFlag(IsInDocument);}voidSetIsElement(){SetBoolFlag(NodeIsElement);}voidSetHasID(){SetBoolFlag(ElementHasID);}voidClearHasID(){ClearBoolFlag(ElementHasID);}voidSetMayHaveStyle(){SetBoolFlag(ElementMayHaveStyle);}voidSetHasName(){SetBoolFlag(ElementHasName);}voidClearHasName(){ClearBoolFlag(ElementHasName);}voidSetMayHaveContentEditableAttr(){SetBoolFlag(ElementMayHaveContentEditableAttr);}boolHasExplicitBaseURI()const{returnGetBoolFlag(NodeHasExplicitBaseURI);}voidSetHasExplicitBaseURI(){SetBoolFlag(NodeHasExplicitBaseURI);}voidSetHasLockedStyleStates(){SetBoolFlag(ElementHasLockedStyleStates);}voidClearHasLockedStyleStates(){ClearBoolFlag(ElementHasLockedStyleStates);}boolHasLockedStyleStates()const{returnGetBoolFlag(ElementHasLockedStyleStates);}voidSetHasWeirdParserInsertionMode(){SetBoolFlag(ElementHasWeirdParserInsertionMode);}boolHasWeirdParserInsertionMode()const{returnGetBoolFlag(ElementHasWeirdParserInsertionMode);}boolHandlingClick()const{returnGetBoolFlag(NodeHandlingClick);}voidSetHandlingClick(){SetBoolFlag(NodeHandlingClick);}voidClearHandlingClick(){ClearBoolFlag(NodeHandlingClick);}voidSetSubtreeRootPointer(nsINode*aSubtreeRoot){NS_ASSERTION(aSubtreeRoot,"aSubtreeRoot can never be null!");NS_ASSERTION(!(IsNodeOfType(eCONTENT)&&IsInDoc())&&!IsInShadowTree(),"Shouldn't be here!");mSubtreeRoot=aSubtreeRoot;}voidClearSubtreeRootPointer(){mSubtreeRoot=nullptr;}public:// Makes nsINode object to keep aObject alive.voidBindObject(nsISupports*aObject);// After calling UnbindObject nsINode object doesn't keep// aObject alive anymore.voidUnbindObject(nsISupports*aObject);voidGetBoundMutationObservers(nsTArray<RefPtr<nsDOMMutationObserver>>&aResult);/** * Returns the length of this node, as specified at * <http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node-length> */uint32_tLength()const;voidGetNodeName(mozilla::dom::DOMString&aNodeName){constnsString&nodeName=NodeName();aNodeName.SetStringBuffer(nsStringBuffer::FromString(nodeName),nodeName.Length());}voidGetBaseURI(nsAString&aBaseURI)const;// Return the base URI for the document.// The returned value may differ if the document is loaded via XHR, and// when accessed from chrome privileged script and// from content privileged script for compatibility.voidGetBaseURIFromJS(nsAString&aBaseURI)const;boolHasChildNodes()const{returnHasChildren();}uint16_tCompareDocumentPosition(nsINode&aOther)const;voidGetNodeValue(nsAString&aNodeValue){GetNodeValueInternal(aNodeValue);}voidSetNodeValue(constnsAString&aNodeValue,mozilla::ErrorResult&aError){SetNodeValueInternal(aNodeValue,aError);}virtualvoidGetNodeValueInternal(nsAString&aNodeValue);virtualvoidSetNodeValueInternal(constnsAString&aNodeValue,mozilla::ErrorResult&aError){// The DOM spec says that when nodeValue is defined to be null "setting it// has no effect", so we don't throw an exception.}voidEnsurePreInsertionValidity(nsINode&aNewChild,nsINode*aRefChild,mozilla::ErrorResult&aError);nsINode*InsertBefore(nsINode&aNode,nsINode*aChild,mozilla::ErrorResult&aError){returnReplaceOrInsertBefore(false,&aNode,aChild,aError);}nsINode*AppendChild(nsINode&aNode,mozilla::ErrorResult&aError){returnInsertBefore(aNode,nullptr,aError);}nsINode*ReplaceChild(nsINode&aNode,nsINode&aChild,mozilla::ErrorResult&aError){returnReplaceOrInsertBefore(true,&aNode,&aChild,aError);}nsINode*RemoveChild(nsINode&aChild,mozilla::ErrorResult&aError);already_AddRefed<nsINode>CloneNode(boolaDeep,mozilla::ErrorResult&aError);boolIsEqualNode(nsINode*aNode);voidGetNamespaceURI(nsAString&aNamespaceURI)const{mNodeInfo->GetNamespaceURI(aNamespaceURI);}#ifdef MOZILLA_INTERNAL_APIvoidGetPrefix(nsAString&aPrefix){mNodeInfo->GetPrefix(aPrefix);}#endifvoidGetLocalName(mozilla::dom::DOMString&aLocalName)const{constnsString&localName=LocalName();if(localName.IsVoid()){aLocalName.SetNull();}else{aLocalName.SetStringBuffer(nsStringBuffer::FromString(localName),localName.Length());}}nsDOMAttributeMap*GetAttributes();voidSetUserData(JSContext*aCx,constnsAString&aKey,JS::Handle<JS::Value>aData,JS::MutableHandle<JS::Value>aRetval,mozilla::ErrorResult&aError);voidGetUserData(JSContext*aCx,constnsAString&aKey,JS::MutableHandle<JS::Value>aRetval,mozilla::ErrorResult&aError);// Helper method to remove this node from its parent. This is not exposed// through WebIDL.// Only call this if the node has a parent node.nsresultRemoveFromParent(){nsINode*parent=GetParentNode();mozilla::ErrorResultrv;parent->RemoveChild(*this,rv);returnrv.StealNSResult();}// ChildNode methodsmozilla::dom::Element*GetPreviousElementSibling()const;mozilla::dom::Element*GetNextElementSibling()const;/** * Remove this node from its parent, if any. */voidRemove();// ParentNode methodsmozilla::dom::Element*GetFirstElementChild()const;mozilla::dom::Element*GetLastElementChild()const;voidGetBoxQuads(constBoxQuadOptions&aOptions,nsTArray<RefPtr<DOMQuad>>&aResult,mozilla::ErrorResult&aRv);already_AddRefed<DOMQuad>ConvertQuadFromNode(DOMQuad&aQuad,constTextOrElementOrDocument&aFrom,constConvertCoordinateOptions&aOptions,ErrorResult&aRv);already_AddRefed<DOMQuad>ConvertRectFromNode(DOMRectReadOnly&aRect,constTextOrElementOrDocument&aFrom,constConvertCoordinateOptions&aOptions,ErrorResult&aRv);already_AddRefed<DOMPoint>ConvertPointFromNode(constDOMPointInit&aPoint,constTextOrElementOrDocument&aFrom,constConvertCoordinateOptions&aOptions,ErrorResult&aRv);protected:// Override this function to create a custom slots class.// Must not return null.virtualnsINode::nsSlots*CreateSlots();boolHasSlots()const{returnmSlots!=nullptr;}nsSlots*GetExistingSlots()const{returnmSlots;}nsSlots*Slots(){if(!HasSlots()){mSlots=CreateSlots();MOZ_ASSERT(mSlots);}returnGetExistingSlots();}nsTObserverArray<nsIMutationObserver*>*GetMutationObservers(){returnHasSlots()?&GetExistingSlots()->mMutationObservers:nullptr;}boolIsEditableInternal()const;virtualboolIsEditableExternal()const{returnIsEditableInternal();}virtualvoidGetTextContentInternal(nsAString&aTextContent,mozilla::ErrorResult&aError);virtualvoidSetTextContentInternal(constnsAString&aTextContent,mozilla::ErrorResult&aError){}#ifdef DEBUG// Note: virtual so that IsInNativeAnonymousSubtree can be called accross// module boundaries.virtualvoidCheckNotNativeAnonymous()const;#endif// These are just used to implement nsIDOMNode using// NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER and for quickstubs.nsresultGetParentNode(nsIDOMNode**aParentNode);nsresultGetParentElement(nsIDOMElement**aParentElement);nsresultGetChildNodes(nsIDOMNodeList**aChildNodes);nsresultGetFirstChild(nsIDOMNode**aFirstChild);nsresultGetLastChild(nsIDOMNode**aLastChild);nsresultGetPreviousSibling(nsIDOMNode**aPrevSibling);nsresultGetNextSibling(nsIDOMNode**aNextSibling);nsresultGetOwnerDocument(nsIDOMDocument**aOwnerDocument);nsresultCompareDocumentPosition(nsIDOMNode*aOther,uint16_t*aReturn);voidEnsurePreInsertionValidity1(nsINode&aNewChild,nsINode*aRefChild,mozilla::ErrorResult&aError);voidEnsurePreInsertionValidity2(boolaReplace,nsINode&aNewChild,nsINode*aRefChild,mozilla::ErrorResult&aError);nsresultReplaceOrInsertBefore(boolaReplace,nsIDOMNode*aNewChild,nsIDOMNode*aRefChild,nsIDOMNode**aReturn);nsINode*ReplaceOrInsertBefore(boolaReplace,nsINode*aNewChild,nsINode*aRefChild,mozilla::ErrorResult&aError);nsresultRemoveChild(nsIDOMNode*aOldChild,nsIDOMNode**aReturn);/** * Returns the Element that should be used for resolving namespaces * on this node (ie the ownerElement for attributes, the documentElement for * documents, the node itself for elements and for other nodes the parentNode * if it is an element). */virtualmozilla::dom::Element*GetNameSpaceElement()=0;/** * Most of the implementation of the nsINode RemoveChildAt method. * Should only be called on document, element, and document fragment * nodes. The aChildArray passed in should be the one for |this|. * * @param aIndex The index to remove at. * @param aNotify Whether to notify. * @param aKid The kid at aIndex. Must not be null. * @param aChildArray The child array to work with. * @param aMutationEvent whether to fire a mutation event for this removal. */voiddoRemoveChildAt(uint32_taIndex,boolaNotify,nsIContent*aKid,nsAttrAndChildArray&aChildArray);/** * Most of the implementation of the nsINode InsertChildAt method. * Should only be called on document, element, and document fragment * nodes. The aChildArray passed in should be the one for |this|. * * @param aKid The child to insert. * @param aIndex The index to insert at. * @param aNotify Whether to notify. * @param aChildArray The child array to work with */nsresultdoInsertChildAt(nsIContent*aKid,uint32_taIndex,boolaNotify,nsAttrAndChildArray&aChildArray);/** * Parse the given selector string into an nsCSSSelectorList. * * A null return value with a non-failing aRv means the string only * contained pseudo-element selectors. * * A failing aRv means the string was not a valid selector. */nsCSSSelectorList*ParseSelectorList(constnsAString&aSelectorString,mozilla::ErrorResult&aRv);public:/* Event stuff that documents and elements share. This needs to be NS_IMETHOD because some subclasses implement DOM methods with this exact name and signature and then the calling convention needs to match. Note that we include DOCUMENT_ONLY_EVENT events here so that we can forward all the document stuff to this implementation. */#define EVENT(name_, id_, type_, struct_) \ mozilla::dom::EventHandlerNonNull* GetOn##name_(); \ void SetOn##name_(mozilla::dom::EventHandlerNonNull* listener);#define TOUCH_EVENT EVENT#define DOCUMENT_ONLY_EVENT EVENT#include"mozilla/EventNameList.h"#undef DOCUMENT_ONLY_EVENT#undef TOUCH_EVENT#undef EVENTprotected:staticboolTraverse(nsINode*tmp,nsCycleCollectionTraversalCallback&cb);staticvoidUnlink(nsINode*tmp);RefPtr<mozilla::dom::NodeInfo>mNodeInfo;// mParent is an owning ref most of the time, except for the case of document// nodes, so it cannot be represented by nsCOMPtr, so mark is as// MOZ_OWNING_REF.nsINode*MOZ_OWNING_REFmParent;private:// Boolean flags.uint32_tmBoolFlags;protected:// These references are non-owning and safe, as they are managed by// nsAttrAndChildArray.nsIContent*MOZ_NON_OWNING_REFmNextSibling;nsIContent*MOZ_NON_OWNING_REFmPreviousSibling;// This reference is non-owning and safe, since in the case of documents,// it is set to null when the document gets destroyed, and in the case of// other nodes, the children keep the parents alive.nsIContent*MOZ_NON_OWNING_REFmFirstChild;union{// Pointer to our primary frame. Might be null.nsIFrame*mPrimaryFrame;// Pointer to the root of our subtree. Might be null.// This reference is non-owning and safe, since it either points to the// object itself, or is reset by ClearSubtreeRootPointer.nsINode*MOZ_NON_OWNING_REFmSubtreeRoot;};// Storage for more members that are usually not needed; allocated lazily.nsSlots*mSlots;};inlinensIDOMNode*GetAsDOMNode(nsINode*aNode){returnaNode?aNode->AsDOMNode():nullptr;}// Useful inline function for getting a node given an nsIContent and an// nsIDocument. Returns the first argument cast to nsINode if it is non-null,// otherwise returns the second (which may be null). We use type variables// instead of nsIContent* and nsIDocument* because the actual types must be// known for the cast to work.template<classC,classD>inlinensINode*NODE_FROM(C&aContent,D&aDocument){if(aContent)returnstatic_cast<nsINode*>(aContent);returnstatic_cast<nsINode*>(aDocument);}NS_DEFINE_STATIC_IID_ACCESSOR(nsINode,NS_INODE_IID)inlinensISupports*ToSupports(nsINode*aPointer){returnaPointer;}inlinensISupports*ToCanonicalSupports(nsINode*aPointer){returnaPointer;}#define NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER(...) \ NS_IMETHOD GetNodeName(nsAString& aNodeName) __VA_ARGS__ override \ { \ aNodeName = nsINode::NodeName(); \ return NS_OK; \ } \ NS_IMETHOD GetNodeValue(nsAString& aNodeValue) __VA_ARGS__ override \ { \ nsINode::GetNodeValue(aNodeValue); \ return NS_OK; \ } \ NS_IMETHOD SetNodeValue(const nsAString& aNodeValue) __VA_ARGS__ override \ { \ mozilla::ErrorResult rv; \ nsINode::SetNodeValue(aNodeValue, rv); \ return rv.StealNSResult(); \ } \ NS_IMETHOD GetNodeType(uint16_t* aNodeType) __VA_ARGS__ override \ { \ *aNodeType = nsINode::NodeType(); \ return NS_OK; \ } \ NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode) __VA_ARGS__ override \ { \ return nsINode::GetParentNode(aParentNode); \ } \ NS_IMETHOD GetParentElement(nsIDOMElement** aParentElement) __VA_ARGS__ override \ { \ return nsINode::GetParentElement(aParentElement); \ } \ NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes) __VA_ARGS__ override \ { \ return nsINode::GetChildNodes(aChildNodes); \ } \ NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild) __VA_ARGS__ override \ { \ return nsINode::GetFirstChild(aFirstChild); \ } \ NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild) __VA_ARGS__ override \ { \ return nsINode::GetLastChild(aLastChild); \ } \ NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling) __VA_ARGS__ override \ { \ return nsINode::GetPreviousSibling(aPreviousSibling); \ } \ NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling) __VA_ARGS__ override \ { \ return nsINode::GetNextSibling(aNextSibling); \ } \ NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument) __VA_ARGS__ override \ { \ return nsINode::GetOwnerDocument(aOwnerDocument); \ } \ NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aResult) __VA_ARGS__ override \ { \ return ReplaceOrInsertBefore(false, aNewChild, aRefChild, aResult); \ } \ NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aResult) __VA_ARGS__ override \ { \ return ReplaceOrInsertBefore(true, aNewChild, aOldChild, aResult); \ } \ NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aResult) __VA_ARGS__ override \ { \ return nsINode::RemoveChild(aOldChild, aResult); \ } \ NS_IMETHOD AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aResult) __VA_ARGS__ override \ { \ return InsertBefore(aNewChild, nullptr, aResult); \ } \ NS_IMETHOD HasChildNodes(bool* aResult) __VA_ARGS__ override \ { \ *aResult = nsINode::HasChildNodes(); \ return NS_OK; \ } \ NS_IMETHOD CloneNode(bool aDeep, uint8_t aArgc, nsIDOMNode** aResult) __VA_ARGS__ override \ { \ if (aArgc == 0) { \ aDeep = true; \ } \ mozilla::ErrorResult rv; \ nsCOMPtr<nsINode> clone = nsINode::CloneNode(aDeep, rv); \ if (rv.Failed()) { \ return rv.StealNSResult(); \ } \ *aResult = clone.forget().take()->AsDOMNode(); \ return NS_OK; \ } \ NS_IMETHOD Normalize() __VA_ARGS__ override \ { \ nsINode::Normalize(); \ return NS_OK; \ } \ NS_IMETHOD GetNamespaceURI(nsAString& aNamespaceURI) __VA_ARGS__ override \ { \ nsINode::GetNamespaceURI(aNamespaceURI); \ return NS_OK; \ } \ NS_IMETHOD GetPrefix(nsAString& aPrefix) __VA_ARGS__ override \ { \ nsINode::GetPrefix(aPrefix); \ return NS_OK; \ } \ NS_IMETHOD GetLocalName(nsAString& aLocalName) __VA_ARGS__ override \ { \ aLocalName = nsINode::LocalName(); \ return NS_OK; \ } \ NS_IMETHOD UnusedPlaceholder(bool* aResult) __VA_ARGS__ override \ { \ *aResult = false; \ return NS_OK; \ } \ NS_IMETHOD GetDOMBaseURI(nsAString& aBaseURI) __VA_ARGS__ override \ { \ nsINode::GetBaseURI(aBaseURI); \ return NS_OK; \ } \ NS_IMETHOD CompareDocumentPosition(nsIDOMNode* aOther, uint16_t* aResult) __VA_ARGS__ override \ { \ return nsINode::CompareDocumentPosition(aOther, aResult); \ } \ NS_IMETHOD GetTextContent(nsAString& aTextContent) __VA_ARGS__ override \ { \ mozilla::ErrorResult rv; \ nsINode::GetTextContent(aTextContent, rv); \ return rv.StealNSResult(); \ } \ NS_IMETHOD SetTextContent(const nsAString& aTextContent) __VA_ARGS__ override \ { \ mozilla::ErrorResult rv; \ nsINode::SetTextContent(aTextContent, rv); \ return rv.StealNSResult(); \ } \ NS_IMETHOD LookupPrefix(const nsAString& aNamespaceURI, nsAString& aResult) __VA_ARGS__ override \ { \ nsINode::LookupPrefix(aNamespaceURI, aResult); \ return NS_OK; \ } \ NS_IMETHOD IsDefaultNamespace(const nsAString& aNamespaceURI, bool* aResult) __VA_ARGS__ override \ { \ *aResult = nsINode::IsDefaultNamespace(aNamespaceURI); \ return NS_OK; \ } \ NS_IMETHOD LookupNamespaceURI(const nsAString& aPrefix, nsAString& aResult) __VA_ARGS__ override \ { \ nsINode::LookupNamespaceURI(aPrefix, aResult); \ return NS_OK; \ } \ NS_IMETHOD IsEqualNode(nsIDOMNode* aArg, bool* aResult) __VA_ARGS__ override \ { \ return nsINode::IsEqualNode(aArg, aResult); \ } \ NS_IMETHOD SetUserData(const nsAString& aKey, nsIVariant* aData, nsIVariant** aResult) __VA_ARGS__ override \ { \ return nsINode::SetUserData(aKey, aData, aResult); \ } \ NS_IMETHOD GetUserData(const nsAString& aKey, nsIVariant** aResult) __VA_ARGS__ override \ { \ return nsINode::GetUserData(aKey, aResult); \ } \ NS_IMETHOD Contains(nsIDOMNode* aOther, bool* aResult) __VA_ARGS__ override \ { \ return nsINode::Contains(aOther, aResult); \ }#define NS_FORWARD_NSIDOMNODE_TO_NSINODE \ NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER(final)#define NS_FORWARD_NSIDOMNODE_TO_NSINODE_OVERRIDABLE \ NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER()#endif /* nsINode_h___ */