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