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