Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / Source / core / dom / Node.h
blobc6fcd05a60fdb1c5e39bac3d30f96fb7f89c5faf
1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2004-2011, 2014 Apple Inc. All rights reserved.
6 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
25 #ifndef Node_h
26 #define Node_h
28 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
29 #include "core/CoreExport.h"
30 #include "core/dom/MutationObserver.h"
31 #include "core/dom/SimulatedClickOptions.h"
32 #include "core/dom/StyleChangeReason.h"
33 #include "core/dom/TreeScope.h"
34 #include "core/dom/TreeShared.h"
35 #include "core/editing/EditingBoundary.h"
36 #include "core/events/EventTarget.h"
37 #include "core/inspector/InstanceCounters.h"
38 #include "core/style/ComputedStyleConstants.h"
39 #include "platform/geometry/LayoutRect.h"
40 #include "platform/heap/Handle.h"
41 #include "platform/weborigin/KURLHash.h"
42 #include "wtf/Forward.h"
44 // This needs to be here because Document.h also depends on it.
45 #define DUMP_NODE_STATISTICS 0
47 namespace blink {
49 class Attribute;
50 class ClassCollection;
51 class ContainerNode;
52 class DOMSettableTokenList;
53 class Document;
54 class Element;
55 class Event;
56 class EventDispatchMediator;
57 class EventListener;
58 class ExceptionState;
59 class FloatPoint;
60 class LocalFrame;
61 class HTMLInputElement;
62 class HTMLQualifiedName;
63 class IntRect;
64 class KeyboardEvent;
65 class NSResolver;
66 class NameNodeList;
67 class NamedNodeMap;
68 class NodeEventContext;
69 class NodeList;
70 class NodeListsNodeData;
71 class NodeRareData;
72 class PlatformGestureEvent;
73 class PlatformKeyboardEvent;
74 class PlatformMouseEvent;
75 class PlatformWheelEvent;
76 class PointerEvent;
77 class QualifiedName;
78 class RadioNodeList;
79 class RegisteredEventListener;
80 class LayoutBox;
81 class LayoutBoxModelObject;
82 class LayoutObject;
83 class ComputedStyle;
84 class SVGQualifiedName;
85 class ShadowRoot;
86 template <typename NodeType> class StaticNodeTypeList;
87 using StaticNodeList = StaticNodeTypeList<Node>;
88 class TagCollection;
89 class Text;
90 class TouchEvent;
91 #if !ENABLE(OILPAN)
92 template <typename T> struct WeakIdentifierMapTraits;
93 #endif
95 const int nodeStyleChangeShift = 19;
97 enum StyleChangeType {
98 NoStyleChange = 0,
99 LocalStyleChange = 1 << nodeStyleChangeShift,
100 SubtreeStyleChange = 2 << nodeStyleChangeShift,
101 NeedsReattachStyleChange = 3 << nodeStyleChangeShift,
104 class NodeRareDataBase {
105 public:
106 LayoutObject* layoutObject() const { return m_layoutObject; }
107 void setLayoutObject(LayoutObject* layoutObject) { m_layoutObject = layoutObject; }
109 protected:
110 NodeRareDataBase(LayoutObject* layoutObject)
111 : m_layoutObject(layoutObject)
114 protected:
115 LayoutObject* m_layoutObject;
118 class Node;
119 WILL_NOT_BE_EAGERLY_TRACED_CLASS(Node);
121 #if ENABLE(OILPAN)
122 #define NODE_BASE_CLASSES public EventTarget
123 #else
124 // TreeShared should be the last to pack TreeShared::m_refCount and
125 // Node::m_nodeFlags on 64bit platforms.
126 #define NODE_BASE_CLASSES public EventTarget, public TreeShared<Node>
127 #endif
129 class CORE_EXPORT Node : NODE_BASE_CLASSES {
130 #if !ENABLE(OILPAN)
131 DEFINE_EVENT_TARGET_REFCOUNTING(TreeShared<Node>);
132 #endif
133 DEFINE_WRAPPERTYPEINFO();
134 friend class TreeScope;
135 friend class TreeScopeAdopter;
136 public:
137 enum NodeType {
138 ELEMENT_NODE = 1,
139 ATTRIBUTE_NODE = 2,
140 TEXT_NODE = 3,
141 CDATA_SECTION_NODE = 4,
142 PROCESSING_INSTRUCTION_NODE = 7,
143 COMMENT_NODE = 8,
144 DOCUMENT_NODE = 9,
145 DOCUMENT_TYPE_NODE = 10,
146 DOCUMENT_FRAGMENT_NODE = 11,
149 // Entity, EntityReference, Notation, and XPathNamespace nodes are impossible to create in Blink.
150 // But for compatibility reasons we want these enum values exist in JS, and this enum makes the bindings
151 // generation not complain about ENTITY_REFERENCE_NODE being missing from the implementation
152 // while not requiring all switch(NodeType) blocks to include this deprecated constant.
153 enum DeprecatedNodeType {
154 ENTITY_REFERENCE_NODE = 5,
155 ENTITY_NODE = 6,
156 NOTATION_NODE = 12,
157 XPATH_NAMESPACE_NODE = 13,
160 enum DocumentPosition {
161 DOCUMENT_POSITION_EQUIVALENT = 0x00,
162 DOCUMENT_POSITION_DISCONNECTED = 0x01,
163 DOCUMENT_POSITION_PRECEDING = 0x02,
164 DOCUMENT_POSITION_FOLLOWING = 0x04,
165 DOCUMENT_POSITION_CONTAINS = 0x08,
166 DOCUMENT_POSITION_CONTAINED_BY = 0x10,
167 DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20,
170 #if ENABLE(OILPAN)
171 // Override operator new to allocate Node subtype objects onto
172 // a dedicated heap.
173 GC_PLUGIN_IGNORE("crbug.com/443854")
174 void* operator new(size_t size)
176 return allocateObject(size, false);
178 static void* allocateObject(size_t size, bool isEager)
180 ThreadState* state = ThreadStateFor<ThreadingTrait<Node>::Affinity>::state();
181 return Heap::allocateOnHeapIndex(state, size, isEager ? ThreadState::EagerSweepHeapIndex : ThreadState::NodeHeapIndex, GCInfoTrait<EventTarget>::index());
183 #else // !ENABLE(OILPAN)
184 // All Nodes are placed in their own heap partition for security.
185 // See http://crbug.com/246860 for detail.
186 void* operator new(size_t);
187 void operator delete(void*);
188 #endif
190 static void dumpStatistics();
192 ~Node() override;
194 // DOM methods & attributes for Node
196 bool hasTagName(const HTMLQualifiedName&) const;
197 bool hasTagName(const SVGQualifiedName&) const;
198 virtual String nodeName() const = 0;
199 virtual String nodeValue() const;
200 virtual void setNodeValue(const String&);
201 virtual NodeType nodeType() const = 0;
202 ContainerNode* parentNode() const;
203 Element* parentElement() const;
204 ContainerNode* parentElementOrShadowRoot() const;
205 ContainerNode* parentElementOrDocumentFragment() const;
206 Node* previousSibling() const { return m_previous; }
207 Node* nextSibling() const { return m_next; }
208 PassRefPtrWillBeRawPtr<NodeList> childNodes();
209 Node* firstChild() const;
210 Node* lastChild() const;
212 void remove(ExceptionState& = ASSERT_NO_EXCEPTION);
214 Node* pseudoAwareNextSibling() const;
215 Node* pseudoAwarePreviousSibling() const;
216 Node* pseudoAwareFirstChild() const;
217 Node* pseudoAwareLastChild() const;
219 virtual KURL baseURI() const;
221 PassRefPtrWillBeRawPtr<Node> insertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION);
222 PassRefPtrWillBeRawPtr<Node> replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, PassRefPtrWillBeRawPtr<Node> oldChild, ExceptionState& = ASSERT_NO_EXCEPTION);
223 PassRefPtrWillBeRawPtr<Node> removeChild(PassRefPtrWillBeRawPtr<Node> child, ExceptionState& = ASSERT_NO_EXCEPTION);
224 PassRefPtrWillBeRawPtr<Node> appendChild(PassRefPtrWillBeRawPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION);
226 bool hasChildren() const { return firstChild(); }
227 virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = false) = 0;
228 void normalize();
230 bool isSameNode(Node* other) const { return this == other; }
231 bool isEqualNode(Node*) const;
232 bool isDefaultNamespace(const AtomicString& namespaceURI) const;
233 const AtomicString& lookupPrefix(const AtomicString& namespaceURI) const;
234 const AtomicString& lookupNamespaceURI(const String& prefix) const;
236 String textContent(bool convertBRsToNewlines = false) const;
237 void setTextContent(const String&);
239 bool supportsAltText();
241 // Other methods (not part of DOM)
243 bool isElementNode() const { return getFlag(IsElementFlag); }
244 bool isContainerNode() const { return getFlag(IsContainerFlag); }
245 bool isTextNode() const { return getFlag(IsTextFlag); }
246 bool isHTMLElement() const { return getFlag(IsHTMLFlag); }
247 bool isSVGElement() const { return getFlag(IsSVGFlag); }
249 bool isPseudoElement() const { return pseudoId() != NOPSEUDO; }
250 bool isBeforePseudoElement() const { return pseudoId() == BEFORE; }
251 bool isAfterPseudoElement() const { return pseudoId() == AFTER; }
252 bool isFirstLetterPseudoElement() const { return pseudoId() == FIRST_LETTER; }
253 virtual PseudoId pseudoId() const { return NOPSEUDO; }
255 bool isCustomElement() const { return getFlag(CustomElementFlag); }
256 enum CustomElementState {
257 NotCustomElement = 0,
258 WaitingForUpgrade = 1 << 0,
259 Upgraded = 1 << 1
261 CustomElementState customElementState() const
263 return isCustomElement()
264 ? (getFlag(CustomElementUpgradedFlag) ? Upgraded : WaitingForUpgrade)
265 : NotCustomElement;
267 void setCustomElementState(CustomElementState newState);
269 virtual bool isMediaControlElement() const { return false; }
270 virtual bool isMediaControls() const { return false; }
271 virtual bool isTextTrackContainer() const { return false; }
272 virtual bool isVTTElement() const { return false; }
273 virtual bool isAttributeNode() const { return false; }
274 virtual bool isCharacterDataNode() const { return false; }
275 virtual bool isFrameOwnerElement() const { return false; }
277 // StyledElements allow inline style (style="border: 1px"), presentational attributes (ex. color),
278 // class names (ex. class="foo bar") and other non-basic styling features. They and also control
279 // if this element can participate in style sharing.
281 // FIXME: The only things that ever go through StyleResolver that aren't StyledElements are
282 // PseudoElements and VTTElements. It's possible we can just eliminate all the checks
283 // since those elements will never have class names, inline style, or other things that
284 // this apparently guards against.
285 bool isStyledElement() const { return isHTMLElement() || isSVGElement(); }
287 bool isDocumentNode() const;
288 bool isTreeScope() const;
289 bool isDocumentFragment() const { return getFlag(IsDocumentFragmentFlag); }
290 bool isShadowRoot() const { return isDocumentFragment() && isTreeScope(); }
291 bool isInsertionPoint() const { return getFlag(IsInsertionPointFlag); }
293 bool canParticipateInComposedTree() const;
295 bool hasCustomStyleCallbacks() const { return getFlag(HasCustomStyleCallbacksFlag); }
297 // If this node is in a shadow tree, returns its shadow host. Otherwise, returns nullptr.
298 // TODO(kochi): crbug.com/507413 shadowHost() can return nullptr even when it is in a
299 // shadow tree but its root is detached from its host. This can happen when handling
300 // queued events (e.g. during execCommand()).
301 Element* shadowHost() const;
302 ShadowRoot* containingShadowRoot() const;
303 ShadowRoot* youngestShadowRoot() const;
305 // Returns nullptr, a child of ShadowRoot, or a legacy shadow root.
306 Node* nonBoundaryShadowTreeRootNode();
308 // Node's parent, shadow tree host.
309 ContainerNode* parentOrShadowHostNode() const;
310 Element* parentOrShadowHostElement() const;
311 void setParentOrShadowHostNode(ContainerNode*);
313 // Knows about all kinds of hosts.
314 ContainerNode* parentOrShadowHostOrTemplateHostNode() const;
316 // Returns the parent node, but nullptr if the parent node is a ShadowRoot.
317 ContainerNode* nonShadowBoundaryParentNode() const;
319 // Returns the enclosing event parent Element (or self) that, when clicked, would trigger a navigation.
320 Element* enclosingLinkEventParentOrSelf() const;
322 // These low-level calls give the caller responsibility for maintaining the integrity of the tree.
323 void setPreviousSibling(Node* previous) { m_previous = previous; }
324 void setNextSibling(Node* next) { m_next = next; }
326 virtual bool canContainRangeEndPoint() const { return false; }
328 bool isRootEditableElement() const;
329 Element* rootEditableElement() const;
330 Element* rootEditableElement(EditableType) const;
332 // For <link> and <style> elements.
333 virtual bool sheetLoaded() { return true; }
334 enum LoadedSheetErrorStatus {
335 NoErrorLoadingSubresource,
336 ErrorOccurredLoadingSubresource
338 virtual void notifyLoadedSheetAndAllCriticalSubresources(LoadedSheetErrorStatus) { }
339 virtual void startLoadingDynamicSheet() { ASSERT_NOT_REACHED(); }
341 bool hasName() const { ASSERT(!isTextNode()); return getFlag(HasNameOrIsEditingTextFlag); }
343 bool isUserActionElement() const { return getFlag(IsUserActionElementFlag); }
344 void setUserActionElement(bool flag) { setFlag(flag, IsUserActionElementFlag); }
346 bool active() const { return isUserActionElement() && isUserActionElementActive(); }
347 bool inActiveChain() const { return isUserActionElement() && isUserActionElementInActiveChain(); }
348 bool hovered() const { return isUserActionElement() && isUserActionElementHovered(); }
349 // Note: As a shadow host whose root with delegatesFocus=false may become focused state when
350 // an inner element gets focused, in that case more than one elements in a document can return
351 // true for |focused()|. Use Element::isFocusedElementInDocument() or Document::focusedElement()
352 // to check which element is exactly focused.
353 bool focused() const { return isUserActionElement() && isUserActionElementFocused(); }
355 bool needsAttach() const { return styleChangeType() == NeedsReattachStyleChange; }
356 bool needsStyleRecalc() const { return styleChangeType() != NoStyleChange; }
357 StyleChangeType styleChangeType() const { return static_cast<StyleChangeType>(m_nodeFlags & StyleChangeMask); }
358 bool childNeedsStyleRecalc() const { return getFlag(ChildNeedsStyleRecalcFlag); }
359 bool isLink() const { return getFlag(IsLinkFlag); }
360 bool isEditingText() const { ASSERT(isTextNode()); return getFlag(HasNameOrIsEditingTextFlag); }
362 void setHasName(bool f) { ASSERT(!isTextNode()); setFlag(f, HasNameOrIsEditingTextFlag); }
363 void setChildNeedsStyleRecalc() { setFlag(ChildNeedsStyleRecalcFlag); }
364 void clearChildNeedsStyleRecalc() { clearFlag(ChildNeedsStyleRecalcFlag); }
366 void setNeedsStyleRecalc(StyleChangeType, const StyleChangeReasonForTracing&);
367 void clearNeedsStyleRecalc();
369 #if ENABLE(ASSERT)
370 bool needsDistributionRecalc() const;
371 #endif
373 bool childNeedsDistributionRecalc() const { return getFlag(ChildNeedsDistributionRecalcFlag); }
374 void setChildNeedsDistributionRecalc() { setFlag(ChildNeedsDistributionRecalcFlag); }
375 void clearChildNeedsDistributionRecalc() { clearFlag(ChildNeedsDistributionRecalcFlag); }
376 void markAncestorsWithChildNeedsDistributionRecalc();
378 bool childNeedsStyleInvalidation() const { return getFlag(ChildNeedsStyleInvalidationFlag); }
379 void setChildNeedsStyleInvalidation() { setFlag(ChildNeedsStyleInvalidationFlag); }
380 void clearChildNeedsStyleInvalidation() { clearFlag(ChildNeedsStyleInvalidationFlag); }
381 void markAncestorsWithChildNeedsStyleInvalidation();
382 bool needsStyleInvalidation() const { return getFlag(NeedsStyleInvalidationFlag); }
383 void clearNeedsStyleInvalidation() { clearFlag(NeedsStyleInvalidationFlag); }
384 void setNeedsStyleInvalidation();
386 void updateDistribution();
388 bool svgFilterNeedsLayerUpdate() const { return getFlag(SVGFilterNeedsLayerUpdateFlag); }
389 void setSVGFilterNeedsLayerUpdate() { setFlag(SVGFilterNeedsLayerUpdateFlag); }
390 void clearSVGFilterNeedsLayerUpdate() { clearFlag(SVGFilterNeedsLayerUpdateFlag); }
392 void setIsLink(bool f);
394 bool hasEventTargetData() const { return getFlag(HasEventTargetDataFlag); }
395 void setHasEventTargetData(bool flag) { setFlag(flag, HasEventTargetDataFlag); }
397 bool isV8CollectableDuringMinorGC() const { return getFlag(V8CollectableDuringMinorGCFlag); }
398 void markV8CollectableDuringMinorGC() { setFlag(true, V8CollectableDuringMinorGCFlag); }
399 void clearV8CollectableDuringMinorGC() { setFlag(false, V8CollectableDuringMinorGCFlag); }
401 virtual void setFocus(bool flag);
402 virtual void setActive(bool flag = true);
403 virtual void setHovered(bool flag = true);
405 virtual short tabIndex() const;
407 virtual Node* focusDelegate();
408 // This is called only when the node is focused.
409 virtual bool shouldHaveFocusAppearance() const;
411 // Whether the node is inert. This can't be in Element because text nodes
412 // must be recognized as inert to prevent text selection.
413 bool isInert() const;
415 enum UserSelectAllTreatment {
416 UserSelectAllDoesNotAffectEditability,
417 UserSelectAllIsAlwaysNonEditable
419 bool isContentEditable(UserSelectAllTreatment = UserSelectAllDoesNotAffectEditability) const;
420 bool isContentRichlyEditable() const;
422 bool hasEditableStyle(EditableType editableType = ContentIsEditable, UserSelectAllTreatment treatment = UserSelectAllIsAlwaysNonEditable) const
424 switch (editableType) {
425 case ContentIsEditable:
426 return hasEditableStyle(Editable, treatment);
427 case HasEditableAXRole:
428 return isEditableToAccessibility(Editable);
430 ASSERT_NOT_REACHED();
431 return false;
434 bool layoutObjectIsRichlyEditable(EditableType editableType = ContentIsEditable) const
436 switch (editableType) {
437 case ContentIsEditable:
438 return hasEditableStyle(RichlyEditable, UserSelectAllIsAlwaysNonEditable);
439 case HasEditableAXRole:
440 return isEditableToAccessibility(RichlyEditable);
442 ASSERT_NOT_REACHED();
443 return false;
446 virtual LayoutRect boundingBox() const;
447 IntRect pixelSnappedBoundingBox() const { return pixelSnappedIntRect(boundingBox()); }
449 unsigned nodeIndex() const;
451 // Returns the DOM ownerDocument attribute. This method never returns null, except in the case
452 // of a Document node.
453 Document* ownerDocument() const;
455 // Returns the document associated with this node. A Document node returns itself.
456 Document& document() const
458 return treeScope().document();
461 TreeScope& treeScope() const
463 ASSERT(m_treeScope);
464 return *m_treeScope;
467 bool inActiveDocument() const;
469 // Returns true if this node is associated with a document and is in its associated document's
470 // node tree, false otherwise.
471 bool inDocument() const
473 return getFlag(InDocumentFlag);
475 bool isInShadowTree() const { return getFlag(IsInShadowTreeFlag); }
476 bool isInTreeScope() const { return getFlag(static_cast<NodeFlags>(InDocumentFlag | IsInShadowTreeFlag)); }
478 bool isDocumentTypeNode() const { return nodeType() == DOCUMENT_TYPE_NODE; }
479 virtual bool childTypeAllowed(NodeType) const { return false; }
480 unsigned countChildren() const;
482 bool isDescendantOf(const Node*) const;
483 bool contains(const Node*) const;
484 bool containsIncludingShadowDOM(const Node*) const;
485 bool containsIncludingHostElements(const Node&) const;
486 Node* commonAncestor(const Node&, ContainerNode* (*parent)(const Node&)) const;
488 // Used to determine whether range offsets use characters or node indices.
489 bool offsetInCharacters() const;
490 // Number of DOM 16-bit units contained in node. Note that laid out text length can be different - e.g. because of
491 // css-transform:capitalize breaking up precomposed characters and ligatures.
492 virtual int maxCharacterOffset() const;
494 // Whether or not a selection can be started in this object
495 virtual bool canStartSelection() const;
497 // -----------------------------------------------------------------------------
498 // Integration with layout tree
500 // As layoutObject() includes a branch you should avoid calling it repeatedly in hot code paths.
501 // Note that if a Node has a layoutObject, it's parentNode is guaranteed to have one as well.
502 LayoutObject* layoutObject() const { return hasRareData() ? m_data.m_rareData->layoutObject() : m_data.m_layoutObject; }
503 void setLayoutObject(LayoutObject* layoutObject)
505 if (hasRareData())
506 m_data.m_rareData->setLayoutObject(layoutObject);
507 else
508 m_data.m_layoutObject = layoutObject;
511 // Use these two methods with caution.
512 LayoutBox* layoutBox() const;
513 LayoutBoxModelObject* layoutBoxModelObject() const;
515 struct AttachContext {
516 STACK_ALLOCATED();
517 ComputedStyle* resolvedStyle;
518 bool performingReattach;
520 AttachContext() : resolvedStyle(nullptr), performingReattach(false) { }
523 // Attaches this node to the layout tree. This calculates the style to be applied to the node and creates an
524 // appropriate LayoutObject which will be inserted into the tree (except when the style has display: none). This
525 // makes the node visible in the FrameView.
526 virtual void attach(const AttachContext& = AttachContext());
528 // Detaches the node from the layout tree, making it invisible in the rendered view. This method will remove
529 // the node's layout object from the layout tree and delete it.
530 virtual void detach(const AttachContext& = AttachContext());
532 void reattach(const AttachContext& = AttachContext());
533 void lazyReattachIfAttached();
535 // Returns true if recalcStyle should be called on the object, if there is such a method (on Document and Element).
536 bool shouldCallRecalcStyle(StyleRecalcChange);
538 // Wrapper for nodes that don't have a layoutObject, but still cache the style (like HTMLOptionElement).
539 ComputedStyle* mutableComputedStyle() const;
540 const ComputedStyle* computedStyle() const;
541 const ComputedStyle* parentComputedStyle() const;
543 const ComputedStyle& computedStyleRef() const;
545 const ComputedStyle* ensureComputedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) { return virtualEnsureComputedStyle(pseudoElementSpecifier); }
547 // -----------------------------------------------------------------------------
548 // Notification of document structure changes (see ContainerNode.h for more notification methods)
550 // At first, WebKit notifies the node that it has been inserted into the document. This is called during document parsing, and also
551 // when a node is added through the DOM methods insertBefore(), appendChild() or replaceChild(). The call happens _after_ the node has been added to the tree.
552 // This is similar to the DOMNodeInsertedIntoDocument DOM event, but does not require the overhead of event
553 // dispatching.
555 // WebKit notifies this callback regardless if the subtree of the node is a document tree or a floating subtree.
556 // Implementation can determine the type of subtree by seeing insertionPoint->inDocument().
557 // For a performance reason, notifications are delivered only to ContainerNode subclasses if the insertionPoint is out of document.
559 // There are another callback named didNotifySubtreeInsertionsToDocument(), which is called after all the descendant is notified,
560 // if this node was inserted into the document tree. Only a few subclasses actually need this. To utilize this, the node should
561 // return InsertionShouldCallDidNotifySubtreeInsertions from insertedInto().
563 enum InsertionNotificationRequest {
564 InsertionDone,
565 InsertionShouldCallDidNotifySubtreeInsertions
568 virtual InsertionNotificationRequest insertedInto(ContainerNode* insertionPoint);
569 virtual void didNotifySubtreeInsertionsToDocument() { }
571 // Notifies the node that it is no longer part of the tree.
573 // This is a dual of insertedInto(), and is similar to the DOMNodeRemovedFromDocument DOM event, but does not require the overhead of event
574 // dispatching, and is called _after_ the node is removed from the tree.
576 virtual void removedFrom(ContainerNode* insertionPoint);
578 String debugName() const;
580 #ifndef NDEBUG
581 virtual void formatForDebugger(char* buffer, unsigned length) const;
583 void showNode(const char* prefix = "") const;
584 void showTreeForThis() const;
585 void showTreeForThisInComposedTree() const;
586 void showNodePathForThis() const;
587 void showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2 = nullptr, const char* markedLabel2 = nullptr) const;
588 void showTreeAndMarkInComposedTree(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2 = nullptr, const char* markedLabel2 = nullptr) const;
589 void showTreeForThisAcrossFrame() const;
590 #endif
592 NodeListsNodeData* nodeLists();
593 void clearNodeLists();
595 virtual bool willRespondToMouseMoveEvents();
596 virtual bool willRespondToMouseClickEvents();
597 virtual bool willRespondToTouchEvents();
599 enum ShadowTreesTreatment {
600 TreatShadowTreesAsDisconnected,
601 TreatShadowTreesAsComposed
604 unsigned short compareDocumentPosition(const Node*, ShadowTreesTreatment = TreatShadowTreesAsDisconnected) const;
606 Node* toNode() final;
608 const AtomicString& interfaceName() const override;
609 ExecutionContext* executionContext() const final;
611 bool addEventListener(const AtomicString& eventType, PassRefPtrWillBeRawPtr<EventListener>, bool useCapture = false) override;
612 bool removeEventListener(const AtomicString& eventType, PassRefPtrWillBeRawPtr<EventListener>, bool useCapture = false) override;
613 void removeAllEventListeners() override;
614 void removeAllEventListenersRecursively();
616 // Handlers to do/undo actions on the target node before an event is dispatched to it and after the event
617 // has been dispatched. The data pointer is handed back by the preDispatch and passed to postDispatch.
618 virtual void* preDispatchEventHandler(Event*) { return nullptr; }
619 virtual void postDispatchEventHandler(Event*, void* /*dataFromPreDispatch*/) { }
621 void dispatchScopedEvent(PassRefPtrWillBeRawPtr<Event>);
623 virtual void handleLocalEvents(Event&);
625 void dispatchSubtreeModifiedEvent();
626 bool dispatchDOMActivateEvent(int detail, PassRefPtrWillBeRawPtr<Event> underlyingEvent);
628 bool dispatchKeyEvent(const PlatformKeyboardEvent&);
629 bool dispatchWheelEvent(const PlatformWheelEvent&);
630 bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType, int clickCount = 0, Node* relatedTarget = nullptr);
631 bool dispatchGestureEvent(const PlatformGestureEvent&);
633 void dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions = SendNoEvents, SimulatedClickCreationScope = SimulatedClickCreationScope::FromUserAgent);
635 void dispatchInputEvent();
637 // Perform the default action for an event.
638 virtual void defaultEventHandler(Event*);
639 virtual void willCallDefaultEventHandler(const Event&);
641 EventTargetData* eventTargetData() override;
642 EventTargetData& ensureEventTargetData() override;
644 void getRegisteredMutationObserversOfType(WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>&, MutationObserver::MutationType, const QualifiedName* attributeName);
645 void registerMutationObserver(MutationObserver&, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
646 void unregisterMutationObserver(MutationObserverRegistration*);
647 void registerTransientMutationObserver(MutationObserverRegistration*);
648 void unregisterTransientMutationObserver(MutationObserverRegistration*);
649 void notifyMutationObserversNodeWillDetach();
651 unsigned connectedSubframeCount() const;
652 void incrementConnectedSubframeCount(unsigned amount = 1);
653 void decrementConnectedSubframeCount(unsigned amount = 1);
654 void updateAncestorConnectedSubframeCountForInsertion() const;
656 PassRefPtrWillBeRawPtr<StaticNodeList> getDestinationInsertionPoints();
658 void setAlreadySpellChecked(bool flag) { setFlag(flag, AlreadySpellCheckedFlag); }
659 bool isAlreadySpellChecked() { return getFlag(AlreadySpellCheckedFlag); }
661 bool isFinishedParsingChildren() const { return getFlag(IsFinishedParsingChildrenFlag); }
663 DECLARE_VIRTUAL_TRACE();
665 unsigned lengthOfContents() const;
667 v8::Local<v8::Object> wrap(v8::Isolate*, v8::Local<v8::Object> creationContext) override;
668 v8::Local<v8::Object> associateWithWrapper(v8::Isolate*, const WrapperTypeInfo*, v8::Local<v8::Object> wrapper) override WARN_UNUSED_RETURN;
670 private:
671 enum NodeFlags {
672 HasRareDataFlag = 1,
674 // Node type flags. These never change once created.
675 IsTextFlag = 1 << 1,
676 IsContainerFlag = 1 << 2,
677 IsElementFlag = 1 << 3,
678 IsHTMLFlag = 1 << 4,
679 IsSVGFlag = 1 << 5,
680 IsDocumentFragmentFlag = 1 << 6,
681 IsInsertionPointFlag = 1 << 7,
683 // Changes based on if the element should be treated like a link,
684 // ex. When setting the href attribute on an <a>.
685 IsLinkFlag = 1 << 8,
687 // Changes based on :hover, :active and :focus state.
688 IsUserActionElementFlag = 1 << 9,
690 // Tree state flags. These change when the element is added/removed
691 // from a DOM tree.
692 InDocumentFlag = 1 << 10,
693 IsInShadowTreeFlag = 1 << 11,
695 // Set by the parser when the children are done parsing.
696 IsFinishedParsingChildrenFlag = 1 << 12,
698 // Flags related to recalcStyle.
699 SVGFilterNeedsLayerUpdateFlag = 1 << 13,
700 HasCustomStyleCallbacksFlag = 1 << 14,
701 ChildNeedsStyleInvalidationFlag = 1 << 15,
702 NeedsStyleInvalidationFlag = 1 << 16,
703 ChildNeedsDistributionRecalcFlag = 1 << 17,
704 ChildNeedsStyleRecalcFlag = 1 << 18,
705 StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1),
707 CustomElementFlag = 1 << 21,
708 CustomElementUpgradedFlag = 1 << 22,
710 HasNameOrIsEditingTextFlag = 1 << 23,
711 HasWeakReferencesFlag = 1 << 24,
712 V8CollectableDuringMinorGCFlag = 1 << 25,
713 HasEventTargetDataFlag = 1 << 26,
714 AlreadySpellCheckedFlag = 1 << 27,
716 DefaultNodeFlags = IsFinishedParsingChildrenFlag | NeedsReattachStyleChange
719 // 3 bits remaining.
721 bool getFlag(NodeFlags mask) const { return m_nodeFlags & mask; }
722 void setFlag(bool f, NodeFlags mask) { m_nodeFlags = (m_nodeFlags & ~mask) | (-(int32_t)f & mask); }
723 void setFlag(NodeFlags mask) { m_nodeFlags |= mask; }
724 void clearFlag(NodeFlags mask) { m_nodeFlags &= ~mask; }
726 protected:
727 enum ConstructionType {
728 CreateOther = DefaultNodeFlags,
729 CreateText = DefaultNodeFlags | IsTextFlag,
730 CreateContainer = DefaultNodeFlags | ChildNeedsStyleRecalcFlag | IsContainerFlag,
731 CreateElement = CreateContainer | IsElementFlag,
732 CreateShadowRoot = CreateContainer | IsDocumentFragmentFlag | IsInShadowTreeFlag,
733 CreateDocumentFragment = CreateContainer | IsDocumentFragmentFlag,
734 CreateHTMLElement = CreateElement | IsHTMLFlag,
735 CreateSVGElement = CreateElement | IsSVGFlag,
736 CreateDocument = CreateContainer | InDocumentFlag,
737 CreateInsertionPoint = CreateHTMLElement | IsInsertionPointFlag,
738 CreateEditingText = CreateText | HasNameOrIsEditingTextFlag,
741 Node(TreeScope*, ConstructionType);
743 virtual void didMoveToNewDocument(Document& oldDocument);
745 bool dispatchEventInternal(PassRefPtrWillBeRawPtr<Event>) override;
747 static void reattachWhitespaceSiblingsIfNeeded(Text* start);
749 #if !ENABLE(OILPAN)
750 void willBeDeletedFromDocument();
751 #endif
753 bool hasRareData() const { return getFlag(HasRareDataFlag); }
755 NodeRareData* rareData() const;
756 NodeRareData& ensureRareData();
757 #if !ENABLE(OILPAN)
758 void clearRareData();
760 void clearEventTargetData();
761 #endif
763 void setHasCustomStyleCallbacks() { setFlag(true, HasCustomStyleCallbacksFlag); }
765 void setTreeScope(TreeScope* scope) { m_treeScope = scope; }
767 // isTreeScopeInitialized() can be false
768 // - in the destruction of Document or ShadowRoot where m_treeScope is set to null or
769 // - in the Node constructor called by these two classes where m_treeScope is set by TreeScope ctor.
770 bool isTreeScopeInitialized() const { return m_treeScope; }
772 void markAncestorsWithChildNeedsStyleRecalc();
774 void setIsFinishedParsingChildren(bool value) { setFlag(value, IsFinishedParsingChildrenFlag); }
776 private:
777 friend class TreeShared<Node>;
778 #if !ENABLE(OILPAN)
779 // FIXME: consider exposing proper API for this instead.
780 friend struct WeakIdentifierMapTraits<Node>;
782 void removedLastRef();
783 #endif
784 bool hasTreeSharedParent() const { return !!parentOrShadowHostNode(); }
786 enum EditableLevel { Editable, RichlyEditable };
787 bool hasEditableStyle(EditableLevel, UserSelectAllTreatment = UserSelectAllIsAlwaysNonEditable) const;
788 bool isEditableToAccessibility(EditableLevel) const;
790 bool isUserActionElementActive() const;
791 bool isUserActionElementInActiveChain() const;
792 bool isUserActionElementHovered() const;
793 bool isUserActionElementFocused() const;
795 void recalcDistribution();
797 void setStyleChange(StyleChangeType);
799 virtual ComputedStyle* nonLayoutObjectComputedStyle() const { return nullptr; }
801 virtual const ComputedStyle* virtualEnsureComputedStyle(PseudoId = NOPSEUDO);
803 void trackForDebugging();
805 WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration>>* mutationObserverRegistry();
806 WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration>>* transientMutationObserverRegistry();
808 uint32_t m_nodeFlags;
809 RawPtrWillBeMember<ContainerNode> m_parentOrShadowHostNode;
810 RawPtrWillBeMember<TreeScope> m_treeScope;
811 RawPtrWillBeMember<Node> m_previous;
812 RawPtrWillBeMember<Node> m_next;
813 // When a node has rare data we move the layoutObject into the rare data.
814 union DataUnion {
815 DataUnion() : m_layoutObject(nullptr) { }
816 LayoutObject* m_layoutObject;
817 NodeRareDataBase* m_rareData;
818 } m_data;
821 inline void Node::setParentOrShadowHostNode(ContainerNode* parent)
823 ASSERT(isMainThread());
824 m_parentOrShadowHostNode = parent;
827 inline ContainerNode* Node::parentOrShadowHostNode() const
829 ASSERT(isMainThread());
830 return m_parentOrShadowHostNode;
833 inline ContainerNode* Node::parentNode() const
835 return isShadowRoot() ? nullptr : parentOrShadowHostNode();
838 inline void Node::lazyReattachIfAttached()
840 if (styleChangeType() == NeedsReattachStyleChange)
841 return;
842 if (!inActiveDocument())
843 return;
845 AttachContext context;
846 context.performingReattach = true;
848 detach(context);
849 markAncestorsWithChildNeedsStyleRecalc();
852 inline bool Node::shouldCallRecalcStyle(StyleRecalcChange change)
854 return change >= Inherit || needsStyleRecalc() || childNeedsStyleRecalc();
857 inline bool isTreeScopeRoot(const Node* node)
859 return !node || node->isDocumentNode() || node->isShadowRoot();
862 inline bool isTreeScopeRoot(const Node& node)
864 return node.isDocumentNode() || node.isShadowRoot();
867 // See the comment at the declaration of ScriptWrappable::fromNode in
868 // bindings/core/v8/ScriptWrappable.h about why this method is defined here.
869 inline ScriptWrappable* ScriptWrappable::fromNode(Node* node)
871 return node;
874 // Allow equality comparisons of Nodes by reference or pointer, interchangeably.
875 DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES_REFCOUNTED(Node)
878 #define DEFINE_NODE_TYPE_CASTS(thisType, predicate) \
879 template<typename T> inline thisType* to##thisType(const RefPtr<T>& node) { return to##thisType(node.get()); } \
880 DEFINE_TYPE_CASTS(thisType, Node, node, node->predicate, node.predicate)
882 // This requires isClassName(const Node&).
883 #define DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(thisType) \
884 template<typename T> inline thisType* to##thisType(const RefPtr<T>& node) { return to##thisType(node.get()); } \
885 DEFINE_TYPE_CASTS(thisType, Node, node, is##thisType(*node), is##thisType(node))
887 #define DECLARE_NODE_FACTORY(T) \
888 static PassRefPtrWillBeRawPtr<T> create(Document&)
889 #define DEFINE_NODE_FACTORY(T) \
890 PassRefPtrWillBeRawPtr<T> T::create(Document& document) \
892 return adoptRefWillBeNoop(new T(document)); \
895 // These printers are available only for testing in "webkit_unit_tests", and
896 // implemented in "core/testing/CoreTestPrinters.cpp".
897 std::ostream& operator<<(std::ostream&, const Node&);
898 std::ostream& operator<<(std::ostream&, const Node*);
900 } // namespace blink
902 #ifndef NDEBUG
903 // Outside the WebCore namespace for ease of invocation from gdb.
904 void showNode(const blink::Node*);
905 void showTree(const blink::Node*);
906 void showNodePath(const blink::Node*);
907 #endif
909 #endif // Node_h