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