summaryrefslogtreecommitdiff
path: root/Source/WebCore/dom/Node.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/dom/Node.h')
-rw-r--r--Source/WebCore/dom/Node.h554
1 files changed, 309 insertions, 245 deletions
diff --git a/Source/WebCore/dom/Node.h b/Source/WebCore/dom/Node.h
index dff49ff96..37a7f5dff 100644
--- a/Source/WebCore/dom/Node.h
+++ b/Source/WebCore/dom/Node.h
@@ -22,84 +22,47 @@
*
*/
-#ifndef Node_h
-#define Node_h
+#pragma once
-#include "EditingBoundary.h"
#include "EventTarget.h"
-#include "URLHash.h"
+#include "ExceptionOr.h"
#include "LayoutRect.h"
#include "MutationObserver.h"
#include "RenderStyleConstants.h"
-#include "ScriptWrappable.h"
-#include "SimulatedClickOptions.h"
+#include "StyleValidity.h"
#include "TreeScope.h"
-#include "TreeShared.h"
+#include "URLHash.h"
#include <wtf/Forward.h>
#include <wtf/ListHashSet.h>
-#include <wtf/text/AtomicString.h>
-
-namespace JSC {
- class VM;
- class SlotVisitor;
-}
+#include <wtf/MainThread.h>
+#include <wtf/TypeCasts.h>
// This needs to be here because Document.h also depends on it.
#define DUMP_NODE_STATISTICS 0
namespace WebCore {
-class Attribute;
-class ClassNodeList;
class ContainerNode;
-class DOMSettableTokenList;
class Document;
class Element;
-class Event;
-class EventListener;
class FloatPoint;
-class Frame;
-class HTMLInputElement;
-class IntRect;
-class KeyboardEvent;
-class NSResolver;
+class HTMLQualifiedName;
+class HTMLSlotElement;
+class MathMLQualifiedName;
class NamedNodeMap;
-class NameNodeList;
class NodeList;
class NodeListsNodeData;
class NodeRareData;
class QualifiedName;
-class RadioNodeList;
-class RegisteredEventListener;
class RenderBox;
class RenderBoxModelObject;
class RenderObject;
class RenderStyle;
+class SVGQualifiedName;
class ShadowRoot;
-class TagNodeList;
-
-#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,
-};
+using NodeOrString = Variant<RefPtr<Node>, String>;
class NodeRareDataBase {
public:
@@ -115,26 +78,28 @@ private:
RenderObject* m_renderer;
};
-class Node : public EventTarget, public ScriptWrappable, public TreeShared<Node> {
+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,
- ENTITY_REFERENCE_NODE = 5,
- ENTITY_NODE = 6,
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,
- XPATH_NAMESPACE_NODE = 13,
};
enum DocumentPosition {
DOCUMENT_POSITION_EQUIVALENT = 0x00,
@@ -146,31 +111,32 @@ public:
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20,
};
- static bool isSupported(const String& feature, const String& version);
-
- static void startIgnoringLeaks();
- static void stopIgnoringLeaks();
+ WEBCORE_EXPORT static void startIgnoringLeaks();
+ WEBCORE_EXPORT static void stopIgnoringLeaks();
static void dumpStatistics();
virtual ~Node();
- void willBeDeletedFrom(Document*);
+ void willBeDeletedFrom(Document&);
// DOM methods & attributes for Node
- bool hasTagName(const QualifiedName&) const;
- bool hasLocalName(const AtomicString&) const;
+ 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 ExceptionOr<void> 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; }
- PassRefPtr<NodeList> childNodes();
+ static ptrdiff_t nextSiblingMemoryOffset() { return OBJECT_OFFSETOF(Node, m_next); }
+ WEBCORE_EXPORT RefPtr<NodeList> childNodes();
Node* firstChild() const;
Node* lastChild() const;
bool hasAttributes() const;
@@ -180,40 +146,54 @@ public:
Node* pseudoAwareFirstChild() const;
Node* pseudoAwareLastChild() const;
- virtual URL baseURI() const;
+ WEBCORE_EXPORT const URL& baseURI() const;
void getSubresourceURLs(ListHashSet<URL>&) 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
- bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&);
- bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&);
- bool removeChild(Node* child, ExceptionCode&);
- bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&);
+ WEBCORE_EXPORT ExceptionOr<void> insertBefore(Node& newChild, Node* refChild);
+ WEBCORE_EXPORT ExceptionOr<void> replaceChild(Node& newChild, Node& oldChild);
+ WEBCORE_EXPORT ExceptionOr<void> removeChild(Node& child);
+ WEBCORE_EXPORT ExceptionOr<void> appendChild(Node& newChild);
- void remove(ExceptionCode&);
bool hasChildNodes() const { return firstChild(); }
- virtual PassRefPtr<Node> cloneNode(bool deep) = 0;
+
+ enum class CloningOperation {
+ OnlySelf,
+ SelfWithTemplateContent,
+ Everything,
+ };
+ virtual Ref<Node> cloneNodeInternal(Document&, CloningOperation) = 0;
+ Ref<Node> cloneNode(bool deep) { return cloneNodeInternal(document(), deep ? CloningOperation::Everything : CloningOperation::OnlySelf); }
+ WEBCORE_EXPORT ExceptionOr<Ref<Node>> cloneNodeForBindings(bool deep);
+
virtual const AtomicString& localName() const;
virtual const AtomicString& namespaceURI() const;
virtual const AtomicString& prefix() const;
- virtual void setPrefix(const AtomicString&, ExceptionCode&);
- void normalize();
+ virtual ExceptionOr<void> setPrefix(const AtomicString&);
+ WEBCORE_EXPORT 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;
-
- String textContent(bool convertBRsToNewlines = false) const;
- void setTextContent(const String&, ExceptionCode&);
+ 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<void> 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<void> before(Vector<NodeOrString>&&);
+ ExceptionOr<void> after(Vector<NodeOrString>&&);
+ ExceptionOr<void> replaceWith(Vector<NodeOrString>&&);
+ WEBCORE_EXPORT ExceptionOr<void> remove();
+
// Other methods (not part of DOM)
bool isElementNode() const { return getFlag(IsElementFlag); }
@@ -238,44 +218,60 @@ public:
virtual bool isCharacterDataNode() const { return false; }
virtual bool isFrameOwnerElement() const { return false; }
virtual bool isPluginElement() const { return false; }
- virtual bool isInsertionPointNode() 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 isInsertionPoint() const { return getFlag(NeedsNodeRenderingTraversalSlowPathFlag) && isInsertionPointNode(); }
- // Returns Node rather than InsertionPoint. Should be used only for language bindings.
- Node* insertionParentForBinding() const;
-
- bool needsNodeRenderingTraversalSlowPath() const;
- bool inNamedFlow() const { return getFlag(InNamedFlowFlag); }
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 0.
- Element* shadowHost() const;
+ // 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.
- Node* deprecatedShadowAncestorNode() const;
+ WEBCORE_EXPORT Node* deprecatedShadowAncestorNode() const;
ShadowRoot* containingShadowRoot() const;
ShadowRoot* shadowRoot() const;
+ bool isClosedShadowHidden(const Node&) const;
- // Returns 0, a child of ShadowRoot, or a legacy shadow root.
+ 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* highestAncestor() const;
+ Node& rootNode() const;
+ Node& shadowIncludingRoot() const;
- // Use when it's guaranteed to that shadowHost is 0.
+ 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 0 if the parent node is a ShadowRoot.
+ // Returns the parent node, but null if the parent node is a ShadowRoot.
ContainerNode* nonShadowBoundaryParentNode() const;
bool selfOrAncestorHasDirAutoAttribute() const { return getFlag(SelfOrAncestorHasDirAutoFlag); }
@@ -291,8 +287,7 @@ public:
virtual bool canContainRangeEndPoint() const { return false; }
bool isRootEditableElement() const;
- Element* rootEditableElement() const;
- Element* rootEditableElement(EditableType) 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.
@@ -312,24 +307,20 @@ public:
void setUserActionElement(bool flag) { setFlag(flag, IsUserActionElement); }
bool inRenderedDocument() const;
- bool needsStyleRecalc() const { return styleChangeType() != NoStyleChange; }
- StyleChangeType styleChangeType() const { return static_cast<StyleChangeType>(m_nodeFlags & StyleChangeMask); }
+ bool needsStyleRecalc() const { return styleValidity() != Style::Validity::Valid; }
+ Style::Validity styleValidity() const;
+ bool styleResolutionShouldRecompositeLayer() const;
bool childNeedsStyleRecalc() const { return getFlag(ChildNeedsStyleRecalcFlag); }
- bool isLink() const { return getFlag(IsLinkFlag); }
- bool isEditingText() const { return getFlag(IsEditingTextFlag); }
+ bool styleIsAffectedByPreviousSibling() const { return getFlag(StyleIsAffectedByPreviousSibling); }
+ bool isEditingText() const { return getFlag(IsTextFlag) && getFlag(IsEditingTextOrUndefinedCustomElementFlag); }
void setChildNeedsStyleRecalc() { setFlag(ChildNeedsStyleRecalcFlag); }
- void clearChildNeedsStyleRecalc() { clearFlag(ChildNeedsStyleRecalcFlag); }
+ void clearChildNeedsStyleRecalc() { m_nodeFlags &= ~(ChildNeedsStyleRecalcFlag | DirectChildNeedsStyleRecalcFlag); }
- void setNeedsStyleRecalc(StyleChangeType changeType = FullStyleChange);
- void clearNeedsStyleRecalc() { m_nodeFlags &= ~StyleChangeMask; }
+ void setHasValidStyle();
- void setIsLink(bool f) { setFlag(f, IsLinkFlag); }
- void setIsLink() { setFlag(IsLinkFlag); }
- void clearIsLink() { clearFlag(IsLinkFlag); }
-
- void setInNamedFlow() { setFlag(InNamedFlowFlag); }
- void clearInNamedFlow() { clearFlag(InNamedFlowFlag); }
+ bool isLink() const { return getFlag(IsLinkFlag); }
+ void setIsLink(bool flag) { setFlag(flag, IsLinkFlag); }
bool hasEventTargetData() const { return getFlag(HasEventTargetDataFlag); }
void setHasEventTargetData(bool flag) { setFlag(flag, HasEventTargetDataFlag); }
@@ -338,53 +329,39 @@ public:
UserSelectAllDoesNotAffectEditability,
UserSelectAllIsAlwaysNonEditable
};
- bool isContentEditable(UserSelectAllTreatment = UserSelectAllDoesNotAffectEditability);
+ WEBCORE_EXPORT bool isContentEditable();
bool isContentRichlyEditable();
- void inspect();
+ WEBCORE_EXPORT void inspect();
- bool hasEditableStyle(EditableType editableType = ContentIsEditable, UserSelectAllTreatment treatment = UserSelectAllIsAlwaysNonEditable) const
+ bool hasEditableStyle(UserSelectAllTreatment treatment = UserSelectAllIsAlwaysNonEditable) const
{
- switch (editableType) {
- case ContentIsEditable:
- return hasEditableStyle(Editable, treatment);
- case HasEditableAXRole:
- return isEditableToAccessibility(Editable);
- }
- ASSERT_NOT_REACHED();
- return false;
+ return computeEditability(treatment, ShouldUpdateStyle::DoNotUpdate) != Editability::ReadOnly;
}
-
- bool hasRichlyEditableStyle(EditableType editableType = ContentIsEditable) const
+ // FIXME: Replace every use of this function by helpers in htmlediting.h
+ bool hasRichlyEditableStyle() const
{
- switch (editableType) {
- case ContentIsEditable:
- return hasEditableStyle(RichlyEditable, UserSelectAllIsAlwaysNonEditable);
- case HasEditableAXRole:
- return isEditableToAccessibility(RichlyEditable);
- }
- ASSERT_NOT_REACHED();
- return false;
+ return computeEditability(UserSelectAllIsAlwaysNonEditable, ShouldUpdateStyle::DoNotUpdate) == Editability::CanEditRichly;
}
- virtual LayoutRect boundingBox() const;
- IntRect pixelSnappedBoundingBox() const { return pixelSnappedIntRect(boundingBox()); }
- LayoutRect renderRect(bool* isReplaced);
- IntRect pixelSnappedRenderRect(bool* isReplaced) { return pixelSnappedIntRect(renderRect(isReplaced)); }
+ enum class Editability { ReadOnly, CanEditPlainText, CanEditRichly };
+ enum class ShouldUpdateStyle { Update, DoNotUpdate };
+ WEBCORE_EXPORT Editability computeEditability(UserSelectAllTreatment, ShouldUpdateStyle) const;
- unsigned nodeIndex() const;
+ WEBCORE_EXPORT LayoutRect renderRect(bool* isReplaced);
+ IntRect pixelSnappedRenderRect(bool* isReplaced) { return snappedIntRect(renderRect(isReplaced)); }
- // Returns the DOM ownerDocument attribute. This method never returns 0, except in the case
+ WEBCORE_EXPORT unsigned computeNodeIndex() const;
+
+ // Returns the DOM ownerDocument attribute. This method never returns null, except in the case
// of a Document node.
- Document* ownerDocument() const;
+ WEBCORE_EXPORT Document* ownerDocument() const;
- // Returns the document associated with this node. This method never returns 0.
+ // Returns the document associated with this node.
// A Document node returns itself.
Document& document() const
{
- ASSERT(this);
- ASSERT(documentInternal());
- return *documentInternal();
+ return treeScope().documentScope();
}
TreeScope& treeScope() const
@@ -392,28 +369,30 @@ public:
ASSERT(m_treeScope);
return *m_treeScope;
}
+ static ptrdiff_t treeScopeMemoryOffset() { return OBJECT_OFFSETOF(Node, m_treeScope); }
// Returns true if this node is associated with a document and is in its associated document's
- // node tree, false otherwise.
- bool inDocument() const
+ // node tree, false otherwise (https://dom.spec.whatwg.org/#connected).
+ bool isConnected() const
{
- ASSERT(documentInternal() || !getFlag(InDocumentFlag));
- return getFlag(InDocumentFlag);
+ return getFlag(IsConnectedFlag);
}
+ bool isInUserAgentShadowTree() const;
bool isInShadowTree() const { return getFlag(IsInShadowTreeFlag); }
- bool isInTreeScope() const { return getFlag(static_cast<NodeFlags>(InDocumentFlag | IsInShadowTreeFlag)); }
+ bool isInTreeScope() const { return getFlag(static_cast<NodeFlags>(IsConnectedFlag | IsInShadowTreeFlag)); }
- bool isReadOnlyNode() const { return nodeType() == ENTITY_REFERENCE_NODE; }
bool isDocumentTypeNode() const { return nodeType() == DOCUMENT_TYPE_NODE; }
virtual bool childTypeAllowed(NodeType) const { return false; }
- unsigned childNodeCount() const;
- Node* childNode(unsigned index) const;
+ unsigned countChildNodes() const;
+ Node* traverseToChildAt(unsigned) const;
+
+ ExceptionOr<void> checkSetPrefix(const AtomicString& prefix);
- void checkSetPrefix(const AtomicString& prefix, ExceptionCode&);
+ WEBCORE_EXPORT bool isDescendantOf(const Node&) const;
+ bool isDescendantOf(const Node* other) const { return other && isDescendantOf(*other); }
- bool isDescendantOf(const Node*) const;
bool isDescendantOrShadowDescendantOf(const Node*) const;
- bool contains(const Node*) const;
+ WEBCORE_EXPORT bool contains(const Node*) const;
bool containsIncludingShadowDOM(const Node*) const;
bool containsIncludingHostElements(const Node*) const;
@@ -426,6 +405,8 @@ public:
// Whether or not a selection can be started in this object
virtual bool canStartSelection() const;
+ virtual bool shouldSelectOnMouseDown() { return false; }
+
// Getting points into and out of screen space
FloatPoint convertToPage(const FloatPoint&) const;
FloatPoint convertFromPage(const FloatPoint&) const;
@@ -444,13 +425,13 @@ public:
}
// Use these two methods with caution.
- RenderBox* renderBox() const;
+ WEBCORE_EXPORT RenderBox* renderBox() const;
RenderBoxModelObject* renderBoxModelObject() const;
// Wrapper for nodes that don't have a renderer, but still cache the style (like HTMLOptionElement).
- RenderStyle* renderStyle() const;
+ const RenderStyle* renderStyle() const;
- virtual RenderStyle* computedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO);
+ virtual const RenderStyle* computedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO);
// -----------------------------------------------------------------------------
// Notification of document structure changes (see ContainerNode.h for more notification methods)
@@ -461,20 +442,20 @@ public:
// dispatching.
//
// WebKit notifies this callback regardless if the subtree of the node is a document tree or a floating subtree.
- // Implementation can determine the type of subtree by seeing insertionPoint->inDocument().
+ // Implementation can determine the type of subtree by seeing insertionPoint->isConnected().
// For a performance reason, notifications are delivered only to ContainerNode subclasses if the insertionPoint is out of document.
//
- // There are another callback named didNotifyDescendantInsertions(), which is called after all the descendant is notified.
- // Only a few subclasses actually need this. To utilize this, the node should return InsertionShouldCallDidNotifyDescendantInsertions
+ // There is another callback named finishedInsertingSubtree(), which is called after all descendants are notified.
+ // Only a few subclasses actually need this. To utilize this, the node should return InsertionShouldCallFinishedInsertingSubtree
// from insrtedInto().
//
enum InsertionNotificationRequest {
InsertionDone,
- InsertionShouldCallDidNotifySubtreeInsertions
+ InsertionShouldCallFinishedInsertingSubtree
};
virtual InsertionNotificationRequest insertedInto(ContainerNode& insertionPoint);
- virtual void didNotifySubtreeInsertions(ContainerNode*) { }
+ virtual void finishedInsertingSubtree() { }
// Notifies the node that it is no longer part of the tree.
//
@@ -483,17 +464,17 @@ public:
//
virtual void removedFrom(ContainerNode& insertionPoint);
-#ifndef NDEBUG
+#if ENABLE(TREE_DEBUGGING)
virtual void formatForDebugger(char* buffer, unsigned length) const;
void showNode(const char* prefix = "") const;
void showTreeForThis() const;
void showNodePathForThis() const;
- void showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2 = 0, const char* markedLabel2 = 0) const;
+ void showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2 = nullptr, const char* markedLabel2 = nullptr) const;
void showTreeForThisAcrossFrame() const;
-#endif
+#endif // ENABLE(TREE_DEBUGGING)
- void invalidateNodeListAndCollectionCachesInAncestors(const QualifiedName* attrName = 0, Element* attributeOwnerElement = 0);
+ void invalidateNodeListAndCollectionCachesInAncestors(const QualifiedName* attrName = nullptr, Element* attributeOwnerElement = nullptr);
NodeListsNodeData* nodeLists();
void clearNodeLists();
@@ -501,55 +482,63 @@ public:
virtual bool willRespondToMouseClickEvents();
virtual bool willRespondToMouseWheelEvents();
- unsigned short compareDocumentPosition(Node*);
+ WEBCORE_EXPORT unsigned short compareDocumentPosition(Node&);
- virtual Node* toNode() override;
- virtual HTMLInputElement* toInputElement();
+ Node* toNode() override;
- virtual EventTargetInterface eventTargetInterface() const override;
- virtual ScriptExecutionContext* scriptExecutionContext() const override final; // Implemented in Document.h
+ EventTargetInterface eventTargetInterface() const override;
+ ScriptExecutionContext* scriptExecutionContext() const final; // Implemented in Document.h
- virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) override;
- virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) override;
+ bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) override;
+ bool removeEventListener(const AtomicString& eventType, EventListener&, const ListenerOptions&) override;
using EventTarget::dispatchEvent;
- virtual bool dispatchEvent(PassRefPtr<Event>) override;
+ bool dispatchEvent(Event&) override;
- void dispatchScopedEvent(PassRefPtr<Event>);
+ void dispatchScopedEvent(Event&);
virtual void handleLocalEvents(Event&);
void dispatchSubtreeModifiedEvent();
- bool dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEvent);
+ bool dispatchDOMActivateEvent(int detail, Event& underlyingEvent);
-#if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS)
- bool dispatchTouchEvent(PassRefPtr<TouchEvent>);
-#endif
-#if ENABLE(INDIE_UI)
- bool dispatchUIRequestEvent(PassRefPtr<UIRequestEvent>);
+#if ENABLE(TOUCH_EVENTS)
+ virtual bool allowsDoubleTapGesture() const { return true; }
#endif
+#if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS)
+ bool dispatchTouchEvent(TouchEvent&);
+#endif
bool dispatchBeforeLoadEvent(const String& sourceURL);
- virtual void dispatchInputEvent();
+ void dispatchInputEvent();
// Perform the default action for an event.
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event&);
- using TreeShared<Node>::ref;
- using TreeShared<Node>::deref;
+ void ref();
+ void deref();
+ bool hasOneRef() const;
+ int refCount() const;
+
+#ifndef NDEBUG
+ bool m_deletionHasBegun { false };
+ bool m_inRemovedLastRefFunction { false };
+ bool m_adoptionIsRequired { true };
+#endif
- virtual EventTargetData* eventTargetData() override final;
- virtual EventTargetData& ensureEventTargetData() override final;
+ EventTargetData* eventTargetData() final;
+ EventTargetData* eventTargetDataConcurrently() final;
+ EventTargetData& ensureEventTargetData() final;
- void getRegisteredMutationObserversOfType(HashMap<MutationObserver*, MutationRecordDeliveryOptions>&, MutationObserver::MutationType, const QualifiedName* attributeName);
- void registerMutationObserver(MutationObserver*, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
- void unregisterMutationObserver(MutationObserverRegistration*);
- void registerTransientMutationObserver(MutationObserverRegistration*);
- void unregisterTransientMutationObserver(MutationObserverRegistration*);
+ HashMap<MutationObserver*, MutationRecordDeliveryOptions> registeredMutationObservers(MutationObserver::MutationType, const QualifiedName* attributeName);
+ void registerMutationObserver(MutationObserver&, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
+ void unregisterMutationObserver(MutationObserverRegistration&);
+ void registerTransientMutationObserver(MutationObserverRegistration&);
+ void unregisterTransientMutationObserver(MutationObserverRegistration&);
void notifyMutationObserversNodeWillDetach();
- void textRects(Vector<IntRect>&) const;
+ WEBCORE_EXPORT void textRects(Vector<IntRect>&) const;
unsigned connectedSubframeCount() const;
void incrementConnectedSubframeCount(unsigned amount = 1);
@@ -557,13 +546,23 @@ public:
void updateAncestorConnectedSubframeCountForRemoval() const;
void updateAncestorConnectedSubframeCountForInsertion() const;
- void markAncestorsWithChildNeedsStyleRecalc();
-
-#if ENABLE(CSS_SELECTOR_JIT)
+#if ENABLE(JIT)
static ptrdiff_t nodeFlagsMemoryOffset() { return OBJECT_OFFSETOF(Node, m_nodeFlags); }
+ static ptrdiff_t rareDataMemoryOffset() { return OBJECT_OFFSETOF(Node, m_data.m_rareData); }
+ static int32_t flagIsText() { return IsTextFlag; }
+ static int32_t flagIsContainer() { return IsContainerFlag; }
static int32_t flagIsElement() { return IsElementFlag; }
+ static int32_t flagIsHTML() { return IsHTMLFlag; }
static int32_t flagIsLink() { return IsLinkFlag; }
-#endif // ENABLE(CSS_SELECTOR_JIT)
+ static int32_t flagHasFocusWithin() { return HasFocusWithin; }
+ static int32_t flagHasRareData() { return HasRareDataFlag; }
+ static int32_t flagIsParsingChildrenFinished() { return IsParsingChildrenFinishedFlag; }
+ static int32_t flagChildrenAffectedByFirstChildRulesFlag() { return ChildrenAffectedByFirstChildRulesFlag; }
+ static int32_t flagChildrenAffectedByLastChildRulesFlag() { return ChildrenAffectedByLastChildRulesFlag; }
+
+ static int32_t flagAffectsNextSiblingElementStyle() { return AffectsNextSiblingElementStyle; }
+ static int32_t flagStyleIsAffectedByPreviousSibling() { return StyleIsAffectedByPreviousSibling; }
+#endif // ENABLE(JIT)
protected:
enum NodeFlags {
@@ -574,7 +573,7 @@ protected:
IsHTMLFlag = 1 << 4,
IsSVGFlag = 1 << 5,
ChildNeedsStyleRecalcFlag = 1 << 7,
- InDocumentFlag = 1 << 8,
+ IsConnectedFlag = 1 << 8,
IsLinkFlag = 1 << 9,
IsUserActionElement = 1 << 10,
HasRareDataFlag = 1 << 11,
@@ -583,23 +582,27 @@ protected:
// These bits are used by derived classes, pulled up here so they can
// be stored in the same memory word as the Node bits above.
IsParsingChildrenFinishedFlag = 1 << 13, // Element
-
- StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1) | 1 << (nodeStyleChangeShift + 2),
- IsEditingTextFlag = 1 << 17,
- InNamedFlowFlag = 1 << 18,
+ StyleValidityShift = 14,
+ StyleValidityMask = 3 << StyleValidityShift,
+ StyleResolutionShouldRecompositeLayerFlag = 1 << 16,
+ IsEditingTextOrUndefinedCustomElementFlag = 1 << 17,
+ HasFocusWithin = 1 << 18,
HasSyntheticAttrChildNodesFlag = 1 << 19,
HasCustomStyleResolveCallbacksFlag = 1 << 20,
HasEventTargetDataFlag = 1 << 21,
- NeedsNodeRenderingTraversalSlowPathFlag = 1 << 22,
+ IsCustomElement = 1 << 22,
IsInShadowTreeFlag = 1 << 23,
IsMathMLFlag = 1 << 24,
ChildrenAffectedByFirstChildRulesFlag = 1 << 25,
ChildrenAffectedByLastChildRulesFlag = 1 << 26,
- ChildrenAffectedByDirectAdjacentRulesFlag = 1 << 27,
- ChildrenAffectedByHoverRulesFlag = 1 << 28,
+ ChildrenAffectedByHoverRulesFlag = 1 << 27,
+
+ DirectChildNeedsStyleRecalcFlag = 1 << 28,
+ AffectsNextSiblingElementStyle = 1 << 29,
+ StyleIsAffectedByPreviousSibling = 1 << 30,
- SelfOrAncestorHasDirAutoFlag = 1 << 29,
+ SelfOrAncestorHasDirAutoFlag = 1 << 31,
DefaultNodeFlags = IsParsingChildrenFinishedFlag
};
@@ -614,20 +617,19 @@ protected:
CreateText = DefaultNodeFlags | IsTextFlag,
CreateContainer = DefaultNodeFlags | IsContainerFlag,
CreateElement = CreateContainer | IsElementFlag,
- CreatePseudoElement = CreateElement | InDocumentFlag | NeedsNodeRenderingTraversalSlowPathFlag,
- CreateShadowRoot = CreateContainer | IsDocumentFragmentFlag | NeedsNodeRenderingTraversalSlowPathFlag | IsInShadowTreeFlag,
+ CreatePseudoElement = CreateElement | IsConnectedFlag,
+ CreateShadowRoot = CreateContainer | IsDocumentFragmentFlag | IsInShadowTreeFlag,
CreateDocumentFragment = CreateContainer | IsDocumentFragmentFlag,
CreateStyledElement = CreateElement | IsStyledElementFlag,
CreateHTMLElement = CreateStyledElement | IsHTMLFlag,
CreateSVGElement = CreateStyledElement | IsSVGFlag | HasCustomStyleResolveCallbacksFlag,
- CreateDocument = CreateContainer | InDocumentFlag,
- CreateInsertionPoint = CreateHTMLElement | NeedsNodeRenderingTraversalSlowPathFlag,
- CreateEditingText = CreateText | IsEditingTextFlag,
- CreateMathMLElement = CreateStyledElement | IsMathMLFlag,
+ CreateDocument = CreateContainer | IsConnectedFlag,
+ CreateEditingText = CreateText | IsEditingTextOrUndefinedCustomElementFlag,
+ CreateMathMLElement = CreateStyledElement | IsMathMLFlag
};
- Node(Document*, ConstructionType);
+ Node(Document&, ConstructionType);
- virtual void didMoveToNewDocument(Document* oldDocument);
+ virtual void didMoveToNewDocument(Document& oldDocument);
virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const { }
@@ -641,52 +643,47 @@ protected:
void setHasCustomStyleResolveCallbacks() { setFlag(true, HasCustomStyleResolveCallbacksFlag); }
- void setNeedsNodeRenderingTraversalSlowPath(bool flag) { setFlag(flag, NeedsNodeRenderingTraversalSlowPathFlag); }
-
- Document* documentInternal() const { return treeScope().documentScope(); }
void setTreeScope(TreeScope& scope) { m_treeScope = &scope; }
- void setStyleChange(StyleChangeType changeType) { m_nodeFlags = (m_nodeFlags & ~StyleChangeMask) | changeType; }
+ void invalidateStyle(Style::Validity, Style::InvalidationMode = Style::InvalidationMode::Normal);
+ void updateAncestorsForStyleRecalc();
-private:
- friend class TreeShared<Node>;
+ ExceptionOr<RefPtr<Node>> convertNodesOrStringsIntoNode(Vector<NodeOrString>&&);
+private:
virtual PseudoId customPseudoId() const
{
ASSERT(hasCustomStyleResolveCallbacks());
return NOPSEUDO;
}
- void removedLastRef();
- bool hasTreeSharedParent() const { return !!parentNode(); }
+ WEBCORE_EXPORT void removedLastRef();
- enum EditableLevel { Editable, RichlyEditable };
- bool hasEditableStyle(EditableLevel, UserSelectAllTreatment = UserSelectAllIsAlwaysNonEditable) const;
- bool isEditableToAccessibility(EditableLevel) const;
-
- virtual void refEventTarget() override;
- virtual void derefEventTarget() override;
-
- virtual RenderStyle* nonRendererStyle() const { return 0; }
-
- Element* ancestorElement() const;
+ void refEventTarget() override;
+ void derefEventTarget() override;
void trackForDebugging();
+ void materializeRareData();
- Vector<OwnPtr<MutationObserverRegistration>>* mutationObserverRegistry();
+ Vector<std::unique_ptr<MutationObserverRegistration>>* mutationObserverRegistry();
HashSet<MutationObserverRegistration*>* transientMutationObserverRegistry();
+ void adjustStyleValidity(Style::Validity, Style::InvalidationMode);
+
+ void* opaqueRootSlow() const;
+
+ int m_refCount;
mutable uint32_t m_nodeFlags;
- ContainerNode* m_parentNode;
- TreeScope* m_treeScope;
- Node* m_previous;
- Node* m_next;
+
+ ContainerNode* m_parentNode { nullptr };
+ TreeScope* m_treeScope { nullptr };
+ Node* m_previous { nullptr };
+ Node* m_next { nullptr };
// When a node has rare data we move the renderer into the rare data.
union DataUnion {
- DataUnion() : m_renderer(0) { }
RenderObject* m_renderer;
NodeRareDataBase* m_rareData;
- } m_data;
+ } m_data { nullptr };
protected:
bool isParsingChildrenFinished() const { return getFlag(IsParsingChildrenFinishedFlag); }
@@ -694,6 +691,53 @@ protected:
void clearIsParsingChildrenFinished() { clearFlag(IsParsingChildrenFinishedFlag); }
};
+#ifndef NDEBUG
+inline void adopted(Node* node)
+{
+ if (!node)
+ return;
+ ASSERT(!node->m_deletionHasBegun);
+ ASSERT(!node->m_inRemovedLastRefFunction);
+ node->m_adoptionIsRequired = false;
+}
+#endif
+
+ALWAYS_INLINE void Node::ref()
+{
+ ASSERT(isMainThread());
+ ASSERT(!m_deletionHasBegun);
+ ASSERT(!m_inRemovedLastRefFunction);
+ ASSERT(!m_adoptionIsRequired);
+ ++m_refCount;
+}
+
+ALWAYS_INLINE void Node::deref()
+{
+ ASSERT(isMainThread());
+ ASSERT(m_refCount >= 0);
+ ASSERT(!m_deletionHasBegun);
+ ASSERT(!m_inRemovedLastRefFunction);
+ ASSERT(!m_adoptionIsRequired);
+ if (--m_refCount <= 0 && !parentNode()) {
+#ifndef NDEBUG
+ m_inRemovedLastRefFunction = true;
+#endif
+ removedLastRef();
+ }
+}
+
+ALWAYS_INLINE bool Node::hasOneRef() const
+{
+ ASSERT(!m_deletionHasBegun);
+ ASSERT(!m_inRemovedLastRefFunction);
+ return m_refCount == 1;
+}
+
+ALWAYS_INLINE int Node::refCount() const
+{
+ return m_refCount;
+}
+
// Used in Node::addSubresourceAttributeURLs() and in addSubresourceStyleURLs()
inline void addSubresourceURL(ListHashSet<URL>& urls, const URL& url)
{
@@ -713,21 +757,41 @@ inline ContainerNode* Node::parentNode() const
return m_parentNode;
}
+inline void* Node::opaqueRoot() const
+{
+ // FIXME: Possible race?
+ // https://bugs.webkit.org/show_bug.cgi?id=165713
+ if (isConnected())
+ return &document();
+ return opaqueRootSlow();
+}
+
inline ContainerNode* Node::parentNodeGuaranteedHostFree() const
{
ASSERT(!isShadowRoot());
return parentNode();
}
-#define NODE_TYPE_CASTS(ToClassName) \
- TYPE_CASTS_BASE(ToClassName, Node, node, WebCore::is##ToClassName(*node), WebCore::is##ToClassName(node))
+inline Style::Validity Node::styleValidity() const
+{
+ return static_cast<Style::Validity>((m_nodeFlags & StyleValidityMask) >> StyleValidityShift);
+}
+
+inline bool Node::styleResolutionShouldRecompositeLayer() const
+{
+ return getFlag(StyleResolutionShouldRecompositeLayerFlag);
+}
+
+inline void Node::setHasValidStyle()
+{
+ m_nodeFlags &= ~StyleValidityMask;
+ clearFlag(StyleResolutionShouldRecompositeLayerFlag);
+}
} // namespace WebCore
-#ifndef NDEBUG
-// Outside the WebCore namespace for ease of invocation from gdb.
+#if ENABLE(TREE_DEBUGGING)
+// Outside the WebCore namespace for ease of invocation from the debugger.
void showTree(const WebCore::Node*);
void showNodePath(const WebCore::Node*);
#endif
-
-#endif