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 "EditingBoundary.h"
29#include "EventTarget.h"
30#include "KURLHash.h"
31#include "LayoutRect.h"
32#include "MutationObserver.h"
33#include "RenderStyleConstants.h"
34#include "ScriptWrappable.h"
35#include "SimulatedClickOptions.h"
36#include "TreeScope.h"
37#include "TreeShared.h"
38#include <wtf/Forward.h>
39#include <wtf/ListHashSet.h>
40#include <wtf/text/AtomicString.h>
41
42namespace JSC {
43    class VM;
44    class SlotVisitor;
45}
46
47// This needs to be here because Document.h also depends on it.
48#define DUMP_NODE_STATISTICS 0
49
50namespace WebCore {
51
52class Attribute;
53class ClassNodeList;
54class ContainerNode;
55class DOMSettableTokenList;
56class Document;
57class Element;
58class Event;
59class EventContext;
60class EventDispatchMediator;
61class EventListener;
62class FloatPoint;
63class Frame;
64class HTMLInputElement;
65class IntRect;
66class KeyboardEvent;
67class NSResolver;
68class NamedNodeMap;
69class NameNodeList;
70class NodeList;
71class NodeListsNodeData;
72class NodeRareData;
73class NodeRenderingContext;
74class PlatformKeyboardEvent;
75class PlatformMouseEvent;
76class PlatformWheelEvent;
77class QualifiedName;
78class RadioNodeList;
79class RegisteredEventListener;
80class RenderArena;
81class RenderBox;
82class RenderBoxModelObject;
83class RenderObject;
84class RenderStyle;
85class ShadowRoot;
86class TagNodeList;
87
88#if ENABLE(GESTURE_EVENTS)
89class PlatformGestureEvent;
90#endif
91
92#if ENABLE(TOUCH_EVENTS)
93class TouchEvent;
94#endif
95
96#if ENABLE(MICRODATA)
97class HTMLPropertiesCollection;
98class PropertyNodeList;
99#endif
100
101typedef int ExceptionCode;
102
103const int nodeStyleChangeShift = 15;
104
105// SyntheticStyleChange means that we need to go through the entire style change logic even though
106// no style property has actually changed. It is used to restructure the tree when, for instance,
107// RenderLayers are created or destroyed due to animation changes.
108enum StyleChangeType {
109    NoStyleChange = 0,
110    InlineStyleChange = 1 << nodeStyleChangeShift,
111    FullStyleChange = 2 << nodeStyleChangeShift,
112    SyntheticStyleChange = 3 << nodeStyleChangeShift
113};
114
115class NodeRareDataBase {
116public:
117    RenderObject* renderer() const { return m_renderer; }
118    void setRenderer(RenderObject* renderer) { m_renderer = renderer; }
119
120protected:
121    NodeRareDataBase(RenderObject* renderer)
122        : m_renderer(renderer)
123    { }
124
125private:
126    RenderObject* m_renderer;
127};
128
129enum AttachBehavior {
130    AttachNow,
131    AttachLazily,
132};
133
134class Node : public EventTarget, public ScriptWrappable, public TreeShared<Node> {
135    friend class Document;
136    friend class TreeScope;
137    friend class TreeScopeAdopter;
138
139public:
140    enum NodeType {
141        ELEMENT_NODE = 1,
142        ATTRIBUTE_NODE = 2,
143        TEXT_NODE = 3,
144        CDATA_SECTION_NODE = 4,
145        ENTITY_REFERENCE_NODE = 5,
146        ENTITY_NODE = 6,
147        PROCESSING_INSTRUCTION_NODE = 7,
148        COMMENT_NODE = 8,
149        DOCUMENT_NODE = 9,
150        DOCUMENT_TYPE_NODE = 10,
151        DOCUMENT_FRAGMENT_NODE = 11,
152        NOTATION_NODE = 12,
153        XPATH_NAMESPACE_NODE = 13,
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    static bool isSupported(const String& feature, const String& version);
166
167    static void startIgnoringLeaks();
168    static void stopIgnoringLeaks();
169
170    static void dumpStatistics();
171
172    enum StyleChange { NoChange, NoInherit, Inherit, Detach, Force };
173    static StyleChange diff(const RenderStyle*, const RenderStyle*, Document*);
174
175    virtual ~Node();
176    void willBeDeletedFrom(Document*);
177
178    // DOM methods & attributes for Node
179
180    bool hasTagName(const QualifiedName&) const;
181    bool hasLocalName(const AtomicString&) const;
182    virtual String nodeName() const = 0;
183    virtual String nodeValue() const;
184    virtual void setNodeValue(const String&, ExceptionCode&);
185    virtual NodeType nodeType() const = 0;
186    ContainerNode* parentNode() const;
187    Element* parentElement() const;
188    Node* previousSibling() const { return m_previous; }
189    Node* nextSibling() const { return m_next; }
190    PassRefPtr<NodeList> childNodes();
191    Node* firstChild() const;
192    Node* lastChild() const;
193    bool hasAttributes() const;
194    NamedNodeMap* attributes() const;
195    Node* pseudoAwareNextSibling() const;
196    Node* pseudoAwarePreviousSibling() const;
197    Node* pseudoAwareFirstChild() const;
198    Node* pseudoAwareLastChild() const;
199
200    virtual KURL baseURI() const;
201
202    void getSubresourceURLs(ListHashSet<KURL>&) const;
203
204    // These should all actually return a node, but this is only important for language bindings,
205    // which will already know and hold a ref on the right node to return. Returning bool allows
206    // these methods to be more efficient since they don't need to return a ref
207    bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&, AttachBehavior = AttachNow);
208    bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&, AttachBehavior = AttachNow);
209    bool removeChild(Node* child, ExceptionCode&);
210    bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, AttachBehavior = AttachNow);
211
212    void remove(ExceptionCode&);
213    bool hasChildNodes() const { return firstChild(); }
214    virtual PassRefPtr<Node> cloneNode(bool deep) = 0;
215    virtual const AtomicString& localName() const;
216    virtual const AtomicString& namespaceURI() const;
217    virtual const AtomicString& prefix() const;
218    virtual void setPrefix(const AtomicString&, ExceptionCode&);
219    void normalize();
220
221    bool isSameNode(Node* other) const { return this == other; }
222    bool isEqualNode(Node*) const;
223    bool isDefaultNamespace(const AtomicString& namespaceURI) const;
224    String lookupPrefix(const AtomicString& namespaceURI) const;
225    String lookupNamespaceURI(const String& prefix) const;
226    String lookupNamespacePrefix(const AtomicString& namespaceURI, const Element* originalElement) const;
227
228    String textContent(bool convertBRsToNewlines = false) const;
229    void setTextContent(const String&, ExceptionCode&);
230
231    Node* lastDescendant() const;
232    Node* firstDescendant() const;
233
234    // Other methods (not part of DOM)
235
236    bool isElementNode() const { return getFlag(IsElementFlag); }
237    bool isContainerNode() const { return getFlag(IsContainerFlag); }
238    bool isTextNode() const { return getFlag(IsTextFlag); }
239    bool isHTMLElement() const { return getFlag(IsHTMLFlag); }
240    bool isSVGElement() const { return getFlag(IsSVGFlag); }
241
242    bool isPseudoElement() const { return pseudoId() != NOPSEUDO; }
243    bool isBeforePseudoElement() const { return pseudoId() == BEFORE; }
244    bool isAfterPseudoElement() const { return pseudoId() == AFTER; }
245    PseudoId pseudoId() const { return (isElementNode() && hasCustomStyleCallbacks()) ? customPseudoId() : NOPSEUDO; }
246
247    virtual bool isMediaControlElement() const { return false; }
248    virtual bool isMediaControls() const { return false; }
249#if ENABLE(VIDEO_TRACK)
250    virtual bool isWebVTTElement() const { return false; }
251#endif
252    bool isStyledElement() const { return getFlag(IsStyledElementFlag); }
253    virtual bool isAttributeNode() const { return false; }
254    virtual bool isCharacterDataNode() const { return false; }
255    virtual bool isFrameOwnerElement() const { return false; }
256    virtual bool isPluginElement() const { return false; }
257    virtual bool isInsertionPointNode() const { return false; }
258
259    bool isDocumentNode() const;
260    bool isTreeScope() const;
261    bool isDocumentFragment() const { return getFlag(IsDocumentFragmentFlag); }
262    bool isShadowRoot() const { return isDocumentFragment() && isTreeScope(); }
263    bool isInsertionPoint() const { return getFlag(NeedsShadowTreeWalkerFlag) && isInsertionPointNode(); }
264    // Returns Node rather than InsertionPoint. Should be used only for language bindings.
265    Node* insertionParentForBinding() const;
266
267    bool needsShadowTreeWalker() const;
268    bool needsShadowTreeWalkerSlow() const;
269    void setNeedsShadowTreeWalker() { setFlag(NeedsShadowTreeWalkerFlag); }
270    void resetNeedsShadowTreeWalker() { setFlag(needsShadowTreeWalkerSlow(), NeedsShadowTreeWalkerFlag); }
271
272    bool inNamedFlow() const { return getFlag(InNamedFlowFlag); }
273    bool hasCustomStyleCallbacks() const { return getFlag(HasCustomStyleCallbacksFlag); }
274
275    bool isRegisteredWithNamedFlow() const;
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    // If this node is in a shadow tree, returns its shadow host. Otherwise, returns this.
283    // Deprecated. Should use shadowHost() and check the return value.
284    Node* deprecatedShadowAncestorNode() const;
285    ShadowRoot* containingShadowRoot() const;
286    ShadowRoot* shadowRoot() const;
287
288    // Returns 0, a child of ShadowRoot, or a legacy shadow root.
289    Node* nonBoundaryShadowTreeRootNode();
290
291    // Node's parent, shadow tree host.
292    ContainerNode* parentOrShadowHostNode() const;
293    Element* parentOrShadowHostElement() const;
294    void setParentOrShadowHostNode(ContainerNode*);
295    Node* highestAncestor() const;
296
297    // Use when it's guaranteed to that shadowHost is 0.
298    ContainerNode* parentNodeGuaranteedHostFree() const;
299    // Returns the parent node, but 0 if the parent node is a ShadowRoot.
300    ContainerNode* nonShadowBoundaryParentNode() const;
301
302    bool selfOrAncestorHasDirAutoAttribute() const { return getFlag(SelfOrAncestorHasDirAutoFlag); }
303    void setSelfOrAncestorHasDirAutoAttribute(bool flag) { setFlag(flag, SelfOrAncestorHasDirAutoFlag); }
304
305    // Returns the enclosing event parent node (or self) that, when clicked, would trigger a navigation.
306    Node* enclosingLinkEventParentOrSelf();
307
308    // These low-level calls give the caller responsibility for maintaining the integrity of the tree.
309    void setPreviousSibling(Node* previous) { m_previous = previous; }
310    void setNextSibling(Node* next) { m_next = next; }
311
312    virtual bool canContainRangeEndPoint() const { return false; }
313
314    bool isRootEditableElement() const;
315    Element* rootEditableElement() const;
316    Element* rootEditableElement(EditableType) const;
317
318    // Called by the parser when this element's close tag is reached,
319    // signaling that all child tags have been parsed and added.
320    // This is needed for <applet> and <object> elements, which can't lay themselves out
321    // until they know all of their nested <param>s. [Radar 3603191, 4040848].
322    // Also used for script elements and some SVG elements for similar purposes,
323    // but making parsing a special case in this respect should be avoided if possible.
324    virtual void finishParsingChildren() { }
325    virtual void beginParsingChildren() { }
326
327    // For <link> and <style> elements.
328    virtual bool sheetLoaded() { return true; }
329    virtual void notifyLoadedSheetAndAllCriticalSubresources(bool /* error loading subresource */) { }
330    virtual void startLoadingDynamicSheet() { ASSERT_NOT_REACHED(); }
331
332    bool isUserActionElement() const { return getFlag(IsUserActionElement); }
333    void setUserActionElement(bool flag) { setFlag(flag, IsUserActionElement); }
334
335    bool attached() const { return getFlag(IsAttachedFlag); }
336    void setAttached() { setFlag(IsAttachedFlag); }
337    bool needsStyleRecalc() const { return styleChangeType() != NoStyleChange; }
338    StyleChangeType styleChangeType() const { return static_cast<StyleChangeType>(m_nodeFlags & StyleChangeMask); }
339    bool childNeedsStyleRecalc() const { return getFlag(ChildNeedsStyleRecalcFlag); }
340    bool isLink() const { return getFlag(IsLinkFlag); }
341    bool isEditingText() const { return getFlag(IsEditingTextFlag); }
342
343    void setChildNeedsStyleRecalc() { setFlag(ChildNeedsStyleRecalcFlag); }
344    void clearChildNeedsStyleRecalc() { clearFlag(ChildNeedsStyleRecalcFlag); }
345
346    void setNeedsStyleRecalc(StyleChangeType changeType = FullStyleChange);
347    void clearNeedsStyleRecalc() { m_nodeFlags &= ~StyleChangeMask; }
348    virtual void scheduleSetNeedsStyleRecalc(StyleChangeType changeType = FullStyleChange) { setNeedsStyleRecalc(changeType); }
349
350    void setIsLink(bool f) { setFlag(f, IsLinkFlag); }
351    void setIsLink() { setFlag(IsLinkFlag); }
352    void clearIsLink() { clearFlag(IsLinkFlag); }
353
354    void setInNamedFlow() { setFlag(InNamedFlowFlag); }
355    void clearInNamedFlow() { clearFlag(InNamedFlowFlag); }
356
357    bool hasScopedHTMLStyleChild() const { return getFlag(HasScopedHTMLStyleChildFlag); }
358    void setHasScopedHTMLStyleChild(bool flag) { setFlag(flag, HasScopedHTMLStyleChildFlag); }
359
360    bool hasEventTargetData() const { return getFlag(HasEventTargetDataFlag); }
361    void setHasEventTargetData(bool flag) { setFlag(flag, HasEventTargetDataFlag); }
362
363    enum ShouldSetAttached {
364        SetAttached,
365        DoNotSetAttached
366    };
367    void lazyAttach(ShouldSetAttached = SetAttached);
368    void lazyReattach(ShouldSetAttached = SetAttached);
369
370    enum UserSelectAllTreatment {
371        UserSelectAllDoesNotAffectEditability,
372        UserSelectAllIsAlwaysNonEditable
373    };
374    bool isContentEditable(UserSelectAllTreatment = UserSelectAllDoesNotAffectEditability);
375    bool isContentRichlyEditable();
376
377    void inspect();
378
379    bool rendererIsEditable(EditableType editableType = ContentIsEditable, UserSelectAllTreatment treatment = UserSelectAllIsAlwaysNonEditable) const
380    {
381        switch (editableType) {
382        case ContentIsEditable:
383            return rendererIsEditable(Editable, treatment);
384        case HasEditableAXRole:
385            return isEditableToAccessibility(Editable);
386        }
387        ASSERT_NOT_REACHED();
388        return false;
389    }
390
391    bool rendererIsRichlyEditable(EditableType editableType = ContentIsEditable) const
392    {
393        switch (editableType) {
394        case ContentIsEditable:
395            return rendererIsEditable(RichlyEditable, UserSelectAllIsAlwaysNonEditable);
396        case HasEditableAXRole:
397            return isEditableToAccessibility(RichlyEditable);
398        }
399        ASSERT_NOT_REACHED();
400        return false;
401    }
402
403    virtual LayoutRect boundingBox() const;
404    IntRect pixelSnappedBoundingBox() const { return pixelSnappedIntRect(boundingBox()); }
405    LayoutRect renderRect(bool* isReplaced);
406    IntRect pixelSnappedRenderRect(bool* isReplaced) { return pixelSnappedIntRect(renderRect(isReplaced)); }
407
408    unsigned nodeIndex() const;
409
410    // Returns the DOM ownerDocument attribute. This method never returns NULL, except in the case
411    // of (1) a Document node or (2) a DocumentType node that is not used with any Document yet.
412    Document* ownerDocument() const;
413
414    // Returns the document associated with this node. This method never returns NULL, except in the case
415    // of a DocumentType node that is not used with any Document yet. A Document node returns itself.
416    Document* document() const
417    {
418        ASSERT(this);
419        // FIXME: below ASSERT is useful, but prevents the use of document() in the constructor or destructor
420        // due to the virtual function call to nodeType().
421        ASSERT(documentInternal() || (nodeType() == DOCUMENT_TYPE_NODE && !inDocument()));
422        return documentInternal();
423    }
424
425    TreeScope* treeScope() const { return m_treeScope; }
426
427    // Returns true if this node is associated with a document and is in its associated document's
428    // node tree, false otherwise.
429    bool inDocument() const
430    {
431        ASSERT(documentInternal() || !getFlag(InDocumentFlag));
432        return getFlag(InDocumentFlag);
433    }
434    bool isInShadowTree() const { return getFlag(IsInShadowTreeFlag); }
435    bool isInTreeScope() const { return getFlag(static_cast<NodeFlags>(InDocumentFlag | IsInShadowTreeFlag)); }
436
437    bool isReadOnlyNode() const { return nodeType() == ENTITY_REFERENCE_NODE; }
438    bool isDocumentTypeNode() const { return nodeType() == DOCUMENT_TYPE_NODE; }
439    virtual bool childTypeAllowed(NodeType) const { return false; }
440    unsigned childNodeCount() const;
441    Node* childNode(unsigned index) const;
442
443    void checkSetPrefix(const AtomicString& prefix, ExceptionCode&);
444    bool isDescendantOf(const Node*) const;
445    bool contains(const Node*) const;
446    bool containsIncludingShadowDOM(const Node*) const;
447    bool containsIncludingHostElements(const Node*) const;
448
449    // Used to determine whether range offsets use characters or node indices.
450    virtual bool offsetInCharacters() const;
451    // Number of DOM 16-bit units contained in node. Note that rendered text length can be different - e.g. because of
452    // css-transform:capitalize breaking up precomposed characters and ligatures.
453    virtual int maxCharacterOffset() const;
454
455    // Whether or not a selection can be started in this object
456    virtual bool canStartSelection() const;
457
458    // Getting points into and out of screen space
459    FloatPoint convertToPage(const FloatPoint&) const;
460    FloatPoint convertFromPage(const FloatPoint&) const;
461
462    // -----------------------------------------------------------------------------
463    // Integration with rendering tree
464
465    // As renderer() includes a branch you should avoid calling it repeatedly in hot code paths.
466    RenderObject* renderer() const { return hasRareData() ? m_data.m_rareData->renderer() : m_data.m_renderer; };
467    void setRenderer(RenderObject* renderer)
468    {
469        if (hasRareData())
470            m_data.m_rareData->setRenderer(renderer);
471        else
472            m_data.m_renderer = renderer;
473    }
474
475    // Use these two methods with caution.
476    RenderBox* renderBox() const;
477    RenderBoxModelObject* renderBoxModelObject() const;
478
479    struct AttachContext {
480        RenderStyle* resolvedStyle;
481        bool performingReattach;
482
483        AttachContext() : resolvedStyle(0), performingReattach(false) { }
484    };
485
486    // Attaches this node to the rendering tree. This calculates the style to be applied to the node and creates an
487    // appropriate RenderObject which will be inserted into the tree (except when the style has display: none). This
488    // makes the node visible in the FrameView.
489    virtual void attach(const AttachContext& = AttachContext());
490
491    // Detaches the node from the rendering tree, making it invisible in the rendered view. This method will remove
492    // the node's rendering object from the rendering tree and delete it.
493    virtual void detach(const AttachContext& = AttachContext());
494
495#ifndef NDEBUG
496    bool inDetach() const;
497#endif
498
499    void reattach(const AttachContext& = AttachContext());
500    void reattachIfAttached(const AttachContext& = AttachContext());
501    ContainerNode* parentNodeForRenderingAndStyle();
502
503    // Wrapper for nodes that don't have a renderer, but still cache the style (like HTMLOptionElement).
504    RenderStyle* renderStyle() const;
505
506    RenderStyle* computedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) { return virtualComputedStyle(pseudoElementSpecifier); }
507
508    // -----------------------------------------------------------------------------
509    // Notification of document structure changes (see ContainerNode.h for more notification methods)
510    //
511    // At first, WebKit notifies the node that it has been inserted into the document. This is called during document parsing, and also
512    // 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.
513    // This is similar to the DOMNodeInsertedIntoDocument DOM event, but does not require the overhead of event
514    // dispatching.
515    //
516    // WebKit notifies this callback regardless if the subtree of the node is a document tree or a floating subtree.
517    // Implementation can determine the type of subtree by seeing insertionPoint->inDocument().
518    // For a performance reason, notifications are delivered only to ContainerNode subclasses if the insertionPoint is out of document.
519    //
520    // There are another callback named didNotifyDescendantInsertions(), which is called after all the descendant is notified.
521    // Only a few subclasses actually need this. To utilize this, the node should return InsertionShouldCallDidNotifyDescendantInsertions
522    // from insrtedInto().
523    //
524    enum InsertionNotificationRequest {
525        InsertionDone,
526        InsertionShouldCallDidNotifySubtreeInsertions
527    };
528
529    virtual InsertionNotificationRequest insertedInto(ContainerNode* insertionPoint);
530    virtual void didNotifySubtreeInsertions(ContainerNode*) { }
531
532    // Notifies the node that it is no longer part of the tree.
533    //
534    // This is a dual of insertedInto(), and is similar to the DOMNodeRemovedFromDocument DOM event, but does not require the overhead of event
535    // dispatching, and is called _after_ the node is removed from the tree.
536    //
537    virtual void removedFrom(ContainerNode* insertionPoint);
538
539#ifndef NDEBUG
540    virtual void formatForDebugger(char* buffer, unsigned length) const;
541
542    void showNode(const char* prefix = "") const;
543    void showTreeForThis() const;
544    void showNodePathForThis() const;
545    void showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2 = 0, const char* markedLabel2 = 0) const;
546    void showTreeForThisAcrossFrame() const;
547#endif
548
549    void invalidateNodeListCachesInAncestors(const QualifiedName* attrName = 0, Element* attributeOwnerElement = 0);
550    NodeListsNodeData* nodeLists();
551    void clearNodeLists();
552
553    PassRefPtr<NodeList> getElementsByTagName(const AtomicString&);
554    PassRefPtr<NodeList> getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName);
555    PassRefPtr<NodeList> getElementsByName(const String& elementName);
556    PassRefPtr<NodeList> getElementsByClassName(const String& classNames);
557    PassRefPtr<RadioNodeList> radioNodeList(const AtomicString&);
558
559    virtual bool willRespondToMouseMoveEvents();
560    virtual bool willRespondToMouseClickEvents();
561    virtual bool willRespondToTouchEvents();
562
563    PassRefPtr<Element> querySelector(const AtomicString& selectors, ExceptionCode&);
564    PassRefPtr<NodeList> querySelectorAll(const AtomicString& selectors, ExceptionCode&);
565
566    unsigned short compareDocumentPosition(Node*);
567
568    virtual Node* toNode();
569    virtual HTMLInputElement* toInputElement();
570
571    virtual const AtomicString& interfaceName() const;
572    virtual ScriptExecutionContext* scriptExecutionContext() const;
573
574    virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
575    virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
576
577    // Handlers to do/undo actions on the target node before an event is dispatched to it and after the event
578    // has been dispatched.  The data pointer is handed back by the preDispatch and passed to postDispatch.
579    virtual void* preDispatchEventHandler(Event*) { return 0; }
580    virtual void postDispatchEventHandler(Event*, void* /*dataFromPreDispatch*/) { }
581
582    using EventTarget::dispatchEvent;
583    virtual bool dispatchEvent(PassRefPtr<Event>) OVERRIDE;
584
585    void dispatchScopedEvent(PassRefPtr<Event>);
586    void dispatchScopedEventDispatchMediator(PassRefPtr<EventDispatchMediator>);
587
588    virtual void handleLocalEvents(Event*);
589
590    void dispatchSubtreeModifiedEvent();
591    bool dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEvent);
592
593    bool dispatchKeyEvent(const PlatformKeyboardEvent&);
594    bool dispatchWheelEvent(const PlatformWheelEvent&);
595    bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType, int clickCount = 0, Node* relatedTarget = 0);
596#if ENABLE(GESTURE_EVENTS)
597    bool dispatchGestureEvent(const PlatformGestureEvent&);
598#endif
599#if ENABLE(TOUCH_EVENTS)
600    bool dispatchTouchEvent(PassRefPtr<TouchEvent>);
601#endif
602
603    bool dispatchBeforeLoadEvent(const String& sourceURL);
604
605    virtual void dispatchInputEvent();
606
607    // Perform the default action for an event.
608    virtual void defaultEventHandler(Event*);
609
610    using TreeShared<Node>::ref;
611    using TreeShared<Node>::deref;
612
613    virtual EventTargetData* eventTargetData();
614    virtual EventTargetData* ensureEventTargetData();
615
616#if ENABLE(MICRODATA)
617    DOMSettableTokenList* itemProp();
618    DOMSettableTokenList* itemRef();
619    DOMSettableTokenList* itemType();
620    PassRefPtr<PropertyNodeList> propertyNodeList(const String&);
621#endif
622
623    void getRegisteredMutationObserversOfType(HashMap<MutationObserver*, MutationRecordDeliveryOptions>&, MutationObserver::MutationType, const QualifiedName* attributeName);
624    void registerMutationObserver(MutationObserver*, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
625    void unregisterMutationObserver(MutationObserverRegistration*);
626    void registerTransientMutationObserver(MutationObserverRegistration*);
627    void unregisterTransientMutationObserver(MutationObserverRegistration*);
628    void notifyMutationObserversNodeWillDetach();
629
630    virtual void registerScopedHTMLStyleChild();
631    virtual void unregisterScopedHTMLStyleChild();
632    size_t numberOfScopedHTMLStyleChildren() const;
633
634    void textRects(Vector<IntRect>&) const;
635
636    unsigned connectedSubframeCount() const;
637    void incrementConnectedSubframeCount(unsigned amount = 1);
638    void decrementConnectedSubframeCount(unsigned amount = 1);
639    void updateAncestorConnectedSubframeCountForRemoval() const;
640    void updateAncestorConnectedSubframeCountForInsertion() const;
641
642private:
643    enum NodeFlags {
644        IsTextFlag = 1,
645        IsContainerFlag = 1 << 1,
646        IsElementFlag = 1 << 2,
647        IsStyledElementFlag = 1 << 3,
648        IsHTMLFlag = 1 << 4,
649        IsSVGFlag = 1 << 5,
650        IsAttachedFlag = 1 << 6,
651        ChildNeedsStyleRecalcFlag = 1 << 7,
652        InDocumentFlag = 1 << 8,
653        IsLinkFlag = 1 << 9,
654        IsUserActionElement = 1 << 10,
655        HasRareDataFlag = 1 << 11,
656        IsDocumentFragmentFlag = 1 << 12,
657
658        // These bits are used by derived classes, pulled up here so they can
659        // be stored in the same memory word as the Node bits above.
660        IsParsingChildrenFinishedFlag = 1 << 13, // Element
661#if ENABLE(SVG)
662        HasSVGRareDataFlag = 1 << 14, // SVGElement
663#endif
664
665        StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1),
666
667        SelfOrAncestorHasDirAutoFlag = 1 << 17,
668
669        IsEditingTextFlag = 1 << 18,
670
671        InNamedFlowFlag = 1 << 19,
672        HasSyntheticAttrChildNodesFlag = 1 << 20,
673        HasCustomStyleCallbacksFlag = 1 << 21,
674        HasScopedHTMLStyleChildFlag = 1 << 22,
675        HasEventTargetDataFlag = 1 << 23,
676        NeedsShadowTreeWalkerFlag = 1 << 25,
677        IsInShadowTreeFlag = 1 << 26,
678
679        DefaultNodeFlags = IsParsingChildrenFinishedFlag
680    };
681
682    // 5 bits remaining
683
684    bool getFlag(NodeFlags mask) const { return m_nodeFlags & mask; }
685    void setFlag(bool f, NodeFlags mask) const { m_nodeFlags = (m_nodeFlags & ~mask) | (-(int32_t)f & mask); }
686    void setFlag(NodeFlags mask) const { m_nodeFlags |= mask; }
687    void clearFlag(NodeFlags mask) const { m_nodeFlags &= ~mask; }
688
689protected:
690    enum ConstructionType {
691        CreateOther = DefaultNodeFlags,
692        CreateText = DefaultNodeFlags | IsTextFlag,
693        CreateContainer = DefaultNodeFlags | IsContainerFlag,
694        CreateElement = CreateContainer | IsElementFlag,
695        CreatePseudoElement =  CreateElement | InDocumentFlag | NeedsShadowTreeWalkerFlag,
696        CreateShadowRoot = CreateContainer | IsDocumentFragmentFlag | NeedsShadowTreeWalkerFlag | IsInShadowTreeFlag,
697        CreateDocumentFragment = CreateContainer | IsDocumentFragmentFlag,
698        CreateStyledElement = CreateElement | IsStyledElementFlag,
699        CreateHTMLElement = CreateStyledElement | IsHTMLFlag,
700        CreateSVGElement = CreateStyledElement | IsSVGFlag,
701        CreateDocument = CreateContainer | InDocumentFlag,
702        CreateInsertionPoint = CreateHTMLElement | NeedsShadowTreeWalkerFlag,
703        CreateEditingText = CreateText | IsEditingTextFlag,
704    };
705    Node(Document*, ConstructionType);
706
707    virtual void didMoveToNewDocument(Document* oldDocument);
708
709    virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const { }
710
711    bool hasRareData() const { return getFlag(HasRareDataFlag); }
712
713    NodeRareData* rareData() const;
714    NodeRareData* ensureRareData();
715    void clearRareData();
716
717    void clearEventTargetData();
718
719    void setHasCustomStyleCallbacks() { setFlag(true, HasCustomStyleCallbacksFlag); }
720
721    Document* documentInternal() const { return treeScope()->documentScope(); }
722    void setTreeScope(TreeScope* scope) { m_treeScope = scope; }
723
724private:
725    friend class TreeShared<Node>;
726
727    virtual PseudoId customPseudoId() const
728    {
729        ASSERT(hasCustomStyleCallbacks());
730        return NOPSEUDO;
731    }
732
733    void removedLastRef();
734    bool hasTreeSharedParent() const { return !!parentOrShadowHostNode(); }
735
736    enum EditableLevel { Editable, RichlyEditable };
737    bool rendererIsEditable(EditableLevel, UserSelectAllTreatment = UserSelectAllIsAlwaysNonEditable) const;
738    bool isEditableToAccessibility(EditableLevel) const;
739
740    void setStyleChange(StyleChangeType);
741
742    // Used to share code between lazyAttach and setNeedsStyleRecalc.
743    void markAncestorsWithChildNeedsStyleRecalc();
744
745    virtual void refEventTarget();
746    virtual void derefEventTarget();
747
748    virtual RenderStyle* nonRendererStyle() const { return 0; }
749    virtual RenderStyle* virtualComputedStyle(PseudoId = NOPSEUDO);
750
751    Element* ancestorElement() const;
752
753    void trackForDebugging();
754
755    Vector<OwnPtr<MutationObserverRegistration> >* mutationObserverRegistry();
756    HashSet<MutationObserverRegistration*>* transientMutationObserverRegistry();
757
758    mutable uint32_t m_nodeFlags;
759    ContainerNode* m_parentOrShadowHostNode;
760    TreeScope* m_treeScope;
761    Node* m_previous;
762    Node* m_next;
763    // When a node has rare data we move the renderer into the rare data.
764    union DataUnion {
765        DataUnion() : m_renderer(0) { }
766        RenderObject* m_renderer;
767        NodeRareDataBase* m_rareData;
768    } m_data;
769
770protected:
771    bool isParsingChildrenFinished() const { return getFlag(IsParsingChildrenFinishedFlag); }
772    void setIsParsingChildrenFinished() { setFlag(IsParsingChildrenFinishedFlag); }
773    void clearIsParsingChildrenFinished() { clearFlag(IsParsingChildrenFinishedFlag); }
774
775#if ENABLE(SVG)
776    bool hasSVGRareData() const { return getFlag(HasSVGRareDataFlag); }
777    void setHasSVGRareData() { setFlag(HasSVGRareDataFlag); }
778    void clearHasSVGRareData() { clearFlag(HasSVGRareDataFlag); }
779#endif
780
781#if ENABLE(MICRODATA)
782    void setItemProp(const String&);
783    void setItemRef(const String&);
784    void setItemType(const String&);
785#endif
786};
787
788// Used in Node::addSubresourceAttributeURLs() and in addSubresourceStyleURLs()
789inline void addSubresourceURL(ListHashSet<KURL>& urls, const KURL& url)
790{
791    if (!url.isNull())
792        urls.add(url);
793}
794
795inline void Node::setParentOrShadowHostNode(ContainerNode* parent)
796{
797    ASSERT(isMainThread());
798    m_parentOrShadowHostNode = parent;
799}
800
801inline ContainerNode* Node::parentOrShadowHostNode() const
802{
803    ASSERT(isMainThreadOrGCThread());
804    return m_parentOrShadowHostNode;
805}
806
807inline ContainerNode* Node::parentNode() const
808{
809    return isShadowRoot() ? 0 : parentOrShadowHostNode();
810}
811
812inline ContainerNode* Node::parentNodeGuaranteedHostFree() const
813{
814    ASSERT(!isShadowRoot());
815    return parentOrShadowHostNode();
816}
817
818inline void Node::reattach(const AttachContext& context)
819{
820    AttachContext reattachContext(context);
821    reattachContext.performingReattach = true;
822
823    if (attached())
824        detach(reattachContext);
825    attach(reattachContext);
826}
827
828inline void Node::reattachIfAttached(const AttachContext& context)
829{
830    if (attached())
831        reattach(context);
832}
833
834inline void Node::lazyReattach(ShouldSetAttached shouldSetAttached)
835{
836    if (attached())
837        detach();
838    lazyAttach(shouldSetAttached);
839}
840
841} //namespace
842
843#ifndef NDEBUG
844// Outside the WebCore namespace for ease of invocation from gdb.
845void showTree(const WebCore::Node*);
846void showNodePath(const WebCore::Node*);
847#endif
848
849#endif
850