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