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