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