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