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/)
7 *
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.
12 *
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.
17 *
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.
22 *
23 */
24
25#ifndef Node_h
26#define Node_h
27
28#include "bindings/core/v8/ExceptionStatePlaceholder.h"
29#include "core/dom/MutationObserver.h"
30#include "core/dom/SimulatedClickOptions.h"
31#include "core/dom/TreeScope.h"
32#include "core/dom/TreeShared.h"
33#include "core/editing/EditingBoundary.h"
34#include "core/events/EventTarget.h"
35#include "core/inspector/InspectorCounters.h"
36#include "core/rendering/style/RenderStyleConstants.h"
37#include "platform/geometry/LayoutRect.h"
38#include "platform/heap/Handle.h"
39#include "platform/weborigin/KURLHash.h"
40#include "wtf/Forward.h"
41
42// This needs to be here because Document.h also depends on it.
43#define DUMP_NODE_STATISTICS 0
44
45namespace blink {
46
47class Attribute;
48class ClassCollection;
49class ContainerNode;
50class DOMSettableTokenList;
51class Document;
52class Element;
53class Event;
54class EventDispatchMediator;
55class EventListener;
56class ExceptionState;
57class FloatPoint;
58class LocalFrame;
59class HTMLInputElement;
60class HTMLQualifiedName;
61class IntRect;
62class KeyboardEvent;
63class NSResolver;
64class NameNodeList;
65class NamedNodeMap;
66class NodeEventContext;
67class NodeList;
68class NodeListsNodeData;
69class NodeRareData;
70class PlatformGestureEvent;
71class PlatformKeyboardEvent;
72class PlatformMouseEvent;
73class PlatformWheelEvent;
74class QualifiedName;
75class RadioNodeList;
76class RegisteredEventListener;
77class RenderBox;
78class RenderBoxModelObject;
79class RenderObject;
80class RenderStyle;
81class SVGQualifiedName;
82class ShadowRoot;
83template <typename NodeType> class StaticNodeTypeList;
84typedef StaticNodeTypeList<Node> StaticNodeList;
85class TagCollection;
86class Text;
87class TouchEvent;
88class WeakNodeMap;
89
90const int nodeStyleChangeShift = 19;
91
92enum StyleChangeType {
93    NoStyleChange = 0,
94    LocalStyleChange = 1 << nodeStyleChangeShift,
95    SubtreeStyleChange = 2 << nodeStyleChangeShift,
96    NeedsReattachStyleChange = 3 << nodeStyleChangeShift,
97};
98
99class NodeRareDataBase {
100public:
101    RenderObject* renderer() const { return m_renderer; }
102    void setRenderer(RenderObject* renderer) { m_renderer = renderer; }
103
104protected:
105    NodeRareDataBase(RenderObject* renderer)
106        : m_renderer(renderer)
107    { }
108
109protected:
110    // Oilpan: This member is traced in NodeRareData.
111    // FIXME: Can we add traceAfterDispatch and finalizeGarbageCollectedObject
112    // to NodeRareDataBase, and make m_renderer Member<>?
113    RenderObject* m_renderer;
114};
115
116#if ENABLE(OILPAN)
117#define NODE_BASE_CLASSES public GarbageCollectedFinalized<Node>, public EventTarget
118#else
119// TreeShared should be the last to pack TreeShared::m_refCount and
120// Node::m_nodeFlags on 64bit platforms.
121#define NODE_BASE_CLASSES public EventTarget, public TreeShared<Node>
122#endif
123
124class Node : NODE_BASE_CLASSES {
125    DEFINE_EVENT_TARGET_REFCOUNTING_WILL_BE_REMOVED(TreeShared<Node>);
126    DEFINE_WRAPPERTYPEINFO();
127    WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(Node);
128    friend class Document;
129    friend class TreeScope;
130    friend class TreeScopeAdopter;
131public:
132    enum NodeType {
133        ELEMENT_NODE = 1,
134        ATTRIBUTE_NODE = 2,
135        TEXT_NODE = 3,
136        CDATA_SECTION_NODE = 4,
137        PROCESSING_INSTRUCTION_NODE = 7,
138        COMMENT_NODE = 8,
139        DOCUMENT_NODE = 9,
140        DOCUMENT_TYPE_NODE = 10,
141        DOCUMENT_FRAGMENT_NODE = 11,
142    };
143
144    // Entity, EntityReference, Notation, and XPathNamespace nodes are impossible to create in Blink.
145    // But for compatibility reasons we want these enum values exist in JS, and this enum makes the bindings
146    // generation not complain about ENTITY_REFERENCE_NODE being missing from the implementation
147    // while not requiring all switch(NodeType) blocks to include this deprecated constant.
148    enum DeprecatedNodeType {
149        ENTITY_REFERENCE_NODE = 5,
150        ENTITY_NODE = 6,
151        NOTATION_NODE = 12,
152        XPATH_NAMESPACE_NODE = 13,
153    };
154
155    enum DocumentPosition {
156        DOCUMENT_POSITION_EQUIVALENT = 0x00,
157        DOCUMENT_POSITION_DISCONNECTED = 0x01,
158        DOCUMENT_POSITION_PRECEDING = 0x02,
159        DOCUMENT_POSITION_FOLLOWING = 0x04,
160        DOCUMENT_POSITION_CONTAINS = 0x08,
161        DOCUMENT_POSITION_CONTAINED_BY = 0x10,
162        DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20,
163    };
164
165#if !ENABLE(OILPAN)
166    // All Nodes are placed in their own heap partition for security.
167    // See http://crbug.com/246860 for detail.
168    void* operator new(size_t);
169    void operator delete(void*);
170#endif
171
172    static void dumpStatistics();
173
174    virtual ~Node();
175
176    // DOM methods & attributes for Node
177
178    bool hasTagName(const HTMLQualifiedName&) const;
179    bool hasTagName(const SVGQualifiedName&) const;
180    virtual String nodeName() const = 0;
181    virtual String nodeValue() const;
182    virtual void setNodeValue(const String&);
183    virtual NodeType nodeType() const = 0;
184    ContainerNode* parentNode() const;
185    Element* parentElement() const;
186    ContainerNode* parentElementOrShadowRoot() const;
187    ContainerNode* parentElementOrDocumentFragment() const;
188    Node* previousSibling() const { return m_previous; }
189    Node* nextSibling() const { return m_next; }
190    PassRefPtrWillBeRawPtr<NodeList> childNodes();
191    Node* firstChild() const;
192    Node* lastChild() const;
193
194    void remove(ExceptionState&);
195
196    Node* pseudoAwareNextSibling() const;
197    Node* pseudoAwarePreviousSibling() const;
198    Node* pseudoAwareFirstChild() const;
199    Node* pseudoAwareLastChild() const;
200
201    virtual KURL baseURI() const;
202
203    // These should all actually return a node, but this is only important for language bindings,
204    // which will already know and hold a ref on the right node to return.
205    PassRefPtrWillBeRawPtr<Node> insertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION);
206    PassRefPtrWillBeRawPtr<Node> replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, PassRefPtrWillBeRawPtr<Node> oldChild, ExceptionState& = ASSERT_NO_EXCEPTION);
207    PassRefPtrWillBeRawPtr<Node> removeChild(PassRefPtrWillBeRawPtr<Node> child, ExceptionState& = ASSERT_NO_EXCEPTION);
208    PassRefPtrWillBeRawPtr<Node> appendChild(PassRefPtrWillBeRawPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION);
209
210    bool hasChildren() const { return firstChild(); }
211    virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = false) = 0;
212    virtual const AtomicString& localName() const;
213    virtual const AtomicString& namespaceURI() const;
214    void normalize();
215
216    bool isSameNode(Node* other) const { return this == other; }
217    bool isEqualNode(Node*) const;
218    bool isDefaultNamespace(const AtomicString& namespaceURI) const;
219    const AtomicString& lookupPrefix(const AtomicString& namespaceURI) const;
220    const AtomicString& lookupNamespaceURI(const String& prefix) const;
221
222    String textContent(bool convertBRsToNewlines = false) const;
223    void setTextContent(const String&);
224
225    // Other methods (not part of DOM)
226
227    bool isElementNode() const { return getFlag(IsElementFlag); }
228    bool isContainerNode() const { return getFlag(IsContainerFlag); }
229    bool isTextNode() const { return getFlag(IsTextFlag); }
230    bool isHTMLElement() const { return getFlag(IsHTMLFlag); }
231    bool isSVGElement() const { return getFlag(IsSVGFlag); }
232
233    bool isPseudoElement() const { return pseudoId() != NOPSEUDO; }
234    bool isBeforePseudoElement() const { return pseudoId() == BEFORE; }
235    bool isAfterPseudoElement() const { return pseudoId() == AFTER; }
236    virtual PseudoId pseudoId() const { return NOPSEUDO; }
237
238    bool isCustomElement() const { return getFlag(CustomElementFlag); }
239    enum CustomElementState {
240        NotCustomElement  = 0,
241        WaitingForUpgrade = 1 << 0,
242        Upgraded          = 1 << 1
243    };
244    CustomElementState customElementState() const
245    {
246        return isCustomElement()
247            ? (getFlag(CustomElementUpgradedFlag) ? Upgraded : WaitingForUpgrade)
248            : NotCustomElement;
249    }
250    void setCustomElementState(CustomElementState newState);
251
252    virtual bool isMediaControlElement() const { return false; }
253    virtual bool isMediaControls() const { return false; }
254    virtual bool isVTTElement() const { return false; }
255    virtual bool isAttributeNode() const { return false; }
256    virtual bool isCharacterDataNode() const { return false; }
257    virtual bool isFrameOwnerElement() const { return false; }
258
259    // StyledElements allow inline style (style="border: 1px"), presentational attributes (ex. color),
260    // class names (ex. class="foo bar") and other non-basic styling features. They and also control
261    // if this element can participate in style sharing.
262    //
263    // FIXME: The only things that ever go through StyleResolver that aren't StyledElements are
264    // PseudoElements and VTTElements. It's possible we can just eliminate all the checks
265    // since those elements will never have class names, inline style, or other things that
266    // this apparently guards against.
267    bool isStyledElement() const { return isHTMLElement() || isSVGElement(); }
268
269    bool isDocumentNode() const;
270    bool isTreeScope() const;
271    bool isDocumentFragment() const { return getFlag(IsDocumentFragmentFlag); }
272    bool isShadowRoot() const { return isDocumentFragment() && isTreeScope(); }
273    bool isInsertionPoint() const { return getFlag(IsInsertionPointFlag); }
274
275    bool hasCustomStyleCallbacks() const { return getFlag(HasCustomStyleCallbacksFlag); }
276
277    bool hasSyntheticAttrChildNodes() const { return getFlag(HasSyntheticAttrChildNodesFlag); }
278    void setHasSyntheticAttrChildNodes(bool flag) { setFlag(flag, HasSyntheticAttrChildNodesFlag); }
279
280    // If this node is in a shadow tree, returns its shadow host. Otherwise, returns 0.
281    Element* shadowHost() const;
282    ShadowRoot* containingShadowRoot() const;
283    ShadowRoot* youngestShadowRoot() const;
284
285    // Returns 0, a child of ShadowRoot, or a legacy shadow root.
286    Node* nonBoundaryShadowTreeRootNode();
287
288    // Node's parent, shadow tree host.
289    ContainerNode* parentOrShadowHostNode() const;
290    Element* parentOrShadowHostElement() const;
291    void setParentOrShadowHostNode(ContainerNode*);
292
293    // Knows about all kinds of hosts.
294    ContainerNode* parentOrShadowHostOrTemplateHostNode() const;
295
296    // Returns the parent node, but 0 if the parent node is a ShadowRoot.
297    ContainerNode* nonShadowBoundaryParentNode() const;
298
299    bool selfOrAncestorHasDirAutoAttribute() const { return getFlag(SelfOrAncestorHasDirAutoFlag); }
300    void setSelfOrAncestorHasDirAutoAttribute(bool flag) { setFlag(flag, SelfOrAncestorHasDirAutoFlag); }
301
302    // Returns the enclosing event parent Element (or self) that, when clicked, would trigger a navigation.
303    Element* enclosingLinkEventParentOrSelf();
304
305    // These low-level calls give the caller responsibility for maintaining the integrity of the tree.
306    void setPreviousSibling(Node* previous) { m_previous = previous; }
307    void setNextSibling(Node* next) { m_next = next; }
308
309    virtual bool canContainRangeEndPoint() const { return false; }
310
311    // FIXME: These two functions belong in editing -- "atomic node" is an editing concept.
312    Node* previousNodeConsideringAtomicNodes() const;
313    Node* nextNodeConsideringAtomicNodes() const;
314
315    // Returns the next leaf node or 0 if there are no more.
316    // Delivers leaf nodes as if the whole DOM tree were a linear chain of its leaf nodes.
317    // Uses an editing-specific concept of what a leaf node is, and should probably be moved
318    // out of the Node class into an editing-specific source file.
319    Node* nextLeafNode() const;
320
321    // Returns the previous leaf node or 0 if there are no more.
322    // Delivers leaf nodes as if the whole DOM tree were a linear chain of its leaf nodes.
323    // Uses an editing-specific concept of what a leaf node is, and should probably be moved
324    // out of the Node class into an editing-specific source file.
325    Node* previousLeafNode() const;
326
327    bool isRootEditableElement() const;
328    Element* rootEditableElement() const;
329    Element* rootEditableElement(EditableType) const;
330
331    // For <link> and <style> elements.
332    virtual bool sheetLoaded() { return true; }
333    virtual void notifyLoadedSheetAndAllCriticalSubresources(bool /* error loading subresource */) { }
334    virtual void startLoadingDynamicSheet() { ASSERT_NOT_REACHED(); }
335
336    bool hasName() const { return !isTextNode() && getFlag(HasNameOrIsEditingTextFlag); }
337
338    bool isUserActionElement() const { return getFlag(IsUserActionElementFlag); }
339    void setUserActionElement(bool flag) { setFlag(flag, IsUserActionElementFlag); }
340
341    bool active() const { return isUserActionElement() && isUserActionElementActive(); }
342    bool inActiveChain() const { return isUserActionElement() && isUserActionElementInActiveChain(); }
343    bool hovered() const { return isUserActionElement() && isUserActionElementHovered(); }
344    bool focused() const { return isUserActionElement() && isUserActionElementFocused(); }
345
346    bool needsAttach() const { return styleChangeType() == NeedsReattachStyleChange; }
347    bool needsStyleRecalc() const { return styleChangeType() != NoStyleChange; }
348    StyleChangeType styleChangeType() const { return static_cast<StyleChangeType>(m_nodeFlags & StyleChangeMask); }
349    bool childNeedsStyleRecalc() const { return getFlag(ChildNeedsStyleRecalcFlag); }
350    bool isLink() const { return getFlag(IsLinkFlag); }
351    bool isEditingText() const { return isTextNode() && getFlag(HasNameOrIsEditingTextFlag); }
352
353    void setHasName(bool f) { ASSERT(!isTextNode()); setFlag(f, HasNameOrIsEditingTextFlag); }
354    void setChildNeedsStyleRecalc() { setFlag(ChildNeedsStyleRecalcFlag); }
355    void clearChildNeedsStyleRecalc() { clearFlag(ChildNeedsStyleRecalcFlag); }
356
357    void setNeedsStyleRecalc(StyleChangeType);
358    void clearNeedsStyleRecalc();
359
360    bool childNeedsDistributionRecalc() const { return getFlag(ChildNeedsDistributionRecalcFlag); }
361    void setChildNeedsDistributionRecalc()  { setFlag(ChildNeedsDistributionRecalcFlag); }
362    void clearChildNeedsDistributionRecalc()  { clearFlag(ChildNeedsDistributionRecalcFlag); }
363    void markAncestorsWithChildNeedsDistributionRecalc();
364
365    bool childNeedsStyleInvalidation() const { return getFlag(ChildNeedsStyleInvalidationFlag); }
366    void setChildNeedsStyleInvalidation()  { setFlag(ChildNeedsStyleInvalidationFlag); }
367    void clearChildNeedsStyleInvalidation()  { clearFlag(ChildNeedsStyleInvalidationFlag); }
368    void markAncestorsWithChildNeedsStyleInvalidation();
369    bool needsStyleInvalidation() const { return getFlag(NeedsStyleInvalidationFlag); }
370    void clearNeedsStyleInvalidation() { clearFlag(NeedsStyleInvalidationFlag); }
371    void setNeedsStyleInvalidation();
372
373    void recalcDistribution();
374
375    bool svgFilterNeedsLayerUpdate() const { return getFlag(SVGFilterNeedsLayerUpdateFlag); }
376    void setSVGFilterNeedsLayerUpdate() { setFlag(SVGFilterNeedsLayerUpdateFlag); }
377    void clearSVGFilterNeedsLayerUpdate() { clearFlag(SVGFilterNeedsLayerUpdateFlag); }
378
379    void setIsLink(bool f);
380
381    bool hasEventTargetData() const { return getFlag(HasEventTargetDataFlag); }
382    void setHasEventTargetData(bool flag) { setFlag(flag, HasEventTargetDataFlag); }
383
384    bool isV8CollectableDuringMinorGC() const { return getFlag(V8CollectableDuringMinorGCFlag); }
385    void markV8CollectableDuringMinorGC() { setFlag(true, V8CollectableDuringMinorGCFlag); }
386    void clearV8CollectableDuringMinorGC() { setFlag(false, V8CollectableDuringMinorGCFlag); }
387
388    virtual void setFocus(bool flag);
389    virtual void setActive(bool flag = true);
390    virtual void setHovered(bool flag = true);
391
392    virtual short tabIndex() const;
393
394    virtual Node* focusDelegate();
395    // This is called only when the node is focused.
396    virtual bool shouldHaveFocusAppearance() const;
397
398    // Whether the node is inert. This can't be in Element because text nodes
399    // must be recognized as inert to prevent text selection.
400    bool isInert() const;
401
402    enum UserSelectAllTreatment {
403        UserSelectAllDoesNotAffectEditability,
404        UserSelectAllIsAlwaysNonEditable
405    };
406    bool isContentEditable(UserSelectAllTreatment = UserSelectAllDoesNotAffectEditability);
407    bool isContentRichlyEditable();
408
409    bool hasEditableStyle(EditableType editableType = ContentIsEditable, UserSelectAllTreatment treatment = UserSelectAllIsAlwaysNonEditable) const
410    {
411        switch (editableType) {
412        case ContentIsEditable:
413            return hasEditableStyle(Editable, treatment);
414        case HasEditableAXRole:
415            return isEditableToAccessibility(Editable);
416        }
417        ASSERT_NOT_REACHED();
418        return false;
419    }
420
421    bool rendererIsRichlyEditable(EditableType editableType = ContentIsEditable) const
422    {
423        switch (editableType) {
424        case ContentIsEditable:
425            return hasEditableStyle(RichlyEditable, UserSelectAllIsAlwaysNonEditable);
426        case HasEditableAXRole:
427            return isEditableToAccessibility(RichlyEditable);
428        }
429        ASSERT_NOT_REACHED();
430        return false;
431    }
432
433    virtual LayoutRect boundingBox() const;
434    IntRect pixelSnappedBoundingBox() const { return pixelSnappedIntRect(boundingBox()); }
435
436    // Returns true if the node has a non-empty bounding box in layout.
437    // This does not 100% guarantee the user can see it, but is pretty close.
438    // Note: This method only works properly after layout has occurred.
439    bool hasNonEmptyBoundingBox() const;
440
441    unsigned nodeIndex() const;
442
443    // Returns the DOM ownerDocument attribute. This method never returns NULL, except in the case
444    // of a Document node.
445    Document* ownerDocument() const;
446
447    // Returns the document associated with this node. A Document node returns itself.
448    Document& document() const
449    {
450        return treeScope().document();
451    }
452
453    TreeScope& treeScope() const
454    {
455        ASSERT(m_treeScope);
456        return *m_treeScope;
457    }
458
459    bool inActiveDocument() const;
460
461    // Returns true if this node is associated with a document and is in its associated document's
462    // node tree, false otherwise.
463    bool inDocument() const
464    {
465        return getFlag(InDocumentFlag);
466    }
467    bool isInShadowTree() const { return getFlag(IsInShadowTreeFlag); }
468    bool isInTreeScope() const { return getFlag(static_cast<NodeFlags>(InDocumentFlag | IsInShadowTreeFlag)); }
469
470    bool isDocumentTypeNode() const { return nodeType() == DOCUMENT_TYPE_NODE; }
471    virtual bool childTypeAllowed(NodeType) const { return false; }
472    unsigned countChildren() const;
473
474    bool isDescendantOf(const Node*) const;
475    bool contains(const Node*) const;
476    bool containsIncludingShadowDOM(const Node*) const;
477    bool containsIncludingHostElements(const Node&) const;
478    Node* commonAncestor(const Node&, Node* (*parent)(const Node&));
479
480    // Used to determine whether range offsets use characters or node indices.
481    virtual bool offsetInCharacters() const;
482    // Number of DOM 16-bit units contained in node. Note that rendered text length can be different - e.g. because of
483    // css-transform:capitalize breaking up precomposed characters and ligatures.
484    virtual int maxCharacterOffset() const;
485
486    // Whether or not a selection can be started in this object
487    virtual bool canStartSelection() const;
488
489    // -----------------------------------------------------------------------------
490    // Integration with rendering tree
491
492    // As renderer() includes a branch you should avoid calling it repeatedly in hot code paths.
493    // Note that if a Node has a renderer, it's parentNode is guaranteed to have one as well.
494    RenderObject* renderer() const { return hasRareData() ? m_data.m_rareData->renderer() : m_data.m_renderer; };
495    void setRenderer(RenderObject* renderer)
496    {
497        if (hasRareData())
498            m_data.m_rareData->setRenderer(renderer);
499        else
500            m_data.m_renderer = renderer;
501    }
502
503    // Use these two methods with caution.
504    RenderBox* renderBox() const;
505    RenderBoxModelObject* renderBoxModelObject() const;
506
507    struct AttachContext {
508        RenderStyle* resolvedStyle;
509        bool performingReattach;
510
511        AttachContext() : resolvedStyle(0), performingReattach(false) { }
512    };
513
514    // Attaches this node to the rendering tree. This calculates the style to be applied to the node and creates an
515    // appropriate RenderObject which will be inserted into the tree (except when the style has display: none). This
516    // makes the node visible in the FrameView.
517    virtual void attach(const AttachContext& = AttachContext());
518
519    // Detaches the node from the rendering tree, making it invisible in the rendered view. This method will remove
520    // the node's rendering object from the rendering tree and delete it.
521    virtual void detach(const AttachContext& = AttachContext());
522
523#if ENABLE(ASSERT)
524    bool inDetach() const;
525#endif
526
527    void reattach(const AttachContext& = AttachContext());
528    void lazyReattachIfAttached();
529
530    // Returns true if recalcStyle should be called on the object, if there is such a method (on Document and Element).
531    bool shouldCallRecalcStyle(StyleRecalcChange);
532
533    // Wrapper for nodes that don't have a renderer, but still cache the style (like HTMLOptionElement).
534    RenderStyle* renderStyle() const;
535    RenderStyle* parentRenderStyle() const;
536
537    RenderStyle* computedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) { return virtualComputedStyle(pseudoElementSpecifier); }
538
539    // -----------------------------------------------------------------------------
540    // Notification of document structure changes (see ContainerNode.h for more notification methods)
541    //
542    // At first, WebKit notifies the node that it has been inserted into the document. This is called during document parsing, and also
543    // 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.
544    // This is similar to the DOMNodeInsertedIntoDocument DOM event, but does not require the overhead of event
545    // dispatching.
546    //
547    // WebKit notifies this callback regardless if the subtree of the node is a document tree or a floating subtree.
548    // Implementation can determine the type of subtree by seeing insertionPoint->inDocument().
549    // For a performance reason, notifications are delivered only to ContainerNode subclasses if the insertionPoint is out of document.
550    //
551    // There are another callback named didNotifySubtreeInsertionsToDocument(), which is called after all the descendant is notified,
552    // if this node was inserted into the document tree. Only a few subclasses actually need this. To utilize this, the node should
553    // return InsertionShouldCallDidNotifySubtreeInsertions from insertedInto().
554    //
555    enum InsertionNotificationRequest {
556        InsertionDone,
557        InsertionShouldCallDidNotifySubtreeInsertions
558    };
559
560    virtual InsertionNotificationRequest insertedInto(ContainerNode* insertionPoint);
561    virtual void didNotifySubtreeInsertionsToDocument() { }
562
563    // Notifies the node that it is no longer part of the tree.
564    //
565    // This is a dual of insertedInto(), and is similar to the DOMNodeRemovedFromDocument DOM event, but does not require the overhead of event
566    // dispatching, and is called _after_ the node is removed from the tree.
567    //
568    virtual void removedFrom(ContainerNode* insertionPoint);
569
570    String debugName() const;
571
572#ifndef NDEBUG
573    virtual void formatForDebugger(char* buffer, unsigned length) const;
574
575    void showNode(const char* prefix = "") const;
576    void showTreeForThis() const;
577    void showNodePathForThis() const;
578    void showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2 = 0, const char* markedLabel2 = 0) const;
579    void showTreeForThisAcrossFrame() const;
580#endif
581
582    NodeListsNodeData* nodeLists();
583    void clearNodeLists();
584
585    virtual bool willRespondToMouseMoveEvents();
586    virtual bool willRespondToMouseClickEvents();
587    virtual bool willRespondToTouchEvents();
588
589    enum ShadowTreesTreatment {
590        TreatShadowTreesAsDisconnected,
591        TreatShadowTreesAsComposed
592    };
593
594    unsigned short compareDocumentPosition(const Node*, ShadowTreesTreatment = TreatShadowTreesAsDisconnected) const;
595
596    virtual Node* toNode() OVERRIDE FINAL;
597
598    virtual const AtomicString& interfaceName() const OVERRIDE;
599    virtual ExecutionContext* executionContext() const OVERRIDE FINAL;
600
601    virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture = false) OVERRIDE;
602    virtual bool removeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture = false) OVERRIDE;
603    virtual void removeAllEventListeners() OVERRIDE;
604    void removeAllEventListenersRecursively();
605
606    // Handlers to do/undo actions on the target node before an event is dispatched to it and after the event
607    // has been dispatched.  The data pointer is handed back by the preDispatch and passed to postDispatch.
608    virtual void* preDispatchEventHandler(Event*) { return 0; }
609    virtual void postDispatchEventHandler(Event*, void* /*dataFromPreDispatch*/) { }
610
611    using EventTarget::dispatchEvent;
612    virtual bool dispatchEvent(PassRefPtrWillBeRawPtr<Event>) OVERRIDE;
613
614    void dispatchScopedEvent(PassRefPtrWillBeRawPtr<Event>);
615    void dispatchScopedEventDispatchMediator(PassRefPtrWillBeRawPtr<EventDispatchMediator>);
616
617    virtual void handleLocalEvents(Event*);
618
619    void dispatchSubtreeModifiedEvent();
620    bool dispatchDOMActivateEvent(int detail, PassRefPtrWillBeRawPtr<Event> underlyingEvent);
621
622    bool dispatchKeyEvent(const PlatformKeyboardEvent&);
623    bool dispatchWheelEvent(const PlatformWheelEvent&);
624    bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType, int clickCount = 0, Node* relatedTarget = 0);
625    bool dispatchGestureEvent(const PlatformGestureEvent&);
626    bool dispatchTouchEvent(PassRefPtrWillBeRawPtr<TouchEvent>);
627
628    void dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions = SendNoEvents);
629
630    void dispatchInputEvent();
631
632    // Perform the default action for an event.
633    virtual void defaultEventHandler(Event*);
634    virtual void willCallDefaultEventHandler(const Event&);
635
636    virtual EventTargetData* eventTargetData() OVERRIDE;
637    virtual EventTargetData& ensureEventTargetData() OVERRIDE;
638
639    void getRegisteredMutationObserversOfType(WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>&, MutationObserver::MutationType, const QualifiedName* attributeName);
640    void registerMutationObserver(MutationObserver&, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
641    void unregisterMutationObserver(MutationObserverRegistration*);
642    void registerTransientMutationObserver(MutationObserverRegistration*);
643    void unregisterTransientMutationObserver(MutationObserverRegistration*);
644    void notifyMutationObserversNodeWillDetach();
645
646    unsigned connectedSubframeCount() const;
647    void incrementConnectedSubframeCount(unsigned amount = 1);
648    void decrementConnectedSubframeCount(unsigned amount = 1);
649    void updateAncestorConnectedSubframeCountForRemoval() const;
650    void updateAncestorConnectedSubframeCountForInsertion() const;
651
652    PassRefPtrWillBeRawPtr<StaticNodeList> getDestinationInsertionPoints();
653
654    void setAlreadySpellChecked(bool flag) { setFlag(flag, AlreadySpellCheckedFlag); }
655    bool isAlreadySpellChecked() { return getFlag(AlreadySpellCheckedFlag); }
656
657    bool isFinishedParsingChildren() const { return getFlag(IsFinishedParsingChildrenFlag); }
658
659    virtual void trace(Visitor*) OVERRIDE;
660
661    unsigned lengthOfContents() const;
662
663    virtual v8::Handle<v8::Object> wrap(v8::Handle<v8::Object> creationContext, v8::Isolate*) OVERRIDE;
664    virtual v8::Handle<v8::Object> associateWithWrapper(const WrapperTypeInfo*, v8::Handle<v8::Object> wrapper, v8::Isolate*) OVERRIDE;
665
666private:
667    enum NodeFlags {
668        HasRareDataFlag = 1,
669
670        // Node type flags. These never change once created.
671        IsTextFlag = 1 << 1,
672        IsContainerFlag = 1 << 2,
673        IsElementFlag = 1 << 3,
674        IsHTMLFlag = 1 << 4,
675        IsSVGFlag = 1 << 5,
676        IsDocumentFragmentFlag = 1 << 6,
677        IsInsertionPointFlag = 1 << 7,
678
679        // Changes based on if the element should be treated like a link,
680        // ex. When setting the href attribute on an <a>.
681        IsLinkFlag = 1 << 8,
682
683        // Changes based on :hover, :active and :focus state.
684        IsUserActionElementFlag = 1 << 9,
685
686        // Tree state flags. These change when the element is added/removed
687        // from a DOM tree.
688        InDocumentFlag = 1 << 10,
689        IsInShadowTreeFlag = 1 << 11,
690
691        // Set by the parser when the children are done parsing.
692        IsFinishedParsingChildrenFlag = 1 << 12,
693
694        // Flags related to recalcStyle.
695        SVGFilterNeedsLayerUpdateFlag = 1 << 13,
696        HasCustomStyleCallbacksFlag = 1 << 14,
697        ChildNeedsStyleInvalidationFlag = 1 << 15,
698        NeedsStyleInvalidationFlag = 1 << 16,
699        ChildNeedsDistributionRecalcFlag = 1 << 17,
700        ChildNeedsStyleRecalcFlag = 1 << 18,
701        StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1),
702
703        CustomElementFlag = 1 << 21,
704        CustomElementUpgradedFlag = 1 << 22,
705
706        HasNameOrIsEditingTextFlag = 1 << 23,
707        HasWeakReferencesFlag = 1 << 24,
708        V8CollectableDuringMinorGCFlag = 1 << 25,
709        HasSyntheticAttrChildNodesFlag = 1 << 26,
710        HasEventTargetDataFlag = 1 << 27,
711        AlreadySpellCheckedFlag = 1 << 28,
712
713        // HTML dir=auto.
714        SelfOrAncestorHasDirAutoFlag = 1 << 29,
715
716        DefaultNodeFlags = IsFinishedParsingChildrenFlag | ChildNeedsStyleRecalcFlag | NeedsReattachStyleChange
717    };
718
719    // 2 bits remaining.
720
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; }
725
726protected:
727    enum ConstructionType {
728        CreateOther = DefaultNodeFlags,
729        CreateText = DefaultNodeFlags | IsTextFlag,
730        CreateContainer = DefaultNodeFlags | 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,
739    };
740
741    Node(TreeScope*, ConstructionType);
742
743    virtual void didMoveToNewDocument(Document& oldDocument);
744
745    static void reattachWhitespaceSiblings(Text* start);
746
747#if !ENABLE(OILPAN)
748    void willBeDeletedFromDocument();
749#endif
750
751    bool hasRareData() const { return getFlag(HasRareDataFlag); }
752
753    NodeRareData* rareData() const;
754    NodeRareData& ensureRareData();
755#if !ENABLE(OILPAN)
756    void clearRareData();
757
758    void clearEventTargetData();
759#endif
760
761    void setHasCustomStyleCallbacks() { setFlag(true, HasCustomStyleCallbacksFlag); }
762
763    void setTreeScope(TreeScope* scope) { m_treeScope = scope; }
764
765    // isTreeScopeInitialized() can be false
766    // - in the destruction of Document or ShadowRoot where m_treeScope is set to null or
767    // - in the Node constructor called by these two classes where m_treeScope is set by TreeScope ctor.
768    bool isTreeScopeInitialized() const { return m_treeScope; }
769
770    void markAncestorsWithChildNeedsStyleRecalc();
771
772    void setIsFinishedParsingChildren(bool value) { setFlag(value, IsFinishedParsingChildrenFlag); }
773
774private:
775    friend class TreeShared<Node>;
776    friend class WeakNodeMap;
777
778    unsigned styledSubtreeSize() const;
779
780#if !ENABLE(OILPAN)
781    void removedLastRef();
782#endif
783    bool hasTreeSharedParent() const { return !!parentOrShadowHostNode(); }
784
785    enum EditableLevel { Editable, RichlyEditable };
786    bool hasEditableStyle(EditableLevel, UserSelectAllTreatment = UserSelectAllIsAlwaysNonEditable) const;
787    bool isEditableToAccessibility(EditableLevel) const;
788
789    bool isUserActionElementActive() const;
790    bool isUserActionElementInActiveChain() const;
791    bool isUserActionElementHovered() const;
792    bool isUserActionElementFocused() const;
793
794    void traceStyleChange(StyleChangeType);
795    void traceStyleChangeIfNeeded(StyleChangeType);
796    void setStyleChange(StyleChangeType);
797
798    virtual RenderStyle* nonRendererStyle() const { return 0; }
799
800    virtual RenderStyle* virtualComputedStyle(PseudoId = NOPSEUDO);
801
802    void trackForDebugging();
803
804    WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* mutationObserverRegistry();
805    WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* transientMutationObserverRegistry();
806
807    uint32_t m_nodeFlags;
808    RawPtrWillBeMember<ContainerNode> m_parentOrShadowHostNode;
809    RawPtrWillBeMember<TreeScope> m_treeScope;
810    RawPtrWillBeMember<Node> m_previous;
811    RawPtrWillBeMember<Node> m_next;
812    // When a node has rare data we move the renderer into the rare data.
813    union DataUnion {
814        DataUnion() : m_renderer(0) { }
815        RenderObject* m_renderer;
816        NodeRareDataBase* m_rareData;
817    } m_data;
818};
819
820inline void Node::setParentOrShadowHostNode(ContainerNode* parent)
821{
822    ASSERT(isMainThread());
823    m_parentOrShadowHostNode = parent;
824}
825
826inline ContainerNode* Node::parentOrShadowHostNode() const
827{
828    ASSERT(isMainThread());
829    return m_parentOrShadowHostNode;
830}
831
832inline ContainerNode* Node::parentNode() const
833{
834    return isShadowRoot() ? 0 : parentOrShadowHostNode();
835}
836
837inline void Node::lazyReattachIfAttached()
838{
839    if (styleChangeType() == NeedsReattachStyleChange)
840        return;
841    if (!inActiveDocument())
842        return;
843
844    AttachContext context;
845    context.performingReattach = true;
846
847    detach(context);
848    markAncestorsWithChildNeedsStyleRecalc();
849}
850
851inline bool Node::shouldCallRecalcStyle(StyleRecalcChange change)
852{
853    return change >= Inherit || needsStyleRecalc() || childNeedsStyleRecalc();
854}
855
856inline bool isTreeScopeRoot(const Node* node)
857{
858    return !node || node->isDocumentNode() || node->isShadowRoot();
859}
860
861inline bool isTreeScopeRoot(const Node& node)
862{
863    return node.isDocumentNode() || node.isShadowRoot();
864}
865
866// Allow equality comparisons of Nodes by reference or pointer, interchangeably.
867DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES_REFCOUNTED(Node)
868
869
870#define DEFINE_NODE_TYPE_CASTS(thisType, predicate) \
871    template<typename T> inline thisType* to##thisType(const RefPtr<T>& node) { return to##thisType(node.get()); } \
872    DEFINE_TYPE_CASTS(thisType, Node, node, node->predicate, node.predicate)
873
874// This requires isClassName(const Node&).
875#define DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(thisType) \
876    template<typename T> inline thisType* to##thisType(const RefPtr<T>& node) { return to##thisType(node.get()); } \
877    DEFINE_TYPE_CASTS(thisType, Node, node, is##thisType(*node), is##thisType(node))
878
879#define DECLARE_NODE_FACTORY(T) \
880    static PassRefPtrWillBeRawPtr<T> create(Document&)
881#define DEFINE_NODE_FACTORY(T) \
882PassRefPtrWillBeRawPtr<T> T::create(Document& document) \
883{ \
884    return adoptRefWillBeNoop(new T(document)); \
885}
886
887} // namespace blink
888
889#ifndef NDEBUG
890// Outside the WebCore namespace for ease of invocation from gdb.
891void showNode(const blink::Node*);
892void showTree(const blink::Node*);
893void showNodePath(const blink::Node*);
894#endif
895
896#endif // Node_h
897