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