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