/* * 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. * */ #ifndef Node_h #define Node_h #include "EventTarget.h" #include "URLHash.h" #include "LayoutRect.h" #include "MutationObserver.h" #include "RenderStyleConstants.h" #include "TreeScope.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 Attribute; class ClassCollection; class ContainerNode; class DOMTokenList; class Document; class Element; class Event; class EventListener; class FloatPoint; class Frame; class HTMLInputElement; class HTMLQualifiedName; class HTMLSlotElement; class IntRect; class KeyboardEvent; class MathMLQualifiedName; class NSResolver; class NameNodeList; class NamedNodeMap; class NodeList; class NodeListsNodeData; class NodeOrString; class NodeRareData; class QualifiedName; class RadioNodeList; class RegisteredEventListener; class RenderBox; class RenderBoxModelObject; class RenderObject; class RenderStyle; class SVGQualifiedName; class ShadowRoot; class TagCollection; #if ENABLE(QT_GESTURE_EVENTS) class PlatformGestureEvent; #endif #if ENABLE(INDIE_UI) class UIRequestEvent; #endif #if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS) class TouchEvent; #endif typedef int ExceptionCode; const int nodeStyleChangeShift = 14; // SyntheticStyleChange means that we need to go through the entire style change logic even though // no style property has actually changed. It is used to restructure the tree when, for instance, // RenderLayers are created or destroyed due to animation changes. enum StyleChangeType { NoStyleChange = 0, InlineStyleChange = 1 << nodeStyleChangeShift, FullStyleChange = 2 << nodeStyleChangeShift, SyntheticStyleChange = 3 << nodeStyleChangeShift, ReconstructRenderTree = 4 << nodeStyleChangeShift, }; 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, }; // Only used by ObjC / GObject bindings. static bool isSupportedForBindings(const String& feature, const String& version); 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 void setNodeValue(const String&, ExceptionCode&); virtual NodeType nodeType() const = 0; 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); } 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; URL baseURI() const; void getSubresourceURLs(ListHashSet&) const; // These should all actually return a node, but this is only important for language bindings, // which will already know and hold a ref on the right node to return. Returning bool allows // these methods to be more efficient since they don't need to return a ref WEBCORE_EXPORT bool insertBefore(PassRefPtr newChild, Node* refChild, ExceptionCode&); bool replaceChild(PassRefPtr newChild, Node* oldChild, ExceptionCode&); WEBCORE_EXPORT bool removeChild(Node* child, ExceptionCode&); WEBCORE_EXPORT bool appendChild(PassRefPtr newChild, ExceptionCode&); 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); } virtual const AtomicString& localName() const; virtual const AtomicString& namespaceURI() const; virtual const AtomicString& prefix() const; virtual void setPrefix(const AtomicString&, ExceptionCode&); void normalize(); bool isSameNode(Node* other) const { return this == other; } bool isEqualNode(Node*) const; bool isDefaultNamespace(const AtomicString& namespaceURI) const; String lookupPrefix(const AtomicString& namespaceURI) const; String lookupNamespaceURI(const String& prefix) const; String lookupNamespacePrefix(const AtomicString& namespaceURI, const Element* originalElement) const; WEBCORE_EXPORT String textContent(bool convertBRsToNewlines = false) const; WEBCORE_EXPORT void setTextContent(const String&, ExceptionCode&); Node* lastDescendant() const; Node* firstDescendant() const; // From the NonDocumentTypeChildNode - https://dom.spec.whatwg.org/#nondocumenttypechildnode Element* previousElementSibling() const; Element* nextElementSibling() const; // From the ChildNode - https://dom.spec.whatwg.org/#childnode void before(Vector&&, ExceptionCode&); void after(Vector&&, ExceptionCode&); void replaceWith(Vector&&, ExceptionCode&); WEBCORE_EXPORT void remove(ExceptionCode&); // 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 isNamedFlowContentNode() const { return getFlag(IsNamedFlowContentNodeFlag); } 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; #if ENABLE(SHADOW_DOM) HTMLSlotElement* assignedSlot() const; #endif #if ENABLE(CUSTOM_ELEMENTS) bool isCustomElement() const { return getFlag(IsCustomElement); } void setIsCustomElement() { return setFlag(IsCustomElement); } #endif // 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* parentOrShadowHostElement() const; void setParentNode(ContainerNode*); Node* highestAncestor() 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