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