• 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 Nokia Corporation and/or its subsidiary(-ies)
7  * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB.  If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24 
25 #include "config.h"
26 #include "core/dom/Node.h"
27 
28 #include "bindings/core/v8/DOMDataStore.h"
29 #include "bindings/core/v8/ExceptionState.h"
30 #include "bindings/core/v8/ScriptCallStackFactory.h"
31 #include "bindings/core/v8/V8DOMWrapper.h"
32 #include "core/HTMLNames.h"
33 #include "core/XMLNames.h"
34 #include "core/accessibility/AXObjectCache.h"
35 #include "core/css/resolver/StyleResolver.h"
36 #include "core/dom/Attr.h"
37 #include "core/dom/Attribute.h"
38 #include "core/dom/ChildListMutationScope.h"
39 #include "core/dom/ChildNodeList.h"
40 #include "core/dom/DOMImplementation.h"
41 #include "core/dom/Document.h"
42 #include "core/dom/DocumentFragment.h"
43 #include "core/dom/DocumentMarkerController.h"
44 #include "core/dom/DocumentType.h"
45 #include "core/dom/Element.h"
46 #include "core/dom/ElementRareData.h"
47 #include "core/dom/ElementTraversal.h"
48 #include "core/dom/ExceptionCode.h"
49 #include "core/dom/LiveNodeList.h"
50 #include "core/dom/NodeRareData.h"
51 #include "core/dom/NodeRenderingTraversal.h"
52 #include "core/dom/NodeTraversal.h"
53 #include "core/dom/ProcessingInstruction.h"
54 #include "core/dom/Range.h"
55 #include "core/dom/StaticNodeList.h"
56 #include "core/dom/TemplateContentDocumentFragment.h"
57 #include "core/dom/Text.h"
58 #include "core/dom/TreeScopeAdopter.h"
59 #include "core/dom/UserActionElementSet.h"
60 #include "core/dom/WeakNodeMap.h"
61 #include "core/dom/shadow/ElementShadow.h"
62 #include "core/dom/shadow/InsertionPoint.h"
63 #include "core/dom/shadow/ShadowRoot.h"
64 #include "core/editing/htmlediting.h"
65 #include "core/editing/markup.h"
66 #include "core/events/Event.h"
67 #include "core/events/EventDispatchMediator.h"
68 #include "core/events/EventDispatcher.h"
69 #include "core/events/EventListener.h"
70 #include "core/events/GestureEvent.h"
71 #include "core/events/KeyboardEvent.h"
72 #include "core/events/MouseEvent.h"
73 #include "core/events/MutationEvent.h"
74 #include "core/events/TextEvent.h"
75 #include "core/events/TouchEvent.h"
76 #include "core/events/UIEvent.h"
77 #include "core/events/WheelEvent.h"
78 #include "core/frame/EventHandlerRegistry.h"
79 #include "core/frame/LocalFrame.h"
80 #include "core/frame/Settings.h"
81 #include "core/html/HTMLAnchorElement.h"
82 #include "core/html/HTMLDialogElement.h"
83 #include "core/html/HTMLFrameOwnerElement.h"
84 #include "core/html/HTMLStyleElement.h"
85 #include "core/page/ContextMenuController.h"
86 #include "core/page/EventHandler.h"
87 #include "core/page/Page.h"
88 #include "core/rendering/FlowThreadController.h"
89 #include "core/rendering/RenderBox.h"
90 #include "core/svg/graphics/SVGImage.h"
91 #include "platform/EventDispatchForbiddenScope.h"
92 #include "platform/Partitions.h"
93 #include "platform/TraceEvent.h"
94 #include "platform/TracedValue.h"
95 #include "wtf/HashSet.h"
96 #include "wtf/PassOwnPtr.h"
97 #include "wtf/RefCountedLeakCounter.h"
98 #include "wtf/Vector.h"
99 #include "wtf/text/CString.h"
100 #include "wtf/text/StringBuilder.h"
101 
102 namespace blink {
103 
104 using namespace HTMLNames;
105 
106 struct SameSizeAsNode : NODE_BASE_CLASSES {
107     uint32_t m_nodeFlags;
108     void* m_pointer[5];
109 };
110 
111 COMPILE_ASSERT(sizeof(Node) <= sizeof(SameSizeAsNode), Node_should_stay_small);
112 
113 #if !ENABLE(OILPAN)
operator new(size_t size)114 void* Node::operator new(size_t size)
115 {
116     ASSERT(isMainThread());
117     return partitionAlloc(Partitions::getObjectModelPartition(), size);
118 }
119 
operator delete(void * ptr)120 void Node::operator delete(void* ptr)
121 {
122     ASSERT(isMainThread());
123     partitionFree(ptr);
124 }
125 #endif
126 
127 #if DUMP_NODE_STATISTICS
128 typedef WillBeHeapHashSet<RawPtrWillBeWeakMember<Node> > WeakNodeSet;
liveNodeSet()129 static WeakNodeSet& liveNodeSet()
130 {
131     DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<WeakNodeSet>, set, (adoptPtrWillBeNoop(new WeakNodeSet())));
132     return *set;
133 }
134 #endif
135 
dumpStatistics()136 void Node::dumpStatistics()
137 {
138 #if DUMP_NODE_STATISTICS
139     size_t nodesWithRareData = 0;
140 
141     size_t elementNodes = 0;
142     size_t attrNodes = 0;
143     size_t textNodes = 0;
144     size_t cdataNodes = 0;
145     size_t commentNodes = 0;
146     size_t piNodes = 0;
147     size_t documentNodes = 0;
148     size_t docTypeNodes = 0;
149     size_t fragmentNodes = 0;
150     size_t shadowRootNodes = 0;
151 
152     HashMap<String, size_t> perTagCount;
153 
154     size_t attributes = 0;
155     size_t elementsWithAttributeStorage = 0;
156     size_t elementsWithRareData = 0;
157     size_t elementsWithNamedNodeMap = 0;
158 
159     for (WeakNodeSet::iterator it = liveNodeSet().begin(); it != liveNodeSet().end(); ++it) {
160         Node* node = *it;
161 
162         if (node->hasRareData()) {
163             ++nodesWithRareData;
164             if (node->isElementNode()) {
165                 ++elementsWithRareData;
166                 if (toElement(node)->hasNamedNodeMap())
167                     ++elementsWithNamedNodeMap;
168             }
169         }
170 
171         switch (node->nodeType()) {
172             case ELEMENT_NODE: {
173                 ++elementNodes;
174 
175                 // Tag stats
176                 Element* element = toElement(node);
177                 HashMap<String, size_t>::AddResult result = perTagCount.add(element->tagName(), 1);
178                 if (!result.isNewEntry)
179                     result.storedValue->value++;
180 
181                 if (const ElementData* elementData = element->elementData()) {
182                     attributes += elementData->attributes().size();
183                     ++elementsWithAttributeStorage;
184                 }
185                 break;
186             }
187             case ATTRIBUTE_NODE: {
188                 ++attrNodes;
189                 break;
190             }
191             case TEXT_NODE: {
192                 ++textNodes;
193                 break;
194             }
195             case CDATA_SECTION_NODE: {
196                 ++cdataNodes;
197                 break;
198             }
199             case COMMENT_NODE: {
200                 ++commentNodes;
201                 break;
202             }
203             case PROCESSING_INSTRUCTION_NODE: {
204                 ++piNodes;
205                 break;
206             }
207             case DOCUMENT_NODE: {
208                 ++documentNodes;
209                 break;
210             }
211             case DOCUMENT_TYPE_NODE: {
212                 ++docTypeNodes;
213                 break;
214             }
215             case DOCUMENT_FRAGMENT_NODE: {
216                 if (node->isShadowRoot())
217                     ++shadowRootNodes;
218                 else
219                     ++fragmentNodes;
220                 break;
221             }
222         }
223     }
224 
225     printf("Number of Nodes: %d\n\n", liveNodeSet().size());
226     printf("Number of Nodes with RareData: %zu\n\n", nodesWithRareData);
227 
228     printf("NodeType distribution:\n");
229     printf("  Number of Element nodes: %zu\n", elementNodes);
230     printf("  Number of Attribute nodes: %zu\n", attrNodes);
231     printf("  Number of Text nodes: %zu\n", textNodes);
232     printf("  Number of CDATASection nodes: %zu\n", cdataNodes);
233     printf("  Number of Comment nodes: %zu\n", commentNodes);
234     printf("  Number of ProcessingInstruction nodes: %zu\n", piNodes);
235     printf("  Number of Document nodes: %zu\n", documentNodes);
236     printf("  Number of DocumentType nodes: %zu\n", docTypeNodes);
237     printf("  Number of DocumentFragment nodes: %zu\n", fragmentNodes);
238     printf("  Number of ShadowRoot nodes: %zu\n", shadowRootNodes);
239 
240     printf("Element tag name distibution:\n");
241     for (HashMap<String, size_t>::iterator it = perTagCount.begin(); it != perTagCount.end(); ++it)
242         printf("  Number of <%s> tags: %zu\n", it->key.utf8().data(), it->value);
243 
244     printf("Attributes:\n");
245     printf("  Number of Attributes (non-Node and Node): %zu [%zu]\n", attributes, sizeof(Attribute));
246     printf("  Number of Elements with attribute storage: %zu [%zu]\n", elementsWithAttributeStorage, sizeof(ElementData));
247     printf("  Number of Elements with RareData: %zu\n", elementsWithRareData);
248     printf("  Number of Elements with NamedNodeMap: %zu [%zu]\n", elementsWithNamedNodeMap, sizeof(NamedNodeMap));
249 #endif
250 }
251 
252 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, nodeCounter, ("WebCoreNode"));
253 
trackForDebugging()254 void Node::trackForDebugging()
255 {
256 #ifndef NDEBUG
257     nodeCounter.increment();
258 #endif
259 
260 #if DUMP_NODE_STATISTICS
261     liveNodeSet().add(this);
262 #endif
263 }
264 
Node(TreeScope * treeScope,ConstructionType type)265 Node::Node(TreeScope* treeScope, ConstructionType type)
266     : m_nodeFlags(type)
267     , m_parentOrShadowHostNode(nullptr)
268     , m_treeScope(treeScope)
269     , m_previous(nullptr)
270     , m_next(nullptr)
271 {
272     ASSERT(m_treeScope || type == CreateDocument || type == CreateShadowRoot);
273 #if !ENABLE(OILPAN)
274     if (m_treeScope)
275         m_treeScope->guardRef();
276 #endif
277 
278 #if !defined(NDEBUG) || (defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS)
279     trackForDebugging();
280 #endif
281     InspectorCounters::incrementCounter(InspectorCounters::NodeCounter);
282 }
283 
~Node()284 Node::~Node()
285 {
286 #ifndef NDEBUG
287     nodeCounter.decrement();
288 #endif
289 
290 #if !ENABLE(OILPAN)
291 #if DUMP_NODE_STATISTICS
292     liveNodeSet().remove(this);
293 #endif
294 
295     if (hasRareData())
296         clearRareData();
297 
298     RELEASE_ASSERT(!renderer());
299 
300     if (!isContainerNode())
301         willBeDeletedFromDocument();
302 
303     if (m_previous)
304         m_previous->setNextSibling(0);
305     if (m_next)
306         m_next->setPreviousSibling(0);
307 
308     if (m_treeScope)
309         m_treeScope->guardDeref();
310 
311     if (getFlag(HasWeakReferencesFlag))
312         WeakNodeMap::notifyNodeDestroyed(this);
313 #else
314     // With Oilpan, the rare data finalizer also asserts for
315     // this condition (we cannot directly access it here.)
316     RELEASE_ASSERT(hasRareData() || !renderer());
317 #endif
318 
319     InspectorCounters::decrementCounter(InspectorCounters::NodeCounter);
320 }
321 
322 #if !ENABLE(OILPAN)
323 // With Oilpan all of this is handled with weak processing of the document.
willBeDeletedFromDocument()324 void Node::willBeDeletedFromDocument()
325 {
326     if (!isTreeScopeInitialized())
327         return;
328 
329     Document& document = this->document();
330 
331     if (hasEventTargetData())
332         clearEventTargetData();
333 
334     if (document.frameHost())
335         document.frameHost()->eventHandlerRegistry().didRemoveAllEventHandlers(*this);
336 
337     if (AXObjectCache* cache = document.existingAXObjectCache())
338         cache->remove(this);
339 
340     document.markers().removeMarkers(this);
341 }
342 #endif
343 
rareData() const344 NodeRareData* Node::rareData() const
345 {
346     ASSERT_WITH_SECURITY_IMPLICATION(hasRareData());
347     return static_cast<NodeRareData*>(m_data.m_rareData);
348 }
349 
ensureRareData()350 NodeRareData& Node::ensureRareData()
351 {
352     if (hasRareData())
353         return *rareData();
354 
355     if (isElementNode())
356         m_data.m_rareData = ElementRareData::create(m_data.m_renderer);
357     else
358         m_data.m_rareData = NodeRareData::create(m_data.m_renderer);
359 
360     ASSERT(m_data.m_rareData);
361 
362     setFlag(HasRareDataFlag);
363     return *rareData();
364 }
365 
366 #if !ENABLE(OILPAN)
clearRareData()367 void Node::clearRareData()
368 {
369     ASSERT(hasRareData());
370     ASSERT(!transientMutationObserverRegistry() || transientMutationObserverRegistry()->isEmpty());
371 
372     RenderObject* renderer = m_data.m_rareData->renderer();
373     if (isElementNode())
374         delete static_cast<ElementRareData*>(m_data.m_rareData);
375     else
376         delete static_cast<NodeRareData*>(m_data.m_rareData);
377     m_data.m_renderer = renderer;
378     clearFlag(HasRareDataFlag);
379 }
380 #endif
381 
toNode()382 Node* Node::toNode()
383 {
384     return this;
385 }
386 
tabIndex() const387 short Node::tabIndex() const
388 {
389     return 0;
390 }
391 
nodeValue() const392 String Node::nodeValue() const
393 {
394     return String();
395 }
396 
setNodeValue(const String &)397 void Node::setNodeValue(const String&)
398 {
399     // By default, setting nodeValue has no effect.
400 }
401 
childNodes()402 PassRefPtrWillBeRawPtr<NodeList> Node::childNodes()
403 {
404     if (isContainerNode())
405         return ensureRareData().ensureNodeLists().ensureChildNodeList(toContainerNode(*this));
406     return ensureRareData().ensureNodeLists().ensureEmptyChildNodeList(*this);
407 }
408 
pseudoAwarePreviousSibling() const409 Node* Node::pseudoAwarePreviousSibling() const
410 {
411     if (parentElement() && !previousSibling()) {
412         Element* parent = parentElement();
413         if (isAfterPseudoElement() && parent->lastChild())
414             return parent->lastChild();
415         if (!isBeforePseudoElement())
416             return parent->pseudoElement(BEFORE);
417     }
418     return previousSibling();
419 }
420 
pseudoAwareNextSibling() const421 Node* Node::pseudoAwareNextSibling() const
422 {
423     if (parentElement() && !nextSibling()) {
424         Element* parent = parentElement();
425         if (isBeforePseudoElement() && parent->hasChildren())
426             return parent->firstChild();
427         if (!isAfterPseudoElement())
428             return parent->pseudoElement(AFTER);
429     }
430     return nextSibling();
431 }
432 
pseudoAwareFirstChild() const433 Node* Node::pseudoAwareFirstChild() const
434 {
435     if (isElementNode()) {
436         const Element* currentElement = toElement(this);
437         Node* first = currentElement->pseudoElement(BEFORE);
438         if (first)
439             return first;
440         first = currentElement->firstChild();
441         if (!first)
442             first = currentElement->pseudoElement(AFTER);
443         return first;
444     }
445 
446     return firstChild();
447 }
448 
pseudoAwareLastChild() const449 Node* Node::pseudoAwareLastChild() const
450 {
451     if (isElementNode()) {
452         const Element* currentElement = toElement(this);
453         Node* last = currentElement->pseudoElement(AFTER);
454         if (last)
455             return last;
456         last = currentElement->lastChild();
457         if (!last)
458             last = currentElement->pseudoElement(BEFORE);
459         return last;
460     }
461 
462     return lastChild();
463 }
464 
insertBefore(PassRefPtrWillBeRawPtr<Node> newChild,Node * refChild,ExceptionState & exceptionState)465 PassRefPtrWillBeRawPtr<Node> Node::insertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node* refChild, ExceptionState& exceptionState)
466 {
467     if (isContainerNode())
468         return toContainerNode(this)->insertBefore(newChild, refChild, exceptionState);
469 
470     exceptionState.throwDOMException(HierarchyRequestError, "This node type does not support this method.");
471     return nullptr;
472 }
473 
replaceChild(PassRefPtrWillBeRawPtr<Node> newChild,PassRefPtrWillBeRawPtr<Node> oldChild,ExceptionState & exceptionState)474 PassRefPtrWillBeRawPtr<Node> Node::replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, PassRefPtrWillBeRawPtr<Node> oldChild, ExceptionState& exceptionState)
475 {
476     if (isContainerNode())
477         return toContainerNode(this)->replaceChild(newChild, oldChild, exceptionState);
478 
479     exceptionState.throwDOMException(HierarchyRequestError,  "This node type does not support this method.");
480     return nullptr;
481 }
482 
removeChild(PassRefPtrWillBeRawPtr<Node> oldChild,ExceptionState & exceptionState)483 PassRefPtrWillBeRawPtr<Node> Node::removeChild(PassRefPtrWillBeRawPtr<Node> oldChild, ExceptionState& exceptionState)
484 {
485     if (isContainerNode())
486         return toContainerNode(this)->removeChild(oldChild, exceptionState);
487 
488     exceptionState.throwDOMException(NotFoundError, "This node type does not support this method.");
489     return nullptr;
490 }
491 
appendChild(PassRefPtrWillBeRawPtr<Node> newChild,ExceptionState & exceptionState)492 PassRefPtrWillBeRawPtr<Node> Node::appendChild(PassRefPtrWillBeRawPtr<Node> newChild, ExceptionState& exceptionState)
493 {
494     if (isContainerNode())
495         return toContainerNode(this)->appendChild(newChild, exceptionState);
496 
497     exceptionState.throwDOMException(HierarchyRequestError, "This node type does not support this method.");
498     return nullptr;
499 }
500 
remove(ExceptionState & exceptionState)501 void Node::remove(ExceptionState& exceptionState)
502 {
503     if (ContainerNode* parent = parentNode())
504         parent->removeChild(this, exceptionState);
505 }
506 
normalize()507 void Node::normalize()
508 {
509     document().updateDistributionForNodeIfNeeded(this);
510 
511     // Go through the subtree beneath us, normalizing all nodes. This means that
512     // any two adjacent text nodes are merged and any empty text nodes are removed.
513 
514     RefPtrWillBeRawPtr<Node> node = this;
515     while (Node* firstChild = node->firstChild())
516         node = firstChild;
517     while (node) {
518         if (node->isElementNode())
519             toElement(node)->normalizeAttributes();
520 
521         if (node == this)
522             break;
523 
524         if (node->nodeType() == TEXT_NODE)
525             node = toText(node)->mergeNextSiblingNodesIfPossible();
526         else
527             node = NodeTraversal::nextPostOrder(*node);
528     }
529 }
530 
localName() const531 const AtomicString& Node::localName() const
532 {
533     return nullAtom;
534 }
535 
namespaceURI() const536 const AtomicString& Node::namespaceURI() const
537 {
538     return nullAtom;
539 }
540 
isContentEditable(UserSelectAllTreatment treatment)541 bool Node::isContentEditable(UserSelectAllTreatment treatment)
542 {
543     document().updateRenderTreeIfNeeded();
544     return hasEditableStyle(Editable, treatment);
545 }
546 
isContentRichlyEditable()547 bool Node::isContentRichlyEditable()
548 {
549     document().updateRenderTreeIfNeeded();
550     return hasEditableStyle(RichlyEditable, UserSelectAllIsAlwaysNonEditable);
551 }
552 
hasEditableStyle(EditableLevel editableLevel,UserSelectAllTreatment treatment) const553 bool Node::hasEditableStyle(EditableLevel editableLevel, UserSelectAllTreatment treatment) const
554 {
555     if (isPseudoElement())
556         return false;
557 
558     // Ideally we'd call ASSERT(!needsStyleRecalc()) here, but
559     // ContainerNode::setFocus() calls setNeedsStyleRecalc(), so the assertion
560     // would fire in the middle of Document::setFocusedNode().
561 
562     for (const Node* node = this; node; node = node->parentNode()) {
563         if ((node->isHTMLElement() || node->isDocumentNode()) && node->renderer()) {
564             // Elements with user-select: all style are considered atomic
565             // therefore non editable.
566             if (Position::nodeIsUserSelectAll(node) && treatment == UserSelectAllIsAlwaysNonEditable)
567                 return false;
568             switch (node->renderer()->style()->userModify()) {
569             case READ_ONLY:
570                 return false;
571             case READ_WRITE:
572                 return true;
573             case READ_WRITE_PLAINTEXT_ONLY:
574                 return editableLevel != RichlyEditable;
575             }
576             ASSERT_NOT_REACHED();
577             return false;
578         }
579     }
580 
581     return false;
582 }
583 
isEditableToAccessibility(EditableLevel editableLevel) const584 bool Node::isEditableToAccessibility(EditableLevel editableLevel) const
585 {
586     if (hasEditableStyle(editableLevel))
587         return true;
588 
589     // FIXME: Respect editableLevel for ARIA editable elements.
590     if (editableLevel == RichlyEditable)
591         return false;
592 
593     ASSERT(document().settings() && document().settings()->accessibilityEnabled());
594     ASSERT(document().existingAXObjectCache());
595 
596     if (AXObjectCache* cache = document().existingAXObjectCache())
597         return cache->rootAXEditableElement(this);
598 
599     return false;
600 }
601 
renderBox() const602 RenderBox* Node::renderBox() const
603 {
604     RenderObject* renderer = this->renderer();
605     return renderer && renderer->isBox() ? toRenderBox(renderer) : 0;
606 }
607 
renderBoxModelObject() const608 RenderBoxModelObject* Node::renderBoxModelObject() const
609 {
610     RenderObject* renderer = this->renderer();
611     return renderer && renderer->isBoxModelObject() ? toRenderBoxModelObject(renderer) : 0;
612 }
613 
boundingBox() const614 LayoutRect Node::boundingBox() const
615 {
616     if (renderer())
617         return renderer()->absoluteBoundingBoxRect();
618     return LayoutRect();
619 }
620 
hasNonEmptyBoundingBox() const621 bool Node::hasNonEmptyBoundingBox() const
622 {
623     // Before calling absoluteRects, check for the common case where the renderer
624     // is non-empty, since this is a faster check and almost always returns true.
625     RenderBoxModelObject* box = renderBoxModelObject();
626     if (!box)
627         return false;
628     if (!box->borderBoundingBox().isEmpty())
629         return true;
630 
631     Vector<IntRect> rects;
632     FloatPoint absPos = renderer()->localToAbsolute();
633     renderer()->absoluteRects(rects, flooredLayoutPoint(absPos));
634     size_t n = rects.size();
635     for (size_t i = 0; i < n; ++i)
636         if (!rects[i].isEmpty())
637             return true;
638 
639     return false;
640 }
641 
642 #ifndef NDEBUG
oldestShadowRootFor(const Node * node)643 inline static ShadowRoot* oldestShadowRootFor(const Node* node)
644 {
645     if (!node->isElementNode())
646         return 0;
647     if (ElementShadow* shadow = toElement(node)->shadow())
648         return shadow->oldestShadowRoot();
649     return 0;
650 }
651 #endif
652 
recalcDistribution()653 void Node::recalcDistribution()
654 {
655     if (isElementNode()) {
656         if (ElementShadow* shadow = toElement(this)->shadow())
657             shadow->distributeIfNeeded();
658     }
659 
660     for (Node* child = firstChild(); child; child = child->nextSibling()) {
661         if (child->childNeedsDistributionRecalc())
662             child->recalcDistribution();
663     }
664 
665     for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
666         if (root->childNeedsDistributionRecalc())
667             root->recalcDistribution();
668     }
669 
670     clearChildNeedsDistributionRecalc();
671 }
672 
setIsLink(bool isLink)673 void Node::setIsLink(bool isLink)
674 {
675     setFlag(isLink && !SVGImage::isInSVGImage(toElement(this)), IsLinkFlag);
676 }
677 
setNeedsStyleInvalidation()678 void Node::setNeedsStyleInvalidation()
679 {
680     setFlag(NeedsStyleInvalidationFlag);
681     markAncestorsWithChildNeedsStyleInvalidation();
682 }
683 
markAncestorsWithChildNeedsStyleInvalidation()684 void Node::markAncestorsWithChildNeedsStyleInvalidation()
685 {
686     for (Node* node = parentOrShadowHostNode(); node && !node->childNeedsStyleInvalidation(); node = node->parentOrShadowHostNode())
687         node->setChildNeedsStyleInvalidation();
688     document().scheduleRenderTreeUpdateIfNeeded();
689 }
690 
markAncestorsWithChildNeedsDistributionRecalc()691 void Node::markAncestorsWithChildNeedsDistributionRecalc()
692 {
693     for (Node* node = this; node && !node->childNeedsDistributionRecalc(); node = node->parentOrShadowHostNode())
694         node->setChildNeedsDistributionRecalc();
695     document().scheduleRenderTreeUpdateIfNeeded();
696 }
697 
698 namespace {
699 
addJsStack(TracedValue * stackFrames)700 void addJsStack(TracedValue* stackFrames)
701 {
702     RefPtrWillBeRawPtr<ScriptCallStack> stack = createScriptCallStack(10);
703     if (!stack)
704         return;
705     for (size_t i = 0; i < stack->size(); i++)
706         stackFrames->pushString(stack->at(i).functionName());
707 }
708 
jsonObjectForStyleInvalidation(unsigned nodeCount,const Node * rootNode)709 PassRefPtr<TraceEvent::ConvertableToTraceFormat> jsonObjectForStyleInvalidation(unsigned nodeCount, const Node* rootNode)
710 {
711     RefPtr<TracedValue> value = TracedValue::create();
712     value->setInteger("node_count", nodeCount);
713     value->setString("root_node", rootNode->debugName());
714     value->beginArray("js_stack");
715     addJsStack(value.get());
716     value->endArray();
717     return value;
718 }
719 
720 } // anonymous namespace'd functions supporting traceStyleChange
721 
styledSubtreeSize() const722 unsigned Node::styledSubtreeSize() const
723 {
724     unsigned nodeCount = 0;
725 
726     for (const Node* node = this; node; node = NodeTraversal::next(*node, this)) {
727         if (node->isTextNode() || node->isElementNode())
728             nodeCount++;
729         for (ShadowRoot* root = node->youngestShadowRoot(); root; root = root->olderShadowRoot())
730             nodeCount += root->styledSubtreeSize();
731     }
732 
733     return nodeCount;
734 }
735 
traceStyleChange(StyleChangeType changeType)736 void Node::traceStyleChange(StyleChangeType changeType)
737 {
738     static const unsigned kMinLoggedSize = 100;
739     unsigned nodeCount = styledSubtreeSize();
740     if (nodeCount < kMinLoggedSize)
741         return;
742 
743     TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("style.debug"),
744         "Node::setNeedsStyleRecalc",
745         "data", jsonObjectForStyleInvalidation(nodeCount, this)
746     );
747 }
748 
traceStyleChangeIfNeeded(StyleChangeType changeType)749 void Node::traceStyleChangeIfNeeded(StyleChangeType changeType)
750 {
751     // TRACE_EVENT_CATEGORY_GROUP_ENABLED macro loads a global static bool into our local bool.
752     bool styleTracingEnabled;
753     TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("style.debug"), &styleTracingEnabled);
754     if (UNLIKELY(styleTracingEnabled))
755         traceStyleChange(changeType);
756 }
757 
setStyleChange(StyleChangeType changeType)758 inline void Node::setStyleChange(StyleChangeType changeType)
759 {
760     m_nodeFlags = (m_nodeFlags & ~StyleChangeMask) | changeType;
761 }
762 
markAncestorsWithChildNeedsStyleRecalc()763 void Node::markAncestorsWithChildNeedsStyleRecalc()
764 {
765     for (ContainerNode* p = parentOrShadowHostNode(); p && !p->childNeedsStyleRecalc(); p = p->parentOrShadowHostNode())
766         p->setChildNeedsStyleRecalc();
767     document().scheduleRenderTreeUpdateIfNeeded();
768 }
769 
setNeedsStyleRecalc(StyleChangeType changeType)770 void Node::setNeedsStyleRecalc(StyleChangeType changeType)
771 {
772     ASSERT(changeType != NoStyleChange);
773     if (!inActiveDocument())
774         return;
775 
776     StyleChangeType existingChangeType = styleChangeType();
777     if (changeType > existingChangeType) {
778         setStyleChange(changeType);
779         if (changeType >= SubtreeStyleChange)
780             traceStyleChangeIfNeeded(changeType);
781     }
782 
783     if (existingChangeType == NoStyleChange)
784         markAncestorsWithChildNeedsStyleRecalc();
785 
786     if (isElementNode() && hasRareData())
787         toElement(*this).setAnimationStyleChange(false);
788 }
789 
clearNeedsStyleRecalc()790 void Node::clearNeedsStyleRecalc()
791 {
792     m_nodeFlags &= ~StyleChangeMask;
793 
794     clearSVGFilterNeedsLayerUpdate();
795 
796     if (isElementNode() && hasRareData())
797         toElement(*this).setAnimationStyleChange(false);
798 }
799 
inActiveDocument() const800 bool Node::inActiveDocument() const
801 {
802     return inDocument() && document().isActive();
803 }
804 
focusDelegate()805 Node* Node::focusDelegate()
806 {
807     return this;
808 }
809 
shouldHaveFocusAppearance() const810 bool Node::shouldHaveFocusAppearance() const
811 {
812     ASSERT(focused());
813     return true;
814 }
815 
isInert() const816 bool Node::isInert() const
817 {
818     const HTMLDialogElement* dialog = document().activeModalDialog();
819     if (dialog && this != document() && !NodeRenderingTraversal::contains(dialog, this))
820         return true;
821     return document().ownerElement() && document().ownerElement()->isInert();
822 }
823 
nodeIndex() const824 unsigned Node::nodeIndex() const
825 {
826     Node *_tempNode = previousSibling();
827     unsigned count=0;
828     for ( count=0; _tempNode; count++ )
829         _tempNode = _tempNode->previousSibling();
830     return count;
831 }
832 
nodeLists()833 NodeListsNodeData* Node::nodeLists()
834 {
835     return hasRareData() ? rareData()->nodeLists() : 0;
836 }
837 
clearNodeLists()838 void Node::clearNodeLists()
839 {
840     rareData()->clearNodeLists();
841 }
842 
isDescendantOf(const Node * other) const843 bool Node::isDescendantOf(const Node *other) const
844 {
845     // Return true if other is an ancestor of this, otherwise false
846     if (!other || !other->hasChildren() || inDocument() != other->inDocument())
847         return false;
848     if (other->treeScope() != treeScope())
849         return false;
850     if (other->isTreeScope())
851         return !isTreeScope();
852     for (const ContainerNode* n = parentNode(); n; n = n->parentNode()) {
853         if (n == other)
854             return true;
855     }
856     return false;
857 }
858 
contains(const Node * node) const859 bool Node::contains(const Node* node) const
860 {
861     if (!node)
862         return false;
863     return this == node || node->isDescendantOf(this);
864 }
865 
containsIncludingShadowDOM(const Node * node) const866 bool Node::containsIncludingShadowDOM(const Node* node) const
867 {
868     if (!node)
869         return false;
870 
871     if (this == node)
872         return true;
873 
874     if (document() != node->document())
875         return false;
876 
877     if (inDocument() != node->inDocument())
878         return false;
879 
880     bool hasChildren = isContainerNode() && toContainerNode(this)->hasChildren();
881     bool hasShadow = isElementNode() && toElement(this)->shadow();
882     if (!hasChildren && !hasShadow)
883         return false;
884 
885     for (; node; node = node->shadowHost()) {
886         if (treeScope() == node->treeScope())
887             return contains(node);
888     }
889 
890     return false;
891 }
892 
containsIncludingHostElements(const Node & node) const893 bool Node::containsIncludingHostElements(const Node& node) const
894 {
895     const Node* current = &node;
896     do {
897         if (current == this)
898             return true;
899         if (current->isDocumentFragment() && toDocumentFragment(current)->isTemplateContent())
900             current = static_cast<const TemplateContentDocumentFragment*>(current)->host();
901         else
902             current = current->parentOrShadowHostNode();
903     } while (current);
904     return false;
905 }
906 
commonAncestor(const Node & other,Node * (* parent)(const Node &))907 Node* Node::commonAncestor(const Node& other, Node* (*parent)(const Node&))
908 {
909     if (this == other)
910         return this;
911     if (document() != other.document())
912         return 0;
913     int thisDepth = 0;
914     for (Node* node = this; node; node = parent(*node)) {
915         if (node == &other)
916             return node;
917         thisDepth++;
918     }
919     int otherDepth = 0;
920     for (const Node* node = &other; node; node = parent(*node)) {
921         if (node == this)
922             return this;
923         otherDepth++;
924     }
925     Node* thisIterator = this;
926     const Node* otherIterator = &other;
927     if (thisDepth > otherDepth) {
928         for (int i = thisDepth; i > otherDepth; --i)
929             thisIterator = parent(*thisIterator);
930     } else if (otherDepth > thisDepth) {
931         for (int i = otherDepth; i > thisDepth; --i)
932             otherIterator = parent(*otherIterator);
933     }
934     while (thisIterator) {
935         if (thisIterator == otherIterator)
936             return thisIterator;
937         thisIterator = parent(*thisIterator);
938         otherIterator = parent(*otherIterator);
939     }
940     ASSERT(!otherIterator);
941     return 0;
942 }
943 
reattach(const AttachContext & context)944 void Node::reattach(const AttachContext& context)
945 {
946     AttachContext reattachContext(context);
947     reattachContext.performingReattach = true;
948 
949     // We only need to detach if the node has already been through attach().
950     if (styleChangeType() < NeedsReattachStyleChange)
951         detach(reattachContext);
952     attach(reattachContext);
953 }
954 
attach(const AttachContext &)955 void Node::attach(const AttachContext&)
956 {
957     ASSERT(document().inStyleRecalc() || isDocumentNode());
958     ASSERT(needsAttach());
959     ASSERT(!renderer() || (renderer()->style() && (renderer()->parent() || renderer()->isRenderView())));
960 
961     clearNeedsStyleRecalc();
962 
963     if (AXObjectCache* cache = document().axObjectCache())
964         cache->updateCacheAfterNodeIsAttached(this);
965 }
966 
967 #if ENABLE(ASSERT)
968 static Node* detachingNode;
969 
inDetach() const970 bool Node::inDetach() const
971 {
972     return detachingNode == this;
973 }
974 #endif
975 
detach(const AttachContext & context)976 void Node::detach(const AttachContext& context)
977 {
978     ASSERT(document().lifecycle().stateAllowsDetach());
979     DocumentLifecycle::DetachScope willDetach(document().lifecycle());
980 
981 #if ENABLE(ASSERT)
982     ASSERT(!detachingNode);
983     detachingNode = this;
984 #endif
985 
986     if (renderer())
987         renderer()->destroyAndCleanupAnonymousWrappers();
988     setRenderer(0);
989 
990     // Do not remove the element's hovered and active status
991     // if performing a reattach.
992     if (!context.performingReattach) {
993         Document& doc = document();
994         if (isUserActionElement()) {
995             if (hovered())
996                 doc.hoveredNodeDetached(this);
997             if (inActiveChain())
998                 doc.activeChainNodeDetached(this);
999             doc.userActionElements().didDetach(this);
1000         }
1001     }
1002 
1003     setStyleChange(NeedsReattachStyleChange);
1004     setChildNeedsStyleRecalc();
1005 
1006     if (StyleResolver* resolver = document().styleResolver())
1007         resolver->ruleFeatureSet().styleInvalidator().clearInvalidation(*this);
1008     clearChildNeedsStyleInvalidation();
1009     clearNeedsStyleInvalidation();
1010 
1011 #if ENABLE(ASSERT)
1012     detachingNode = 0;
1013 #endif
1014 }
1015 
reattachWhitespaceSiblings(Text * start)1016 void Node::reattachWhitespaceSiblings(Text* start)
1017 {
1018     for (Node* sibling = start; sibling; sibling = sibling->nextSibling()) {
1019         if (sibling->isTextNode() && toText(sibling)->containsOnlyWhitespace()) {
1020             bool hadRenderer = !!sibling->renderer();
1021             sibling->reattach();
1022             // If the reattach didn't toggle the visibility of the whitespace we don't
1023             // need to continue reattaching siblings since they won't toggle visibility
1024             // either.
1025             if (hadRenderer == !!sibling->renderer())
1026                 return;
1027         } else if (sibling->renderer()) {
1028             return;
1029         }
1030     }
1031 }
1032 
1033 // FIXME: This code is used by editing.  Seems like it could move over there and not pollute Node.
previousNodeConsideringAtomicNodes() const1034 Node *Node::previousNodeConsideringAtomicNodes() const
1035 {
1036     if (previousSibling()) {
1037         Node *n = previousSibling();
1038         while (!isAtomicNode(n) && n->lastChild())
1039             n = n->lastChild();
1040         return n;
1041     }
1042     else if (parentNode()) {
1043         return parentNode();
1044     }
1045     else {
1046         return 0;
1047     }
1048 }
1049 
nextNodeConsideringAtomicNodes() const1050 Node *Node::nextNodeConsideringAtomicNodes() const
1051 {
1052     if (!isAtomicNode(this) && hasChildren())
1053         return firstChild();
1054     if (nextSibling())
1055         return nextSibling();
1056     const Node *n = this;
1057     while (n && !n->nextSibling())
1058         n = n->parentNode();
1059     if (n)
1060         return n->nextSibling();
1061     return 0;
1062 }
1063 
previousLeafNode() const1064 Node *Node::previousLeafNode() const
1065 {
1066     Node *node = previousNodeConsideringAtomicNodes();
1067     while (node) {
1068         if (isAtomicNode(node))
1069             return node;
1070         node = node->previousNodeConsideringAtomicNodes();
1071     }
1072     return 0;
1073 }
1074 
nextLeafNode() const1075 Node *Node::nextLeafNode() const
1076 {
1077     Node *node = nextNodeConsideringAtomicNodes();
1078     while (node) {
1079         if (isAtomicNode(node))
1080             return node;
1081         node = node->nextNodeConsideringAtomicNodes();
1082     }
1083     return 0;
1084 }
1085 
virtualComputedStyle(PseudoId pseudoElementSpecifier)1086 RenderStyle* Node::virtualComputedStyle(PseudoId pseudoElementSpecifier)
1087 {
1088     return parentOrShadowHostNode() ? parentOrShadowHostNode()->computedStyle(pseudoElementSpecifier) : 0;
1089 }
1090 
maxCharacterOffset() const1091 int Node::maxCharacterOffset() const
1092 {
1093     ASSERT_NOT_REACHED();
1094     return 0;
1095 }
1096 
1097 // FIXME: Shouldn't these functions be in the editing code?  Code that asks questions about HTML in the core DOM class
1098 // is obviously misplaced.
canStartSelection() const1099 bool Node::canStartSelection() const
1100 {
1101     if (hasEditableStyle())
1102         return true;
1103 
1104     if (renderer()) {
1105         RenderStyle* style = renderer()->style();
1106         // We allow selections to begin within an element that has -webkit-user-select: none set,
1107         // but if the element is draggable then dragging should take priority over selection.
1108         if (style->userDrag() == DRAG_ELEMENT && style->userSelect() == SELECT_NONE)
1109             return false;
1110     }
1111     return parentOrShadowHostNode() ? parentOrShadowHostNode()->canStartSelection() : true;
1112 }
1113 
shadowHost() const1114 Element* Node::shadowHost() const
1115 {
1116     if (ShadowRoot* root = containingShadowRoot())
1117         return root->host();
1118     return 0;
1119 }
1120 
containingShadowRoot() const1121 ShadowRoot* Node::containingShadowRoot() const
1122 {
1123     Node& root = treeScope().rootNode();
1124     return root.isShadowRoot() ? toShadowRoot(&root) : 0;
1125 }
1126 
nonBoundaryShadowTreeRootNode()1127 Node* Node::nonBoundaryShadowTreeRootNode()
1128 {
1129     ASSERT(!isShadowRoot());
1130     Node* root = this;
1131     while (root) {
1132         if (root->isShadowRoot())
1133             return root;
1134         Node* parent = root->parentOrShadowHostNode();
1135         if (parent && parent->isShadowRoot())
1136             return root;
1137         root = parent;
1138     }
1139     return 0;
1140 }
1141 
nonShadowBoundaryParentNode() const1142 ContainerNode* Node::nonShadowBoundaryParentNode() const
1143 {
1144     ContainerNode* parent = parentNode();
1145     return parent && !parent->isShadowRoot() ? parent : 0;
1146 }
1147 
parentOrShadowHostElement() const1148 Element* Node::parentOrShadowHostElement() const
1149 {
1150     ContainerNode* parent = parentOrShadowHostNode();
1151     if (!parent)
1152         return 0;
1153 
1154     if (parent->isShadowRoot())
1155         return toShadowRoot(parent)->host();
1156 
1157     if (!parent->isElementNode())
1158         return 0;
1159 
1160     return toElement(parent);
1161 }
1162 
parentOrShadowHostOrTemplateHostNode() const1163 ContainerNode* Node::parentOrShadowHostOrTemplateHostNode() const
1164 {
1165     if (isDocumentFragment() && toDocumentFragment(this)->isTemplateContent())
1166         return static_cast<const TemplateContentDocumentFragment*>(this)->host();
1167     return parentOrShadowHostNode();
1168 }
1169 
isRootEditableElement() const1170 bool Node::isRootEditableElement() const
1171 {
1172     return hasEditableStyle() && isElementNode() && (!parentNode() || !parentNode()->hasEditableStyle()
1173         || !parentNode()->isElementNode() || isHTMLBodyElement((*this)));
1174 }
1175 
rootEditableElement(EditableType editableType) const1176 Element* Node::rootEditableElement(EditableType editableType) const
1177 {
1178     if (editableType == HasEditableAXRole) {
1179         if (AXObjectCache* cache = document().existingAXObjectCache())
1180             return const_cast<Element*>(cache->rootAXEditableElement(this));
1181     }
1182 
1183     return rootEditableElement();
1184 }
1185 
rootEditableElement() const1186 Element* Node::rootEditableElement() const
1187 {
1188     Element* result = 0;
1189     for (Node* n = const_cast<Node*>(this); n && n->hasEditableStyle(); n = n->parentNode()) {
1190         if (n->isElementNode())
1191             result = toElement(n);
1192         if (isHTMLBodyElement(*n))
1193             break;
1194     }
1195     return result;
1196 }
1197 
1198 // FIXME: End of obviously misplaced HTML editing functions.  Try to move these out of Node.
1199 
ownerDocument() const1200 Document* Node::ownerDocument() const
1201 {
1202     Document* doc = &document();
1203     return doc == this ? 0 : doc;
1204 }
1205 
baseURI() const1206 KURL Node::baseURI() const
1207 {
1208     return parentNode() ? parentNode()->baseURI() : KURL();
1209 }
1210 
isEqualNode(Node * other) const1211 bool Node::isEqualNode(Node* other) const
1212 {
1213     if (!other)
1214         return false;
1215 
1216     NodeType nodeType = this->nodeType();
1217     if (nodeType != other->nodeType())
1218         return false;
1219 
1220     if (nodeName() != other->nodeName())
1221         return false;
1222 
1223     if (localName() != other->localName())
1224         return false;
1225 
1226     if (namespaceURI() != other->namespaceURI())
1227         return false;
1228 
1229     if (nodeValue() != other->nodeValue())
1230         return false;
1231 
1232     if (isElementNode() && !toElement(this)->hasEquivalentAttributes(toElement(other)))
1233         return false;
1234 
1235     Node* child = firstChild();
1236     Node* otherChild = other->firstChild();
1237 
1238     while (child) {
1239         if (!child->isEqualNode(otherChild))
1240             return false;
1241 
1242         child = child->nextSibling();
1243         otherChild = otherChild->nextSibling();
1244     }
1245 
1246     if (otherChild)
1247         return false;
1248 
1249     if (isDocumentTypeNode()) {
1250         const DocumentType* documentTypeThis = toDocumentType(this);
1251         const DocumentType* documentTypeOther = toDocumentType(other);
1252 
1253         if (documentTypeThis->publicId() != documentTypeOther->publicId())
1254             return false;
1255 
1256         if (documentTypeThis->systemId() != documentTypeOther->systemId())
1257             return false;
1258     }
1259 
1260     return true;
1261 }
1262 
isDefaultNamespace(const AtomicString & namespaceURIMaybeEmpty) const1263 bool Node::isDefaultNamespace(const AtomicString& namespaceURIMaybeEmpty) const
1264 {
1265     const AtomicString& namespaceURI = namespaceURIMaybeEmpty.isEmpty() ? nullAtom : namespaceURIMaybeEmpty;
1266 
1267     switch (nodeType()) {
1268         case ELEMENT_NODE: {
1269             const Element& element = toElement(*this);
1270 
1271             if (element.prefix().isNull())
1272                 return element.namespaceURI() == namespaceURI;
1273 
1274             AttributeCollection attributes = element.attributes();
1275             AttributeCollection::iterator end = attributes.end();
1276             for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) {
1277                 if (it->localName() == xmlnsAtom)
1278                     return it->value() == namespaceURI;
1279             }
1280 
1281             if (Element* parent = parentElement())
1282                 return parent->isDefaultNamespace(namespaceURI);
1283 
1284             return false;
1285         }
1286         case DOCUMENT_NODE:
1287             if (Element* de = toDocument(this)->documentElement())
1288                 return de->isDefaultNamespace(namespaceURI);
1289             return false;
1290         case DOCUMENT_TYPE_NODE:
1291         case DOCUMENT_FRAGMENT_NODE:
1292             return false;
1293         case ATTRIBUTE_NODE: {
1294             const Attr* attr = toAttr(this);
1295             if (attr->ownerElement())
1296                 return attr->ownerElement()->isDefaultNamespace(namespaceURI);
1297             return false;
1298         }
1299         default:
1300             if (Element* parent = parentElement())
1301                 return parent->isDefaultNamespace(namespaceURI);
1302             return false;
1303     }
1304 }
1305 
lookupPrefix(const AtomicString & namespaceURI) const1306 const AtomicString& Node::lookupPrefix(const AtomicString& namespaceURI) const
1307 {
1308     // Implemented according to
1309     // http://dom.spec.whatwg.org/#dom-node-lookupprefix
1310 
1311     if (namespaceURI.isEmpty() || namespaceURI.isNull())
1312         return nullAtom;
1313 
1314     const Element* context;
1315 
1316     switch (nodeType()) {
1317         case ELEMENT_NODE:
1318             context = toElement(this);
1319             break;
1320         case DOCUMENT_NODE:
1321             context = toDocument(this)->documentElement();
1322             break;
1323         case DOCUMENT_FRAGMENT_NODE:
1324         case DOCUMENT_TYPE_NODE:
1325             context = 0;
1326             break;
1327         // FIXME: Remove this when Attr no longer extends Node (CR305105)
1328         case ATTRIBUTE_NODE:
1329             context = toAttr(this)->ownerElement();
1330             break;
1331         default:
1332             context = parentElement();
1333             break;
1334     }
1335 
1336     if (!context)
1337         return nullAtom;
1338 
1339     return context->locateNamespacePrefix(namespaceURI);
1340 }
1341 
lookupNamespaceURI(const String & prefix) const1342 const AtomicString& Node::lookupNamespaceURI(const String& prefix) const
1343 {
1344     // Implemented according to
1345     // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#lookupNamespaceURIAlgo
1346 
1347     if (!prefix.isNull() && prefix.isEmpty())
1348         return nullAtom;
1349 
1350     switch (nodeType()) {
1351         case ELEMENT_NODE: {
1352             const Element& element = toElement(*this);
1353 
1354             if (!element.namespaceURI().isNull() && element.prefix() == prefix)
1355                 return element.namespaceURI();
1356 
1357             AttributeCollection attributes = element.attributes();
1358             AttributeCollection::iterator end = attributes.end();
1359             for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) {
1360                 if (it->prefix() == xmlnsAtom && it->localName() == prefix) {
1361                     if (!it->value().isEmpty())
1362                         return it->value();
1363                     return nullAtom;
1364                 }
1365                 if (it->localName() == xmlnsAtom && prefix.isNull()) {
1366                     if (!it->value().isEmpty())
1367                         return it->value();
1368                     return nullAtom;
1369                 }
1370             }
1371 
1372             if (Element* parent = parentElement())
1373                 return parent->lookupNamespaceURI(prefix);
1374             return nullAtom;
1375         }
1376         case DOCUMENT_NODE:
1377             if (Element* de = toDocument(this)->documentElement())
1378                 return de->lookupNamespaceURI(prefix);
1379             return nullAtom;
1380         case DOCUMENT_TYPE_NODE:
1381         case DOCUMENT_FRAGMENT_NODE:
1382             return nullAtom;
1383         case ATTRIBUTE_NODE: {
1384             const Attr *attr = toAttr(this);
1385             if (attr->ownerElement())
1386                 return attr->ownerElement()->lookupNamespaceURI(prefix);
1387             else
1388                 return nullAtom;
1389         }
1390         default:
1391             if (Element* parent = parentElement())
1392                 return parent->lookupNamespaceURI(prefix);
1393             return nullAtom;
1394     }
1395 }
1396 
appendTextContent(const Node * node,bool convertBRsToNewlines,bool & isNullString,StringBuilder & content)1397 static void appendTextContent(const Node* node, bool convertBRsToNewlines, bool& isNullString, StringBuilder& content)
1398 {
1399     switch (node->nodeType()) {
1400     case Node::TEXT_NODE:
1401     case Node::CDATA_SECTION_NODE:
1402     case Node::COMMENT_NODE:
1403         isNullString = false;
1404         content.append(toCharacterData(node)->data());
1405         break;
1406 
1407     case Node::PROCESSING_INSTRUCTION_NODE:
1408         isNullString = false;
1409         content.append(toProcessingInstruction(node)->data());
1410         break;
1411 
1412     case Node::ELEMENT_NODE:
1413         if (isHTMLBRElement(*node) && convertBRsToNewlines) {
1414             isNullString = false;
1415             content.append('\n');
1416             break;
1417         }
1418     // Fall through.
1419     case Node::ATTRIBUTE_NODE:
1420     case Node::DOCUMENT_FRAGMENT_NODE:
1421         isNullString = false;
1422         for (Node* child = toContainerNode(node)->firstChild(); child; child = child->nextSibling()) {
1423             Node::NodeType childNodeType = child->nodeType();
1424             if (childNodeType == Node::COMMENT_NODE || childNodeType == Node::PROCESSING_INSTRUCTION_NODE)
1425                 continue;
1426             appendTextContent(child, convertBRsToNewlines, isNullString, content);
1427         }
1428         break;
1429 
1430     case Node::DOCUMENT_NODE:
1431     case Node::DOCUMENT_TYPE_NODE:
1432         break;
1433     }
1434 }
1435 
textContent(bool convertBRsToNewlines) const1436 String Node::textContent(bool convertBRsToNewlines) const
1437 {
1438     StringBuilder content;
1439     bool isNullString = true;
1440     appendTextContent(this, convertBRsToNewlines, isNullString, content);
1441     return isNullString ? String() : content.toString();
1442 }
1443 
setTextContent(const String & text)1444 void Node::setTextContent(const String& text)
1445 {
1446     switch (nodeType()) {
1447         case TEXT_NODE:
1448         case CDATA_SECTION_NODE:
1449         case COMMENT_NODE:
1450         case PROCESSING_INSTRUCTION_NODE:
1451             setNodeValue(text);
1452             return;
1453         case ELEMENT_NODE:
1454         case ATTRIBUTE_NODE:
1455         case DOCUMENT_FRAGMENT_NODE: {
1456             // FIXME: Merge this logic into replaceChildrenWithText.
1457             RefPtrWillBeRawPtr<ContainerNode> container = toContainerNode(this);
1458 
1459             // Note: This is an intentional optimization.
1460             // See crbug.com/352836 also.
1461             // No need to do anything if the text is identical.
1462             if (container->hasOneTextChild() && toText(container->firstChild())->data() == text)
1463                 return;
1464 
1465             ChildListMutationScope mutation(*this);
1466             container->removeChildren();
1467             // Note: This API will not insert empty text nodes:
1468             // http://dom.spec.whatwg.org/#dom-node-textcontent
1469             if (!text.isEmpty())
1470                 container->appendChild(document().createTextNode(text), ASSERT_NO_EXCEPTION);
1471             return;
1472         }
1473         case DOCUMENT_NODE:
1474         case DOCUMENT_TYPE_NODE:
1475             // Do nothing.
1476             return;
1477     }
1478     ASSERT_NOT_REACHED();
1479 }
1480 
offsetInCharacters() const1481 bool Node::offsetInCharacters() const
1482 {
1483     return false;
1484 }
1485 
compareDocumentPosition(const Node * otherNode,ShadowTreesTreatment treatment) const1486 unsigned short Node::compareDocumentPosition(const Node* otherNode, ShadowTreesTreatment treatment) const
1487 {
1488     // It is not clear what should be done if |otherNode| is 0.
1489     if (!otherNode)
1490         return DOCUMENT_POSITION_DISCONNECTED;
1491 
1492     if (otherNode == this)
1493         return DOCUMENT_POSITION_EQUIVALENT;
1494 
1495     const Attr* attr1 = nodeType() == ATTRIBUTE_NODE ? toAttr(this) : 0;
1496     const Attr* attr2 = otherNode->nodeType() == ATTRIBUTE_NODE ? toAttr(otherNode) : 0;
1497 
1498     const Node* start1 = attr1 ? attr1->ownerElement() : this;
1499     const Node* start2 = attr2 ? attr2->ownerElement() : otherNode;
1500 
1501     // If either of start1 or start2 is null, then we are disconnected, since one of the nodes is
1502     // an orphaned attribute node.
1503     if (!start1 || !start2) {
1504         unsigned short direction = (this > otherNode) ? DOCUMENT_POSITION_PRECEDING : DOCUMENT_POSITION_FOLLOWING;
1505         return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | direction;
1506     }
1507 
1508     Vector<const Node*, 16> chain1;
1509     Vector<const Node*, 16> chain2;
1510     if (attr1)
1511         chain1.append(attr1);
1512     if (attr2)
1513         chain2.append(attr2);
1514 
1515     if (attr1 && attr2 && start1 == start2 && start1) {
1516         // We are comparing two attributes on the same node. Crawl our attribute map and see which one we hit first.
1517         const Element* owner1 = attr1->ownerElement();
1518         AttributeCollection attributes = owner1->attributes();
1519         AttributeCollection::iterator end = attributes.end();
1520         for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) {
1521             // If neither of the two determining nodes is a child node and nodeType is the same for both determining nodes, then an
1522             // implementation-dependent order between the determining nodes is returned. This order is stable as long as no nodes of
1523             // the same nodeType are inserted into or removed from the direct container. This would be the case, for example,
1524             // when comparing two attributes of the same element, and inserting or removing additional attributes might change
1525             // the order between existing attributes.
1526             if (attr1->qualifiedName() == it->name())
1527                 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_FOLLOWING;
1528             if (attr2->qualifiedName() == it->name())
1529                 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_PRECEDING;
1530         }
1531 
1532         ASSERT_NOT_REACHED();
1533         return DOCUMENT_POSITION_DISCONNECTED;
1534     }
1535 
1536     // If one node is in the document and the other is not, we must be disconnected.
1537     // If the nodes have different owning documents, they must be disconnected.  Note that we avoid
1538     // comparing Attr nodes here, since they return false from inDocument() all the time (which seems like a bug).
1539     if (start1->inDocument() != start2->inDocument() || (treatment == TreatShadowTreesAsDisconnected && start1->treeScope() != start2->treeScope())) {
1540         unsigned short direction = (this > otherNode) ? DOCUMENT_POSITION_PRECEDING : DOCUMENT_POSITION_FOLLOWING;
1541         return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | direction;
1542     }
1543 
1544     // We need to find a common ancestor container, and then compare the indices of the two immediate children.
1545     const Node* current;
1546     for (current = start1; current; current = current->parentOrShadowHostNode())
1547         chain1.append(current);
1548     for (current = start2; current; current = current->parentOrShadowHostNode())
1549         chain2.append(current);
1550 
1551     unsigned index1 = chain1.size();
1552     unsigned index2 = chain2.size();
1553 
1554     // If the two elements don't have a common root, they're not in the same tree.
1555     if (chain1[index1 - 1] != chain2[index2 - 1]) {
1556         unsigned short direction = (this > otherNode) ? DOCUMENT_POSITION_PRECEDING : DOCUMENT_POSITION_FOLLOWING;
1557         return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | direction;
1558     }
1559 
1560     unsigned connection = start1->treeScope() != start2->treeScope() ? DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC : 0;
1561 
1562     // Walk the two chains backwards and look for the first difference.
1563     for (unsigned i = std::min(index1, index2); i; --i) {
1564         const Node* child1 = chain1[--index1];
1565         const Node* child2 = chain2[--index2];
1566         if (child1 != child2) {
1567             // If one of the children is an attribute, it wins.
1568             if (child1->nodeType() == ATTRIBUTE_NODE)
1569                 return DOCUMENT_POSITION_FOLLOWING | connection;
1570             if (child2->nodeType() == ATTRIBUTE_NODE)
1571                 return DOCUMENT_POSITION_PRECEDING | connection;
1572 
1573             // If one of the children is a shadow root,
1574             if (child1->isShadowRoot() || child2->isShadowRoot()) {
1575                 if (!child2->isShadowRoot())
1576                     return Node::DOCUMENT_POSITION_FOLLOWING | connection;
1577                 if (!child1->isShadowRoot())
1578                     return Node::DOCUMENT_POSITION_PRECEDING | connection;
1579 
1580                 for (ShadowRoot* child = toShadowRoot(child2)->olderShadowRoot(); child; child = child->olderShadowRoot())
1581                     if (child == child1)
1582                         return Node::DOCUMENT_POSITION_FOLLOWING | connection;
1583 
1584                 return Node::DOCUMENT_POSITION_PRECEDING | connection;
1585             }
1586 
1587             if (!child2->nextSibling())
1588                 return DOCUMENT_POSITION_FOLLOWING | connection;
1589             if (!child1->nextSibling())
1590                 return DOCUMENT_POSITION_PRECEDING | connection;
1591 
1592             // Otherwise we need to see which node occurs first.  Crawl backwards from child2 looking for child1.
1593             for (Node* child = child2->previousSibling(); child; child = child->previousSibling()) {
1594                 if (child == child1)
1595                     return DOCUMENT_POSITION_FOLLOWING | connection;
1596             }
1597             return DOCUMENT_POSITION_PRECEDING | connection;
1598         }
1599     }
1600 
1601     // There was no difference between the two parent chains, i.e., one was a subset of the other.  The shorter
1602     // chain is the ancestor.
1603     return index1 < index2 ?
1604                DOCUMENT_POSITION_FOLLOWING | DOCUMENT_POSITION_CONTAINED_BY | connection :
1605                DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_CONTAINS | connection;
1606 }
1607 
debugName() const1608 String Node::debugName() const
1609 {
1610     StringBuilder name;
1611     name.append(nodeName());
1612 
1613     if (isElementNode()) {
1614         const Element& thisElement = toElement(*this);
1615         if (thisElement.hasID()) {
1616             name.appendLiteral(" id=\'");
1617             name.append(thisElement.getIdAttribute());
1618             name.append('\'');
1619         }
1620 
1621         if (thisElement.hasClass()) {
1622             name.appendLiteral(" class=\'");
1623             for (size_t i = 0; i < thisElement.classNames().size(); ++i) {
1624                 if (i > 0)
1625                     name.append(' ');
1626                 name.append(thisElement.classNames()[i]);
1627             }
1628             name.append('\'');
1629         }
1630     }
1631 
1632     return name.toString();
1633 }
1634 
1635 #ifndef NDEBUG
1636 
appendAttributeDesc(const Node * node,StringBuilder & stringBuilder,const QualifiedName & name,const char * attrDesc)1637 static void appendAttributeDesc(const Node* node, StringBuilder& stringBuilder, const QualifiedName& name, const char* attrDesc)
1638 {
1639     if (!node->isElementNode())
1640         return;
1641 
1642     String attr = toElement(node)->getAttribute(name);
1643     if (attr.isEmpty())
1644         return;
1645 
1646     stringBuilder.append(attrDesc);
1647     stringBuilder.appendLiteral("=\"");
1648     stringBuilder.append(attr);
1649     stringBuilder.appendLiteral("\"");
1650 }
1651 
showNode(const char * prefix) const1652 void Node::showNode(const char* prefix) const
1653 {
1654     if (!prefix)
1655         prefix = "";
1656     if (isTextNode()) {
1657         String value = nodeValue();
1658         value.replaceWithLiteral('\\', "\\\\");
1659         value.replaceWithLiteral('\n', "\\n");
1660         fprintf(stderr, "%s%s\t%p \"%s\"\n", prefix, nodeName().utf8().data(), this, value.utf8().data());
1661     } else {
1662         StringBuilder attrs;
1663         appendAttributeDesc(this, attrs, idAttr, " ID");
1664         appendAttributeDesc(this, attrs, classAttr, " CLASS");
1665         appendAttributeDesc(this, attrs, styleAttr, " STYLE");
1666         fprintf(stderr, "%s%s\t%p%s\n", prefix, nodeName().utf8().data(), this, attrs.toString().utf8().data());
1667     }
1668 }
1669 
showTreeForThis() const1670 void Node::showTreeForThis() const
1671 {
1672     showTreeAndMark(this, "*");
1673 }
1674 
showNodePathForThis() const1675 void Node::showNodePathForThis() const
1676 {
1677     Vector<const Node*, 16> chain;
1678     const Node* node = this;
1679     while (node->parentOrShadowHostNode()) {
1680         chain.append(node);
1681         node = node->parentOrShadowHostNode();
1682     }
1683     for (unsigned index = chain.size(); index > 0; --index) {
1684         const Node* node = chain[index - 1];
1685         if (node->isShadowRoot()) {
1686             int count = 0;
1687             for (ShadowRoot* shadowRoot = toShadowRoot(node)->olderShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot())
1688                 ++count;
1689             fprintf(stderr, "/#shadow-root[%d]", count);
1690             continue;
1691         }
1692 
1693         switch (node->nodeType()) {
1694         case ELEMENT_NODE: {
1695             fprintf(stderr, "/%s", node->nodeName().utf8().data());
1696 
1697             const Element* element = toElement(node);
1698             const AtomicString& idattr = element->getIdAttribute();
1699             bool hasIdAttr = !idattr.isNull() && !idattr.isEmpty();
1700             if (node->previousSibling() || node->nextSibling()) {
1701                 int count = 0;
1702                 for (Node* previous = node->previousSibling(); previous; previous = previous->previousSibling())
1703                     if (previous->nodeName() == node->nodeName())
1704                         ++count;
1705                 if (hasIdAttr)
1706                     fprintf(stderr, "[@id=\"%s\" and position()=%d]", idattr.utf8().data(), count);
1707                 else
1708                     fprintf(stderr, "[%d]", count);
1709             } else if (hasIdAttr) {
1710                 fprintf(stderr, "[@id=\"%s\"]", idattr.utf8().data());
1711             }
1712             break;
1713         }
1714         case TEXT_NODE:
1715             fprintf(stderr, "/text()");
1716             break;
1717         case ATTRIBUTE_NODE:
1718             fprintf(stderr, "/@%s", node->nodeName().utf8().data());
1719             break;
1720         default:
1721             break;
1722         }
1723     }
1724     fprintf(stderr, "\n");
1725 }
1726 
traverseTreeAndMark(const String & baseIndent,const Node * rootNode,const Node * markedNode1,const char * markedLabel1,const Node * markedNode2,const char * markedLabel2)1727 static void traverseTreeAndMark(const String& baseIndent, const Node* rootNode, const Node* markedNode1, const char* markedLabel1, const Node* markedNode2, const char* markedLabel2)
1728 {
1729     for (const Node* node = rootNode; node; node = NodeTraversal::next(*node)) {
1730         if (node == markedNode1)
1731             fprintf(stderr, "%s", markedLabel1);
1732         if (node == markedNode2)
1733             fprintf(stderr, "%s", markedLabel2);
1734 
1735         StringBuilder indent;
1736         indent.append(baseIndent);
1737         for (const Node* tmpNode = node; tmpNode && tmpNode != rootNode; tmpNode = tmpNode->parentOrShadowHostNode())
1738             indent.append('\t');
1739         fprintf(stderr, "%s", indent.toString().utf8().data());
1740         node->showNode();
1741         indent.append('\t');
1742         if (node->isShadowRoot()) {
1743             if (ShadowRoot* youngerShadowRoot = toShadowRoot(node)->youngerShadowRoot())
1744                 traverseTreeAndMark(indent.toString(), youngerShadowRoot, markedNode1, markedLabel1, markedNode2, markedLabel2);
1745         } else if (ShadowRoot* oldestShadowRoot = oldestShadowRootFor(node))
1746             traverseTreeAndMark(indent.toString(), oldestShadowRoot, markedNode1, markedLabel1, markedNode2, markedLabel2);
1747     }
1748 }
1749 
showTreeAndMark(const Node * markedNode1,const char * markedLabel1,const Node * markedNode2,const char * markedLabel2) const1750 void Node::showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2, const char* markedLabel2) const
1751 {
1752     const Node* rootNode;
1753     const Node* node = this;
1754     while (node->parentOrShadowHostNode() && !isHTMLBodyElement(*node))
1755         node = node->parentOrShadowHostNode();
1756     rootNode = node;
1757 
1758     String startingIndent;
1759     traverseTreeAndMark(startingIndent, rootNode, markedNode1, markedLabel1, markedNode2, markedLabel2);
1760 }
1761 
formatForDebugger(char * buffer,unsigned length) const1762 void Node::formatForDebugger(char* buffer, unsigned length) const
1763 {
1764     String result;
1765     String s;
1766 
1767     s = nodeName();
1768     if (s.isEmpty())
1769         result = "<none>";
1770     else
1771         result = s;
1772 
1773     strncpy(buffer, result.utf8().data(), length - 1);
1774 }
1775 
parentOrShadowHostOrFrameOwner(const Node * node)1776 static ContainerNode* parentOrShadowHostOrFrameOwner(const Node* node)
1777 {
1778     ContainerNode* parent = node->parentOrShadowHostNode();
1779     if (!parent && node->document().frame())
1780         parent = node->document().frame()->deprecatedLocalOwner();
1781     return parent;
1782 }
1783 
showSubTreeAcrossFrame(const Node * node,const Node * markedNode,const String & indent)1784 static void showSubTreeAcrossFrame(const Node* node, const Node* markedNode, const String& indent)
1785 {
1786     if (node == markedNode)
1787         fputs("*", stderr);
1788     fputs(indent.utf8().data(), stderr);
1789     node->showNode();
1790     if (node->isShadowRoot()) {
1791         if (ShadowRoot* youngerShadowRoot = toShadowRoot(node)->youngerShadowRoot())
1792             showSubTreeAcrossFrame(youngerShadowRoot, markedNode, indent + "\t");
1793     } else {
1794         if (node->isFrameOwnerElement())
1795             showSubTreeAcrossFrame(toHTMLFrameOwnerElement(node)->contentDocument(), markedNode, indent + "\t");
1796         if (ShadowRoot* oldestShadowRoot = oldestShadowRootFor(node))
1797             showSubTreeAcrossFrame(oldestShadowRoot, markedNode, indent + "\t");
1798     }
1799     for (Node* child = node->firstChild(); child; child = child->nextSibling())
1800         showSubTreeAcrossFrame(child, markedNode, indent + "\t");
1801 }
1802 
showTreeForThisAcrossFrame() const1803 void Node::showTreeForThisAcrossFrame() const
1804 {
1805     Node* rootNode = const_cast<Node*>(this);
1806     while (parentOrShadowHostOrFrameOwner(rootNode))
1807         rootNode = parentOrShadowHostOrFrameOwner(rootNode);
1808     showSubTreeAcrossFrame(rootNode, this, "");
1809 }
1810 
1811 #endif
1812 
1813 // --------
1814 
enclosingLinkEventParentOrSelf()1815 Element* Node::enclosingLinkEventParentOrSelf()
1816 {
1817     for (Node* node = this; node; node = NodeRenderingTraversal::parent(node)) {
1818         // For imagemaps, the enclosing link node is the associated area element not the image itself.
1819         // So we don't let images be the enclosingLinkNode, even though isLink sometimes returns true
1820         // for them.
1821         if (node->isLink() && !isHTMLImageElement(*node)) {
1822             // Casting to Element is safe because only HTMLAnchorElement, HTMLImageElement and
1823             // SVGAElement can return true for isLink().
1824             return toElement(node);
1825         }
1826     }
1827 
1828     return 0;
1829 }
1830 
interfaceName() const1831 const AtomicString& Node::interfaceName() const
1832 {
1833     return EventTargetNames::Node;
1834 }
1835 
executionContext() const1836 ExecutionContext* Node::executionContext() const
1837 {
1838     return document().contextDocument().get();
1839 }
1840 
didMoveToNewDocument(Document & oldDocument)1841 void Node::didMoveToNewDocument(Document& oldDocument)
1842 {
1843     TreeScopeAdopter::ensureDidMoveToNewDocumentWasCalled(oldDocument);
1844 
1845     if (const EventTargetData* eventTargetData = this->eventTargetData()) {
1846         const EventListenerMap& listenerMap = eventTargetData->eventListenerMap;
1847         if (!listenerMap.isEmpty()) {
1848             Vector<AtomicString> types = listenerMap.eventTypes();
1849             for (unsigned i = 0; i < types.size(); ++i)
1850                 document().addListenerTypeIfNeeded(types[i]);
1851         }
1852     }
1853 
1854     Settings* settings = document().settings();
1855     if (settings && settings->accessibilityEnabled()) {
1856         if (AXObjectCache* cache = oldDocument.existingAXObjectCache())
1857             cache->remove(this);
1858     }
1859 
1860     oldDocument.markers().removeMarkers(this);
1861     oldDocument.updateRangesAfterNodeMovedToAnotherDocument(*this);
1862     if (oldDocument.frameHost() && !document().frameHost())
1863         oldDocument.frameHost()->eventHandlerRegistry().didMoveOutOfFrameHost(*this);
1864     else if (document().frameHost() && !oldDocument.frameHost())
1865         document().frameHost()->eventHandlerRegistry().didMoveIntoFrameHost(*this);
1866     else if (oldDocument.frameHost() != document().frameHost())
1867         EventHandlerRegistry::didMoveBetweenFrameHosts(*this, oldDocument.frameHost(), document().frameHost());
1868 
1869     if (WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* registry = mutationObserverRegistry()) {
1870         for (size_t i = 0; i < registry->size(); ++i) {
1871             document().addMutationObserverTypes(registry->at(i)->mutationTypes());
1872         }
1873     }
1874 
1875     if (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* transientRegistry = transientMutationObserverRegistry()) {
1876         for (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter) {
1877             document().addMutationObserverTypes((*iter)->mutationTypes());
1878         }
1879     }
1880 }
1881 
tryAddEventListener(Node * targetNode,const AtomicString & eventType,PassRefPtr<EventListener> listener,bool useCapture)1882 static inline bool tryAddEventListener(Node* targetNode, const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
1883 {
1884     if (!targetNode->EventTarget::addEventListener(eventType, listener, useCapture))
1885         return false;
1886 
1887     Document& document = targetNode->document();
1888     document.addListenerTypeIfNeeded(eventType);
1889     if (document.frameHost())
1890         document.frameHost()->eventHandlerRegistry().didAddEventHandler(*targetNode, eventType);
1891 
1892     return true;
1893 }
1894 
addEventListener(const AtomicString & eventType,PassRefPtr<EventListener> listener,bool useCapture)1895 bool Node::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
1896 {
1897     return tryAddEventListener(this, eventType, listener, useCapture);
1898 }
1899 
tryRemoveEventListener(Node * targetNode,const AtomicString & eventType,PassRefPtr<EventListener> listener,bool useCapture)1900 static inline bool tryRemoveEventListener(Node* targetNode, const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
1901 {
1902     if (!targetNode->EventTarget::removeEventListener(eventType, listener, useCapture))
1903         return false;
1904 
1905     // FIXME: Notify Document that the listener has vanished. We need to keep track of a number of
1906     // listeners for each type, not just a bool - see https://bugs.webkit.org/show_bug.cgi?id=33861
1907     Document& document = targetNode->document();
1908     if (document.frameHost())
1909         document.frameHost()->eventHandlerRegistry().didRemoveEventHandler(*targetNode, eventType);
1910 
1911     return true;
1912 }
1913 
removeEventListener(const AtomicString & eventType,PassRefPtr<EventListener> listener,bool useCapture)1914 bool Node::removeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
1915 {
1916     return tryRemoveEventListener(this, eventType, listener, useCapture);
1917 }
1918 
removeAllEventListeners()1919 void Node::removeAllEventListeners()
1920 {
1921     if (hasEventListeners() && document().frameHost())
1922         document().frameHost()->eventHandlerRegistry().didRemoveAllEventHandlers(*this);
1923     EventTarget::removeAllEventListeners();
1924 }
1925 
removeAllEventListenersRecursively()1926 void Node::removeAllEventListenersRecursively()
1927 {
1928     for (Node* node = this; node; node = NodeTraversal::next(*node)) {
1929         node->removeAllEventListeners();
1930         for (ShadowRoot* root = node->youngestShadowRoot(); root; root = root->olderShadowRoot())
1931             root->removeAllEventListenersRecursively();
1932     }
1933 }
1934 
1935 typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<Node>, OwnPtr<EventTargetData> > EventTargetDataMap;
1936 
eventTargetDataMap()1937 static EventTargetDataMap& eventTargetDataMap()
1938 {
1939     DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<EventTargetDataMap>, map, (adoptPtrWillBeNoop(new EventTargetDataMap())));
1940     return *map;
1941 }
1942 
eventTargetData()1943 EventTargetData* Node::eventTargetData()
1944 {
1945     return hasEventTargetData() ? eventTargetDataMap().get(this) : 0;
1946 }
1947 
ensureEventTargetData()1948 EventTargetData& Node::ensureEventTargetData()
1949 {
1950     if (hasEventTargetData())
1951         return *eventTargetDataMap().get(this);
1952     setHasEventTargetData(true);
1953     EventTargetData* data = new EventTargetData;
1954     eventTargetDataMap().set(this, adoptPtr(data));
1955     return *data;
1956 }
1957 
1958 #if !ENABLE(OILPAN)
clearEventTargetData()1959 void Node::clearEventTargetData()
1960 {
1961     eventTargetDataMap().remove(this);
1962 }
1963 #endif
1964 
mutationObserverRegistry()1965 WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* Node::mutationObserverRegistry()
1966 {
1967     if (!hasRareData())
1968         return 0;
1969     NodeMutationObserverData* data = rareData()->mutationObserverData();
1970     if (!data)
1971         return 0;
1972     return &data->registry;
1973 }
1974 
transientMutationObserverRegistry()1975 WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* Node::transientMutationObserverRegistry()
1976 {
1977     if (!hasRareData())
1978         return 0;
1979     NodeMutationObserverData* data = rareData()->mutationObserverData();
1980     if (!data)
1981         return 0;
1982     return &data->transientRegistry;
1983 }
1984 
1985 template<typename Registry>
collectMatchingObserversForMutation(WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>,MutationRecordDeliveryOptions> & observers,Registry * registry,Node & target,MutationObserver::MutationType type,const QualifiedName * attributeName)1986 static inline void collectMatchingObserversForMutation(WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>& observers, Registry* registry, Node& target, MutationObserver::MutationType type, const QualifiedName* attributeName)
1987 {
1988     if (!registry)
1989         return;
1990     for (typename Registry::iterator iter = registry->begin(); iter != registry->end(); ++iter) {
1991         const MutationObserverRegistration& registration = **iter;
1992         if (registration.shouldReceiveMutationFrom(target, type, attributeName)) {
1993             MutationRecordDeliveryOptions deliveryOptions = registration.deliveryOptions();
1994             WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>::AddResult result = observers.add(&registration.observer(), deliveryOptions);
1995             if (!result.isNewEntry)
1996                 result.storedValue->value |= deliveryOptions;
1997         }
1998     }
1999 }
2000 
getRegisteredMutationObserversOfType(WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>,MutationRecordDeliveryOptions> & observers,MutationObserver::MutationType type,const QualifiedName * attributeName)2001 void Node::getRegisteredMutationObserversOfType(WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>& observers, MutationObserver::MutationType type, const QualifiedName* attributeName)
2002 {
2003     ASSERT((type == MutationObserver::Attributes && attributeName) || !attributeName);
2004     collectMatchingObserversForMutation(observers, mutationObserverRegistry(), *this, type, attributeName);
2005     collectMatchingObserversForMutation(observers, transientMutationObserverRegistry(), *this, type, attributeName);
2006     for (Node* node = parentNode(); node; node = node->parentNode()) {
2007         collectMatchingObserversForMutation(observers, node->mutationObserverRegistry(), *this, type, attributeName);
2008         collectMatchingObserversForMutation(observers, node->transientMutationObserverRegistry(), *this, type, attributeName);
2009     }
2010 }
2011 
registerMutationObserver(MutationObserver & observer,MutationObserverOptions options,const HashSet<AtomicString> & attributeFilter)2012 void Node::registerMutationObserver(MutationObserver& observer, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
2013 {
2014     MutationObserverRegistration* registration = 0;
2015     WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >& registry = ensureRareData().ensureMutationObserverData().registry;
2016     for (size_t i = 0; i < registry.size(); ++i) {
2017         if (&registry[i]->observer() == &observer) {
2018             registration = registry[i].get();
2019             registration->resetObservation(options, attributeFilter);
2020         }
2021     }
2022 
2023     if (!registration) {
2024         registry.append(MutationObserverRegistration::create(observer, this, options, attributeFilter));
2025         registration = registry.last().get();
2026     }
2027 
2028     document().addMutationObserverTypes(registration->mutationTypes());
2029 }
2030 
unregisterMutationObserver(MutationObserverRegistration * registration)2031 void Node::unregisterMutationObserver(MutationObserverRegistration* registration)
2032 {
2033     WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* registry = mutationObserverRegistry();
2034     ASSERT(registry);
2035     if (!registry)
2036         return;
2037 
2038     size_t index = registry->find(registration);
2039     ASSERT(index != kNotFound);
2040     if (index == kNotFound)
2041         return;
2042 
2043     // Deleting the registration may cause this node to be derefed, so we must make sure the Vector operation completes
2044     // before that, in case |this| is destroyed (see MutationObserverRegistration::m_registrationNodeKeepAlive).
2045     // FIXME: Simplify the registration/transient registration logic to make this understandable by humans.
2046     RefPtrWillBeRawPtr<Node> protect(this);
2047 #if ENABLE(OILPAN)
2048     // The explicit dispose() is needed to have the registration
2049     // object unregister itself promptly.
2050     registration->dispose();
2051 #endif
2052     registry->remove(index);
2053 }
2054 
registerTransientMutationObserver(MutationObserverRegistration * registration)2055 void Node::registerTransientMutationObserver(MutationObserverRegistration* registration)
2056 {
2057     ensureRareData().ensureMutationObserverData().transientRegistry.add(registration);
2058 }
2059 
unregisterTransientMutationObserver(MutationObserverRegistration * registration)2060 void Node::unregisterTransientMutationObserver(MutationObserverRegistration* registration)
2061 {
2062     WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* transientRegistry = transientMutationObserverRegistry();
2063     ASSERT(transientRegistry);
2064     if (!transientRegistry)
2065         return;
2066 
2067     ASSERT(transientRegistry->contains(registration));
2068     transientRegistry->remove(registration);
2069 }
2070 
notifyMutationObserversNodeWillDetach()2071 void Node::notifyMutationObserversNodeWillDetach()
2072 {
2073     if (!document().hasMutationObservers())
2074         return;
2075 
2076     for (Node* node = parentNode(); node; node = node->parentNode()) {
2077         if (WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* registry = node->mutationObserverRegistry()) {
2078             const size_t size = registry->size();
2079             for (size_t i = 0; i < size; ++i)
2080                 registry->at(i)->observedSubtreeNodeWillDetach(*this);
2081         }
2082 
2083         if (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* transientRegistry = node->transientMutationObserverRegistry()) {
2084             for (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter)
2085                 (*iter)->observedSubtreeNodeWillDetach(*this);
2086         }
2087     }
2088 }
2089 
handleLocalEvents(Event * event)2090 void Node::handleLocalEvents(Event* event)
2091 {
2092     if (!hasEventTargetData())
2093         return;
2094 
2095     if (isDisabledFormControl(this) && event->isMouseEvent())
2096         return;
2097 
2098     fireEventListeners(event);
2099 }
2100 
dispatchScopedEvent(PassRefPtrWillBeRawPtr<Event> event)2101 void Node::dispatchScopedEvent(PassRefPtrWillBeRawPtr<Event> event)
2102 {
2103     dispatchScopedEventDispatchMediator(EventDispatchMediator::create(event));
2104 }
2105 
dispatchScopedEventDispatchMediator(PassRefPtrWillBeRawPtr<EventDispatchMediator> eventDispatchMediator)2106 void Node::dispatchScopedEventDispatchMediator(PassRefPtrWillBeRawPtr<EventDispatchMediator> eventDispatchMediator)
2107 {
2108     EventDispatcher::dispatchScopedEvent(this, eventDispatchMediator);
2109 }
2110 
dispatchEvent(PassRefPtrWillBeRawPtr<Event> event)2111 bool Node::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event)
2112 {
2113     if (event->isMouseEvent())
2114         return EventDispatcher::dispatchEvent(this, MouseEventDispatchMediator::create(static_pointer_cast<MouseEvent>(event), MouseEventDispatchMediator::SyntheticMouseEvent));
2115     if (event->isTouchEvent())
2116         return dispatchTouchEvent(static_pointer_cast<TouchEvent>(event));
2117     return EventDispatcher::dispatchEvent(this, EventDispatchMediator::create(event));
2118 }
2119 
dispatchSubtreeModifiedEvent()2120 void Node::dispatchSubtreeModifiedEvent()
2121 {
2122     if (isInShadowTree())
2123         return;
2124 
2125     ASSERT(!EventDispatchForbiddenScope::isEventDispatchForbidden());
2126 
2127     if (!document().hasListenerType(Document::DOMSUBTREEMODIFIED_LISTENER))
2128         return;
2129 
2130     dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMSubtreeModified, true));
2131 }
2132 
dispatchDOMActivateEvent(int detail,PassRefPtrWillBeRawPtr<Event> underlyingEvent)2133 bool Node::dispatchDOMActivateEvent(int detail, PassRefPtrWillBeRawPtr<Event> underlyingEvent)
2134 {
2135     ASSERT(!EventDispatchForbiddenScope::isEventDispatchForbidden());
2136     RefPtrWillBeRawPtr<UIEvent> event = UIEvent::create(EventTypeNames::DOMActivate, true, true, document().domWindow(), detail);
2137     event->setUnderlyingEvent(underlyingEvent);
2138     dispatchScopedEvent(event);
2139     return event->defaultHandled();
2140 }
2141 
dispatchKeyEvent(const PlatformKeyboardEvent & event)2142 bool Node::dispatchKeyEvent(const PlatformKeyboardEvent& event)
2143 {
2144     return EventDispatcher::dispatchEvent(this, KeyboardEventDispatchMediator::create(KeyboardEvent::create(event, document().domWindow())));
2145 }
2146 
dispatchMouseEvent(const PlatformMouseEvent & event,const AtomicString & eventType,int detail,Node * relatedTarget)2147 bool Node::dispatchMouseEvent(const PlatformMouseEvent& event, const AtomicString& eventType,
2148     int detail, Node* relatedTarget)
2149 {
2150     return EventDispatcher::dispatchEvent(this, MouseEventDispatchMediator::create(MouseEvent::create(eventType, document().domWindow(), event, detail, relatedTarget)));
2151 }
2152 
dispatchGestureEvent(const PlatformGestureEvent & event)2153 bool Node::dispatchGestureEvent(const PlatformGestureEvent& event)
2154 {
2155     RefPtrWillBeRawPtr<GestureEvent> gestureEvent = GestureEvent::create(document().domWindow(), event);
2156     if (!gestureEvent.get())
2157         return false;
2158     return EventDispatcher::dispatchEvent(this, GestureEventDispatchMediator::create(gestureEvent));
2159 }
2160 
dispatchTouchEvent(PassRefPtrWillBeRawPtr<TouchEvent> event)2161 bool Node::dispatchTouchEvent(PassRefPtrWillBeRawPtr<TouchEvent> event)
2162 {
2163     return EventDispatcher::dispatchEvent(this, TouchEventDispatchMediator::create(event));
2164 }
2165 
dispatchSimulatedClick(Event * underlyingEvent,SimulatedClickMouseEventOptions eventOptions)2166 void Node::dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions eventOptions)
2167 {
2168     EventDispatcher::dispatchSimulatedClick(this, underlyingEvent, eventOptions);
2169 }
2170 
dispatchWheelEvent(const PlatformWheelEvent & event)2171 bool Node::dispatchWheelEvent(const PlatformWheelEvent& event)
2172 {
2173     return EventDispatcher::dispatchEvent(this, WheelEventDispatchMediator::create(event, document().domWindow()));
2174 }
2175 
dispatchInputEvent()2176 void Node::dispatchInputEvent()
2177 {
2178     dispatchScopedEvent(Event::createBubble(EventTypeNames::input));
2179 }
2180 
defaultEventHandler(Event * event)2181 void Node::defaultEventHandler(Event* event)
2182 {
2183     if (event->target() != this)
2184         return;
2185     const AtomicString& eventType = event->type();
2186     if (eventType == EventTypeNames::keydown || eventType == EventTypeNames::keypress) {
2187         if (event->isKeyboardEvent()) {
2188             if (LocalFrame* frame = document().frame())
2189                 frame->eventHandler().defaultKeyboardEventHandler(toKeyboardEvent(event));
2190         }
2191     } else if (eventType == EventTypeNames::click) {
2192         int detail = event->isUIEvent() ? static_cast<UIEvent*>(event)->detail() : 0;
2193         if (dispatchDOMActivateEvent(detail, event))
2194             event->setDefaultHandled();
2195     } else if (eventType == EventTypeNames::contextmenu) {
2196         if (Page* page = document().page())
2197             page->contextMenuController().handleContextMenuEvent(event);
2198     } else if (eventType == EventTypeNames::textInput) {
2199         if (event->hasInterface(EventNames::TextEvent)) {
2200             if (LocalFrame* frame = document().frame())
2201                 frame->eventHandler().defaultTextInputEventHandler(toTextEvent(event));
2202         }
2203 #if OS(WIN)
2204     } else if (eventType == EventTypeNames::mousedown && event->isMouseEvent()) {
2205         MouseEvent* mouseEvent = toMouseEvent(event);
2206         if (mouseEvent->button() == MiddleButton) {
2207             if (enclosingLinkEventParentOrSelf())
2208                 return;
2209 
2210             // Avoid that canBeScrolledAndHasScrollableArea changes render tree
2211             // structure.
2212             // FIXME: We should avoid synchronous layout if possible. We can
2213             // remove this synchronous layout if we avoid synchronous layout in
2214             // RenderTextControlSingleLine::scrollHeight
2215             document().updateLayoutIgnorePendingStylesheets();
2216             RenderObject* renderer = this->renderer();
2217             while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeScrolledAndHasScrollableArea()))
2218                 renderer = renderer->parent();
2219 
2220             if (renderer) {
2221                 if (LocalFrame* frame = document().frame())
2222                     frame->eventHandler().startPanScrolling(renderer);
2223             }
2224         }
2225 #endif
2226     } else if ((eventType == EventTypeNames::wheel || eventType == EventTypeNames::mousewheel) && event->hasInterface(EventNames::WheelEvent)) {
2227         WheelEvent* wheelEvent = toWheelEvent(event);
2228 
2229         // If we don't have a renderer, send the wheel event to the first node we find with a renderer.
2230         // This is needed for <option> and <optgroup> elements so that <select>s get a wheel scroll.
2231         Node* startNode = this;
2232         while (startNode && !startNode->renderer())
2233             startNode = startNode->parentOrShadowHostNode();
2234 
2235         if (startNode && startNode->renderer()) {
2236             if (LocalFrame* frame = document().frame())
2237                 frame->eventHandler().defaultWheelEventHandler(startNode, wheelEvent);
2238         }
2239     } else if (event->type() == EventTypeNames::webkitEditableContentChanged) {
2240         dispatchInputEvent();
2241     }
2242 }
2243 
willCallDefaultEventHandler(const Event &)2244 void Node::willCallDefaultEventHandler(const Event&)
2245 {
2246 }
2247 
willRespondToMouseMoveEvents()2248 bool Node::willRespondToMouseMoveEvents()
2249 {
2250     if (isDisabledFormControl(this))
2251         return false;
2252     return hasEventListeners(EventTypeNames::mousemove) || hasEventListeners(EventTypeNames::mouseover) || hasEventListeners(EventTypeNames::mouseout);
2253 }
2254 
willRespondToMouseClickEvents()2255 bool Node::willRespondToMouseClickEvents()
2256 {
2257     if (isDisabledFormControl(this))
2258         return false;
2259     return isContentEditable(UserSelectAllIsAlwaysNonEditable) || hasEventListeners(EventTypeNames::mouseup) || hasEventListeners(EventTypeNames::mousedown) || hasEventListeners(EventTypeNames::click) || hasEventListeners(EventTypeNames::DOMActivate);
2260 }
2261 
willRespondToTouchEvents()2262 bool Node::willRespondToTouchEvents()
2263 {
2264     if (isDisabledFormControl(this))
2265         return false;
2266     return hasEventListeners(EventTypeNames::touchstart) || hasEventListeners(EventTypeNames::touchmove) || hasEventListeners(EventTypeNames::touchcancel) || hasEventListeners(EventTypeNames::touchend);
2267 }
2268 
2269 #if !ENABLE(OILPAN)
2270 // This is here for inlining
removedLastRefToScope()2271 inline void TreeScope::removedLastRefToScope()
2272 {
2273     ASSERT_WITH_SECURITY_IMPLICATION(!deletionHasBegun());
2274     if (m_guardRefCount) {
2275         // If removing a child removes the last self-only ref, we don't
2276         // want the scope to be destructed until after
2277         // removeDetachedChildren returns, so we guard ourselves with an
2278         // extra self-only ref.
2279         guardRef();
2280         dispose();
2281 #if ENABLE(ASSERT)
2282         // We need to do this right now since guardDeref() can delete this.
2283         rootNode().m_inRemovedLastRefFunction = false;
2284 #endif
2285         guardDeref();
2286     } else {
2287 #if ENABLE(ASSERT)
2288         rootNode().m_inRemovedLastRefFunction = false;
2289 #endif
2290 #if ENABLE(SECURITY_ASSERT)
2291         beginDeletion();
2292 #endif
2293         delete this;
2294     }
2295 }
2296 
2297 // It's important not to inline removedLastRef, because we don't want to inline the code to
2298 // delete a Node at each deref call site.
removedLastRef()2299 void Node::removedLastRef()
2300 {
2301     // An explicit check for Document here is better than a virtual function since it is
2302     // faster for non-Document nodes, and because the call to removedLastRef that is inlined
2303     // at all deref call sites is smaller if it's a non-virtual function.
2304     if (isTreeScope()) {
2305         treeScope().removedLastRefToScope();
2306         return;
2307     }
2308 
2309 #if ENABLE(SECURITY_ASSERT)
2310     m_deletionHasBegun = true;
2311 #endif
2312     delete this;
2313 }
2314 #endif
2315 
connectedSubframeCount() const2316 unsigned Node::connectedSubframeCount() const
2317 {
2318     return hasRareData() ? rareData()->connectedSubframeCount() : 0;
2319 }
2320 
incrementConnectedSubframeCount(unsigned amount)2321 void Node::incrementConnectedSubframeCount(unsigned amount)
2322 {
2323     ASSERT(isContainerNode());
2324     ensureRareData().incrementConnectedSubframeCount(amount);
2325 }
2326 
decrementConnectedSubframeCount(unsigned amount)2327 void Node::decrementConnectedSubframeCount(unsigned amount)
2328 {
2329     rareData()->decrementConnectedSubframeCount(amount);
2330 }
2331 
updateAncestorConnectedSubframeCountForRemoval() const2332 void Node::updateAncestorConnectedSubframeCountForRemoval() const
2333 {
2334     unsigned count = connectedSubframeCount();
2335 
2336     if (!count)
2337         return;
2338 
2339     for (Node* node = parentOrShadowHostNode(); node; node = node->parentOrShadowHostNode())
2340         node->decrementConnectedSubframeCount(count);
2341 }
2342 
updateAncestorConnectedSubframeCountForInsertion() const2343 void Node::updateAncestorConnectedSubframeCountForInsertion() const
2344 {
2345     unsigned count = connectedSubframeCount();
2346 
2347     if (!count)
2348         return;
2349 
2350     for (Node* node = parentOrShadowHostNode(); node; node = node->parentOrShadowHostNode())
2351         node->incrementConnectedSubframeCount(count);
2352 }
2353 
getDestinationInsertionPoints()2354 PassRefPtrWillBeRawPtr<StaticNodeList> Node::getDestinationInsertionPoints()
2355 {
2356     document().updateDistributionForNodeIfNeeded(this);
2357     WillBeHeapVector<RawPtrWillBeMember<InsertionPoint>, 8> insertionPoints;
2358     collectDestinationInsertionPoints(*this, insertionPoints);
2359     WillBeHeapVector<RefPtrWillBeMember<Node> > filteredInsertionPoints;
2360     for (size_t i = 0; i < insertionPoints.size(); ++i) {
2361         InsertionPoint* insertionPoint = insertionPoints[i];
2362         ASSERT(insertionPoint->containingShadowRoot());
2363         if (insertionPoint->containingShadowRoot()->type() != ShadowRoot::UserAgentShadowRoot)
2364             filteredInsertionPoints.append(insertionPoint);
2365     }
2366     return StaticNodeList::adopt(filteredInsertionPoints);
2367 }
2368 
setFocus(bool flag)2369 void Node::setFocus(bool flag)
2370 {
2371     document().userActionElements().setFocused(this, flag);
2372 }
2373 
setActive(bool flag)2374 void Node::setActive(bool flag)
2375 {
2376     document().userActionElements().setActive(this, flag);
2377 }
2378 
setHovered(bool flag)2379 void Node::setHovered(bool flag)
2380 {
2381     document().userActionElements().setHovered(this, flag);
2382 }
2383 
isUserActionElementActive() const2384 bool Node::isUserActionElementActive() const
2385 {
2386     ASSERT(isUserActionElement());
2387     return document().userActionElements().isActive(this);
2388 }
2389 
isUserActionElementInActiveChain() const2390 bool Node::isUserActionElementInActiveChain() const
2391 {
2392     ASSERT(isUserActionElement());
2393     return document().userActionElements().isInActiveChain(this);
2394 }
2395 
isUserActionElementHovered() const2396 bool Node::isUserActionElementHovered() const
2397 {
2398     ASSERT(isUserActionElement());
2399     return document().userActionElements().isHovered(this);
2400 }
2401 
isUserActionElementFocused() const2402 bool Node::isUserActionElementFocused() const
2403 {
2404     ASSERT(isUserActionElement());
2405     return document().userActionElements().isFocused(this);
2406 }
2407 
setCustomElementState(CustomElementState newState)2408 void Node::setCustomElementState(CustomElementState newState)
2409 {
2410     CustomElementState oldState = customElementState();
2411 
2412     switch (newState) {
2413     case NotCustomElement:
2414         ASSERT_NOT_REACHED(); // Everything starts in this state
2415         return;
2416 
2417     case WaitingForUpgrade:
2418         ASSERT(NotCustomElement == oldState);
2419         break;
2420 
2421     case Upgraded:
2422         ASSERT(WaitingForUpgrade == oldState);
2423         break;
2424     }
2425 
2426     ASSERT(isHTMLElement() || isSVGElement());
2427     setFlag(CustomElementFlag);
2428     setFlag(newState == Upgraded, CustomElementUpgradedFlag);
2429 
2430     if (oldState == NotCustomElement || newState == Upgraded)
2431         setNeedsStyleRecalc(SubtreeStyleChange); // :unresolved has changed
2432 }
2433 
trace(Visitor * visitor)2434 void Node::trace(Visitor* visitor)
2435 {
2436 #if ENABLE(OILPAN)
2437     visitor->trace(m_parentOrShadowHostNode);
2438     visitor->trace(m_previous);
2439     visitor->trace(m_next);
2440     // rareData() and m_data.m_renderer share their storage. We have to trace
2441     // only one of them.
2442     if (hasRareData())
2443         visitor->trace(rareData());
2444     else
2445         visitor->trace(m_data.m_renderer);
2446     visitor->trace(m_treeScope);
2447 #endif
2448     EventTarget::trace(visitor);
2449 }
2450 
lengthOfContents() const2451 unsigned Node::lengthOfContents() const
2452 {
2453     // This switch statement must be consistent with that of Range::processContentsBetweenOffsets.
2454     switch (nodeType()) {
2455     case Node::TEXT_NODE:
2456     case Node::CDATA_SECTION_NODE:
2457     case Node::COMMENT_NODE:
2458         return toCharacterData(this)->length();
2459     case Node::PROCESSING_INSTRUCTION_NODE:
2460         return toProcessingInstruction(this)->data().length();
2461     case Node::ELEMENT_NODE:
2462     case Node::ATTRIBUTE_NODE:
2463     case Node::DOCUMENT_NODE:
2464     case Node::DOCUMENT_FRAGMENT_NODE:
2465         return toContainerNode(this)->countChildren();
2466     case Node::DOCUMENT_TYPE_NODE:
2467         return 0;
2468     }
2469     ASSERT_NOT_REACHED();
2470     return 0;
2471 }
2472 
wrap(v8::Handle<v8::Object> creationContext,v8::Isolate * isolate)2473 v8::Handle<v8::Object> Node::wrap(v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
2474 {
2475     // It's possible that no one except for the new wrapper owns this object at
2476     // this moment, so we have to prevent GC to collect this object until the
2477     // object gets associated with the wrapper.
2478     RefPtrWillBeRawPtr<Node> protect(this);
2479 
2480     ASSERT(!DOMDataStore::containsWrapperNonTemplate(this, isolate));
2481 
2482     const WrapperTypeInfo* wrapperType = wrapperTypeInfo();
2483 
2484     v8::Handle<v8::Object> wrapper = V8DOMWrapper::createWrapper(creationContext, wrapperType, toScriptWrappableBase(), isolate);
2485     if (UNLIKELY(wrapper.IsEmpty()))
2486         return wrapper;
2487 
2488     wrapperType->installConditionallyEnabledProperties(wrapper, isolate);
2489     return associateWithWrapper(wrapperType, wrapper, isolate);
2490 }
2491 
associateWithWrapper(const WrapperTypeInfo * wrapperType,v8::Handle<v8::Object> wrapper,v8::Isolate * isolate)2492 v8::Handle<v8::Object> Node::associateWithWrapper(const WrapperTypeInfo* wrapperType, v8::Handle<v8::Object> wrapper, v8::Isolate* isolate)
2493 {
2494     return V8DOMWrapper::associateObjectWithWrapperNonTemplate(this, wrapperType, wrapper, isolate);
2495 }
2496 
2497 } // namespace blink
2498 
2499 #ifndef NDEBUG
2500 
showNode(const blink::Node * node)2501 void showNode(const blink::Node* node)
2502 {
2503     if (node)
2504         node->showNode("");
2505 }
2506 
showTree(const blink::Node * node)2507 void showTree(const blink::Node* node)
2508 {
2509     if (node)
2510         node->showTreeForThis();
2511 }
2512 
showNodePath(const blink::Node * node)2513 void showNodePath(const blink::Node* node)
2514 {
2515     if (node)
2516         node->showNodePathForThis();
2517 }
2518 
2519 #endif
2520