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