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