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, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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.
28 #include "bindings/v8/ExceptionStatePlaceholder.h"
29 #include "bindings/v8/ScriptWrappable.h"
30 #include "core/dom/MutationObserver.h"
31 #include "core/dom/SimulatedClickOptions.h"
32 #include "core/dom/TreeScope.h"
33 #include "core/dom/TreeShared.h"
34 #include "core/editing/EditingBoundary.h"
35 #include "core/events/EventTarget.h"
36 #include "core/inspector/InspectorCounters.h"
37 #include "core/rendering/style/RenderStyleConstants.h"
38 #include "platform/geometry/LayoutRect.h"
39 #include "platform/weborigin/KURLHash.h"
40 #include "wtf/Forward.h"
41 #include "wtf/ListHashSet.h"
42 #include "wtf/text/AtomicString.h"
44 // This needs to be here because Document.h also depends on it.
45 #define DUMP_NODE_STATISTICS 0
50 class ClassCollection;
52 class DOMSettableTokenList;
56 class EventDispatchMediator;
61 class HTMLInputElement;
67 class NodeEventContext;
69 class NodeListsNodeData;
71 class PlatformGestureEvent;
72 class PlatformKeyboardEvent;
73 class PlatformMouseEvent;
74 class PlatformWheelEvent;
77 class RegisteredEventListener;
79 class RenderBoxModelObject;
87 const int nodeStyleChangeShift = 14;
89 enum StyleChangeType {
91 LocalStyleChange = 1 << nodeStyleChangeShift,
92 SubtreeStyleChange = 2 << nodeStyleChangeShift,
93 NeedsReattachStyleChange = 3 << nodeStyleChangeShift,
96 // If the style change is from the renderer then we'll call setStyle on the
97 // renderer even if the style computed from CSS is identical.
98 enum StyleChangeSource {
100 StyleChangeFromRenderer
103 class NodeRareDataBase {
105 RenderObject* renderer() const { return m_renderer; }
106 void setRenderer(RenderObject* renderer) { m_renderer = renderer; }
109 NodeRareDataBase(RenderObject* renderer)
110 : m_renderer(renderer)
114 RenderObject* m_renderer;
117 class Node : public EventTarget, public ScriptWrappable, public TreeShared<Node> {
118 friend class Document;
119 friend class TreeScope;
120 friend class TreeScopeAdopter;
122 DEFINE_EVENT_TARGET_REFCOUNTING(TreeShared<Node>);
128 CDATA_SECTION_NODE = 4,
129 PROCESSING_INSTRUCTION_NODE = 7,
132 DOCUMENT_TYPE_NODE = 10,
133 DOCUMENT_FRAGMENT_NODE = 11,
136 // Entity, EntityReference, Notation, and XPathNamespace nodes are impossible to create in Blink.
137 // But for compatibility reasons we want these enum values exist in JS, and this enum makes the bindings
138 // generation not complain about ENTITY_REFERENCE_NODE being missing from the implementation
139 // while not requiring all switch(NodeType) blocks to include this deprecated constant.
140 enum DeprecatedNodeType {
141 ENTITY_REFERENCE_NODE = 5,
144 XPATH_NAMESPACE_NODE = 13,
147 enum DocumentPosition {
148 DOCUMENT_POSITION_EQUIVALENT = 0x00,
149 DOCUMENT_POSITION_DISCONNECTED = 0x01,
150 DOCUMENT_POSITION_PRECEDING = 0x02,
151 DOCUMENT_POSITION_FOLLOWING = 0x04,
152 DOCUMENT_POSITION_CONTAINS = 0x08,
153 DOCUMENT_POSITION_CONTAINED_BY = 0x10,
154 DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20,
157 // All Nodes are placed in their own heap partition for security.
158 // See http://crbug.com/246860 for detail.
159 void* operator new(size_t);
160 void operator delete(void*);
162 static void dumpStatistics();
166 // DOM methods & attributes for Node
168 bool hasTagName(const QualifiedName&) const;
169 virtual String nodeName() const = 0;
170 virtual String nodeValue() const;
171 virtual void setNodeValue(const String&);
172 virtual NodeType nodeType() const = 0;
173 ContainerNode* parentNode() const;
174 Element* parentElement() const;
175 Node* previousSibling() const { return m_previous; }
176 Node* nextSibling() const { return m_next; }
177 PassRefPtr<NodeList> childNodes();
178 Node* firstChild() const;
179 Node* lastChild() const;
181 void remove(ExceptionState&);
183 Node* pseudoAwareNextSibling() const;
184 Node* pseudoAwarePreviousSibling() const;
185 Node* pseudoAwareFirstChild() const;
186 Node* pseudoAwareLastChild() const;
188 virtual KURL baseURI() const;
190 // These should all actually return a node, but this is only important for language bindings,
191 // which will already know and hold a ref on the right node to return.
192 void insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION);
193 void replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& = ASSERT_NO_EXCEPTION);
194 void removeChild(Node* child, ExceptionState&);
195 void appendChild(PassRefPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION);
197 bool hasChildNodes() const { return firstChild(); }
198 virtual PassRefPtr<Node> cloneNode(bool deep = false) = 0;
199 virtual const AtomicString& localName() const;
200 virtual const AtomicString& namespaceURI() const;
203 bool isSameNode(Node* other) const { return this == other; }
204 bool isEqualNode(Node*) const;
205 bool isDefaultNamespace(const AtomicString& namespaceURI) const;
206 const AtomicString& lookupPrefix(const AtomicString& namespaceURI) const;
207 const AtomicString& lookupNamespaceURI(const String& prefix) const;
209 String textContent(bool convertBRsToNewlines = false) const;
210 void setTextContent(const String&);
212 Node& lastDescendant() const;
214 // Other methods (not part of DOM)
216 bool isElementNode() const { return getFlag(IsElementFlag); }
217 bool isContainerNode() const { return getFlag(IsContainerFlag); }
218 bool isTextNode() const { return getFlag(IsTextFlag); }
219 bool isHTMLElement() const { return getFlag(IsHTMLFlag); }
220 bool isSVGElement() const { return getFlag(IsSVGFlag); }
222 bool isPseudoElement() const { return pseudoId() != NOPSEUDO; }
223 bool isBeforePseudoElement() const { return pseudoId() == BEFORE; }
224 bool isAfterPseudoElement() const { return pseudoId() == AFTER; }
225 PseudoId pseudoId() const { return (isElementNode() && hasCustomStyleCallbacks()) ? customPseudoId() : NOPSEUDO; }
227 bool isCustomElement() const { return getFlag(CustomElement); }
228 enum CustomElementState {
229 NotCustomElement = 0,
230 WaitingForUpgrade = 1 << 0,
233 CustomElementState customElementState() const
235 return isCustomElement()
236 ? (getFlag(CustomElementUpgraded) ? Upgraded : WaitingForUpgrade)
239 void setCustomElementState(CustomElementState newState);
241 virtual bool isMediaControlElement() const { return false; }
242 virtual bool isMediaControls() const { return false; }
243 virtual bool isVTTElement() const { return false; }
244 virtual bool isAttributeNode() const { return false; }
245 virtual bool isCharacterDataNode() const { return false; }
246 virtual bool isFrameOwnerElement() const { return false; }
247 virtual bool isPluginElement() const { return false; }
249 // StyledElements allow inline style (style="border: 1px"), presentational attributes (ex. color),
250 // class names (ex. class="foo bar") and other non-basic styling features. They and also control
251 // if this element can participate in style sharing.
253 // FIXME: The only things that ever go through StyleResolver that aren't StyledElements are
254 // PseudoElements and VTTElements. It's possible we can just eliminate all the checks
255 // since those elements will never have class names, inline style, or other things that
256 // this apparently guards against.
257 bool isStyledElement() const { return isHTMLElement() || isSVGElement(); }
259 bool isDocumentNode() const;
260 bool isTreeScope() const { return &treeScope().rootNode() == this; }
261 bool isDocumentFragment() const { return getFlag(IsDocumentFragmentFlag); }
262 bool isShadowRoot() const { return isDocumentFragment() && isTreeScope(); }
263 bool isInsertionPoint() const { return getFlag(IsInsertionPointFlag); }
265 bool hasCustomStyleCallbacks() const { return getFlag(HasCustomStyleCallbacksFlag); }
267 bool hasSyntheticAttrChildNodes() const { return getFlag(HasSyntheticAttrChildNodesFlag); }
268 void setHasSyntheticAttrChildNodes(bool flag) { setFlag(flag, HasSyntheticAttrChildNodesFlag); }
270 // If this node is in a shadow tree, returns its shadow host. Otherwise, returns 0.
271 Element* shadowHost() const;
272 // If this node is in a shadow tree, returns its shadow host. Otherwise, returns this.
273 // Deprecated. Should use shadowHost() and check the return value.
274 Node* deprecatedShadowAncestorNode() const;
275 ShadowRoot* containingShadowRoot() const;
276 ShadowRoot* youngestShadowRoot() const;
278 // Returns 0, a child of ShadowRoot, or a legacy shadow root.
279 Node* nonBoundaryShadowTreeRootNode();
281 // Node's parent, shadow tree host.
282 ContainerNode* parentOrShadowHostNode() const;
283 Element* parentOrShadowHostElement() const;
284 void setParentOrShadowHostNode(ContainerNode*);
285 Node* highestAncestor() const;
287 // Knows about all kinds of hosts.
288 ContainerNode* parentOrShadowHostOrTemplateHostNode() const;
290 // Returns the parent node, but 0 if the parent node is a ShadowRoot.
291 ContainerNode* nonShadowBoundaryParentNode() const;
293 bool selfOrAncestorHasDirAutoAttribute() const { return getFlag(SelfOrAncestorHasDirAutoFlag); }
294 void setSelfOrAncestorHasDirAutoAttribute(bool flag) { setFlag(flag, SelfOrAncestorHasDirAutoFlag); }
296 // Returns the enclosing event parent node (or self) that, when clicked, would trigger a navigation.
297 Node* enclosingLinkEventParentOrSelf();
299 bool isBlockFlowElement() const;
301 // These low-level calls give the caller responsibility for maintaining the integrity of the tree.
302 void setPreviousSibling(Node* previous) { m_previous = previous; }
303 void setNextSibling(Node* next) { m_next = next; }
305 virtual bool canContainRangeEndPoint() const { return false; }
307 // FIXME: These two functions belong in editing -- "atomic node" is an editing concept.
308 Node* previousNodeConsideringAtomicNodes() const;
309 Node* nextNodeConsideringAtomicNodes() const;
311 // Returns the next leaf node or 0 if there are no more.
312 // Delivers leaf nodes as if the whole DOM tree were a linear chain of its leaf nodes.
313 // Uses an editing-specific concept of what a leaf node is, and should probably be moved
314 // out of the Node class into an editing-specific source file.
315 Node* nextLeafNode() const;
317 // Returns the previous leaf node or 0 if there are no more.
318 // Delivers leaf nodes as if the whole DOM tree were a linear chain of its leaf nodes.
319 // Uses an editing-specific concept of what a leaf node is, and should probably be moved
320 // out of the Node class into an editing-specific source file.
321 Node* previousLeafNode() const;
323 // enclosingBlockFlowElement() is deprecated. Use enclosingBlock instead.
324 Element* enclosingBlockFlowElement() const;
326 bool isRootEditableElement() const;
327 Element* rootEditableElement() const;
328 Element* rootEditableElement(EditableType) const;
330 bool inSameContainingBlockFlowElement(Node*);
332 // For <link> and <style> elements.
333 virtual bool sheetLoaded() { return true; }
334 virtual void notifyLoadedSheetAndAllCriticalSubresources(bool /* error loading subresource */) { }
335 virtual void startLoadingDynamicSheet() { ASSERT_NOT_REACHED(); }
337 bool hasName() const { return !isTextNode() && getFlag(HasNameOrIsEditingTextFlag); }
339 bool hasClass() const;
341 bool isUserActionElement() const { return getFlag(IsUserActionElement); }
342 void setUserActionElement(bool flag) { setFlag(flag, IsUserActionElement); }
344 bool active() const { return isUserActionElement() && isUserActionElementActive(); }
345 bool inActiveChain() const { return isUserActionElement() && isUserActionElementInActiveChain(); }
346 bool hovered() const { return isUserActionElement() && isUserActionElementHovered(); }
347 bool focused() const { return isUserActionElement() && isUserActionElementFocused(); }
349 bool needsAttach() const { return styleChangeType() == NeedsReattachStyleChange; }
350 bool needsStyleRecalc() const { return styleChangeType() != NoStyleChange; }
351 StyleChangeType styleChangeType() const { return static_cast<StyleChangeType>(m_nodeFlags & StyleChangeMask); }
352 bool childNeedsStyleRecalc() const { return getFlag(ChildNeedsStyleRecalcFlag); }
353 bool isLink() const { return getFlag(IsLinkFlag); }
354 bool isEditingText() const { return isTextNode() && getFlag(HasNameOrIsEditingTextFlag); }
356 void setHasName(bool f) { ASSERT(!isTextNode()); setFlag(f, HasNameOrIsEditingTextFlag); }
357 void setChildNeedsStyleRecalc() { setFlag(ChildNeedsStyleRecalcFlag); }
358 void clearChildNeedsStyleRecalc() { clearFlag(ChildNeedsStyleRecalcFlag); }
360 void setNeedsStyleRecalc(StyleChangeType, StyleChangeSource = StyleChangeFromCSS);
361 void clearNeedsStyleRecalc();
363 bool childNeedsDistributionRecalc() const { return getFlag(ChildNeedsDistributionRecalc); }
364 void setChildNeedsDistributionRecalc() { setFlag(ChildNeedsDistributionRecalc); }
365 void clearChildNeedsDistributionRecalc() { clearFlag(ChildNeedsDistributionRecalc); }
366 void markAncestorsWithChildNeedsDistributionRecalc();
368 bool childNeedsStyleInvalidation() const { return getFlag(ChildNeedsStyleInvalidation); }
369 void setChildNeedsStyleInvalidation() { setFlag(ChildNeedsStyleInvalidation); }
370 void clearChildNeedsStyleInvalidation() { clearFlag(ChildNeedsStyleInvalidation); }
371 void markAncestorsWithChildNeedsStyleInvalidation();
372 bool needsStyleInvalidation() { return getFlag(NeedsStyleInvalidation); }
373 void setNeedsStyleInvalidation();
375 void recalcDistribution();
377 bool shouldNotifyRendererWithIdenticalStyles() const { return getFlag(NotifyRendererWithIdenticalStyles); }
379 void setIsLink(bool f);
381 bool hasScopedHTMLStyleChild() const { return getFlag(HasScopedHTMLStyleChildFlag); }
382 void setHasScopedHTMLStyleChild(bool flag) { setFlag(flag, HasScopedHTMLStyleChildFlag); }
384 bool hasEventTargetData() const { return getFlag(HasEventTargetDataFlag); }
385 void setHasEventTargetData(bool flag) { setFlag(flag, HasEventTargetDataFlag); }
387 bool isV8CollectableDuringMinorGC() const { return getFlag(V8CollectableDuringMinorGCFlag); }
388 void markV8CollectableDuringMinorGC() { setFlag(true, V8CollectableDuringMinorGCFlag); }
389 void clearV8CollectableDuringMinorGC() { setFlag(false, V8CollectableDuringMinorGCFlag); }
391 virtual void setFocus(bool flag);
392 virtual void setActive(bool flag = true);
393 virtual void setHovered(bool flag = true);
395 virtual short tabIndex() const;
397 virtual Node* focusDelegate();
398 // This is called only when the node is focused.
399 virtual bool shouldHaveFocusAppearance() const;
401 // Whether the node is inert. This can't be in Element because text nodes
402 // must be recognized as inert to prevent text selection.
403 bool isInert() const;
405 enum UserSelectAllTreatment {
406 UserSelectAllDoesNotAffectEditability,
407 UserSelectAllIsAlwaysNonEditable
409 bool isContentEditable(UserSelectAllTreatment = UserSelectAllDoesNotAffectEditability);
410 bool isContentRichlyEditable();
412 bool rendererIsEditable(EditableType editableType = ContentIsEditable, UserSelectAllTreatment treatment = UserSelectAllIsAlwaysNonEditable) const
414 switch (editableType) {
415 case ContentIsEditable:
416 return rendererIsEditable(Editable, treatment);
417 case HasEditableAXRole:
418 return isEditableToAccessibility(Editable);
420 ASSERT_NOT_REACHED();
424 bool rendererIsRichlyEditable(EditableType editableType = ContentIsEditable) const
426 switch (editableType) {
427 case ContentIsEditable:
428 return rendererIsEditable(RichlyEditable, UserSelectAllIsAlwaysNonEditable);
429 case HasEditableAXRole:
430 return isEditableToAccessibility(RichlyEditable);
432 ASSERT_NOT_REACHED();
436 virtual bool shouldUseInputMethod();
437 virtual LayoutRect boundingBox() const;
438 IntRect pixelSnappedBoundingBox() const { return pixelSnappedIntRect(boundingBox()); }
440 // Returns true if the node has a non-empty bounding box in layout.
441 // This does not 100% guarantee the user can see it, but is pretty close.
442 // Note: This method only works properly after layout has occurred.
443 bool hasNonEmptyBoundingBox() const;
445 unsigned nodeIndex() const;
447 // Returns the DOM ownerDocument attribute. This method never returns NULL, except in the case
448 // of a Document node.
449 Document* ownerDocument() const;
451 // Returns the document associated with this node. A Document node returns itself.
452 Document& document() const
454 return treeScope().document();
457 TreeScope& treeScope() const
463 bool inActiveDocument() const;
465 // Returns true if this node is associated with a document and is in its associated document's
466 // node tree, false otherwise.
467 bool inDocument() const
469 return getFlag(InDocumentFlag);
471 bool isInShadowTree() const { return getFlag(IsInShadowTreeFlag); }
472 bool isInTreeScope() const { return getFlag(static_cast<NodeFlags>(InDocumentFlag | IsInShadowTreeFlag)); }
474 bool isDocumentTypeNode() const { return nodeType() == DOCUMENT_TYPE_NODE; }
475 virtual bool childTypeAllowed(NodeType) const { return false; }
476 unsigned childNodeCount() const;
477 Node* childNode(unsigned index) const;
479 bool isDescendantOf(const Node*) const;
480 bool contains(const Node*) const;
481 bool containsIncludingShadowDOM(const Node*) const;
482 bool containsIncludingHostElements(const Node&) const;
483 Node* commonAncestor(const Node&, Node* (*parent)(const Node&));
485 // Used to determine whether range offsets use characters or node indices.
486 virtual bool offsetInCharacters() const;
487 // Number of DOM 16-bit units contained in node. Note that rendered text length can be different - e.g. because of
488 // css-transform:capitalize breaking up precomposed characters and ligatures.
489 virtual int maxCharacterOffset() const;
491 // Whether or not a selection can be started in this object
492 virtual bool canStartSelection() const;
494 // Getting points into and out of screen space
495 FloatPoint convertToPage(const FloatPoint&) const;
496 FloatPoint convertFromPage(const FloatPoint&) const;
498 // -----------------------------------------------------------------------------
499 // Integration with rendering tree
501 // As renderer() includes a branch you should avoid calling it repeatedly in hot code paths.
502 // Note that if a Node has a renderer, it's parentNode is guaranteed to have one as well.
503 RenderObject* renderer() const { return hasRareData() ? m_data.m_rareData->renderer() : m_data.m_renderer; };
504 void setRenderer(RenderObject* renderer)
507 m_data.m_rareData->setRenderer(renderer);
509 m_data.m_renderer = renderer;
511 bool hasRenderer() const { return renderer(); }
513 // Use these two methods with caution.
514 RenderBox* renderBox() const;
515 RenderBoxModelObject* renderBoxModelObject() const;
517 struct AttachContext {
518 RenderStyle* resolvedStyle;
519 bool performingReattach;
521 AttachContext() : resolvedStyle(0), performingReattach(false) { }
524 // Attaches this node to the rendering tree. This calculates the style to be applied to the node and creates an
525 // appropriate RenderObject which will be inserted into the tree (except when the style has display: none). This
526 // makes the node visible in the FrameView.
527 virtual void attach(const AttachContext& = AttachContext());
529 // Detaches the node from the rendering tree, making it invisible in the rendered view. This method will remove
530 // the node's rendering object from the rendering tree and delete it.
531 virtual void detach(const AttachContext& = AttachContext());
534 bool inDetach() const;
537 void reattach(const AttachContext& = AttachContext());
538 void lazyReattachIfAttached();
540 // Returns true if recalcStyle should be called on the object, if there is such a method (on Document and Element).
541 bool shouldCallRecalcStyle(StyleRecalcChange);
543 // Wrapper for nodes that don't have a renderer, but still cache the style (like HTMLOptionElement).
544 RenderStyle* renderStyle() const;
545 RenderStyle* parentRenderStyle() const;
547 RenderStyle* computedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) { return virtualComputedStyle(pseudoElementSpecifier); }
549 // -----------------------------------------------------------------------------
550 // Notification of document structure changes (see ContainerNode.h for more notification methods)
552 // At first, WebKit notifies the node that it has been inserted into the document. This is called during document parsing, and also
553 // 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.
554 // This is similar to the DOMNodeInsertedIntoDocument DOM event, but does not require the overhead of event
557 // WebKit notifies this callback regardless if the subtree of the node is a document tree or a floating subtree.
558 // Implementation can determine the type of subtree by seeing insertionPoint->inDocument().
559 // For a performance reason, notifications are delivered only to ContainerNode subclasses if the insertionPoint is out of document.
561 // There are another callback named didNotifySubtreeInsertionsToDocument(), which is called after all the descendant is notified,
562 // if this node was inserted into the document tree. Only a few subclasses actually need this. To utilize this, the node should
563 // return InsertionShouldCallDidNotifySubtreeInsertions from insrtedInto().
565 enum InsertionNotificationRequest {
567 InsertionShouldCallDidNotifySubtreeInsertions
570 virtual InsertionNotificationRequest insertedInto(ContainerNode* insertionPoint);
571 virtual void didNotifySubtreeInsertionsToDocument() { }
573 // Notifies the node that it is no longer part of the tree.
575 // This is a dual of insertedInto(), and is similar to the DOMNodeRemovedFromDocument DOM event, but does not require the overhead of event
576 // dispatching, and is called _after_ the node is removed from the tree.
578 virtual void removedFrom(ContainerNode* insertionPoint);
580 String debugName() const;
583 virtual void formatForDebugger(char* buffer, unsigned length) const;
585 void showNode(const char* prefix = "") const;
586 void showTreeForThis() const;
587 void showNodePathForThis() const;
588 void showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2 = 0, const char* markedLabel2 = 0) const;
589 void showTreeForThisAcrossFrame() const;
592 void invalidateNodeListCachesInAncestors(const QualifiedName* attrName = 0, Element* attributeOwnerElement = 0);
593 NodeListsNodeData* nodeLists();
594 void clearNodeLists();
596 virtual bool willRespondToMouseMoveEvents();
597 virtual bool willRespondToMouseClickEvents();
598 virtual bool willRespondToTouchEvents();
600 unsigned short compareDocumentPosition(const Node*) const;
602 enum ShadowTreesTreatment {
603 TreatShadowTreesAsDisconnected,
604 TreatShadowTreesAsComposed
607 unsigned short compareDocumentPositionInternal(const Node*, ShadowTreesTreatment) const;
609 virtual Node* toNode() OVERRIDE FINAL;
611 virtual const AtomicString& interfaceName() const OVERRIDE;
612 virtual ExecutionContext* executionContext() const OVERRIDE;
614 virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) OVERRIDE;
615 virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) OVERRIDE;
616 virtual void removeAllEventListeners() OVERRIDE;
618 // Handlers to do/undo actions on the target node before an event is dispatched to it and after the event
619 // has been dispatched. The data pointer is handed back by the preDispatch and passed to postDispatch.
620 virtual void* preDispatchEventHandler(Event*) { return 0; }
621 virtual void postDispatchEventHandler(Event*, void* /*dataFromPreDispatch*/) { }
623 using EventTarget::dispatchEvent;
624 virtual bool dispatchEvent(PassRefPtr<Event>) OVERRIDE;
626 void dispatchScopedEvent(PassRefPtr<Event>);
627 void dispatchScopedEventDispatchMediator(PassRefPtr<EventDispatchMediator>);
629 virtual void handleLocalEvents(Event*);
631 void dispatchSubtreeModifiedEvent();
632 bool dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEvent);
634 bool dispatchKeyEvent(const PlatformKeyboardEvent&);
635 bool dispatchWheelEvent(const PlatformWheelEvent&);
636 bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType, int clickCount = 0, Node* relatedTarget = 0);
637 bool dispatchGestureEvent(const PlatformGestureEvent&);
638 bool dispatchTouchEvent(PassRefPtr<TouchEvent>);
640 void dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions = SendNoEvents);
642 virtual bool dispatchBeforeLoadEvent(const String& sourceURL);
643 void dispatchInputEvent();
645 // Perform the default action for an event.
646 virtual void defaultEventHandler(Event*);
647 virtual void willCallDefaultEventHandler(const Event&);
649 virtual EventTargetData* eventTargetData() OVERRIDE;
650 virtual EventTargetData& ensureEventTargetData() OVERRIDE;
652 void getRegisteredMutationObserversOfType(HashMap<MutationObserver*, MutationRecordDeliveryOptions>&, MutationObserver::MutationType, const QualifiedName* attributeName);
653 void registerMutationObserver(MutationObserver*, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
654 void unregisterMutationObserver(MutationObserverRegistration*);
655 void registerTransientMutationObserver(MutationObserverRegistration*);
656 void unregisterTransientMutationObserver(MutationObserverRegistration*);
657 void notifyMutationObserversNodeWillDetach();
659 virtual void registerScopedHTMLStyleChild();
660 virtual void unregisterScopedHTMLStyleChild();
661 size_t numberOfScopedHTMLStyleChildren() const;
663 unsigned connectedSubframeCount() const;
664 void incrementConnectedSubframeCount(unsigned amount = 1);
665 void decrementConnectedSubframeCount(unsigned amount = 1);
666 void updateAncestorConnectedSubframeCountForRemoval() const;
667 void updateAncestorConnectedSubframeCountForInsertion() const;
669 PassRefPtr<NodeList> getDestinationInsertionPoints();
671 void setAlreadySpellChecked(bool flag) { setFlag(flag, AlreadySpellCheckedFlag); }
672 bool isAlreadySpellChecked() { return getFlag(AlreadySpellCheckedFlag); }
677 IsContainerFlag = 1 << 1,
678 IsElementFlag = 1 << 2,
682 ChildNeedsDistributionRecalc = 1 << 5,
683 ChildNeedsStyleRecalcFlag = 1 << 6,
684 InDocumentFlag = 1 << 7,
686 IsUserActionElement = 1 << 9,
687 HasRareDataFlag = 1 << 10,
688 IsDocumentFragmentFlag = 1 << 11,
690 // These bits are used by derived classes, pulled up here so they can
691 // be stored in the same memory word as the Node bits above.
692 IsFinishedParsingChildrenFlag = 1 << 12, // Element
694 AlreadySpellCheckedFlag = 1 << 13,
696 StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1),
698 SelfOrAncestorHasDirAutoFlag = 1 << 16,
700 HasNameOrIsEditingTextFlag = 1 << 17,
702 // Bit 18 is available
704 HasSyntheticAttrChildNodesFlag = 1 << 19,
705 HasCustomStyleCallbacksFlag = 1 << 20,
706 HasScopedHTMLStyleChildFlag = 1 << 21,
707 HasEventTargetDataFlag = 1 << 22,
708 V8CollectableDuringMinorGCFlag = 1 << 23,
709 IsInsertionPointFlag = 1 << 24,
710 IsInShadowTreeFlag = 1 << 25,
712 NotifyRendererWithIdenticalStyles = 1 << 26,
714 CustomElement = 1 << 27,
715 CustomElementUpgraded = 1 << 28,
717 ChildNeedsStyleInvalidation = 1 << 29,
718 NeedsStyleInvalidation = 1 << 30,
720 DefaultNodeFlags = IsFinishedParsingChildrenFlag | ChildNeedsStyleRecalcFlag | NeedsReattachStyleChange
725 bool getFlag(NodeFlags mask) const { return m_nodeFlags & mask; }
726 void setFlag(bool f, NodeFlags mask) const { m_nodeFlags = (m_nodeFlags & ~mask) | (-(int32_t)f & mask); }
727 void setFlag(NodeFlags mask) const { m_nodeFlags |= mask; }
728 void clearFlag(NodeFlags mask) const { m_nodeFlags &= ~mask; }
731 enum ConstructionType {
732 CreateOther = DefaultNodeFlags,
733 CreateText = DefaultNodeFlags | IsTextFlag,
734 CreateContainer = DefaultNodeFlags | IsContainerFlag,
735 CreateElement = CreateContainer | IsElementFlag,
736 CreateShadowRoot = CreateContainer | IsDocumentFragmentFlag | IsInShadowTreeFlag,
737 CreateDocumentFragment = CreateContainer | IsDocumentFragmentFlag,
738 CreateHTMLElement = CreateElement | IsHTMLFlag,
739 CreateSVGElement = CreateElement | IsSVGFlag,
740 CreateDocument = CreateContainer | InDocumentFlag,
741 CreateInsertionPoint = CreateHTMLElement | IsInsertionPointFlag,
742 CreateEditingText = CreateText | HasNameOrIsEditingTextFlag,
745 Node(TreeScope* treeScope, ConstructionType type)
747 , m_parentOrShadowHostNode(0)
748 , m_treeScope(treeScope)
752 ASSERT(m_treeScope || type == CreateDocument || type == CreateShadowRoot);
753 ScriptWrappable::init(this);
755 m_treeScope->guardRef();
757 #if !defined(NDEBUG) || (defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS)
760 InspectorCounters::incrementCounter(InspectorCounters::NodeCounter);
763 virtual void didMoveToNewDocument(Document& oldDocument);
765 static void reattachWhitespaceSiblings(Text* start);
767 void willBeDeletedFromDocument();
769 bool hasRareData() const { return getFlag(HasRareDataFlag); }
771 NodeRareData* rareData() const;
772 NodeRareData& ensureRareData();
773 void clearRareData();
775 void clearEventTargetData();
777 void setHasCustomStyleCallbacks() { setFlag(true, HasCustomStyleCallbacksFlag); }
779 void setTreeScope(TreeScope* scope) { m_treeScope = scope; }
781 // isTreeScopeInitialized() can be false
782 // - in the destruction of Document or ShadowRoot where m_treeScope is set to null or
783 // - in the Node constructor called by these two classes where m_treeScope is set by TreeScope ctor.
784 bool isTreeScopeInitialized() const { return m_treeScope; }
786 void markAncestorsWithChildNeedsStyleRecalc();
788 bool isFinishedParsingChildren() const { return getFlag(IsFinishedParsingChildrenFlag); }
789 void setIsFinishedParsingChildren(bool value) { setFlag(value, IsFinishedParsingChildrenFlag); }
792 friend class TreeShared<Node>;
794 virtual PseudoId customPseudoId() const
796 ASSERT(hasCustomStyleCallbacks());
800 void removedLastRef();
801 bool hasTreeSharedParent() const { return !!parentOrShadowHostNode(); }
803 enum EditableLevel { Editable, RichlyEditable };
804 bool rendererIsEditable(EditableLevel, UserSelectAllTreatment = UserSelectAllIsAlwaysNonEditable) const;
805 bool isEditableToAccessibility(EditableLevel) const;
807 bool isUserActionElementActive() const;
808 bool isUserActionElementInActiveChain() const;
809 bool isUserActionElementHovered() const;
810 bool isUserActionElementFocused() const;
812 void traceStyleChange(StyleChangeType);
813 void traceStyleChangeIfNeeded(StyleChangeType);
814 void setStyleChange(StyleChangeType);
816 virtual RenderStyle* nonRendererStyle() const { return 0; }
818 virtual RenderStyle* virtualComputedStyle(PseudoId = NOPSEUDO);
820 void trackForDebugging();
822 Vector<OwnPtr<MutationObserverRegistration> >* mutationObserverRegistry();
823 HashSet<MutationObserverRegistration*>* transientMutationObserverRegistry();
825 mutable uint32_t m_nodeFlags;
826 ContainerNode* m_parentOrShadowHostNode;
827 TreeScope* m_treeScope;
830 // When a node has rare data we move the renderer into the rare data.
832 DataUnion() : m_renderer(0) { }
833 RenderObject* m_renderer;
834 NodeRareDataBase* m_rareData;
838 inline void Node::setParentOrShadowHostNode(ContainerNode* parent)
840 ASSERT(isMainThread());
841 m_parentOrShadowHostNode = parent;
844 inline ContainerNode* Node::parentOrShadowHostNode() const
846 ASSERT(isMainThread());
847 return m_parentOrShadowHostNode;
850 inline ContainerNode* Node::parentNode() const
852 return isShadowRoot() ? 0 : parentOrShadowHostNode();
855 inline void Node::lazyReattachIfAttached()
857 if (styleChangeType() == NeedsReattachStyleChange)
859 if (!inActiveDocument())
862 AttachContext context;
863 context.performingReattach = true;
866 markAncestorsWithChildNeedsStyleRecalc();
869 inline bool Node::shouldCallRecalcStyle(StyleRecalcChange change)
871 return change >= Inherit || needsStyleRecalc() || childNeedsStyleRecalc();
874 inline bool isTreeScopeRoot(const Node* node)
876 return !node || node->isDocumentNode() || node->isShadowRoot();
879 inline bool isTreeScopeRoot(const Node& node)
881 return node.isDocumentNode() || node.isShadowRoot();
884 // Allow equality comparisons of Nodes by reference or pointer, interchangeably.
885 inline bool operator==(const Node& a, const Node& b) { return &a == &b; }
886 inline bool operator==(const Node& a, const Node* b) { return &a == b; }
887 inline bool operator==(const Node* a, const Node& b) { return a == &b; }
888 inline bool operator!=(const Node& a, const Node& b) { return !(a == b); }
889 inline bool operator!=(const Node& a, const Node* b) { return !(a == b); }
890 inline bool operator!=(const Node* a, const Node& b) { return !(a == b); }
891 inline bool operator==(const PassRefPtr<Node>& a, const Node& b) { return a.get() == &b; }
892 inline bool operator==(const Node& a, const PassRefPtr<Node>& b) { return &a == b.get(); }
893 inline bool operator!=(const PassRefPtr<Node>& a, const Node& b) { return !(a == b); }
894 inline bool operator!=(const Node& a, const PassRefPtr<Node>& b) { return !(a == b); }
897 #define DEFINE_NODE_TYPE_CASTS(thisType, predicate) \
898 template<typename T> inline thisType* to##thisType(const RefPtr<T>& node) { return to##thisType(node.get()); } \
899 DEFINE_TYPE_CASTS(thisType, Node, node, node->predicate, node.predicate)
901 // This requires isClassName(const Node&).
902 #define DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(thisType) \
903 template<typename T> inline thisType* to##thisType(const RefPtr<T>& node) { return to##thisType(node.get()); } \
904 DEFINE_TYPE_CASTS(thisType, Node, node, is##thisType(*node), is##thisType(node))
906 } // namespace WebCore
909 // Outside the WebCore namespace for ease of invocation from gdb.
910 void showTree(const WebCore::Node*);
911 void showNodePath(const WebCore::Node*);