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 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 "Node.h"
27 
28 #include "AXObjectCache.h"
29 #include "Attr.h"
30 #include "Attribute.h"
31 #include "CSSParser.h"
32 #include "CSSRule.h"
33 #include "CSSRuleList.h"
34 #include "CSSSelector.h"
35 #include "CSSSelectorList.h"
36 #include "CSSStyleRule.h"
37 #include "CSSStyleSelector.h"
38 #include "CSSStyleSheet.h"
39 #include "ChildNodeList.h"
40 #include "ClassNodeList.h"
41 #include "ContextMenuController.h"
42 #include "DOMImplementation.h"
43 #include "Document.h"
44 #include "DocumentType.h"
45 #include "DynamicNodeList.h"
46 #include "Element.h"
47 #include "Event.h"
48 #include "EventContext.h"
49 #include "EventDispatcher.h"
50 #include "EventException.h"
51 #include "EventHandler.h"
52 #include "EventListener.h"
53 #include "EventNames.h"
54 #include "ExceptionCode.h"
55 #include "Frame.h"
56 #include "FrameView.h"
57 #include "HTMLElement.h"
58 #include "HTMLNames.h"
59 #include "InspectorInstrumentation.h"
60 #include "KeyboardEvent.h"
61 #include "LabelsNodeList.h"
62 #include "Logging.h"
63 #include "MouseEvent.h"
64 #include "MutationEvent.h"
65 #include "NameNodeList.h"
66 #include "NamedNodeMap.h"
67 #include "NodeRareData.h"
68 #include "Page.h"
69 #include "PlatformMouseEvent.h"
70 #include "PlatformWheelEvent.h"
71 #include "ProcessingInstruction.h"
72 #include "ProgressEvent.h"
73 #include "RegisteredEventListener.h"
74 #include "RenderBlock.h"
75 #include "RenderBox.h"
76 #include "RenderFullScreen.h"
77 #include "RenderTextControl.h"
78 #include "RenderView.h"
79 #include "ScopedEventQueue.h"
80 #include "SelectorNodeList.h"
81 #include "ShadowRoot.h"
82 #include "StaticNodeList.h"
83 #include "TagNodeList.h"
84 #include "Text.h"
85 #include "TextEvent.h"
86 #include "UIEvent.h"
87 #include "UIEventWithKeyState.h"
88 #include "WebKitAnimationEvent.h"
89 #include "WebKitTransitionEvent.h"
90 #include "WheelEvent.h"
91 #include "WindowEventContext.h"
92 #include "XMLNames.h"
93 #include "htmlediting.h"
94 #include <wtf/HashSet.h>
95 #include <wtf/PassOwnPtr.h>
96 #include <wtf/RefCountedLeakCounter.h>
97 #include <wtf/UnusedParam.h>
98 #include <wtf/text/CString.h>
99 #include <wtf/text/StringBuilder.h>
100 
101 #if ENABLE(DOM_STORAGE)
102 #include "StorageEvent.h"
103 #endif
104 
105 #if ENABLE(SVG)
106 #include "SVGElementInstance.h"
107 #include "SVGUseElement.h"
108 #endif
109 
110 #if ENABLE(XHTMLMP)
111 #include "HTMLNoScriptElement.h"
112 #endif
113 
114 #if USE(JSC)
115 #include <runtime/JSGlobalData.h>
116 #endif
117 
118 #define DUMP_NODE_STATISTICS 0
119 
120 using namespace std;
121 
122 namespace WebCore {
123 
124 using namespace HTMLNames;
125 
isSupported(const String & feature,const String & version)126 bool Node::isSupported(const String& feature, const String& version)
127 {
128     return DOMImplementation::hasFeature(feature, version);
129 }
130 
131 #if DUMP_NODE_STATISTICS
132 static HashSet<Node*> liveNodeSet;
133 #endif
134 
dumpStatistics()135 void Node::dumpStatistics()
136 {
137 #if DUMP_NODE_STATISTICS
138     size_t nodesWithRareData = 0;
139 
140     size_t elementNodes = 0;
141     size_t attrNodes = 0;
142     size_t textNodes = 0;
143     size_t cdataNodes = 0;
144     size_t commentNodes = 0;
145     size_t entityReferenceNodes = 0;
146     size_t entityNodes = 0;
147     size_t piNodes = 0;
148     size_t documentNodes = 0;
149     size_t docTypeNodes = 0;
150     size_t fragmentNodes = 0;
151     size_t notationNodes = 0;
152     size_t xpathNSNodes = 0;
153     size_t shadowRootNodes = 0;
154 
155     HashMap<String, size_t> perTagCount;
156 
157     size_t attributes = 0;
158     size_t mappedAttributes = 0;
159     size_t mappedAttributesWithStyleDecl = 0;
160     size_t attributesWithAttr = 0;
161     size_t attrMaps = 0;
162 
163     for (HashSet<Node*>::iterator it = liveNodeSet.begin(); it != liveNodeSet.end(); ++it) {
164         Node* node = *it;
165 
166         if (node->hasRareData())
167             ++nodesWithRareData;
168 
169         switch (node->nodeType()) {
170             case ELEMENT_NODE: {
171                 ++elementNodes;
172 
173                 // Tag stats
174                 Element* element = static_cast<Element*>(node);
175                 pair<HashMap<String, size_t>::iterator, bool> result = perTagCount.add(element->tagName(), 1);
176                 if (!result.second)
177                     result.first->second++;
178 
179                 // AttributeMap stats
180                 if (NamedNodeMap* attrMap = element->attributes(true)) {
181                     attributes += attrMap->length();
182                     ++attrMaps;
183                     for (unsigned i = 0; i < attrMap->length(); ++i) {
184                         Attribute* attr = attrMap->attributeItem(i);
185                         if (attr->attr())
186                             ++attributesWithAttr;
187                         if (attr->isMappedAttribute()) {
188                             ++mappedAttributes;
189                             if (attr->style())
190                                 ++mappedAttributesWithStyleDecl;
191                         }
192                     }
193                 }
194                 break;
195             }
196             case ATTRIBUTE_NODE: {
197                 ++attrNodes;
198                 break;
199             }
200             case TEXT_NODE: {
201                 ++textNodes;
202                 break;
203             }
204             case CDATA_SECTION_NODE: {
205                 ++cdataNodes;
206                 break;
207             }
208             case COMMENT_NODE: {
209                 ++commentNodes;
210                 break;
211             }
212             case ENTITY_REFERENCE_NODE: {
213                 ++entityReferenceNodes;
214                 break;
215             }
216             case ENTITY_NODE: {
217                 ++entityNodes;
218                 break;
219             }
220             case PROCESSING_INSTRUCTION_NODE: {
221                 ++piNodes;
222                 break;
223             }
224             case DOCUMENT_NODE: {
225                 ++documentNodes;
226                 break;
227             }
228             case DOCUMENT_TYPE_NODE: {
229                 ++docTypeNodes;
230                 break;
231             }
232             case DOCUMENT_FRAGMENT_NODE: {
233                 ++fragmentNodes;
234                 break;
235             }
236             case NOTATION_NODE: {
237                 ++notationNodes;
238                 break;
239             }
240             case XPATH_NAMESPACE_NODE: {
241                 ++xpathNSNodes;
242                 break;
243             }
244             case SHADOW_ROOT_NODE: {
245                 ++shadowRootNodes;
246                 break;
247             }
248         }
249     }
250 
251     printf("Number of Nodes: %d\n\n", liveNodeSet.size());
252     printf("Number of Nodes with RareData: %zu\n\n", nodesWithRareData);
253 
254     printf("NodeType distrubution:\n");
255     printf("  Number of Element nodes: %zu\n", elementNodes);
256     printf("  Number of Attribute nodes: %zu\n", attrNodes);
257     printf("  Number of Text nodes: %zu\n", textNodes);
258     printf("  Number of CDATASection nodes: %zu\n", cdataNodes);
259     printf("  Number of Comment nodes: %zu\n", commentNodes);
260     printf("  Number of EntityReference nodes: %zu\n", entityReferenceNodes);
261     printf("  Number of Entity nodes: %zu\n", entityNodes);
262     printf("  Number of ProcessingInstruction nodes: %zu\n", piNodes);
263     printf("  Number of Document nodes: %zu\n", documentNodes);
264     printf("  Number of DocumentType nodes: %zu\n", docTypeNodes);
265     printf("  Number of DocumentFragment nodes: %zu\n", fragmentNodes);
266     printf("  Number of Notation nodes: %zu\n", notationNodes);
267     printf("  Number of XPathNS nodes: %zu\n", xpathNSNodes);
268     printf("  Number of ShadowRoot nodes: %zu\n", shadowRootNodes);
269 
270     printf("Element tag name distibution:\n");
271     for (HashMap<String, size_t>::iterator it = perTagCount.begin(); it != perTagCount.end(); ++it)
272         printf("  Number of <%s> tags: %zu\n", it->first.utf8().data(), it->second);
273 
274     printf("Attribute Maps:\n");
275     printf("  Number of Attributes (non-Node and Node): %zu [%zu]\n", attributes, sizeof(Attribute));
276     printf("  Number of Attributes that are mapped: %zu\n", mappedAttributes);
277     printf("  Number of Attributes with a StyleDeclaration: %zu\n", mappedAttributesWithStyleDecl);
278     printf("  Number of Attributes with an Attr: %zu\n", attributesWithAttr);
279     printf("  Number of NamedNodeMaps: %zu [%zu]\n", attrMaps, sizeof(NamedNodeMap));
280 #endif
281 }
282 
283 #ifndef NDEBUG
284 static WTF::RefCountedLeakCounter nodeCounter("WebCoreNode");
285 
286 static bool shouldIgnoreLeaks = false;
287 static HashSet<Node*> ignoreSet;
288 #endif
289 
startIgnoringLeaks()290 void Node::startIgnoringLeaks()
291 {
292 #ifndef NDEBUG
293     shouldIgnoreLeaks = true;
294 #endif
295 }
296 
stopIgnoringLeaks()297 void Node::stopIgnoringLeaks()
298 {
299 #ifndef NDEBUG
300     shouldIgnoreLeaks = false;
301 #endif
302 }
303 
diff(const RenderStyle * s1,const RenderStyle * s2)304 Node::StyleChange Node::diff(const RenderStyle* s1, const RenderStyle* s2)
305 {
306     // FIXME: The behavior of this function is just totally wrong.  It doesn't handle
307     // explicit inheritance of non-inherited properties and so you end up not re-resolving
308     // style in cases where you need to.
309     StyleChange ch = NoInherit;
310     EDisplay display1 = s1 ? s1->display() : NONE;
311     bool fl1 = s1 && s1->hasPseudoStyle(FIRST_LETTER);
312     EDisplay display2 = s2 ? s2->display() : NONE;
313     bool fl2 = s2 && s2->hasPseudoStyle(FIRST_LETTER);
314 
315     // We just detach if a renderer acquires or loses a column-span, since spanning elements
316     // typically won't contain much content.
317     bool colSpan1 = s1 && s1->columnSpan();
318     bool colSpan2 = s2 && s2->columnSpan();
319 
320     if (display1 != display2 || fl1 != fl2 || colSpan1 != colSpan2 || (s1 && s2 && !s1->contentDataEquivalent(s2)))
321         ch = Detach;
322     else if (!s1 || !s2)
323         ch = Inherit;
324     else if (*s1 == *s2)
325         ch = NoChange;
326     else if (s1->inheritedNotEqual(s2))
327         ch = Inherit;
328 
329     // For nth-child and other positional rules, treat styles as different if they have
330     // changed positionally in the DOM. This way subsequent sibling resolutions won't be confused
331     // by the wrong child index and evaluate to incorrect results.
332     if (ch == NoChange && s1->childIndex() != s2->childIndex())
333         ch = NoInherit;
334 
335     // If the pseudoStyles have changed, we want any StyleChange that is not NoChange
336     // because setStyle will do the right thing with anything else.
337     if (ch == NoChange && s1->hasAnyPublicPseudoStyles()) {
338         for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; ch == NoChange && pseudoId < FIRST_INTERNAL_PSEUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) {
339             if (s1->hasPseudoStyle(pseudoId)) {
340                 RenderStyle* ps2 = s2->getCachedPseudoStyle(pseudoId);
341                 if (!ps2)
342                     ch = NoInherit;
343                 else {
344                     RenderStyle* ps1 = s1->getCachedPseudoStyle(pseudoId);
345                     ch = ps1 && *ps1 == *ps2 ? NoChange : NoInherit;
346                 }
347             }
348         }
349     }
350 
351     // When text-combine property has been changed, we need to prepare a separate renderer object.
352     // When text-combine is on, we use RenderCombineText, otherwise RenderText.
353     // https://bugs.webkit.org/show_bug.cgi?id=55069
354     if ((s1 && s2) && (s1->hasTextCombine() != s2->hasTextCombine()))
355         ch = Detach;
356 
357     return ch;
358 }
359 
trackForDebugging()360 void Node::trackForDebugging()
361 {
362 #ifndef NDEBUG
363     if (shouldIgnoreLeaks)
364         ignoreSet.add(this);
365     else
366         nodeCounter.increment();
367 #endif
368 
369 #if DUMP_NODE_STATISTICS
370     liveNodeSet.add(this);
371 #endif
372 }
373 
~Node()374 Node::~Node()
375 {
376 #ifndef NDEBUG
377     HashSet<Node*>::iterator it = ignoreSet.find(this);
378     if (it != ignoreSet.end())
379         ignoreSet.remove(it);
380     else
381         nodeCounter.decrement();
382 #endif
383 
384 #if DUMP_NODE_STATISTICS
385     liveNodeSet.remove(this);
386 #endif
387 
388     if (!hasRareData())
389         ASSERT(!NodeRareData::rareDataMap().contains(this));
390     else {
391         if (m_document && rareData()->nodeLists())
392             m_document->removeNodeListCache();
393 
394         NodeRareData::NodeRareDataMap& dataMap = NodeRareData::rareDataMap();
395         NodeRareData::NodeRareDataMap::iterator it = dataMap.find(this);
396         ASSERT(it != dataMap.end());
397         delete it->second;
398         dataMap.remove(it);
399     }
400 
401     if (renderer())
402         detach();
403 
404     if (AXObjectCache::accessibilityEnabled() && m_document && m_document->axObjectCacheExists())
405         m_document->axObjectCache()->removeNodeForUse(this);
406 
407     if (m_previous)
408         m_previous->setNextSibling(0);
409     if (m_next)
410         m_next->setPreviousSibling(0);
411 
412     if (m_document)
413         m_document->guardDeref();
414 }
415 
416 #ifdef NDEBUG
417 
setWillMoveToNewOwnerDocumentWasCalled(bool)418 static inline void setWillMoveToNewOwnerDocumentWasCalled(bool)
419 {
420 }
421 
setDidMoveToNewOwnerDocumentWasCalled(bool)422 static inline void setDidMoveToNewOwnerDocumentWasCalled(bool)
423 {
424 }
425 
426 #else
427 
428 static bool willMoveToNewOwnerDocumentWasCalled;
429 static bool didMoveToNewOwnerDocumentWasCalled;
430 
setWillMoveToNewOwnerDocumentWasCalled(bool wasCalled)431 static void setWillMoveToNewOwnerDocumentWasCalled(bool wasCalled)
432 {
433     willMoveToNewOwnerDocumentWasCalled = wasCalled;
434 }
435 
setDidMoveToNewOwnerDocumentWasCalled(bool wasCalled)436 static void setDidMoveToNewOwnerDocumentWasCalled(bool wasCalled)
437 {
438     didMoveToNewOwnerDocumentWasCalled = wasCalled;
439 }
440 
441 #endif
442 
setDocument(Document * document)443 void Node::setDocument(Document* document)
444 {
445     ASSERT(!inDocument() || m_document == document);
446     if (inDocument() || m_document == document)
447         return;
448 
449     document->guardRef();
450 
451     setWillMoveToNewOwnerDocumentWasCalled(false);
452     willMoveToNewOwnerDocument();
453     ASSERT(willMoveToNewOwnerDocumentWasCalled);
454 
455     if (hasRareData() && rareData()->nodeLists()) {
456         if (m_document)
457             m_document->removeNodeListCache();
458         document->addNodeListCache();
459     }
460 
461     if (m_document) {
462         m_document->moveNodeIteratorsToNewDocument(this, document);
463         m_document->guardDeref();
464     }
465 
466     m_document = document;
467 
468     setDidMoveToNewOwnerDocumentWasCalled(false);
469     didMoveToNewOwnerDocument();
470     ASSERT(didMoveToNewOwnerDocumentWasCalled);
471 }
472 
treeScope() const473 TreeScope* Node::treeScope() const
474 {
475     // FIXME: Using m_document directly is not good -> see comment with document() in the header file.
476     if (!hasRareData())
477         return m_document;
478     TreeScope* scope = rareData()->treeScope();
479     return scope ? scope : m_document;
480 }
481 
setTreeScopeRecursively(TreeScope * newTreeScope,bool includeRoot)482 void Node::setTreeScopeRecursively(TreeScope* newTreeScope, bool includeRoot)
483 {
484     ASSERT(this);
485     ASSERT(!includeRoot || !isDocumentNode());
486     ASSERT(newTreeScope);
487     ASSERT(!m_deletionHasBegun);
488 
489     TreeScope* currentTreeScope = treeScope();
490     if (currentTreeScope == newTreeScope)
491         return;
492 
493     Document* currentDocument = document();
494     Document* newDocument = newTreeScope->document();
495     // If an element is moved from a document and then eventually back again the collection cache for
496     // that element may contain stale data as changes made to it will have updated the DOMTreeVersion
497     // of the document it was moved to. By increasing the DOMTreeVersion of the donating document here
498     // we ensure that the collection cache will be invalidated as needed when the element is moved back.
499     if (currentDocument && currentDocument != newDocument)
500         currentDocument->incDOMTreeVersion();
501 
502     for (Node* node = includeRoot ? this : traverseNextNode(this); node; node = node->traverseNextNode(this)) {
503         if (newTreeScope == newDocument) {
504             if (node->hasRareData())
505                 node->rareData()->setTreeScope(0);
506             // Setting the new document tree scope will be handled implicitly
507             // by setDocument() below.
508         } else
509             node->ensureRareData()->setTreeScope(newTreeScope);
510 
511         node->setDocument(newDocument);
512 
513         if (!node->isElementNode())
514             continue;
515         if (ShadowRoot* shadowRoot = toElement(node)->shadowRoot()) {
516             shadowRoot->setParentTreeScope(newTreeScope);
517             if (currentDocument != newDocument)
518                 shadowRoot->setDocumentRecursively(newDocument);
519         }
520     }
521 }
522 
rareData() const523 NodeRareData* Node::rareData() const
524 {
525     ASSERT(hasRareData());
526     return NodeRareData::rareDataFromMap(this);
527 }
528 
ensureRareData()529 NodeRareData* Node::ensureRareData()
530 {
531     if (hasRareData())
532         return rareData();
533 
534     ASSERT(!NodeRareData::rareDataMap().contains(this));
535     NodeRareData* data = createRareData();
536     NodeRareData::rareDataMap().set(this, data);
537     setFlag(HasRareDataFlag);
538     return data;
539 }
540 
createRareData()541 NodeRareData* Node::createRareData()
542 {
543     return new NodeRareData;
544 }
545 
shadowHost() const546 Element* Node::shadowHost() const
547 {
548     return toElement(getFlag(IsShadowRootFlag) ? parent() : 0);
549 }
550 
setShadowHost(Element * host)551 void Node::setShadowHost(Element* host)
552 {
553     ASSERT(!parentNode() && !isSVGShadowRoot());
554     if (host)
555         setFlag(IsShadowRootFlag);
556     else
557         clearFlag(IsShadowRootFlag);
558 
559     setParent(host);
560 }
561 
toInputElement()562 InputElement* Node::toInputElement()
563 {
564     // If one of the below ASSERTs trigger, you are calling this function
565     // directly or indirectly from a constructor or destructor of this object.
566     // Don't do this!
567     ASSERT(!(isHTMLElement() && hasTagName(inputTag)));
568     return 0;
569 }
570 
tabIndex() const571 short Node::tabIndex() const
572 {
573     return hasRareData() ? rareData()->tabIndex() : 0;
574 }
575 
setTabIndexExplicitly(short i)576 void Node::setTabIndexExplicitly(short i)
577 {
578     ensureRareData()->setTabIndexExplicitly(i);
579 }
580 
clearTabIndexExplicitly()581 void Node::clearTabIndexExplicitly()
582 {
583     ensureRareData()->clearTabIndexExplicitly();
584 }
585 
nodeValue() const586 String Node::nodeValue() const
587 {
588     return String();
589 }
590 
setNodeValue(const String &,ExceptionCode & ec)591 void Node::setNodeValue(const String& /*nodeValue*/, ExceptionCode& ec)
592 {
593     // NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly
594     if (isReadOnlyNode()) {
595         ec = NO_MODIFICATION_ALLOWED_ERR;
596         return;
597     }
598 
599     // By default, setting nodeValue has no effect.
600 }
601 
childNodes()602 PassRefPtr<NodeList> Node::childNodes()
603 {
604     NodeRareData* data = ensureRareData();
605     if (!data->nodeLists()) {
606         data->setNodeLists(NodeListsNodeData::create());
607         if (document())
608             document()->addNodeListCache();
609     }
610 
611     return ChildNodeList::create(this, data->nodeLists()->m_childNodeListCaches.get());
612 }
613 
lastDescendant() const614 Node *Node::lastDescendant() const
615 {
616     Node *n = const_cast<Node *>(this);
617     while (n && n->lastChild())
618         n = n->lastChild();
619     return n;
620 }
621 
firstDescendant() const622 Node* Node::firstDescendant() const
623 {
624     Node *n = const_cast<Node *>(this);
625     while (n && n->firstChild())
626         n = n->firstChild();
627     return n;
628 }
629 
insertBefore(PassRefPtr<Node> newChild,Node * refChild,ExceptionCode & ec,bool shouldLazyAttach)630 bool Node::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec, bool shouldLazyAttach)
631 {
632     if (!isContainerNode()) {
633         ec = HIERARCHY_REQUEST_ERR;
634         return false;
635     }
636     return toContainerNode(this)->insertBefore(newChild, refChild, ec, shouldLazyAttach);
637 }
638 
replaceChild(PassRefPtr<Node> newChild,Node * oldChild,ExceptionCode & ec,bool shouldLazyAttach)639 bool Node::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec, bool shouldLazyAttach)
640 {
641     if (!isContainerNode()) {
642         ec = HIERARCHY_REQUEST_ERR;
643         return false;
644     }
645     return toContainerNode(this)->replaceChild(newChild, oldChild, ec, shouldLazyAttach);
646 }
647 
removeChild(Node * oldChild,ExceptionCode & ec)648 bool Node::removeChild(Node* oldChild, ExceptionCode& ec)
649 {
650     if (!isContainerNode()) {
651         ec = NOT_FOUND_ERR;
652         return false;
653     }
654     return toContainerNode(this)->removeChild(oldChild, ec);
655 }
656 
appendChild(PassRefPtr<Node> newChild,ExceptionCode & ec,bool shouldLazyAttach)657 bool Node::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bool shouldLazyAttach)
658 {
659     if (!isContainerNode()) {
660         ec = HIERARCHY_REQUEST_ERR;
661         return false;
662     }
663     return toContainerNode(this)->appendChild(newChild, ec, shouldLazyAttach);
664 }
665 
remove(ExceptionCode & ec)666 void Node::remove(ExceptionCode& ec)
667 {
668     if (ContainerNode* parent = parentNode())
669         parent->removeChild(this, ec);
670     else
671         ec = HIERARCHY_REQUEST_ERR;
672 }
673 
normalize()674 void Node::normalize()
675 {
676     // Go through the subtree beneath us, normalizing all nodes. This means that
677     // any two adjacent text nodes are merged and any empty text nodes are removed.
678 
679     RefPtr<Node> node = this;
680     while (Node* firstChild = node->firstChild())
681         node = firstChild;
682     while (node) {
683         NodeType type = node->nodeType();
684         if (type == ELEMENT_NODE)
685             static_cast<Element*>(node.get())->normalizeAttributes();
686 
687         if (node == this)
688             break;
689 
690         if (type != TEXT_NODE) {
691             node = node->traverseNextNodePostOrder();
692             continue;
693         }
694 
695         Text* text = static_cast<Text*>(node.get());
696 
697         // Remove empty text nodes.
698         if (!text->length()) {
699             // Care must be taken to get the next node before removing the current node.
700             node = node->traverseNextNodePostOrder();
701             ExceptionCode ec;
702             text->remove(ec);
703             continue;
704         }
705 
706         // Merge text nodes.
707         while (Node* nextSibling = node->nextSibling()) {
708             if (nextSibling->nodeType() != TEXT_NODE)
709                 break;
710             RefPtr<Text> nextText = static_cast<Text*>(nextSibling);
711 
712             // Remove empty text nodes.
713             if (!nextText->length()) {
714                 ExceptionCode ec;
715                 nextText->remove(ec);
716                 continue;
717             }
718 
719             // Both non-empty text nodes. Merge them.
720             unsigned offset = text->length();
721             ExceptionCode ec;
722             text->appendData(nextText->data(), ec);
723             document()->textNodesMerged(nextText.get(), offset);
724             nextText->remove(ec);
725         }
726 
727         node = node->traverseNextNodePostOrder();
728     }
729 }
730 
virtualPrefix() const731 const AtomicString& Node::virtualPrefix() const
732 {
733     // For nodes other than elements and attributes, the prefix is always null
734     return nullAtom;
735 }
736 
setPrefix(const AtomicString &,ExceptionCode & ec)737 void Node::setPrefix(const AtomicString& /*prefix*/, ExceptionCode& ec)
738 {
739     // The spec says that for nodes other than elements and attributes, prefix is always null.
740     // It does not say what to do when the user tries to set the prefix on another type of
741     // node, however Mozilla throws a NAMESPACE_ERR exception.
742     ec = NAMESPACE_ERR;
743 }
744 
virtualLocalName() const745 const AtomicString& Node::virtualLocalName() const
746 {
747     return nullAtom;
748 }
749 
virtualNamespaceURI() const750 const AtomicString& Node::virtualNamespaceURI() const
751 {
752     return nullAtom;
753 }
754 
deprecatedParserAddChild(PassRefPtr<Node>)755 void Node::deprecatedParserAddChild(PassRefPtr<Node>)
756 {
757 }
758 
isContentEditable() const759 bool Node::isContentEditable() const
760 {
761     document()->updateLayoutIgnorePendingStylesheets();
762     return rendererIsEditable(Editable);
763 }
764 
rendererIsEditable(EditableLevel editableLevel) const765 bool Node::rendererIsEditable(EditableLevel editableLevel) const
766 {
767     if (document()->frame() && document()->frame()->page() && document()->frame()->page()->isEditable())
768         return true;
769 
770     // Ideally we'd call ASSERT(!needsStyleRecalc()) here, but
771     // ContainerNode::setFocus() calls setNeedsStyleRecalc(), so the assertion
772     // would fire in the middle of Document::setFocusedNode().
773 
774     for (const Node* node = this; node; node = node->parentNode()) {
775         if ((node->isHTMLElement() || node->isDocumentNode()) && node->renderer()) {
776             switch (node->renderer()->style()->userModify()) {
777             case READ_ONLY:
778                 return false;
779             case READ_WRITE:
780                 return true;
781             case READ_WRITE_PLAINTEXT_ONLY:
782                 return editableLevel != RichlyEditable;
783             }
784             ASSERT_NOT_REACHED();
785             return false;
786         }
787     }
788 
789     return false;
790 }
791 
shouldUseInputMethod() const792 bool Node::shouldUseInputMethod() const
793 {
794     return isContentEditable();
795 }
796 
renderBox() const797 RenderBox* Node::renderBox() const
798 {
799     return m_renderer && m_renderer->isBox() ? toRenderBox(m_renderer) : 0;
800 }
801 
renderBoxModelObject() const802 RenderBoxModelObject* Node::renderBoxModelObject() const
803 {
804     return m_renderer && m_renderer->isBoxModelObject() ? toRenderBoxModelObject(m_renderer) : 0;
805 }
806 
getRect() const807 IntRect Node::getRect() const
808 {
809     if (renderer())
810         return renderer()->absoluteBoundingBoxRect(true);
811     return IntRect();
812 }
813 
renderRect(bool * isReplaced)814 IntRect Node::renderRect(bool* isReplaced)
815 {
816     RenderObject* hitRenderer = this->renderer();
817     ASSERT(hitRenderer);
818     RenderObject* renderer = hitRenderer;
819     while (renderer && !renderer->isBody() && !renderer->isRoot()) {
820         if (renderer->isRenderBlock() || renderer->isInlineBlockOrInlineTable() || renderer->isReplaced()) {
821             *isReplaced = renderer->isReplaced();
822             return renderer->absoluteBoundingBoxRect(true);
823         }
824         renderer = renderer->parent();
825     }
826     return IntRect();
827 }
828 
hasNonEmptyBoundingBox() const829 bool Node::hasNonEmptyBoundingBox() const
830 {
831     // Before calling absoluteRects, check for the common case where the renderer
832     // is non-empty, since this is a faster check and almost always returns true.
833     RenderBoxModelObject* box = renderBoxModelObject();
834     if (!box)
835         return false;
836     if (!box->borderBoundingBox().isEmpty())
837         return true;
838 
839     Vector<IntRect> rects;
840     FloatPoint absPos = renderer()->localToAbsolute();
841     renderer()->absoluteRects(rects, absPos.x(), absPos.y());
842     size_t n = rects.size();
843     for (size_t i = 0; i < n; ++i)
844         if (!rects[i].isEmpty())
845             return true;
846 
847     return false;
848 }
849 
shadowRoot(Node * node)850 inline static ShadowRoot* shadowRoot(Node* node)
851 {
852     return node->isElementNode() ? toElement(node)->shadowRoot() : 0;
853 }
854 
setDocumentRecursively(Document * newDocument)855 void Node::setDocumentRecursively(Document* newDocument)
856 {
857     ASSERT(document() != newDocument);
858 
859     for (Node* node = this; node; node = node->traverseNextNode(this)) {
860         node->setDocument(newDocument);
861         if (!node->isElementNode())
862             continue;
863         if (ShadowRoot* shadow = shadowRoot(node))
864             shadow->setDocumentRecursively(newDocument);
865     }
866 }
867 
setStyleChange(StyleChangeType changeType)868 inline void Node::setStyleChange(StyleChangeType changeType)
869 {
870     m_nodeFlags = (m_nodeFlags & ~StyleChangeMask) | changeType;
871 }
872 
markAncestorsWithChildNeedsStyleRecalc()873 inline void Node::markAncestorsWithChildNeedsStyleRecalc()
874 {
875     for (ContainerNode* p = parentOrHostNode(); p && !p->childNeedsStyleRecalc(); p = p->parentOrHostNode())
876         p->setChildNeedsStyleRecalc();
877 
878     if (document()->childNeedsStyleRecalc())
879         document()->scheduleStyleRecalc();
880 }
881 
refEventTarget()882 void Node::refEventTarget()
883 {
884     ref();
885 }
886 
derefEventTarget()887 void Node::derefEventTarget()
888 {
889     deref();
890 }
891 
setNeedsStyleRecalc(StyleChangeType changeType)892 void Node::setNeedsStyleRecalc(StyleChangeType changeType)
893 {
894     ASSERT(changeType != NoStyleChange);
895     if (!attached()) // changed compared to what?
896         return;
897 
898     StyleChangeType existingChangeType = styleChangeType();
899     if (changeType > existingChangeType)
900         setStyleChange(changeType);
901 
902     if (existingChangeType == NoStyleChange)
903         markAncestorsWithChildNeedsStyleRecalc();
904 }
905 
lazyAttach(ShouldSetAttached shouldSetAttached)906 void Node::lazyAttach(ShouldSetAttached shouldSetAttached)
907 {
908     for (Node* n = this; n; n = n->traverseNextNode(this)) {
909         if (n->firstChild())
910             n->setChildNeedsStyleRecalc();
911         n->setStyleChange(FullStyleChange);
912         if (shouldSetAttached == SetAttached)
913             n->setAttached();
914     }
915     markAncestorsWithChildNeedsStyleRecalc();
916 }
917 
setFocus(bool b)918 void Node::setFocus(bool b)
919 {
920     if (b || hasRareData())
921         ensureRareData()->setFocused(b);
922 }
923 
rareDataFocused() const924 bool Node::rareDataFocused() const
925 {
926     ASSERT(hasRareData());
927     return rareData()->isFocused();
928 }
929 
supportsFocus() const930 bool Node::supportsFocus() const
931 {
932     return hasRareData() && rareData()->tabIndexSetExplicitly();
933 }
934 
isFocusable() const935 bool Node::isFocusable() const
936 {
937     if (!inDocument() || !supportsFocus())
938         return false;
939 
940     if (renderer())
941         ASSERT(!renderer()->needsLayout());
942     else
943         // If the node is in a display:none tree it might say it needs style recalc but
944         // the whole document is actually up to date.
945         ASSERT(!document()->childNeedsStyleRecalc());
946 
947     // FIXME: Even if we are not visible, we might have a child that is visible.
948     // Hyatt wants to fix that some day with a "has visible content" flag or the like.
949     if (!renderer() || renderer()->style()->visibility() != VISIBLE)
950         return false;
951 
952     return true;
953 }
954 
isKeyboardFocusable(KeyboardEvent *) const955 bool Node::isKeyboardFocusable(KeyboardEvent*) const
956 {
957     return isFocusable() && tabIndex() >= 0;
958 }
959 
isMouseFocusable() const960 bool Node::isMouseFocusable() const
961 {
962     return isFocusable();
963 }
964 
nodeIndex() const965 unsigned Node::nodeIndex() const
966 {
967     Node *_tempNode = previousSibling();
968     unsigned count=0;
969     for ( count=0; _tempNode; count++ )
970         _tempNode = _tempNode->previousSibling();
971     return count;
972 }
973 
registerDynamicNodeList(DynamicNodeList * list)974 void Node::registerDynamicNodeList(DynamicNodeList* list)
975 {
976     NodeRareData* data = ensureRareData();
977     if (!data->nodeLists()) {
978         data->setNodeLists(NodeListsNodeData::create());
979         document()->addNodeListCache();
980     } else if (!m_document || !m_document->hasNodeListCaches()) {
981         // We haven't been receiving notifications while there were no registered lists, so the cache is invalid now.
982         data->nodeLists()->invalidateCaches();
983     }
984 
985     if (list->hasOwnCaches())
986         data->nodeLists()->m_listsWithCaches.add(list);
987 }
988 
unregisterDynamicNodeList(DynamicNodeList * list)989 void Node::unregisterDynamicNodeList(DynamicNodeList* list)
990 {
991     ASSERT(rareData());
992     ASSERT(rareData()->nodeLists());
993     if (list->hasOwnCaches()) {
994         NodeRareData* data = rareData();
995         data->nodeLists()->m_listsWithCaches.remove(list);
996         if (data->nodeLists()->isEmpty()) {
997             data->clearNodeLists();
998             if (document())
999                 document()->removeNodeListCache();
1000         }
1001     }
1002 }
1003 
notifyLocalNodeListsAttributeChanged()1004 void Node::notifyLocalNodeListsAttributeChanged()
1005 {
1006     if (!hasRareData())
1007         return;
1008     NodeRareData* data = rareData();
1009     if (!data->nodeLists())
1010         return;
1011 
1012     if (!isAttributeNode())
1013         data->nodeLists()->invalidateCachesThatDependOnAttributes();
1014     else
1015         data->nodeLists()->invalidateCaches();
1016 
1017     if (data->nodeLists()->isEmpty()) {
1018         data->clearNodeLists();
1019         document()->removeNodeListCache();
1020     }
1021 }
1022 
notifyNodeListsAttributeChanged()1023 void Node::notifyNodeListsAttributeChanged()
1024 {
1025     for (Node *n = this; n; n = n->parentNode())
1026         n->notifyLocalNodeListsAttributeChanged();
1027 }
1028 
notifyLocalNodeListsChildrenChanged()1029 void Node::notifyLocalNodeListsChildrenChanged()
1030 {
1031     if (!hasRareData())
1032         return;
1033     NodeRareData* data = rareData();
1034     if (!data->nodeLists())
1035         return;
1036 
1037     data->nodeLists()->invalidateCaches();
1038 
1039     NodeListsNodeData::NodeListSet::iterator end = data->nodeLists()->m_listsWithCaches.end();
1040     for (NodeListsNodeData::NodeListSet::iterator i = data->nodeLists()->m_listsWithCaches.begin(); i != end; ++i)
1041         (*i)->invalidateCache();
1042 
1043     if (data->nodeLists()->isEmpty()) {
1044         data->clearNodeLists();
1045         document()->removeNodeListCache();
1046     }
1047 }
1048 
notifyNodeListsChildrenChanged()1049 void Node::notifyNodeListsChildrenChanged()
1050 {
1051     for (Node* n = this; n; n = n->parentNode())
1052         n->notifyLocalNodeListsChildrenChanged();
1053 }
1054 
notifyLocalNodeListsLabelChanged()1055 void Node::notifyLocalNodeListsLabelChanged()
1056 {
1057     if (!hasRareData())
1058         return;
1059     NodeRareData* data = rareData();
1060     if (!data->nodeLists())
1061         return;
1062 
1063     if (data->nodeLists()->m_labelsNodeListCache)
1064         data->nodeLists()->m_labelsNodeListCache->invalidateCache();
1065 }
1066 
removeCachedClassNodeList(ClassNodeList * list,const String & className)1067 void Node::removeCachedClassNodeList(ClassNodeList* list, const String& className)
1068 {
1069     ASSERT(rareData());
1070     ASSERT(rareData()->nodeLists());
1071     ASSERT_UNUSED(list, list->hasOwnCaches());
1072 
1073     NodeListsNodeData* data = rareData()->nodeLists();
1074     ASSERT_UNUSED(list, list == data->m_classNodeListCache.get(className));
1075     data->m_classNodeListCache.remove(className);
1076 }
1077 
removeCachedNameNodeList(NameNodeList * list,const String & nodeName)1078 void Node::removeCachedNameNodeList(NameNodeList* list, const String& nodeName)
1079 {
1080     ASSERT(rareData());
1081     ASSERT(rareData()->nodeLists());
1082     ASSERT_UNUSED(list, list->hasOwnCaches());
1083 
1084     NodeListsNodeData* data = rareData()->nodeLists();
1085     ASSERT_UNUSED(list, list == data->m_nameNodeListCache.get(nodeName));
1086     data->m_nameNodeListCache.remove(nodeName);
1087 }
1088 
removeCachedTagNodeList(TagNodeList * list,const AtomicString & name)1089 void Node::removeCachedTagNodeList(TagNodeList* list, const AtomicString& name)
1090 {
1091     ASSERT(rareData());
1092     ASSERT(rareData()->nodeLists());
1093     ASSERT_UNUSED(list, list->hasOwnCaches());
1094 
1095     NodeListsNodeData* data = rareData()->nodeLists();
1096     ASSERT_UNUSED(list, list == data->m_tagNodeListCache.get(name.impl()));
1097     data->m_tagNodeListCache.remove(name.impl());
1098 }
1099 
removeCachedTagNodeList(TagNodeList * list,const QualifiedName & name)1100 void Node::removeCachedTagNodeList(TagNodeList* list, const QualifiedName& name)
1101 {
1102     ASSERT(rareData());
1103     ASSERT(rareData()->nodeLists());
1104     ASSERT_UNUSED(list, list->hasOwnCaches());
1105 
1106     NodeListsNodeData* data = rareData()->nodeLists();
1107     ASSERT_UNUSED(list, list == data->m_tagNodeListCacheNS.get(name.impl()));
1108     data->m_tagNodeListCacheNS.remove(name.impl());
1109 }
1110 
removeCachedLabelsNodeList(DynamicNodeList * list)1111 void Node::removeCachedLabelsNodeList(DynamicNodeList* list)
1112 {
1113     ASSERT(rareData());
1114     ASSERT(rareData()->nodeLists());
1115     ASSERT_UNUSED(list, list->hasOwnCaches());
1116 
1117     NodeListsNodeData* data = rareData()->nodeLists();
1118     data->m_labelsNodeListCache = 0;
1119 }
1120 
traverseNextNode(const Node * stayWithin) const1121 Node* Node::traverseNextNode(const Node* stayWithin) const
1122 {
1123     if (firstChild())
1124         return firstChild();
1125     if (this == stayWithin)
1126         return 0;
1127     if (nextSibling())
1128         return nextSibling();
1129     const Node *n = this;
1130     while (n && !n->nextSibling() && (!stayWithin || n->parentNode() != stayWithin))
1131         n = n->parentNode();
1132     if (n)
1133         return n->nextSibling();
1134     return 0;
1135 }
1136 
traverseNextSibling(const Node * stayWithin) const1137 Node* Node::traverseNextSibling(const Node* stayWithin) const
1138 {
1139     if (this == stayWithin)
1140         return 0;
1141     if (nextSibling())
1142         return nextSibling();
1143     const Node *n = this;
1144     while (n && !n->nextSibling() && (!stayWithin || n->parentNode() != stayWithin))
1145         n = n->parentNode();
1146     if (n)
1147         return n->nextSibling();
1148     return 0;
1149 }
1150 
traverseNextNodePostOrder() const1151 Node* Node::traverseNextNodePostOrder() const
1152 {
1153     Node* next = nextSibling();
1154     if (!next)
1155         return parentNode();
1156     while (Node* firstChild = next->firstChild())
1157         next = firstChild;
1158     return next;
1159 }
1160 
traversePreviousNode(const Node * stayWithin) const1161 Node* Node::traversePreviousNode(const Node* stayWithin) const
1162 {
1163     if (this == stayWithin)
1164         return 0;
1165     if (previousSibling()) {
1166         Node *n = previousSibling();
1167         while (n->lastChild())
1168             n = n->lastChild();
1169         return n;
1170     }
1171     return parentNode();
1172 }
1173 
traversePreviousNodePostOrder(const Node * stayWithin) const1174 Node* Node::traversePreviousNodePostOrder(const Node* stayWithin) const
1175 {
1176     if (lastChild())
1177         return lastChild();
1178     if (this == stayWithin)
1179         return 0;
1180     if (previousSibling())
1181         return previousSibling();
1182     const Node *n = this;
1183     while (n && !n->previousSibling() && (!stayWithin || n->parentNode() != stayWithin))
1184         n = n->parentNode();
1185     if (n)
1186         return n->previousSibling();
1187     return 0;
1188 }
1189 
traversePreviousSiblingPostOrder(const Node * stayWithin) const1190 Node* Node::traversePreviousSiblingPostOrder(const Node* stayWithin) const
1191 {
1192     if (this == stayWithin)
1193         return 0;
1194     if (previousSibling())
1195         return previousSibling();
1196     const Node *n = this;
1197     while (n && !n->previousSibling() && (!stayWithin || n->parentNode() != stayWithin))
1198         n = n->parentNode();
1199     if (n)
1200         return n->previousSibling();
1201     return 0;
1202 }
1203 
checkSetPrefix(const AtomicString & prefix,ExceptionCode & ec)1204 void Node::checkSetPrefix(const AtomicString& prefix, ExceptionCode& ec)
1205 {
1206     // Perform error checking as required by spec for setting Node.prefix. Used by
1207     // Element::setPrefix() and Attr::setPrefix()
1208 
1209     // FIXME: Implement support for INVALID_CHARACTER_ERR: Raised if the specified prefix contains an illegal character.
1210 
1211     if (isReadOnlyNode()) {
1212         ec = NO_MODIFICATION_ALLOWED_ERR;
1213         return;
1214     }
1215 
1216     // FIXME: Raise NAMESPACE_ERR if prefix is malformed per the Namespaces in XML specification.
1217 
1218     const AtomicString& nodeNamespaceURI = namespaceURI();
1219     if ((nodeNamespaceURI.isEmpty() && !prefix.isEmpty())
1220         || (prefix == xmlAtom && nodeNamespaceURI != XMLNames::xmlNamespaceURI)) {
1221         ec = NAMESPACE_ERR;
1222         return;
1223     }
1224     // Attribute-specific checks are in Attr::setPrefix().
1225 }
1226 
isChildTypeAllowed(Node * newParent,Node * child)1227 static bool isChildTypeAllowed(Node* newParent, Node* child)
1228 {
1229     if (child->nodeType() != Node::DOCUMENT_FRAGMENT_NODE) {
1230         if (!newParent->childTypeAllowed(child->nodeType()))
1231             return false;
1232         return true;
1233     }
1234 
1235     for (Node *n = child->firstChild(); n; n = n->nextSibling()) {
1236         if (!newParent->childTypeAllowed(n->nodeType()))
1237             return false;
1238     }
1239     return true;
1240 }
1241 
canReplaceChild(Node * newChild,Node *)1242 bool Node::canReplaceChild(Node* newChild, Node*)
1243 {
1244     return isChildTypeAllowed(this, newChild);
1245 }
1246 
checkAcceptChild(Node * newParent,Node * newChild,ExceptionCode & ec)1247 static void checkAcceptChild(Node* newParent, Node* newChild, ExceptionCode& ec)
1248 {
1249     // Not mentioned in spec: throw NOT_FOUND_ERR if newChild is null
1250     if (!newChild) {
1251         ec = NOT_FOUND_ERR;
1252         return;
1253     }
1254 
1255     if (newParent->isReadOnlyNode()) {
1256         ec = NO_MODIFICATION_ALLOWED_ERR;
1257         return;
1258     }
1259 
1260     if (newChild->inDocument() && newChild->nodeType() == Node::DOCUMENT_TYPE_NODE) {
1261         ec = HIERARCHY_REQUEST_ERR;
1262         return;
1263     }
1264 
1265     // HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not allow children of the type of the
1266     // newChild node, or if the node to append is one of this node's ancestors.
1267 
1268     if (newChild == newParent || newParent->isDescendantOf(newChild)) {
1269         ec = HIERARCHY_REQUEST_ERR;
1270         return;
1271     }
1272 }
1273 
checkReplaceChild(Node * newChild,Node * oldChild,ExceptionCode & ec)1274 void Node::checkReplaceChild(Node* newChild, Node* oldChild, ExceptionCode& ec)
1275 {
1276     if (!oldChild) {
1277         ec = NOT_FOUND_ERR;
1278         return;
1279     }
1280 
1281     checkAcceptChild(this, newChild, ec);
1282     if (ec)
1283         return;
1284 
1285     if (!canReplaceChild(newChild, oldChild)) {
1286         ec = HIERARCHY_REQUEST_ERR;
1287         return;
1288     }
1289 }
1290 
checkAddChild(Node * newChild,ExceptionCode & ec)1291 void Node::checkAddChild(Node *newChild, ExceptionCode& ec)
1292 {
1293     checkAcceptChild(this, newChild, ec);
1294     if (ec)
1295         return;
1296 
1297     if (!isChildTypeAllowed(this, newChild)) {
1298         ec = HIERARCHY_REQUEST_ERR;
1299         return;
1300     }
1301 }
1302 
isDescendantOf(const Node * other) const1303 bool Node::isDescendantOf(const Node *other) const
1304 {
1305     // Return true if other is an ancestor of this, otherwise false
1306     if (!other)
1307         return false;
1308     for (const ContainerNode* n = parentNode(); n; n = n->parentNode()) {
1309         if (n == other)
1310             return true;
1311     }
1312     return false;
1313 }
1314 
contains(const Node * node) const1315 bool Node::contains(const Node* node) const
1316 {
1317     if (!node)
1318         return false;
1319     return this == node || node->isDescendantOf(this);
1320 }
1321 
containsIncludingShadowDOM(Node * node)1322 bool Node::containsIncludingShadowDOM(Node* node)
1323 {
1324     if (!node)
1325         return false;
1326     for (Node* n = node; n; n = n->parentOrHostNode()) {
1327         if (n == this)
1328             return true;
1329     }
1330     return false;
1331 }
1332 
attach()1333 void Node::attach()
1334 {
1335     ASSERT(!attached());
1336     ASSERT(!renderer() || (renderer()->style() && renderer()->parent()));
1337 
1338     // FIXME: This is O(N^2) for the innerHTML case, where all children are replaced at once (and not attached).
1339     // If this node got a renderer it may be the previousRenderer() of sibling text nodes and thus affect the
1340     // result of Text::rendererIsNeeded() for those nodes.
1341     if (renderer()) {
1342         for (Node* next = nextSibling(); next; next = next->nextSibling()) {
1343             if (next->renderer())
1344                 break;
1345             if (!next->attached())
1346                 break;  // Assume this means none of the following siblings are attached.
1347             if (next->isTextNode())
1348                 next->createRendererIfNeeded();
1349         }
1350     }
1351 
1352     setAttached();
1353     clearNeedsStyleRecalc();
1354 }
1355 
willRemove()1356 void Node::willRemove()
1357 {
1358 }
1359 
detach()1360 void Node::detach()
1361 {
1362     setFlag(InDetachFlag);
1363 
1364     if (renderer())
1365         renderer()->destroy();
1366     setRenderer(0);
1367 
1368     Document* doc = document();
1369     if (hovered())
1370         doc->hoveredNodeDetached(this);
1371     if (inActiveChain())
1372         doc->activeChainNodeDetached(this);
1373 
1374     clearFlag(IsActiveFlag);
1375     clearFlag(IsHoveredFlag);
1376     clearFlag(InActiveChainFlag);
1377     clearFlag(IsAttachedFlag);
1378 
1379     clearFlag(InDetachFlag);
1380 }
1381 
previousRenderer()1382 RenderObject* Node::previousRenderer()
1383 {
1384     // FIXME: We should have the same O(N^2) avoidance as nextRenderer does
1385     // however, when I tried adding it, several tests failed.
1386     for (Node* n = previousSibling(); n; n = n->previousSibling()) {
1387         if (n->renderer())
1388             return n->renderer();
1389     }
1390     return 0;
1391 }
1392 
nextRenderer()1393 RenderObject* Node::nextRenderer()
1394 {
1395     // Avoid an O(n^2) problem with this function by not checking for
1396     // nextRenderer() when the parent element hasn't attached yet.
1397     if (parentOrHostNode() && !parentOrHostNode()->attached())
1398         return 0;
1399 
1400     for (Node* n = nextSibling(); n; n = n->nextSibling()) {
1401         if (n->renderer())
1402             return n->renderer();
1403     }
1404     return 0;
1405 }
1406 
1407 // FIXME: This code is used by editing.  Seems like it could move over there and not pollute Node.
previousNodeConsideringAtomicNodes() const1408 Node *Node::previousNodeConsideringAtomicNodes() const
1409 {
1410     if (previousSibling()) {
1411         Node *n = previousSibling();
1412         while (!isAtomicNode(n) && n->lastChild())
1413             n = n->lastChild();
1414         return n;
1415     }
1416     else if (parentNode()) {
1417         return parentNode();
1418     }
1419     else {
1420         return 0;
1421     }
1422 }
1423 
nextNodeConsideringAtomicNodes() const1424 Node *Node::nextNodeConsideringAtomicNodes() const
1425 {
1426     if (!isAtomicNode(this) && firstChild())
1427         return firstChild();
1428     if (nextSibling())
1429         return nextSibling();
1430     const Node *n = this;
1431     while (n && !n->nextSibling())
1432         n = n->parentNode();
1433     if (n)
1434         return n->nextSibling();
1435     return 0;
1436 }
1437 
previousLeafNode() const1438 Node *Node::previousLeafNode() const
1439 {
1440     Node *node = previousNodeConsideringAtomicNodes();
1441     while (node) {
1442         if (isAtomicNode(node))
1443             return node;
1444         node = node->previousNodeConsideringAtomicNodes();
1445     }
1446     return 0;
1447 }
1448 
nextLeafNode() const1449 Node *Node::nextLeafNode() const
1450 {
1451     Node *node = nextNodeConsideringAtomicNodes();
1452     while (node) {
1453         if (isAtomicNode(node))
1454             return node;
1455         node = node->nextNodeConsideringAtomicNodes();
1456     }
1457     return 0;
1458 }
1459 
1460 
1461 class NodeRendererFactory {
1462 public:
1463     enum Type {
1464         NotFound,
1465         AsLightChild,
1466         AsShadowChild,
1467         AsContentChild
1468     };
1469 
NodeRendererFactory(Node * node)1470     NodeRendererFactory(Node* node)
1471         : m_type(NotFound)
1472         , m_node(node)
1473         , m_visualParentShadowRoot(0)
1474     {
1475         m_parentNodeForRenderingAndStyle = findVisualParent();
1476     }
1477 
parentNodeForRenderingAndStyle() const1478     ContainerNode* parentNodeForRenderingAndStyle() const { return m_parentNodeForRenderingAndStyle; }
1479     void createRendererIfNeeded();
1480 
1481 private:
document()1482     Document* document() { return m_node->document(); }
1483     ContainerNode* findVisualParent();
nextRenderer() const1484     RenderObject* nextRenderer() const { return m_node->nextRenderer(); }
1485     RenderObject* createRendererAndStyle();
1486     bool shouldCreateRenderer() const;
1487 
1488     Type m_type;
1489     Node* m_node;
1490     ContainerNode* m_parentNodeForRenderingAndStyle;
1491     ShadowRoot* m_visualParentShadowRoot;
1492 };
1493 
findVisualParent()1494 ContainerNode* NodeRendererFactory::findVisualParent()
1495 {
1496     ContainerNode* parent = m_node->parentOrHostNode();
1497     if (!parent)
1498         return 0;
1499 
1500     if (parent->isShadowBoundary()) {
1501         m_type = AsShadowChild;
1502         return parent->shadowHost();
1503     }
1504 
1505     if (parent->isElementNode()) {
1506         m_visualParentShadowRoot = toElement(parent)->shadowRoot();
1507         if (m_visualParentShadowRoot) {
1508             if (ContainerNode* contentContainer = m_visualParentShadowRoot->contentContainerFor(m_node)) {
1509                 m_type = AsContentChild;
1510                 return NodeRendererFactory(contentContainer).parentNodeForRenderingAndStyle();
1511             }
1512 
1513             // FIXME: should be not found once light/shadow is mutual exclusive.
1514         }
1515     }
1516 
1517     m_type = AsLightChild;
1518     return parent;
1519 }
1520 
shouldCreateRenderer() const1521 bool NodeRendererFactory::shouldCreateRenderer() const
1522 {
1523     ASSERT(m_parentNodeForRenderingAndStyle);
1524 
1525     RenderObject* parentRenderer = m_parentNodeForRenderingAndStyle->renderer();
1526     if (!parentRenderer)
1527         return false;
1528 
1529     if (m_type == AsLightChild) {
1530         // FIXME: Ignoring canHaveChildren() in a case of shadow children might be wrong.
1531         // See https://bugs.webkit.org/show_bug.cgi?id=52423
1532         if (!parentRenderer->canHaveChildren())
1533             return false;
1534 
1535         if (m_visualParentShadowRoot && !m_parentNodeForRenderingAndStyle->canHaveLightChildRendererWithShadow())
1536             return false;
1537     }
1538 
1539     if (!m_parentNodeForRenderingAndStyle->childShouldCreateRenderer(m_node))
1540         return false;
1541 
1542     return true;
1543 }
1544 
createRendererAndStyle()1545 RenderObject* NodeRendererFactory::createRendererAndStyle()
1546 {
1547     ASSERT(!m_node->renderer());
1548     ASSERT(document()->shouldCreateRenderers());
1549 
1550     if (!shouldCreateRenderer())
1551         return 0;
1552 
1553     RefPtr<RenderStyle> style = m_node->styleForRenderer();
1554     if (!m_node->rendererIsNeeded(style.get()))
1555         return 0;
1556 
1557     RenderObject* newRenderer = m_node->createRenderer(document()->renderArena(), style.get());
1558     if (!newRenderer)
1559         return 0;
1560 
1561     if (!m_parentNodeForRenderingAndStyle->renderer()->isChildAllowed(newRenderer, style.get())) {
1562         newRenderer->destroy();
1563         return 0;
1564     }
1565 
1566     m_node->setRenderer(newRenderer);
1567     newRenderer->setAnimatableStyle(style.release()); // setAnimatableStyle() can depend on renderer() already being set.
1568     return newRenderer;
1569 }
1570 
1571 #if ENABLE(FULLSCREEN_API)
wrapWithRenderFullScreen(RenderObject * object,Document * document)1572 static RenderFullScreen* wrapWithRenderFullScreen(RenderObject* object, Document* document)
1573 {
1574     RenderFullScreen* fullscreenRenderer = new (document->renderArena()) RenderFullScreen(document);
1575     fullscreenRenderer->setStyle(RenderFullScreen::createFullScreenStyle());
1576     // It's possible that we failed to create the new render and end up wrapping nothing.
1577     // We'll end up displaying a black screen, but Jer says this is expected.
1578     if (object)
1579         fullscreenRenderer->addChild(object);
1580     document->setFullScreenRenderer(fullscreenRenderer);
1581     return fullscreenRenderer;
1582 }
1583 #endif
1584 
createRendererIfNeeded()1585 void NodeRendererFactory::createRendererIfNeeded()
1586 {
1587     if (!document()->shouldCreateRenderers())
1588         return;
1589 
1590     ASSERT(!m_node->renderer());
1591 
1592     RenderObject* newRenderer = createRendererAndStyle();
1593 
1594 #if ENABLE(FULLSCREEN_API)
1595     if (document()->webkitIsFullScreen() && document()->webkitCurrentFullScreenElement() == m_node)
1596         newRenderer = wrapWithRenderFullScreen(newRenderer, document());
1597 #endif
1598 
1599     if (!newRenderer)
1600         return;
1601 
1602     // Note: Adding newRenderer instead of renderer(). renderer() may be a child of newRenderer.
1603     m_parentNodeForRenderingAndStyle->renderer()->addChild(newRenderer, nextRenderer());
1604 }
1605 
parentNodeForRenderingAndStyle()1606 ContainerNode* Node::parentNodeForRenderingAndStyle()
1607 {
1608     return NodeRendererFactory(this).parentNodeForRenderingAndStyle();
1609 }
1610 
createRendererIfNeeded()1611 void Node::createRendererIfNeeded()
1612 {
1613     NodeRendererFactory(this).createRendererIfNeeded();
1614 }
1615 
styleForRenderer()1616 PassRefPtr<RenderStyle> Node::styleForRenderer()
1617 {
1618     if (isElementNode()) {
1619         bool allowSharing = true;
1620 #if ENABLE(XHTMLMP)
1621         // noscript needs the display property protected - it's a special case
1622         allowSharing = localName() != HTMLNames::noscriptTag.localName();
1623 #endif
1624         return document()->styleSelector()->styleForElement(static_cast<Element*>(this), 0, allowSharing);
1625     }
1626     return parentNode() && parentNode()->renderer() ? parentNode()->renderer()->style() : 0;
1627 }
1628 
rendererIsNeeded(RenderStyle * style)1629 bool Node::rendererIsNeeded(RenderStyle *style)
1630 {
1631     return (document()->documentElement() == this) || (style->display() != NONE);
1632 }
1633 
createRenderer(RenderArena *,RenderStyle *)1634 RenderObject* Node::createRenderer(RenderArena*, RenderStyle*)
1635 {
1636     ASSERT(false);
1637     return 0;
1638 }
1639 
nonRendererRenderStyle() const1640 RenderStyle* Node::nonRendererRenderStyle() const
1641 {
1642     return 0;
1643 }
1644 
setRenderStyle(PassRefPtr<RenderStyle> s)1645 void Node::setRenderStyle(PassRefPtr<RenderStyle> s)
1646 {
1647     if (m_renderer)
1648         m_renderer->setAnimatableStyle(s);
1649 }
1650 
virtualComputedStyle(PseudoId pseudoElementSpecifier)1651 RenderStyle* Node::virtualComputedStyle(PseudoId pseudoElementSpecifier)
1652 {
1653     return parentOrHostNode() ? parentOrHostNode()->computedStyle(pseudoElementSpecifier) : 0;
1654 }
1655 
maxCharacterOffset() const1656 int Node::maxCharacterOffset() const
1657 {
1658     ASSERT_NOT_REACHED();
1659     return 0;
1660 }
1661 
1662 // FIXME: Shouldn't these functions be in the editing code?  Code that asks questions about HTML in the core DOM class
1663 // is obviously misplaced.
canStartSelection() const1664 bool Node::canStartSelection() const
1665 {
1666     if (rendererIsEditable())
1667         return true;
1668 
1669     if (renderer()) {
1670         RenderStyle* style = renderer()->style();
1671         // We allow selections to begin within an element that has -webkit-user-select: none set,
1672         // but if the element is draggable then dragging should take priority over selection.
1673         if (style->userDrag() == DRAG_ELEMENT && style->userSelect() == SELECT_NONE)
1674             return false;
1675     }
1676     return parentOrHostNode() ? parentOrHostNode()->canStartSelection() : true;
1677 }
1678 
1679 #if ENABLE(SVG)
svgShadowHost() const1680 SVGUseElement* Node::svgShadowHost() const
1681 {
1682     return isSVGShadowRoot() ? static_cast<SVGUseElement*>(parent()) : 0;
1683 }
1684 #endif
1685 
shadowAncestorNode()1686 Node* Node::shadowAncestorNode()
1687 {
1688 #if ENABLE(SVG)
1689     // SVG elements living in a shadow tree only occur when <use> created them.
1690     // For these cases we do NOT want to return the shadowParentNode() here
1691     // but the actual shadow tree element - as main difference to the HTML forms
1692     // shadow tree concept. (This function _could_ be made virtual - opinions?)
1693     if (isSVGElement())
1694         return this;
1695 #endif
1696 
1697     Node* root = shadowTreeRootNode();
1698     if (root)
1699         return root->shadowHost();
1700     return this;
1701 }
1702 
shadowTreeRootNode()1703 Node* Node::shadowTreeRootNode()
1704 {
1705     Node* root = this;
1706     while (root) {
1707         if (root->isShadowRoot() || root->isSVGShadowRoot())
1708             return root;
1709         root = root->parentNodeGuaranteedHostFree();
1710     }
1711     return 0;
1712 }
1713 
isInShadowTree()1714 bool Node::isInShadowTree()
1715 {
1716     for (Node* n = this; n; n = n->parentNode())
1717         if (n->isShadowRoot())
1718             return true;
1719     return false;
1720 }
1721 
parentOrHostElement() const1722 Element* Node::parentOrHostElement() const
1723 {
1724     ContainerNode* parent = parentOrHostNode();
1725     if (!parent)
1726         return 0;
1727 
1728     if (parent->isShadowRoot())
1729         parent = parent->shadowHost();
1730 
1731     if (!parent->isElementNode())
1732         return 0;
1733 
1734     return toElement(parent);
1735 }
1736 
1737 
isBlockFlow() const1738 bool Node::isBlockFlow() const
1739 {
1740     return renderer() && renderer()->isBlockFlow();
1741 }
1742 
isBlockFlowOrBlockTable() const1743 bool Node::isBlockFlowOrBlockTable() const
1744 {
1745     return renderer() && (renderer()->isBlockFlow() || (renderer()->isTable() && !renderer()->isInline()));
1746 }
1747 
enclosingBlockFlowElement() const1748 Element *Node::enclosingBlockFlowElement() const
1749 {
1750     Node *n = const_cast<Node *>(this);
1751     if (isBlockFlow())
1752         return static_cast<Element *>(n);
1753 
1754     while (1) {
1755         n = n->parentNode();
1756         if (!n)
1757             break;
1758         if (n->isBlockFlow() || n->hasTagName(bodyTag))
1759             return static_cast<Element *>(n);
1760     }
1761     return 0;
1762 }
1763 
rootEditableElement() const1764 Element* Node::rootEditableElement() const
1765 {
1766     Element* result = 0;
1767     for (Node* n = const_cast<Node*>(this); n && n->rendererIsEditable(); n = n->parentNode()) {
1768         if (n->isElementNode())
1769             result = static_cast<Element*>(n);
1770         if (n->hasTagName(bodyTag))
1771             break;
1772     }
1773     return result;
1774 }
1775 
inSameContainingBlockFlowElement(Node * n)1776 bool Node::inSameContainingBlockFlowElement(Node *n)
1777 {
1778     return n ? enclosingBlockFlowElement() == n->enclosingBlockFlowElement() : false;
1779 }
1780 
1781 // FIXME: End of obviously misplaced HTML editing functions.  Try to move these out of Node.
1782 
getElementsByTagName(const AtomicString & localName)1783 PassRefPtr<NodeList> Node::getElementsByTagName(const AtomicString& localName)
1784 {
1785     if (localName.isNull())
1786         return 0;
1787 
1788     NodeRareData* data = ensureRareData();
1789     if (!data->nodeLists()) {
1790         data->setNodeLists(NodeListsNodeData::create());
1791         document()->addNodeListCache();
1792     }
1793 
1794     String name = localName;
1795     if (document()->isHTMLDocument())
1796         name = localName.lower();
1797 
1798     AtomicString localNameAtom = name;
1799 
1800     pair<NodeListsNodeData::TagNodeListCache::iterator, bool> result = data->nodeLists()->m_tagNodeListCache.add(localNameAtom, 0);
1801     if (!result.second)
1802         return PassRefPtr<TagNodeList>(result.first->second);
1803 
1804     RefPtr<TagNodeList> list = TagNodeList::create(this, starAtom, localNameAtom);
1805     result.first->second = list.get();
1806     return list.release();
1807 }
1808 
getElementsByTagNameNS(const AtomicString & namespaceURI,const AtomicString & localName)1809 PassRefPtr<NodeList> Node::getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName)
1810 {
1811     if (localName.isNull())
1812         return 0;
1813 
1814     if (namespaceURI == starAtom)
1815         return getElementsByTagName(localName);
1816 
1817     NodeRareData* data = ensureRareData();
1818     if (!data->nodeLists()) {
1819         data->setNodeLists(NodeListsNodeData::create());
1820         document()->addNodeListCache();
1821     }
1822 
1823     String name = localName;
1824     if (document()->isHTMLDocument())
1825         name = localName.lower();
1826 
1827     AtomicString localNameAtom = name;
1828 
1829     pair<NodeListsNodeData::TagNodeListCacheNS::iterator, bool> result = data->nodeLists()->m_tagNodeListCacheNS.add(QualifiedName(nullAtom, localNameAtom, namespaceURI).impl(), 0);
1830     if (!result.second)
1831         return PassRefPtr<TagNodeList>(result.first->second);
1832 
1833     RefPtr<TagNodeList> list = TagNodeList::create(this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localNameAtom);
1834     result.first->second = list.get();
1835     return list.release();
1836 }
1837 
getElementsByName(const String & elementName)1838 PassRefPtr<NodeList> Node::getElementsByName(const String& elementName)
1839 {
1840     NodeRareData* data = ensureRareData();
1841     if (!data->nodeLists()) {
1842         data->setNodeLists(NodeListsNodeData::create());
1843         document()->addNodeListCache();
1844     }
1845 
1846     pair<NodeListsNodeData::NameNodeListCache::iterator, bool> result = data->nodeLists()->m_nameNodeListCache.add(elementName, 0);
1847     if (!result.second)
1848         return PassRefPtr<NodeList>(result.first->second);
1849 
1850     RefPtr<NameNodeList> list = NameNodeList::create(this, elementName);
1851     result.first->second = list.get();
1852     return list.release();
1853 }
1854 
getElementsByClassName(const String & classNames)1855 PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames)
1856 {
1857     NodeRareData* data = ensureRareData();
1858     if (!data->nodeLists()) {
1859         data->setNodeLists(NodeListsNodeData::create());
1860         document()->addNodeListCache();
1861     }
1862 
1863     pair<NodeListsNodeData::ClassNodeListCache::iterator, bool> result = data->nodeLists()->m_classNodeListCache.add(classNames, 0);
1864     if (!result.second)
1865         return PassRefPtr<NodeList>(result.first->second);
1866 
1867     RefPtr<ClassNodeList> list = ClassNodeList::create(this, classNames);
1868     result.first->second = list.get();
1869     return list.release();
1870 }
1871 
querySelector(const String & selectors,ExceptionCode & ec)1872 PassRefPtr<Element> Node::querySelector(const String& selectors, ExceptionCode& ec)
1873 {
1874     if (selectors.isEmpty()) {
1875         ec = SYNTAX_ERR;
1876         return 0;
1877     }
1878     bool strictParsing = !document()->inQuirksMode();
1879     CSSParser p(strictParsing);
1880 
1881     CSSSelectorList querySelectorList;
1882     p.parseSelector(selectors, document(), querySelectorList);
1883 
1884     if (!querySelectorList.first() || querySelectorList.hasUnknownPseudoElements()) {
1885         ec = SYNTAX_ERR;
1886         return 0;
1887     }
1888 
1889     // throw a NAMESPACE_ERR if the selector includes any namespace prefixes.
1890     if (querySelectorList.selectorsNeedNamespaceResolution()) {
1891         ec = NAMESPACE_ERR;
1892         return 0;
1893     }
1894 
1895     CSSStyleSelector::SelectorChecker selectorChecker(document(), strictParsing);
1896 
1897     // FIXME: we could also optimize for the the [id="foo"] case
1898     if (strictParsing && inDocument() && querySelectorList.hasOneSelector() && querySelectorList.first()->m_match == CSSSelector::Id) {
1899         Element* element = treeScope()->getElementById(querySelectorList.first()->value());
1900         if (element && (isDocumentNode() || element->isDescendantOf(this)) && selectorChecker.checkSelector(querySelectorList.first(), element))
1901             return element;
1902         return 0;
1903     }
1904 
1905     // FIXME: We can speed this up by implementing caching similar to the one use by getElementById
1906     for (Node* n = firstChild(); n; n = n->traverseNextNode(this)) {
1907         if (n->isElementNode()) {
1908             Element* element = static_cast<Element*>(n);
1909             for (CSSSelector* selector = querySelectorList.first(); selector; selector = CSSSelectorList::next(selector)) {
1910                 if (selectorChecker.checkSelector(selector, element))
1911                     return element;
1912             }
1913         }
1914     }
1915 
1916     return 0;
1917 }
1918 
querySelectorAll(const String & selectors,ExceptionCode & ec)1919 PassRefPtr<NodeList> Node::querySelectorAll(const String& selectors, ExceptionCode& ec)
1920 {
1921     if (selectors.isEmpty()) {
1922         ec = SYNTAX_ERR;
1923         return 0;
1924     }
1925     bool strictParsing = !document()->inQuirksMode();
1926     CSSParser p(strictParsing);
1927 
1928     CSSSelectorList querySelectorList;
1929     p.parseSelector(selectors, document(), querySelectorList);
1930 
1931     if (!querySelectorList.first() || querySelectorList.hasUnknownPseudoElements()) {
1932         ec = SYNTAX_ERR;
1933         return 0;
1934     }
1935 
1936     // Throw a NAMESPACE_ERR if the selector includes any namespace prefixes.
1937     if (querySelectorList.selectorsNeedNamespaceResolution()) {
1938         ec = NAMESPACE_ERR;
1939         return 0;
1940     }
1941 
1942     return createSelectorNodeList(this, querySelectorList);
1943 }
1944 
ownerDocument() const1945 Document *Node::ownerDocument() const
1946 {
1947     Document *doc = document();
1948     return doc == this ? 0 : doc;
1949 }
1950 
baseURI() const1951 KURL Node::baseURI() const
1952 {
1953     return parentNode() ? parentNode()->baseURI() : KURL();
1954 }
1955 
isEqualNode(Node * other) const1956 bool Node::isEqualNode(Node* other) const
1957 {
1958     if (!other)
1959         return false;
1960 
1961     NodeType nodeType = this->nodeType();
1962     if (nodeType != other->nodeType())
1963         return false;
1964 
1965     if (nodeName() != other->nodeName())
1966         return false;
1967 
1968     if (localName() != other->localName())
1969         return false;
1970 
1971     if (namespaceURI() != other->namespaceURI())
1972         return false;
1973 
1974     if (prefix() != other->prefix())
1975         return false;
1976 
1977     if (nodeValue() != other->nodeValue())
1978         return false;
1979 
1980     NamedNodeMap* attributes = this->attributes();
1981     NamedNodeMap* otherAttributes = other->attributes();
1982 
1983     if (!attributes && otherAttributes)
1984         return false;
1985 
1986     if (attributes && !attributes->mapsEquivalent(otherAttributes))
1987         return false;
1988 
1989     Node* child = firstChild();
1990     Node* otherChild = other->firstChild();
1991 
1992     while (child) {
1993         if (!child->isEqualNode(otherChild))
1994             return false;
1995 
1996         child = child->nextSibling();
1997         otherChild = otherChild->nextSibling();
1998     }
1999 
2000     if (otherChild)
2001         return false;
2002 
2003     if (nodeType == DOCUMENT_TYPE_NODE) {
2004         const DocumentType* documentTypeThis = static_cast<const DocumentType*>(this);
2005         const DocumentType* documentTypeOther = static_cast<const DocumentType*>(other);
2006 
2007         if (documentTypeThis->publicId() != documentTypeOther->publicId())
2008             return false;
2009 
2010         if (documentTypeThis->systemId() != documentTypeOther->systemId())
2011             return false;
2012 
2013         if (documentTypeThis->internalSubset() != documentTypeOther->internalSubset())
2014             return false;
2015 
2016         NamedNodeMap* entities = documentTypeThis->entities();
2017         NamedNodeMap* otherEntities = documentTypeOther->entities();
2018         if (!entities && otherEntities)
2019             return false;
2020         if (entities && !entities->mapsEquivalent(otherEntities))
2021             return false;
2022 
2023         NamedNodeMap* notations = documentTypeThis->notations();
2024         NamedNodeMap* otherNotations = documentTypeOther->notations();
2025         if (!notations && otherNotations)
2026             return false;
2027         if (notations && !notations->mapsEquivalent(otherNotations))
2028             return false;
2029     }
2030 
2031     return true;
2032 }
2033 
isDefaultNamespace(const AtomicString & namespaceURIMaybeEmpty) const2034 bool Node::isDefaultNamespace(const AtomicString& namespaceURIMaybeEmpty) const
2035 {
2036     const AtomicString& namespaceURI = namespaceURIMaybeEmpty.isEmpty() ? nullAtom : namespaceURIMaybeEmpty;
2037 
2038     switch (nodeType()) {
2039         case ELEMENT_NODE: {
2040             const Element* elem = static_cast<const Element*>(this);
2041 
2042             if (elem->prefix().isNull())
2043                 return elem->namespaceURI() == namespaceURI;
2044 
2045             if (elem->hasAttributes()) {
2046                 NamedNodeMap* attrs = elem->attributes();
2047 
2048                 for (unsigned i = 0; i < attrs->length(); i++) {
2049                     Attribute* attr = attrs->attributeItem(i);
2050 
2051                     if (attr->localName() == xmlnsAtom)
2052                         return attr->value() == namespaceURI;
2053                 }
2054             }
2055 
2056             if (Element* ancestor = ancestorElement())
2057                 return ancestor->isDefaultNamespace(namespaceURI);
2058 
2059             return false;
2060         }
2061         case DOCUMENT_NODE:
2062             if (Element* de = static_cast<const Document*>(this)->documentElement())
2063                 return de->isDefaultNamespace(namespaceURI);
2064             return false;
2065         case ENTITY_NODE:
2066         case NOTATION_NODE:
2067         case DOCUMENT_TYPE_NODE:
2068         case DOCUMENT_FRAGMENT_NODE:
2069         case SHADOW_ROOT_NODE:
2070             return false;
2071         case ATTRIBUTE_NODE: {
2072             const Attr* attr = static_cast<const Attr*>(this);
2073             if (attr->ownerElement())
2074                 return attr->ownerElement()->isDefaultNamespace(namespaceURI);
2075             return false;
2076         }
2077         default:
2078             if (Element* ancestor = ancestorElement())
2079                 return ancestor->isDefaultNamespace(namespaceURI);
2080             return false;
2081     }
2082 }
2083 
lookupPrefix(const AtomicString & namespaceURI) const2084 String Node::lookupPrefix(const AtomicString &namespaceURI) const
2085 {
2086     // Implemented according to
2087     // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#lookupNamespacePrefixAlgo
2088 
2089     if (namespaceURI.isEmpty())
2090         return String();
2091 
2092     switch (nodeType()) {
2093         case ELEMENT_NODE:
2094             return lookupNamespacePrefix(namespaceURI, static_cast<const Element *>(this));
2095         case DOCUMENT_NODE:
2096             if (Element* de = static_cast<const Document*>(this)->documentElement())
2097                 return de->lookupPrefix(namespaceURI);
2098             return String();
2099         case ENTITY_NODE:
2100         case NOTATION_NODE:
2101         case DOCUMENT_FRAGMENT_NODE:
2102         case DOCUMENT_TYPE_NODE:
2103         case SHADOW_ROOT_NODE:
2104             return String();
2105         case ATTRIBUTE_NODE: {
2106             const Attr *attr = static_cast<const Attr *>(this);
2107             if (attr->ownerElement())
2108                 return attr->ownerElement()->lookupPrefix(namespaceURI);
2109             return String();
2110         }
2111         default:
2112             if (Element* ancestor = ancestorElement())
2113                 return ancestor->lookupPrefix(namespaceURI);
2114             return String();
2115     }
2116 }
2117 
lookupNamespaceURI(const String & prefix) const2118 String Node::lookupNamespaceURI(const String &prefix) const
2119 {
2120     // Implemented according to
2121     // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#lookupNamespaceURIAlgo
2122 
2123     if (!prefix.isNull() && prefix.isEmpty())
2124         return String();
2125 
2126     switch (nodeType()) {
2127         case ELEMENT_NODE: {
2128             const Element *elem = static_cast<const Element *>(this);
2129 
2130             if (!elem->namespaceURI().isNull() && elem->prefix() == prefix)
2131                 return elem->namespaceURI();
2132 
2133             if (elem->hasAttributes()) {
2134                 NamedNodeMap *attrs = elem->attributes();
2135 
2136                 for (unsigned i = 0; i < attrs->length(); i++) {
2137                     Attribute *attr = attrs->attributeItem(i);
2138 
2139                     if (attr->prefix() == xmlnsAtom && attr->localName() == prefix) {
2140                         if (!attr->value().isEmpty())
2141                             return attr->value();
2142 
2143                         return String();
2144                     } else if (attr->localName() == xmlnsAtom && prefix.isNull()) {
2145                         if (!attr->value().isEmpty())
2146                             return attr->value();
2147 
2148                         return String();
2149                     }
2150                 }
2151             }
2152             if (Element* ancestor = ancestorElement())
2153                 return ancestor->lookupNamespaceURI(prefix);
2154             return String();
2155         }
2156         case DOCUMENT_NODE:
2157             if (Element* de = static_cast<const Document*>(this)->documentElement())
2158                 return de->lookupNamespaceURI(prefix);
2159             return String();
2160         case ENTITY_NODE:
2161         case NOTATION_NODE:
2162         case DOCUMENT_TYPE_NODE:
2163         case DOCUMENT_FRAGMENT_NODE:
2164         case SHADOW_ROOT_NODE:
2165             return String();
2166         case ATTRIBUTE_NODE: {
2167             const Attr *attr = static_cast<const Attr *>(this);
2168 
2169             if (attr->ownerElement())
2170                 return attr->ownerElement()->lookupNamespaceURI(prefix);
2171             else
2172                 return String();
2173         }
2174         default:
2175             if (Element* ancestor = ancestorElement())
2176                 return ancestor->lookupNamespaceURI(prefix);
2177             return String();
2178     }
2179 }
2180 
lookupNamespacePrefix(const AtomicString & _namespaceURI,const Element * originalElement) const2181 String Node::lookupNamespacePrefix(const AtomicString &_namespaceURI, const Element *originalElement) const
2182 {
2183     if (_namespaceURI.isNull())
2184         return String();
2185 
2186     if (originalElement->lookupNamespaceURI(prefix()) == _namespaceURI)
2187         return prefix();
2188 
2189     if (hasAttributes()) {
2190         NamedNodeMap *attrs = attributes();
2191 
2192         for (unsigned i = 0; i < attrs->length(); i++) {
2193             Attribute *attr = attrs->attributeItem(i);
2194 
2195             if (attr->prefix() == xmlnsAtom &&
2196                 attr->value() == _namespaceURI &&
2197                 originalElement->lookupNamespaceURI(attr->localName()) == _namespaceURI)
2198                 return attr->localName();
2199         }
2200     }
2201 
2202     if (Element* ancestor = ancestorElement())
2203         return ancestor->lookupNamespacePrefix(_namespaceURI, originalElement);
2204     return String();
2205 }
2206 
appendTextContent(const Node * node,bool convertBRsToNewlines,bool & isNullString,StringBuilder & content)2207 static void appendTextContent(const Node* node, bool convertBRsToNewlines, bool& isNullString, StringBuilder& content)
2208 {
2209     switch (node->nodeType()) {
2210     case Node::TEXT_NODE:
2211     case Node::CDATA_SECTION_NODE:
2212     case Node::COMMENT_NODE:
2213         isNullString = false;
2214         content.append(static_cast<const CharacterData*>(node)->data());
2215         break;
2216 
2217     case Node::PROCESSING_INSTRUCTION_NODE:
2218         isNullString = false;
2219         content.append(static_cast<const ProcessingInstruction*>(node)->data());
2220         break;
2221 
2222     case Node::ELEMENT_NODE:
2223         if (node->hasTagName(brTag) && convertBRsToNewlines) {
2224             isNullString = false;
2225             content.append('\n');
2226             break;
2227         }
2228     // Fall through.
2229     case Node::ATTRIBUTE_NODE:
2230     case Node::ENTITY_NODE:
2231     case Node::ENTITY_REFERENCE_NODE:
2232     case Node::DOCUMENT_FRAGMENT_NODE:
2233     case Node::SHADOW_ROOT_NODE:
2234         isNullString = false;
2235         for (Node* child = node->firstChild(); child; child = child->nextSibling()) {
2236             if (child->nodeType() == Node::COMMENT_NODE || child->nodeType() == Node::PROCESSING_INSTRUCTION_NODE)
2237                 continue;
2238             appendTextContent(child, convertBRsToNewlines, isNullString, content);
2239         }
2240         break;
2241 
2242     case Node::DOCUMENT_NODE:
2243     case Node::DOCUMENT_TYPE_NODE:
2244     case Node::NOTATION_NODE:
2245     case Node::XPATH_NAMESPACE_NODE:
2246         break;
2247     }
2248 }
2249 
textContent(bool convertBRsToNewlines) const2250 String Node::textContent(bool convertBRsToNewlines) const
2251 {
2252     StringBuilder content;
2253     bool isNullString = true;
2254     appendTextContent(this, convertBRsToNewlines, isNullString, content);
2255     return isNullString ? String() : content.toString();
2256 }
2257 
setTextContent(const String & text,ExceptionCode & ec)2258 void Node::setTextContent(const String& text, ExceptionCode& ec)
2259 {
2260     switch (nodeType()) {
2261         case TEXT_NODE:
2262         case CDATA_SECTION_NODE:
2263         case COMMENT_NODE:
2264         case PROCESSING_INSTRUCTION_NODE:
2265             setNodeValue(text, ec);
2266             return;
2267         case ELEMENT_NODE:
2268         case ATTRIBUTE_NODE:
2269         case ENTITY_NODE:
2270         case ENTITY_REFERENCE_NODE:
2271         case DOCUMENT_FRAGMENT_NODE:
2272         case SHADOW_ROOT_NODE: {
2273             ContainerNode* container = toContainerNode(this);
2274             container->removeChildren();
2275             if (!text.isEmpty())
2276                 container->appendChild(document()->createTextNode(text), ec);
2277             return;
2278         }
2279         case DOCUMENT_NODE:
2280         case DOCUMENT_TYPE_NODE:
2281         case NOTATION_NODE:
2282         case XPATH_NAMESPACE_NODE:
2283             // Do nothing.
2284             return;
2285     }
2286     ASSERT_NOT_REACHED();
2287 }
2288 
ancestorElement() const2289 Element* Node::ancestorElement() const
2290 {
2291     // In theory, there can be EntityReference nodes between elements, but this is currently not supported.
2292     for (ContainerNode* n = parentNode(); n; n = n->parentNode()) {
2293         if (n->isElementNode())
2294             return static_cast<Element*>(n);
2295     }
2296     return 0;
2297 }
2298 
offsetInCharacters() const2299 bool Node::offsetInCharacters() const
2300 {
2301     return false;
2302 }
2303 
compareDocumentPosition(Node * otherNode)2304 unsigned short Node::compareDocumentPosition(Node* otherNode)
2305 {
2306     // It is not clear what should be done if |otherNode| is 0.
2307     if (!otherNode)
2308         return DOCUMENT_POSITION_DISCONNECTED;
2309 
2310     if (otherNode == this)
2311         return DOCUMENT_POSITION_EQUIVALENT;
2312 
2313     Attr* attr1 = nodeType() == ATTRIBUTE_NODE ? static_cast<Attr*>(this) : 0;
2314     Attr* attr2 = otherNode->nodeType() == ATTRIBUTE_NODE ? static_cast<Attr*>(otherNode) : 0;
2315 
2316     Node* start1 = attr1 ? attr1->ownerElement() : this;
2317     Node* start2 = attr2 ? attr2->ownerElement() : otherNode;
2318 
2319     // If either of start1 or start2 is null, then we are disconnected, since one of the nodes is
2320     // an orphaned attribute node.
2321     if (!start1 || !start2)
2322         return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
2323 
2324     Vector<Node*, 16> chain1;
2325     Vector<Node*, 16> chain2;
2326     if (attr1)
2327         chain1.append(attr1);
2328     if (attr2)
2329         chain2.append(attr2);
2330 
2331     if (attr1 && attr2 && start1 == start2 && start1) {
2332         // We are comparing two attributes on the same node.  Crawl our attribute map
2333         // and see which one we hit first.
2334         NamedNodeMap* map = attr1->ownerElement()->attributes(true);
2335         unsigned length = map->length();
2336         for (unsigned i = 0; i < length; ++i) {
2337             // If neither of the two determining nodes is a child node and nodeType is the same for both determining nodes, then an
2338             // implementation-dependent order between the determining nodes is returned. This order is stable as long as no nodes of
2339             // the same nodeType are inserted into or removed from the direct container. This would be the case, for example,
2340             // when comparing two attributes of the same element, and inserting or removing additional attributes might change
2341             // the order between existing attributes.
2342             Attribute* attr = map->attributeItem(i);
2343             if (attr1->attr() == attr)
2344                 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_FOLLOWING;
2345             if (attr2->attr() == attr)
2346                 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_PRECEDING;
2347         }
2348 
2349         ASSERT_NOT_REACHED();
2350         return DOCUMENT_POSITION_DISCONNECTED;
2351     }
2352 
2353     // If one node is in the document and the other is not, we must be disconnected.
2354     // If the nodes have different owning documents, they must be disconnected.  Note that we avoid
2355     // comparing Attr nodes here, since they return false from inDocument() all the time (which seems like a bug).
2356     if (start1->inDocument() != start2->inDocument() ||
2357         start1->document() != start2->document())
2358         return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
2359 
2360     // We need to find a common ancestor container, and then compare the indices of the two immediate children.
2361     Node* current;
2362     for (current = start1; current; current = current->parentNode())
2363         chain1.append(current);
2364     for (current = start2; current; current = current->parentNode())
2365         chain2.append(current);
2366 
2367     // Walk the two chains backwards and look for the first difference.
2368     unsigned index1 = chain1.size();
2369     unsigned index2 = chain2.size();
2370     for (unsigned i = min(index1, index2); i; --i) {
2371         Node* child1 = chain1[--index1];
2372         Node* child2 = chain2[--index2];
2373         if (child1 != child2) {
2374             // If one of the children is an attribute, it wins.
2375             if (child1->nodeType() == ATTRIBUTE_NODE)
2376                 return DOCUMENT_POSITION_FOLLOWING;
2377             if (child2->nodeType() == ATTRIBUTE_NODE)
2378                 return DOCUMENT_POSITION_PRECEDING;
2379 
2380             if (!child2->nextSibling())
2381                 return DOCUMENT_POSITION_FOLLOWING;
2382             if (!child1->nextSibling())
2383                 return DOCUMENT_POSITION_PRECEDING;
2384 
2385             // Otherwise we need to see which node occurs first.  Crawl backwards from child2 looking for child1.
2386             for (Node* child = child2->previousSibling(); child; child = child->previousSibling()) {
2387                 if (child == child1)
2388                     return DOCUMENT_POSITION_FOLLOWING;
2389             }
2390             return DOCUMENT_POSITION_PRECEDING;
2391         }
2392     }
2393 
2394     // There was no difference between the two parent chains, i.e., one was a subset of the other.  The shorter
2395     // chain is the ancestor.
2396     return index1 < index2 ?
2397                DOCUMENT_POSITION_FOLLOWING | DOCUMENT_POSITION_CONTAINED_BY :
2398                DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_CONTAINS;
2399 }
2400 
convertToPage(const FloatPoint & p) const2401 FloatPoint Node::convertToPage(const FloatPoint& p) const
2402 {
2403     // If there is a renderer, just ask it to do the conversion
2404     if (renderer())
2405         return renderer()->localToAbsolute(p, false, true);
2406 
2407     // Otherwise go up the tree looking for a renderer
2408     Element *parent = ancestorElement();
2409     if (parent)
2410         return parent->convertToPage(p);
2411 
2412     // No parent - no conversion needed
2413     return p;
2414 }
2415 
convertFromPage(const FloatPoint & p) const2416 FloatPoint Node::convertFromPage(const FloatPoint& p) const
2417 {
2418     // If there is a renderer, just ask it to do the conversion
2419     if (renderer())
2420         return renderer()->absoluteToLocal(p, false, true);
2421 
2422     // Otherwise go up the tree looking for a renderer
2423     Element *parent = ancestorElement();
2424     if (parent)
2425         return parent->convertFromPage(p);
2426 
2427     // No parent - no conversion needed
2428     return p;
2429 }
2430 
2431 #ifndef NDEBUG
2432 
appendAttributeDesc(const Node * node,String & string,const QualifiedName & name,const char * attrDesc)2433 static void appendAttributeDesc(const Node* node, String& string, const QualifiedName& name, const char* attrDesc)
2434 {
2435     if (node->isElementNode()) {
2436         String attr = static_cast<const Element*>(node)->getAttribute(name);
2437         if (!attr.isEmpty()) {
2438             string += attrDesc;
2439             string += attr;
2440         }
2441     }
2442 }
2443 
showNode(const char * prefix) const2444 void Node::showNode(const char* prefix) const
2445 {
2446     if (!prefix)
2447         prefix = "";
2448     if (isTextNode()) {
2449         String value = nodeValue();
2450         value.replace('\\', "\\\\");
2451         value.replace('\n', "\\n");
2452         fprintf(stderr, "%s%s\t%p \"%s\"\n", prefix, nodeName().utf8().data(), this, value.utf8().data());
2453     } else {
2454         String attrs = "";
2455         appendAttributeDesc(this, attrs, classAttr, " CLASS=");
2456         appendAttributeDesc(this, attrs, styleAttr, " STYLE=");
2457         fprintf(stderr, "%s%s\t%p%s\n", prefix, nodeName().utf8().data(), this, attrs.utf8().data());
2458     }
2459 }
2460 
showTreeForThis() const2461 void Node::showTreeForThis() const
2462 {
2463     showTreeAndMark(this, "*");
2464 }
2465 
traverseTreeAndMark(const String & baseIndent,const Node * rootNode,const Node * markedNode1,const char * markedLabel1,const Node * markedNode2,const char * markedLabel2)2466 static void traverseTreeAndMark(const String& baseIndent, const Node* rootNode, const Node* markedNode1, const char* markedLabel1, const Node* markedNode2, const char* markedLabel2)
2467 {
2468     for (const Node* node = rootNode; node; node = node->traverseNextNode()) {
2469         if (node == markedNode1)
2470             fprintf(stderr, "%s", markedLabel1);
2471         if (node == markedNode2)
2472             fprintf(stderr, "%s", markedLabel2);
2473 
2474         String indent = baseIndent;
2475         for (const Node* tmpNode = node; tmpNode && tmpNode != rootNode; tmpNode = tmpNode->parentOrHostNode())
2476             indent += "\t";
2477         fprintf(stderr, "%s", indent.utf8().data());
2478         node->showNode();
2479 
2480         ContainerNode* shadow = shadowRoot(const_cast<Node*>(node));
2481 
2482         if (!shadow && node->renderer() && node->renderer()->isTextControl())
2483             shadow = static_cast<RenderTextControl*>(node->renderer())->innerTextElement();
2484 
2485         if (shadow) {
2486             indent += "\t";
2487             traverseTreeAndMark(indent, shadow, markedNode1, markedLabel1, markedNode2, markedLabel2);
2488         }
2489     }
2490 }
2491 
showTreeAndMark(const Node * markedNode1,const char * markedLabel1,const Node * markedNode2,const char * markedLabel2) const2492 void Node::showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2, const char* markedLabel2) const
2493 {
2494     const Node* rootNode;
2495     const Node* node = this;
2496     while (node->parentOrHostNode() && !node->hasTagName(bodyTag))
2497         node = node->parentOrHostNode();
2498     rootNode = node;
2499 
2500     String startingIndent;
2501     traverseTreeAndMark(startingIndent, rootNode, markedNode1, markedLabel1, markedNode2, markedLabel2);
2502 }
2503 
formatForDebugger(char * buffer,unsigned length) const2504 void Node::formatForDebugger(char* buffer, unsigned length) const
2505 {
2506     String result;
2507     String s;
2508 
2509     s = nodeName();
2510     if (s.length() == 0)
2511         result += "<none>";
2512     else
2513         result += s;
2514 
2515     strncpy(buffer, result.utf8().data(), length - 1);
2516 }
2517 
2518 #endif
2519 
2520 // --------
2521 
invalidateCaches()2522 void NodeListsNodeData::invalidateCaches()
2523 {
2524     m_childNodeListCaches->reset();
2525 
2526     if (m_labelsNodeListCache)
2527         m_labelsNodeListCache->invalidateCache();
2528     TagNodeListCache::const_iterator tagCacheEnd = m_tagNodeListCache.end();
2529     for (TagNodeListCache::const_iterator it = m_tagNodeListCache.begin(); it != tagCacheEnd; ++it)
2530         it->second->invalidateCache();
2531     TagNodeListCacheNS::const_iterator tagCacheNSEnd = m_tagNodeListCacheNS.end();
2532     for (TagNodeListCacheNS::const_iterator it = m_tagNodeListCacheNS.begin(); it != tagCacheNSEnd; ++it)
2533         it->second->invalidateCache();
2534     invalidateCachesThatDependOnAttributes();
2535 }
2536 
invalidateCachesThatDependOnAttributes()2537 void NodeListsNodeData::invalidateCachesThatDependOnAttributes()
2538 {
2539     ClassNodeListCache::iterator classCacheEnd = m_classNodeListCache.end();
2540     for (ClassNodeListCache::iterator it = m_classNodeListCache.begin(); it != classCacheEnd; ++it)
2541         it->second->invalidateCache();
2542 
2543     NameNodeListCache::iterator nameCacheEnd = m_nameNodeListCache.end();
2544     for (NameNodeListCache::iterator it = m_nameNodeListCache.begin(); it != nameCacheEnd; ++it)
2545         it->second->invalidateCache();
2546     if (m_labelsNodeListCache)
2547         m_labelsNodeListCache->invalidateCache();
2548 }
2549 
isEmpty() const2550 bool NodeListsNodeData::isEmpty() const
2551 {
2552     if (!m_listsWithCaches.isEmpty())
2553         return false;
2554 
2555     if (m_childNodeListCaches->refCount())
2556         return false;
2557 
2558     TagNodeListCache::const_iterator tagCacheEnd = m_tagNodeListCache.end();
2559     for (TagNodeListCache::const_iterator it = m_tagNodeListCache.begin(); it != tagCacheEnd; ++it) {
2560         if (it->second->refCount())
2561             return false;
2562     }
2563 
2564     TagNodeListCacheNS::const_iterator tagCacheNSEnd = m_tagNodeListCacheNS.end();
2565     for (TagNodeListCacheNS::const_iterator it = m_tagNodeListCacheNS.begin(); it != tagCacheNSEnd; ++it) {
2566         if (it->second->refCount())
2567             return false;
2568     }
2569 
2570     ClassNodeListCache::const_iterator classCacheEnd = m_classNodeListCache.end();
2571     for (ClassNodeListCache::const_iterator it = m_classNodeListCache.begin(); it != classCacheEnd; ++it) {
2572         if (it->second->refCount())
2573             return false;
2574     }
2575 
2576     NameNodeListCache::const_iterator nameCacheEnd = m_nameNodeListCache.end();
2577     for (NameNodeListCache::const_iterator it = m_nameNodeListCache.begin(); it != nameCacheEnd; ++it) {
2578         if (it->second->refCount())
2579             return false;
2580     }
2581 
2582     if (m_labelsNodeListCache)
2583         return false;
2584 
2585     return true;
2586 }
2587 
getSubresourceURLs(ListHashSet<KURL> & urls) const2588 void Node::getSubresourceURLs(ListHashSet<KURL>& urls) const
2589 {
2590     addSubresourceAttributeURLs(urls);
2591 }
2592 
enclosingLinkEventParentOrSelf()2593 Node* Node::enclosingLinkEventParentOrSelf()
2594 {
2595     for (Node* node = this; node; node = node->parentOrHostNode()) {
2596         // For imagemaps, the enclosing link node is the associated area element not the image itself.
2597         // So we don't let images be the enclosingLinkNode, even though isLink sometimes returns true
2598         // for them.
2599         if (node->isLink() && !node->hasTagName(imgTag))
2600             return node;
2601     }
2602 
2603     return 0;
2604 }
2605 
2606 // --------
2607 
scriptExecutionContext() const2608 ScriptExecutionContext* Node::scriptExecutionContext() const
2609 {
2610     return document();
2611 }
2612 
insertedIntoDocument()2613 void Node::insertedIntoDocument()
2614 {
2615     setInDocument();
2616 }
2617 
removedFromDocument()2618 void Node::removedFromDocument()
2619 {
2620     clearInDocument();
2621 }
2622 
willMoveToNewOwnerDocument()2623 void Node::willMoveToNewOwnerDocument()
2624 {
2625     ASSERT(!willMoveToNewOwnerDocumentWasCalled);
2626     setWillMoveToNewOwnerDocumentWasCalled(true);
2627 }
2628 
didMoveToNewOwnerDocument()2629 void Node::didMoveToNewOwnerDocument()
2630 {
2631     ASSERT(!didMoveToNewOwnerDocumentWasCalled);
2632     setDidMoveToNewOwnerDocumentWasCalled(true);
2633 }
2634 
2635 #if ENABLE(SVG)
instancesForSVGElement(Node * node)2636 static inline HashSet<SVGElementInstance*> instancesForSVGElement(Node* node)
2637 {
2638     HashSet<SVGElementInstance*> instances;
2639 
2640     ASSERT(node);
2641     if (!node->isSVGElement() || node->shadowTreeRootNode())
2642         return HashSet<SVGElementInstance*>();
2643 
2644     SVGElement* element = static_cast<SVGElement*>(node);
2645     if (!element->isStyled())
2646         return HashSet<SVGElementInstance*>();
2647 
2648     SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(element);
2649     ASSERT(!styledElement->instanceUpdatesBlocked());
2650 
2651     return styledElement->instancesForElement();
2652 }
2653 #endif
2654 
tryAddEventListener(Node * targetNode,const AtomicString & eventType,PassRefPtr<EventListener> listener,bool useCapture)2655 static inline bool tryAddEventListener(Node* targetNode, const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
2656 {
2657     if (!targetNode->EventTarget::addEventListener(eventType, listener, useCapture))
2658         return false;
2659 
2660     if (Document* document = targetNode->document())
2661         document->addListenerTypeIfNeeded(eventType);
2662 
2663     return true;
2664 }
2665 
addEventListener(const AtomicString & eventType,PassRefPtr<EventListener> listener,bool useCapture)2666 bool Node::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
2667 {
2668 #if !ENABLE(SVG)
2669     return tryAddEventListener(this, eventType, listener, useCapture);
2670 #else
2671     if (!isSVGElement())
2672         return tryAddEventListener(this, eventType, listener, useCapture);
2673 
2674     HashSet<SVGElementInstance*> instances = instancesForSVGElement(this);
2675     if (instances.isEmpty())
2676         return tryAddEventListener(this, eventType, listener, useCapture);
2677 
2678     RefPtr<EventListener> listenerForRegularTree = listener;
2679     RefPtr<EventListener> listenerForShadowTree = listenerForRegularTree;
2680 
2681     // Add event listener to regular DOM element
2682     if (!tryAddEventListener(this, eventType, listenerForRegularTree.release(), useCapture))
2683         return false;
2684 
2685     // Add event listener to all shadow tree DOM element instances
2686     const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
2687     for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
2688         ASSERT((*it)->shadowTreeElement());
2689         ASSERT((*it)->correspondingElement() == this);
2690 
2691         RefPtr<EventListener> listenerForCurrentShadowTreeElement = listenerForShadowTree;
2692         bool result = tryAddEventListener((*it)->shadowTreeElement(), eventType, listenerForCurrentShadowTreeElement.release(), useCapture);
2693         ASSERT_UNUSED(result, result);
2694     }
2695 
2696     return true;
2697 #endif
2698 }
2699 
tryRemoveEventListener(Node * targetNode,const AtomicString & eventType,EventListener * listener,bool useCapture)2700 static inline bool tryRemoveEventListener(Node* targetNode, const AtomicString& eventType, EventListener* listener, bool useCapture)
2701 {
2702     if (!targetNode->EventTarget::removeEventListener(eventType, listener, useCapture))
2703         return false;
2704 
2705     // FIXME: Notify Document that the listener has vanished. We need to keep track of a number of
2706     // listeners for each type, not just a bool - see https://bugs.webkit.org/show_bug.cgi?id=33861
2707 
2708     return true;
2709 }
2710 
removeEventListener(const AtomicString & eventType,EventListener * listener,bool useCapture)2711 bool Node::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
2712 {
2713 #if !ENABLE(SVG)
2714     return tryRemoveEventListener(this, eventType, listener, useCapture);
2715 #else
2716     if (!isSVGElement())
2717         return tryRemoveEventListener(this, eventType, listener, useCapture);
2718 
2719     HashSet<SVGElementInstance*> instances = instancesForSVGElement(this);
2720     if (instances.isEmpty())
2721         return tryRemoveEventListener(this, eventType, listener, useCapture);
2722 
2723     // EventTarget::removeEventListener creates a PassRefPtr around the given EventListener
2724     // object when creating a temporary RegisteredEventListener object used to look up the
2725     // event listener in a cache. If we want to be able to call removeEventListener() multiple
2726     // times on different nodes, we have to delay its immediate destruction, which would happen
2727     // after the first call below.
2728     RefPtr<EventListener> protector(listener);
2729 
2730     // Remove event listener from regular DOM element
2731     if (!tryRemoveEventListener(this, eventType, listener, useCapture))
2732         return false;
2733 
2734     // Remove event listener from all shadow tree DOM element instances
2735     const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
2736     for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
2737         ASSERT((*it)->correspondingElement() == this);
2738 
2739         SVGElement* shadowTreeElement = (*it)->shadowTreeElement();
2740         ASSERT(shadowTreeElement);
2741 
2742         if (tryRemoveEventListener(shadowTreeElement, eventType, listener, useCapture))
2743             continue;
2744 
2745         // This case can only be hit for event listeners created from markup
2746         ASSERT(listener->wasCreatedFromMarkup());
2747 
2748         // If the event listener 'listener' has been created from markup and has been fired before
2749         // then JSLazyEventListener::parseCode() has been called and m_jsFunction of that listener
2750         // has been created (read: it's not 0 anymore). During shadow tree creation, the event
2751         // listener DOM attribute has been cloned, and another event listener has been setup in
2752         // the shadow tree. If that event listener has not been used yet, m_jsFunction is still 0,
2753         // and tryRemoveEventListener() above will fail. Work around that very seldom problem.
2754         EventTargetData* data = shadowTreeElement->eventTargetData();
2755         ASSERT(data);
2756 
2757         EventListenerMap::iterator result = data->eventListenerMap.find(eventType);
2758         ASSERT(result != data->eventListenerMap.end());
2759 
2760         EventListenerVector* entry = result->second;
2761         ASSERT(entry);
2762 
2763         unsigned int index = 0;
2764         bool foundListener = false;
2765 
2766         EventListenerVector::iterator end = entry->end();
2767         for (EventListenerVector::iterator it = entry->begin(); it != end; ++it) {
2768             if (!(*it).listener->wasCreatedFromMarkup()) {
2769                 ++index;
2770                 continue;
2771             }
2772 
2773             foundListener = true;
2774             entry->remove(index);
2775             break;
2776         }
2777 
2778         ASSERT_UNUSED(foundListener, foundListener);
2779 
2780         if (entry->isEmpty()) {
2781             delete entry;
2782             data->eventListenerMap.remove(result);
2783         }
2784     }
2785 
2786     return true;
2787 #endif
2788 }
2789 
eventTargetData()2790 EventTargetData* Node::eventTargetData()
2791 {
2792     return hasRareData() ? rareData()->eventTargetData() : 0;
2793 }
2794 
ensureEventTargetData()2795 EventTargetData* Node::ensureEventTargetData()
2796 {
2797     return ensureRareData()->ensureEventTargetData();
2798 }
2799 
handleLocalEvents(Event * event)2800 void Node::handleLocalEvents(Event* event)
2801 {
2802     if (!hasRareData() || !rareData()->eventTargetData())
2803         return;
2804 
2805     if (disabled() && event->isMouseEvent())
2806         return;
2807 
2808     fireEventListeners(event);
2809 }
2810 
dispatchScopedEvent(PassRefPtr<Event> event)2811 void Node::dispatchScopedEvent(PassRefPtr<Event> event)
2812 {
2813     EventDispatcher::dispatchScopedEvent(this, event);
2814 }
2815 
dispatchEvent(PassRefPtr<Event> event)2816 bool Node::dispatchEvent(PassRefPtr<Event> event)
2817 {
2818     return EventDispatcher::dispatchEvent(this, EventDispatchMediator(event));
2819 }
2820 
dispatchSubtreeModifiedEvent()2821 void Node::dispatchSubtreeModifiedEvent()
2822 {
2823     ASSERT(!eventDispatchForbidden());
2824 
2825     document()->incDOMTreeVersion();
2826 
2827     notifyNodeListsAttributeChanged(); // FIXME: Can do better some day. Really only care about the name attribute changing.
2828 
2829     if (!document()->hasListenerType(Document::DOMSUBTREEMODIFIED_LISTENER))
2830         return;
2831 
2832     dispatchScopedEvent(MutationEvent::create(eventNames().DOMSubtreeModifiedEvent, true));
2833 }
2834 
dispatchUIEvent(const AtomicString & eventType,int detail,PassRefPtr<Event> underlyingEvent)2835 void Node::dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr<Event> underlyingEvent)
2836 {
2837     ASSERT(!eventDispatchForbidden());
2838     ASSERT(eventType == eventNames().focusinEvent || eventType == eventNames().focusoutEvent ||
2839            eventType == eventNames().DOMFocusInEvent || eventType == eventNames().DOMFocusOutEvent || eventType == eventNames().DOMActivateEvent);
2840 
2841     bool cancelable = eventType == eventNames().DOMActivateEvent;
2842 
2843     RefPtr<UIEvent> event = UIEvent::create(eventType, true, cancelable, document()->defaultView(), detail);
2844     event->setUnderlyingEvent(underlyingEvent);
2845     dispatchScopedEvent(event.release());
2846 }
2847 
dispatchKeyEvent(const PlatformKeyboardEvent & event)2848 bool Node::dispatchKeyEvent(const PlatformKeyboardEvent& event)
2849 {
2850     return EventDispatcher::dispatchEvent(this, KeyboardEventDispatchMediator(KeyboardEvent::create(event, document()->defaultView())));
2851 }
2852 
dispatchMouseEvent(const PlatformMouseEvent & event,const AtomicString & eventType,int detail,Node * relatedTarget)2853 bool Node::dispatchMouseEvent(const PlatformMouseEvent& event, const AtomicString& eventType,
2854     int detail, Node* relatedTarget)
2855 {
2856     return EventDispatcher::dispatchEvent(this, MouseEventDispatchMediator(MouseEvent::create(eventType, document()->defaultView(), event, detail, relatedTarget)));
2857 }
2858 
dispatchSimulatedClick(PassRefPtr<Event> event,bool sendMouseEvents,bool showPressedLook)2859 void Node::dispatchSimulatedClick(PassRefPtr<Event> event, bool sendMouseEvents, bool showPressedLook)
2860 {
2861     EventDispatcher::dispatchSimulatedClick(this, event, sendMouseEvents, showPressedLook);
2862 }
2863 
dispatchWheelEvent(const PlatformWheelEvent & event)2864 bool Node::dispatchWheelEvent(const PlatformWheelEvent& event)
2865 {
2866     return EventDispatcher::dispatchEvent(this, WheelEventDispatchMediator(event, document()->defaultView()));
2867 }
2868 
dispatchFocusEvent()2869 void Node::dispatchFocusEvent()
2870 {
2871     dispatchEvent(Event::create(eventNames().focusEvent, false, false));
2872 }
2873 
dispatchBlurEvent()2874 void Node::dispatchBlurEvent()
2875 {
2876     dispatchEvent(Event::create(eventNames().blurEvent, false, false));
2877 }
2878 
dispatchChangeEvent()2879 void Node::dispatchChangeEvent()
2880 {
2881     dispatchEvent(Event::create(eventNames().changeEvent, true, false));
2882 }
2883 
dispatchInputEvent()2884 void Node::dispatchInputEvent()
2885 {
2886     dispatchEvent(Event::create(eventNames().inputEvent, true, false));
2887 }
2888 
disabled() const2889 bool Node::disabled() const
2890 {
2891     return false;
2892 }
2893 
defaultEventHandler(Event * event)2894 void Node::defaultEventHandler(Event* event)
2895 {
2896     if (event->target() != this)
2897         return;
2898     const AtomicString& eventType = event->type();
2899     if (eventType == eventNames().keydownEvent || eventType == eventNames().keypressEvent) {
2900         if (event->isKeyboardEvent())
2901             if (Frame* frame = document()->frame())
2902                 frame->eventHandler()->defaultKeyboardEventHandler(static_cast<KeyboardEvent*>(event));
2903     } else if (eventType == eventNames().clickEvent) {
2904         int detail = event->isUIEvent() ? static_cast<UIEvent*>(event)->detail() : 0;
2905         dispatchUIEvent(eventNames().DOMActivateEvent, detail, event);
2906 #if ENABLE(CONTEXT_MENUS)
2907     } else if (eventType == eventNames().contextmenuEvent) {
2908         if (Frame* frame = document()->frame())
2909             if (Page* page = frame->page())
2910                 page->contextMenuController()->handleContextMenuEvent(event);
2911 #endif
2912     } else if (eventType == eventNames().textInputEvent) {
2913         if (event->isTextEvent())
2914             if (Frame* frame = document()->frame())
2915                 frame->eventHandler()->defaultTextInputEventHandler(static_cast<TextEvent*>(event));
2916 #if ENABLE(PAN_SCROLLING)
2917     } else if (eventType == eventNames().mousedownEvent && event->isMouseEvent()) {
2918         MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
2919         if (mouseEvent->button() == MiddleButton) {
2920             if (enclosingLinkEventParentOrSelf())
2921                 return;
2922 
2923             RenderObject* renderer = this->renderer();
2924             while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeScrolledAndHasScrollableArea()))
2925                 renderer = renderer->parent();
2926 
2927             if (renderer) {
2928                 if (Frame* frame = document()->frame())
2929                     frame->eventHandler()->startPanScrolling(renderer);
2930             }
2931         }
2932 #endif
2933     } else if (eventType == eventNames().mousewheelEvent && event->isWheelEvent()) {
2934         WheelEvent* wheelEvent = static_cast<WheelEvent*>(event);
2935 
2936         // If we don't have a renderer, send the wheel event to the first node we find with a renderer.
2937         // This is needed for <option> and <optgroup> elements so that <select>s get a wheel scroll.
2938         Node* startNode = this;
2939         while (startNode && !startNode->renderer())
2940             startNode = startNode->parentOrHostNode();
2941 
2942         if (startNode && startNode->renderer())
2943             if (Frame* frame = document()->frame())
2944                 frame->eventHandler()->defaultWheelEventHandler(startNode, wheelEvent);
2945     } else if (event->type() == eventNames().webkitEditableContentChangedEvent) {
2946         dispatchInputEvent();
2947     }
2948 }
2949 
2950 } // namespace WebCore
2951 
2952 #ifndef NDEBUG
2953 
showTree(const WebCore::Node * node)2954 void showTree(const WebCore::Node* node)
2955 {
2956     if (node)
2957         node->showTreeForThis();
2958 }
2959 
2960 #endif
2961