/* * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2001 Dirk Mueller (mueller@kde.org) * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #pragma once #include "EventTarget.h" #include "ExceptionOr.h" #include "LayoutRect.h" #include "MutationObserver.h" #include "RenderStyleConstants.h" #include "StyleValidity.h" #include "TreeScope.h" #include "URLHash.h" #include #include #include #include // This needs to be here because Document.h also depends on it. #define DUMP_NODE_STATISTICS 0 namespace WebCore { class ContainerNode; class Document; class Element; class FloatPoint; class HTMLQualifiedName; class HTMLSlotElement; class MathMLQualifiedName; class NamedNodeMap; class NodeList; class NodeListsNodeData; class NodeRareData; class QualifiedName; class RenderBox; class RenderBoxModelObject; class RenderObject; class RenderStyle; class SVGQualifiedName; class ShadowRoot; class TouchEvent; using NodeOrString = Variant, String>; class NodeRareDataBase { public: RenderObject* renderer() const { return m_renderer; } void setRenderer(RenderObject* renderer) { m_renderer = renderer; } protected: NodeRareDataBase(RenderObject* renderer) : m_renderer(renderer) { } private: RenderObject* m_renderer; }; class Node : public EventTarget { WTF_MAKE_FAST_ALLOCATED; friend class Document; friend class TreeScope; friend class TreeScopeAdopter; public: enum NodeType { ELEMENT_NODE = 1, ATTRIBUTE_NODE = 2, TEXT_NODE = 3, CDATA_SECTION_NODE = 4, PROCESSING_INSTRUCTION_NODE = 7, COMMENT_NODE = 8, DOCUMENT_NODE = 9, DOCUMENT_TYPE_NODE = 10, DOCUMENT_FRAGMENT_NODE = 11, }; enum DeprecatedNodeType { ENTITY_REFERENCE_NODE = 5, ENTITY_NODE = 6, NOTATION_NODE = 12, }; enum DocumentPosition { DOCUMENT_POSITION_EQUIVALENT = 0x00, DOCUMENT_POSITION_DISCONNECTED = 0x01, DOCUMENT_POSITION_PRECEDING = 0x02, DOCUMENT_POSITION_FOLLOWING = 0x04, DOCUMENT_POSITION_CONTAINS = 0x08, DOCUMENT_POSITION_CONTAINED_BY = 0x10, DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20, }; WEBCORE_EXPORT static void startIgnoringLeaks(); WEBCORE_EXPORT static void stopIgnoringLeaks(); static void dumpStatistics(); virtual ~Node(); void willBeDeletedFrom(Document&); // DOM methods & attributes for Node bool hasTagName(const HTMLQualifiedName&) const; bool hasTagName(const MathMLQualifiedName&) const; bool hasTagName(const SVGQualifiedName&) const; virtual String nodeName() const = 0; virtual String nodeValue() const; virtual ExceptionOr setNodeValue(const String&); virtual NodeType nodeType() const = 0; virtual size_t approximateMemoryCost() const { return sizeof(*this); } ContainerNode* parentNode() const; static ptrdiff_t parentNodeMemoryOffset() { return OBJECT_OFFSETOF(Node, m_parentNode); } Element* parentElement() const; Node* previousSibling() const { return m_previous; } static ptrdiff_t previousSiblingMemoryOffset() { return OBJECT_OFFSETOF(Node, m_previous); } Node* nextSibling() const { return m_next; } static ptrdiff_t nextSiblingMemoryOffset() { return OBJECT_OFFSETOF(Node, m_next); } WEBCORE_EXPORT RefPtr childNodes(); Node* firstChild() const; Node* lastChild() const; bool hasAttributes() const; NamedNodeMap* attributes() const; Node* pseudoAwareNextSibling() const; Node* pseudoAwarePreviousSibling() const; Node* pseudoAwareFirstChild() const; Node* pseudoAwareLastChild() const; WEBCORE_EXPORT const URL& baseURI() const; void getSubresourceURLs(ListHashSet&) const; WEBCORE_EXPORT ExceptionOr insertBefore(Node& newChild, Node* refChild); WEBCORE_EXPORT ExceptionOr replaceChild(Node& newChild, Node& oldChild); WEBCORE_EXPORT ExceptionOr removeChild(Node& child); WEBCORE_EXPORT ExceptionOr appendChild(Node& newChild); bool hasChildNodes() const { return firstChild(); } enum class CloningOperation { OnlySelf, SelfWithTemplateContent, Everything, }; virtual Ref cloneNodeInternal(Document&, CloningOperation) = 0; Ref cloneNode(bool deep) { return cloneNodeInternal(document(), deep ? CloningOperation::Everything : CloningOperation::OnlySelf); } WEBCORE_EXPORT ExceptionOr> cloneNodeForBindings(bool deep); virtual const AtomicString& localName() const; virtual const AtomicString& namespaceURI() const; virtual const AtomicString& prefix() const; virtual ExceptionOr setPrefix(const AtomicString&); WEBCORE_EXPORT void normalize(); bool isSameNode(Node* other) const { return this == other; } WEBCORE_EXPORT bool isEqualNode(Node*) const; WEBCORE_EXPORT bool isDefaultNamespace(const AtomicString& namespaceURI) const; WEBCORE_EXPORT const AtomicString& lookupPrefix(const AtomicString& namespaceURI) const; WEBCORE_EXPORT const AtomicString& lookupNamespaceURI(const AtomicString& prefix) const; WEBCORE_EXPORT String textContent(bool convertBRsToNewlines = false) const; WEBCORE_EXPORT ExceptionOr setTextContent(const String&); Node* lastDescendant() const; Node* firstDescendant() const; // From the NonDocumentTypeChildNode - https://dom.spec.whatwg.org/#nondocumenttypechildnode WEBCORE_EXPORT Element* previousElementSibling() const; WEBCORE_EXPORT Element* nextElementSibling() const; // From the ChildNode - https://dom.spec.whatwg.org/#childnode ExceptionOr before(Vector&&); ExceptionOr after(Vector&&); ExceptionOr replaceWith(Vector&&); WEBCORE_EXPORT ExceptionOr remove(); // Other methods (not part of DOM) bool isElementNode() const { return getFlag(IsElementFlag); } bool isContainerNode() const { return getFlag(IsContainerFlag); } bool isTextNode() const { return getFlag(IsTextFlag); } bool isHTMLElement() const { return getFlag(IsHTMLFlag); } bool isSVGElement() const { return getFlag(IsSVGFlag); } bool isMathMLElement() const { return getFlag(IsMathMLFlag); } bool isPseudoElement() const { return pseudoId() != NOPSEUDO; } bool isBeforePseudoElement() const { return pseudoId() == BEFORE; } bool isAfterPseudoElement() const { return pseudoId() == AFTER; } PseudoId pseudoId() const { return (isElementNode() && hasCustomStyleResolveCallbacks()) ? customPseudoId() : NOPSEUDO; } virtual bool isMediaControlElement() const { return false; } virtual bool isMediaControls() const { return false; } #if ENABLE(VIDEO_TRACK) virtual bool isWebVTTElement() const { return false; } #endif bool isStyledElement() const { return getFlag(IsStyledElementFlag); } virtual bool isAttributeNode() const { return false; } virtual bool isCharacterDataNode() const { return false; } virtual bool isFrameOwnerElement() const { return false; } virtual bool isPluginElement() const { return false; } #if ENABLE(SERVICE_CONTROLS) virtual bool isImageControlsRootElement() const { return false; } virtual bool isImageControlsButtonElement() const { return false; } #endif bool isDocumentNode() const; bool isTreeScope() const; bool isDocumentFragment() const { return getFlag(IsDocumentFragmentFlag); } bool isShadowRoot() const { return isDocumentFragment() && isTreeScope(); } bool hasCustomStyleResolveCallbacks() const { return getFlag(HasCustomStyleResolveCallbacksFlag); } bool hasSyntheticAttrChildNodes() const { return getFlag(HasSyntheticAttrChildNodesFlag); } void setHasSyntheticAttrChildNodes(bool flag) { setFlag(flag, HasSyntheticAttrChildNodesFlag); } // If this node is in a shadow tree, returns its shadow host. Otherwise, returns null. WEBCORE_EXPORT Element* shadowHost() const; // If this node is in a shadow tree, returns its shadow host. Otherwise, returns this. // Deprecated. Should use shadowHost() and check the return value. WEBCORE_EXPORT Node* deprecatedShadowAncestorNode() const; ShadowRoot* containingShadowRoot() const; ShadowRoot* shadowRoot() const; bool isClosedShadowHidden(const Node&) const; HTMLSlotElement* assignedSlot() const; HTMLSlotElement* assignedSlotForBindings() const; bool isUndefinedCustomElement() const { return isElementNode() && getFlag(IsEditingTextOrUndefinedCustomElementFlag); } bool isCustomElementUpgradeCandidate() const { return getFlag(IsCustomElement) && getFlag(IsEditingTextOrUndefinedCustomElementFlag); } bool isDefinedCustomElement() const { return getFlag(IsCustomElement) && !getFlag(IsEditingTextOrUndefinedCustomElementFlag); } bool isFailedCustomElement() const { return isElementNode() && !getFlag(IsCustomElement) && getFlag(IsEditingTextOrUndefinedCustomElementFlag); } // Returns null, a child of ShadowRoot, or a legacy shadow root. Node* nonBoundaryShadowTreeRootNode(); // Node's parent or shadow tree host. ContainerNode* parentOrShadowHostNode() const; ContainerNode* parentInComposedTree() const; Element* parentElementInComposedTree() const; Element* parentOrShadowHostElement() const; void setParentNode(ContainerNode*); Node& rootNode() const; Node& shadowIncludingRoot() const; struct GetRootNodeOptions { bool composed; }; Node& getRootNode(const GetRootNodeOptions&) const; void* opaqueRoot() const; // Use when it's guaranteed to that shadowHost is null. ContainerNode* parentNodeGuaranteedHostFree() const; // Returns the parent node, but null if the parent node is a ShadowRoot. ContainerNode* nonShadowBoundaryParentNode() const; bool selfOrAncestorHasDirAutoAttribute() const { return getFlag(SelfOrAncestorHasDirAutoFlag); } void setSelfOrAncestorHasDirAutoAttribute(bool flag) { setFlag(flag, SelfOrAncestorHasDirAutoFlag); } // Returns the enclosing event parent Element (or self) that, when clicked, would trigger a navigation. Element* enclosingLinkEventParentOrSelf(); // These low-level calls give the caller responsibility for maintaining the integrity of the tree. void setPreviousSibling(Node* previous) { m_previous = previous; } void setNextSibling(Node* next) { m_next = next; } virtual bool canContainRangeEndPoint() const { return false; } bool isRootEditableElement() const; WEBCORE_EXPORT Element* rootEditableElement() const; // Called by the parser when this element's close tag is reached, // signaling that all child tags have been parsed and added. // This is needed for and elements, which can't lay themselves out // until they know all of their nested s. [Radar 3603191, 4040848]. // Also used for script elements and some SVG elements for similar purposes, // but making parsing a special case in this respect should be avoided if possible. virtual void finishParsingChildren() { } virtual void beginParsingChildren() { } // For and