1/* 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org) 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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#include "AXObjectCache.h" 29#include "Attr.h" 30#include "BeforeLoadEvent.h" 31#include "ChildListMutationScope.h" 32#include "Chrome.h" 33#include "ChromeClient.h" 34#include "CSSParser.h" 35#include "CSSRule.h" 36#include "CSSSelector.h" 37#include "CSSSelectorList.h" 38#include "CSSStyleRule.h" 39#include "CSSStyleSheet.h" 40#include "ContainerNodeAlgorithms.h" 41#include "ContextMenuController.h" 42#include "DOMImplementation.h" 43#include "DocumentType.h" 44#include "ElementIterator.h" 45#include "ElementRareData.h" 46#include "EventDispatcher.h" 47#include "EventException.h" 48#include "EventHandler.h" 49#include "FlowThreadController.h" 50#include "FrameView.h" 51#include "HTMLCollection.h" 52#include "HTMLElement.h" 53#include "HTMLImageElement.h" 54#include "HTMLStyleElement.h" 55#include "InsertionPoint.h" 56#include "KeyboardEvent.h" 57#include "Logging.h" 58#include "MutationEvent.h" 59#include "NodeRenderStyle.h" 60#include "PlatformMouseEvent.h" 61#include "PlatformWheelEvent.h" 62#include "ProcessingInstruction.h" 63#include "ProgressEvent.h" 64#include "Range.h" 65#include "RenderBlock.h" 66#include "RenderBox.h" 67#include "RenderTextControl.h" 68#include "RenderView.h" 69#include "ScopedEventQueue.h" 70#include "Settings.h" 71#include "StorageEvent.h" 72#include "StyleResolver.h" 73#include "TemplateContentDocumentFragment.h" 74#include "TextEvent.h" 75#include "TouchEvent.h" 76#include "TreeScopeAdopter.h" 77#include "WheelEvent.h" 78#include "XMLNames.h" 79#include "htmlediting.h" 80#include <runtime/JSCInlines.h> 81#include <runtime/VM.h> 82#include <wtf/RefCountedLeakCounter.h> 83#include <wtf/text/CString.h> 84#include <wtf/text/StringBuilder.h> 85 86#if ENABLE(INDIE_UI) 87#include "UIRequestEvent.h" 88#endif 89 90#if ENABLE(INSPECTOR) 91#include "InspectorController.h" 92#endif 93 94namespace WebCore { 95 96using namespace HTMLNames; 97 98bool Node::isSupported(const String& feature, const String& version) 99{ 100 return DOMImplementation::hasFeature(feature, version); 101} 102 103#if DUMP_NODE_STATISTICS 104static HashSet<Node*> liveNodeSet; 105#endif 106 107void Node::dumpStatistics() 108{ 109#if DUMP_NODE_STATISTICS 110 size_t nodesWithRareData = 0; 111 112 size_t elementNodes = 0; 113 size_t attrNodes = 0; 114 size_t textNodes = 0; 115 size_t cdataNodes = 0; 116 size_t commentNodes = 0; 117 size_t entityReferenceNodes = 0; 118 size_t entityNodes = 0; 119 size_t piNodes = 0; 120 size_t documentNodes = 0; 121 size_t docTypeNodes = 0; 122 size_t fragmentNodes = 0; 123 size_t notationNodes = 0; 124 size_t xpathNSNodes = 0; 125 size_t shadowRootNodes = 0; 126 127 HashMap<String, size_t> perTagCount; 128 129 size_t attributes = 0; 130 size_t attributesWithAttr = 0; 131 size_t elementsWithAttributeStorage = 0; 132 size_t elementsWithRareData = 0; 133 size_t elementsWithNamedNodeMap = 0; 134 135 for (HashSet<Node*>::iterator it = liveNodeSet.begin(); it != liveNodeSet.end(); ++it) { 136 Node* node = *it; 137 138 if (node->hasRareData()) { 139 ++nodesWithRareData; 140 if (node->isElementNode()) { 141 ++elementsWithRareData; 142 if (toElement(node)->hasNamedNodeMap()) 143 ++elementsWithNamedNodeMap; 144 } 145 } 146 147 switch (node->nodeType()) { 148 case ELEMENT_NODE: { 149 ++elementNodes; 150 151 // Tag stats 152 Element* element = toElement(node); 153 HashMap<String, size_t>::AddResult result = perTagCount.add(element->tagName(), 1); 154 if (!result.isNewEntry) 155 result.iterator->value++; 156 157 if (ElementData* elementData = element->elementData()) { 158 unsigned length = elementData->length(); 159 attributes += length; 160 ++elementsWithAttributeStorage; 161 for (unsigned i = 0; i < length; ++i) { 162 Attribute& attr = elementData->attributeAt(i); 163 if (attr.attr()) 164 ++attributesWithAttr; 165 } 166 } 167 break; 168 } 169 case ATTRIBUTE_NODE: { 170 ++attrNodes; 171 break; 172 } 173 case TEXT_NODE: { 174 ++textNodes; 175 break; 176 } 177 case CDATA_SECTION_NODE: { 178 ++cdataNodes; 179 break; 180 } 181 case COMMENT_NODE: { 182 ++commentNodes; 183 break; 184 } 185 case ENTITY_REFERENCE_NODE: { 186 ++entityReferenceNodes; 187 break; 188 } 189 case ENTITY_NODE: { 190 ++entityNodes; 191 break; 192 } 193 case PROCESSING_INSTRUCTION_NODE: { 194 ++piNodes; 195 break; 196 } 197 case DOCUMENT_NODE: { 198 ++documentNodes; 199 break; 200 } 201 case DOCUMENT_TYPE_NODE: { 202 ++docTypeNodes; 203 break; 204 } 205 case DOCUMENT_FRAGMENT_NODE: { 206 if (node->isShadowRoot()) 207 ++shadowRootNodes; 208 else 209 ++fragmentNodes; 210 break; 211 } 212 case NOTATION_NODE: { 213 ++notationNodes; 214 break; 215 } 216 case XPATH_NAMESPACE_NODE: { 217 ++xpathNSNodes; 218 break; 219 } 220 } 221 } 222 223 printf("Number of Nodes: %d\n\n", liveNodeSet.size()); 224 printf("Number of Nodes with RareData: %zu\n\n", nodesWithRareData); 225 226 printf("NodeType distribution:\n"); 227 printf(" Number of Element nodes: %zu\n", elementNodes); 228 printf(" Number of Attribute nodes: %zu\n", attrNodes); 229 printf(" Number of Text nodes: %zu\n", textNodes); 230 printf(" Number of CDATASection nodes: %zu\n", cdataNodes); 231 printf(" Number of Comment nodes: %zu\n", commentNodes); 232 printf(" Number of EntityReference nodes: %zu\n", entityReferenceNodes); 233 printf(" Number of Entity nodes: %zu\n", entityNodes); 234 printf(" Number of ProcessingInstruction nodes: %zu\n", piNodes); 235 printf(" Number of Document nodes: %zu\n", documentNodes); 236 printf(" Number of DocumentType nodes: %zu\n", docTypeNodes); 237 printf(" Number of DocumentFragment nodes: %zu\n", fragmentNodes); 238 printf(" Number of Notation nodes: %zu\n", notationNodes); 239 printf(" Number of XPathNS nodes: %zu\n", xpathNSNodes); 240 printf(" Number of ShadowRoot nodes: %zu\n", shadowRootNodes); 241 242 printf("Element tag name distibution:\n"); 243 for (HashMap<String, size_t>::iterator it = perTagCount.begin(); it != perTagCount.end(); ++it) 244 printf(" Number of <%s> tags: %zu\n", it->key.utf8().data(), it->value); 245 246 printf("Attributes:\n"); 247 printf(" Number of Attributes (non-Node and Node): %zu [%zu]\n", attributes, sizeof(Attribute)); 248 printf(" Number of Attributes with an Attr: %zu\n", attributesWithAttr); 249 printf(" Number of Elements with attribute storage: %zu [%zu]\n", elementsWithAttributeStorage, sizeof(ElementData)); 250 printf(" Number of Elements with RareData: %zu\n", elementsWithRareData); 251 printf(" Number of Elements with NamedNodeMap: %zu [%zu]\n", elementsWithNamedNodeMap, sizeof(NamedNodeMap)); 252#endif 253} 254 255DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, nodeCounter, ("WebCoreNode")); 256DEFINE_DEBUG_ONLY_GLOBAL(HashSet<Node*>, ignoreSet, ); 257 258#ifndef NDEBUG 259static bool shouldIgnoreLeaks = false; 260#endif 261 262void Node::startIgnoringLeaks() 263{ 264#ifndef NDEBUG 265 shouldIgnoreLeaks = true; 266#endif 267} 268 269void Node::stopIgnoringLeaks() 270{ 271#ifndef NDEBUG 272 shouldIgnoreLeaks = false; 273#endif 274} 275 276void Node::trackForDebugging() 277{ 278#ifndef NDEBUG 279 if (shouldIgnoreLeaks) 280 ignoreSet.add(this); 281 else 282 nodeCounter.increment(); 283#endif 284 285#if DUMP_NODE_STATISTICS 286 liveNodeSet.add(this); 287#endif 288} 289 290Node::~Node() 291{ 292#ifndef NDEBUG 293 if (!ignoreSet.remove(this)) 294 nodeCounter.decrement(); 295#endif 296 297#if DUMP_NODE_STATISTICS 298 liveNodeSet.remove(this); 299#endif 300 301 ASSERT(!renderer()); 302 ASSERT(!parentNode()); 303 ASSERT(!m_previous); 304 ASSERT(!m_next); 305 306 if (hasRareData()) 307 clearRareData(); 308 309 if (!isContainerNode()) 310 willBeDeletedFrom(document()); 311 312 document().decrementReferencingNodeCount(); 313} 314 315void Node::willBeDeletedFrom(Document& document) 316{ 317 if (hasEventTargetData()) { 318#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS) 319 document.removeTouchEventListener(this, true); 320#endif 321 clearEventTargetData(); 322 } 323 324 if (AXObjectCache* cache = document.existingAXObjectCache()) 325 cache->remove(this); 326} 327 328void Node::materializeRareData() 329{ 330 NodeRareData* data; 331 if (isElementNode()) 332 data = ElementRareData::create(toRenderElement(m_data.m_renderer)).leakPtr(); 333 else 334 data = NodeRareData::create(m_data.m_renderer).leakPtr(); 335 ASSERT(data); 336 337 m_data.m_rareData = data; 338 setFlag(HasRareDataFlag); 339} 340 341void Node::clearRareData() 342{ 343 ASSERT(hasRareData()); 344 ASSERT(!transientMutationObserverRegistry() || transientMutationObserverRegistry()->isEmpty()); 345 346 RenderObject* renderer = m_data.m_rareData->renderer(); 347 if (isElementNode()) 348 delete static_cast<ElementRareData*>(m_data.m_rareData); 349 else 350 delete static_cast<NodeRareData*>(m_data.m_rareData); 351 m_data.m_renderer = renderer; 352 clearFlag(HasRareDataFlag); 353} 354 355Node* Node::toNode() 356{ 357 return this; 358} 359 360HTMLInputElement* Node::toInputElement() 361{ 362 // If one of the below ASSERTs trigger, you are calling this function 363 // directly or indirectly from a constructor or destructor of this object. 364 // Don't do this! 365 ASSERT(!(isHTMLElement() && hasTagName(inputTag))); 366 return 0; 367} 368 369String Node::nodeValue() const 370{ 371 return String(); 372} 373 374void Node::setNodeValue(const String& /*nodeValue*/, ExceptionCode& ec) 375{ 376 // NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly 377 if (isReadOnlyNode()) { 378 ec = NO_MODIFICATION_ALLOWED_ERR; 379 return; 380 } 381 382 // By default, setting nodeValue has no effect. 383} 384 385PassRefPtr<NodeList> Node::childNodes() 386{ 387 if (isContainerNode()) 388 return ensureRareData().ensureNodeLists().ensureChildNodeList(toContainerNode(*this)); 389 return ensureRareData().ensureNodeLists().ensureEmptyChildNodeList(*this); 390} 391 392Node *Node::lastDescendant() const 393{ 394 Node *n = const_cast<Node *>(this); 395 while (n && n->lastChild()) 396 n = n->lastChild(); 397 return n; 398} 399 400Node* Node::firstDescendant() const 401{ 402 Node *n = const_cast<Node *>(this); 403 while (n && n->firstChild()) 404 n = n->firstChild(); 405 return n; 406} 407 408bool Node::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec) 409{ 410 if (!isContainerNode()) { 411 ec = HIERARCHY_REQUEST_ERR; 412 return false; 413 } 414 return toContainerNode(this)->insertBefore(newChild, refChild, ec); 415} 416 417bool Node::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec) 418{ 419 if (!isContainerNode()) { 420 ec = HIERARCHY_REQUEST_ERR; 421 return false; 422 } 423 return toContainerNode(this)->replaceChild(newChild, oldChild, ec); 424} 425 426bool Node::removeChild(Node* oldChild, ExceptionCode& ec) 427{ 428 if (!isContainerNode()) { 429 ec = NOT_FOUND_ERR; 430 return false; 431 } 432 return toContainerNode(this)->removeChild(oldChild, ec); 433} 434 435bool Node::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec) 436{ 437 if (!isContainerNode()) { 438 ec = HIERARCHY_REQUEST_ERR; 439 return false; 440 } 441 return toContainerNode(this)->appendChild(newChild, ec); 442} 443 444void Node::remove(ExceptionCode& ec) 445{ 446 if (ContainerNode* parent = parentNode()) 447 parent->removeChild(this, ec); 448} 449 450void Node::normalize() 451{ 452 // Go through the subtree beneath us, normalizing all nodes. This means that 453 // any two adjacent text nodes are merged and any empty text nodes are removed. 454 455 RefPtr<Node> node = this; 456 while (Node* firstChild = node->firstChild()) 457 node = firstChild; 458 while (node) { 459 NodeType type = node->nodeType(); 460 if (type == ELEMENT_NODE) 461 toElement(node.get())->normalizeAttributes(); 462 463 if (node == this) 464 break; 465 466 if (type != TEXT_NODE) { 467 node = NodeTraversal::nextPostOrder(node.get()); 468 continue; 469 } 470 471 RefPtr<Text> text = toText(node.get()); 472 473 // Remove empty text nodes. 474 if (!text->length()) { 475 // Care must be taken to get the next node before removing the current node. 476 node = NodeTraversal::nextPostOrder(node.get()); 477 text->remove(IGNORE_EXCEPTION); 478 continue; 479 } 480 481 // Merge text nodes. 482 while (Node* nextSibling = node->nextSibling()) { 483 if (nextSibling->nodeType() != TEXT_NODE) 484 break; 485 RefPtr<Text> nextText = toText(nextSibling); 486 487 // Remove empty text nodes. 488 if (!nextText->length()) { 489 nextText->remove(IGNORE_EXCEPTION); 490 continue; 491 } 492 493 // Both non-empty text nodes. Merge them. 494 unsigned offset = text->length(); 495 text->appendData(nextText->data(), IGNORE_EXCEPTION); 496 document().textNodesMerged(nextText.get(), offset); 497 nextText->remove(IGNORE_EXCEPTION); 498 } 499 500 node = NodeTraversal::nextPostOrder(node.get()); 501 } 502} 503 504const AtomicString& Node::prefix() const 505{ 506 // For nodes other than elements and attributes, the prefix is always null 507 return nullAtom; 508} 509 510void Node::setPrefix(const AtomicString& /*prefix*/, ExceptionCode& ec) 511{ 512 // The spec says that for nodes other than elements and attributes, prefix is always null. 513 // It does not say what to do when the user tries to set the prefix on another type of 514 // node, however Mozilla throws a NAMESPACE_ERR exception. 515 ec = NAMESPACE_ERR; 516} 517 518const AtomicString& Node::localName() const 519{ 520 return nullAtom; 521} 522 523const AtomicString& Node::namespaceURI() const 524{ 525 return nullAtom; 526} 527 528bool Node::isContentEditable(UserSelectAllTreatment treatment) 529{ 530 document().updateStyleIfNeeded(); 531 return hasEditableStyle(Editable, treatment); 532} 533 534bool Node::isContentRichlyEditable() 535{ 536 document().updateStyleIfNeeded(); 537 return hasEditableStyle(RichlyEditable, UserSelectAllIsAlwaysNonEditable); 538} 539 540void Node::inspect() 541{ 542#if ENABLE(INSPECTOR) 543 if (document().page()) 544 document().page()->inspectorController().inspect(this); 545#endif 546} 547 548bool Node::hasEditableStyle(EditableLevel editableLevel, UserSelectAllTreatment treatment) const 549{ 550 if (!document().hasLivingRenderTree()) 551 return false; 552 if (document().frame() && document().frame()->page() && document().frame()->page()->isEditable() && !containingShadowRoot()) 553 return true; 554 555 if (isPseudoElement()) 556 return false; 557 558 // Ideally we'd call ASSERT(!needsStyleRecalc()) here, but 559 // ContainerNode::setFocus() calls setNeedsStyleRecalc(), so the assertion 560 // would fire in the middle of Document::setFocusedElement(). 561 562 for (const Node* node = this; node; node = node->parentNode()) { 563 RenderStyle* style = node->isDocumentNode() ? node->renderStyle() : const_cast<Node*>(node)->computedStyle(); 564 if (!style) 565 continue; 566 if (style->display() == NONE) 567 continue; 568#if ENABLE(USERSELECT_ALL) 569 // Elements with user-select: all style are considered atomic 570 // therefore non editable. 571 if (treatment == UserSelectAllIsAlwaysNonEditable && style->userSelect() == SELECT_ALL) 572 return false; 573#else 574 UNUSED_PARAM(treatment); 575#endif 576 switch (style->userModify()) { 577 case READ_ONLY: 578 return false; 579 case READ_WRITE: 580 return true; 581 case READ_WRITE_PLAINTEXT_ONLY: 582 return editableLevel != RichlyEditable; 583 } 584 ASSERT_NOT_REACHED(); 585 return false; 586 } 587 return false; 588} 589 590bool Node::isEditableToAccessibility(EditableLevel editableLevel) const 591{ 592 if (hasEditableStyle(editableLevel)) 593 return true; 594 595 // FIXME: Respect editableLevel for ARIA editable elements. 596 if (editableLevel == RichlyEditable) 597 return false; 598 599 ASSERT(AXObjectCache::accessibilityEnabled()); 600 ASSERT(document().existingAXObjectCache()); 601 602 if (AXObjectCache* cache = document().existingAXObjectCache()) 603 return cache->rootAXEditableElement(this); 604 605 return false; 606} 607 608RenderBox* Node::renderBox() const 609{ 610 RenderObject* renderer = this->renderer(); 611 return renderer && renderer->isBox() ? toRenderBox(renderer) : 0; 612} 613 614RenderBoxModelObject* Node::renderBoxModelObject() const 615{ 616 RenderObject* renderer = this->renderer(); 617 return renderer && renderer->isBoxModelObject() ? toRenderBoxModelObject(renderer) : 0; 618} 619 620LayoutRect Node::boundingBox() const 621{ 622 if (renderer()) 623 return renderer()->absoluteBoundingBoxRect(); 624 return LayoutRect(); 625} 626 627LayoutRect Node::renderRect(bool* isReplaced) 628{ 629 RenderObject* hitRenderer = this->renderer(); 630 ASSERT(hitRenderer); 631 RenderObject* renderer = hitRenderer; 632 while (renderer && !renderer->isBody() && !renderer->isRoot()) { 633 if (renderer->isRenderBlock() || renderer->isInlineBlockOrInlineTable() || renderer->isReplaced()) { 634 *isReplaced = renderer->isReplaced(); 635 return renderer->absoluteBoundingBoxRect(); 636 } 637 renderer = renderer->parent(); 638 } 639 return LayoutRect(); 640} 641 642void Node::markAncestorsWithChildNeedsStyleRecalc() 643{ 644 ContainerNode* ancestor = isPseudoElement() ? toPseudoElement(this)->hostElement() : parentOrShadowHostNode(); 645 for (; ancestor && !ancestor->childNeedsStyleRecalc(); ancestor = ancestor->parentOrShadowHostNode()) 646 ancestor->setChildNeedsStyleRecalc(); 647 648 if (document().childNeedsStyleRecalc()) 649 document().scheduleStyleRecalc(); 650} 651 652void Node::refEventTarget() 653{ 654 ref(); 655} 656 657void Node::derefEventTarget() 658{ 659 deref(); 660} 661 662void Node::setNeedsStyleRecalc(StyleChangeType changeType) 663{ 664 ASSERT(changeType != NoStyleChange); 665 if (!inRenderedDocument()) 666 return; 667 668 StyleChangeType existingChangeType = styleChangeType(); 669 if (changeType > existingChangeType) 670 setStyleChange(changeType); 671 672 if (existingChangeType == NoStyleChange || changeType == ReconstructRenderTree) 673 markAncestorsWithChildNeedsStyleRecalc(); 674} 675 676unsigned Node::nodeIndex() const 677{ 678 Node *_tempNode = previousSibling(); 679 unsigned count=0; 680 for ( count=0; _tempNode; count++ ) 681 _tempNode = _tempNode->previousSibling(); 682 return count; 683} 684 685template<unsigned type> 686bool shouldInvalidateNodeListCachesForAttr(const unsigned nodeListCounts[], const QualifiedName& attrName) 687{ 688 if (nodeListCounts[type] && shouldInvalidateTypeOnAttributeChange(static_cast<NodeListInvalidationType>(type), attrName)) 689 return true; 690 return shouldInvalidateNodeListCachesForAttr<type + 1>(nodeListCounts, attrName); 691} 692 693template<> 694bool shouldInvalidateNodeListCachesForAttr<numNodeListInvalidationTypes>(const unsigned[], const QualifiedName&) 695{ 696 return false; 697} 698 699bool Document::shouldInvalidateNodeListAndCollectionCaches(const QualifiedName* attrName) const 700{ 701 if (attrName) 702 return shouldInvalidateNodeListCachesForAttr<DoNotInvalidateOnAttributeChanges + 1>(m_nodeListAndCollectionCounts, *attrName); 703 704 for (int type = 0; type < numNodeListInvalidationTypes; type++) { 705 if (m_nodeListAndCollectionCounts[type]) 706 return true; 707 } 708 709 return false; 710} 711 712void Document::invalidateNodeListAndCollectionCaches(const QualifiedName* attrName) 713{ 714#if !ASSERT_DISABLED 715 m_inInvalidateNodeListAndCollectionCaches = true; 716#endif 717 HashSet<LiveNodeList*> lists = WTF::move(m_listsInvalidatedAtDocument); 718 for (auto* list : lists) 719 list->invalidateCacheForAttribute(attrName); 720 HashSet<HTMLCollection*> collections = WTF::move(m_collectionsInvalidatedAtDocument); 721 for (auto* collection : collections) 722 collection->invalidateCache(attrName); 723#if !ASSERT_DISABLED 724 m_inInvalidateNodeListAndCollectionCaches = false; 725#endif 726} 727 728void Node::invalidateNodeListAndCollectionCachesInAncestors(const QualifiedName* attrName, Element* attributeOwnerElement) 729{ 730 if (hasRareData() && (!attrName || isAttributeNode())) { 731 if (NodeListsNodeData* lists = rareData()->nodeLists()) 732 lists->clearChildNodeListCache(); 733 } 734 735 // Modifications to attributes that are not associated with an Element can't invalidate NodeList caches. 736 if (attrName && !attributeOwnerElement) 737 return; 738 739 if (!document().shouldInvalidateNodeListAndCollectionCaches(attrName)) 740 return; 741 742 document().invalidateNodeListAndCollectionCaches(attrName); 743 744 for (Node* node = this; node; node = node->parentNode()) { 745 if (!node->hasRareData()) 746 continue; 747 NodeRareData* data = node->rareData(); 748 if (data->nodeLists()) 749 data->nodeLists()->invalidateCaches(attrName); 750 } 751} 752 753NodeListsNodeData* Node::nodeLists() 754{ 755 return hasRareData() ? rareData()->nodeLists() : 0; 756} 757 758void Node::clearNodeLists() 759{ 760 rareData()->clearNodeLists(); 761} 762 763void Node::checkSetPrefix(const AtomicString& prefix, ExceptionCode& ec) 764{ 765 // Perform error checking as required by spec for setting Node.prefix. Used by 766 // Element::setPrefix() and Attr::setPrefix() 767 768 if (!prefix.isEmpty() && !Document::isValidName(prefix)) { 769 ec = INVALID_CHARACTER_ERR; 770 return; 771 } 772 773 if (isReadOnlyNode()) { 774 ec = NO_MODIFICATION_ALLOWED_ERR; 775 return; 776 } 777 778 // FIXME: Raise NAMESPACE_ERR if prefix is malformed per the Namespaces in XML specification. 779 780 const AtomicString& nodeNamespaceURI = namespaceURI(); 781 if ((nodeNamespaceURI.isEmpty() && !prefix.isEmpty()) 782 || (prefix == xmlAtom && nodeNamespaceURI != XMLNames::xmlNamespaceURI)) { 783 ec = NAMESPACE_ERR; 784 return; 785 } 786 // Attribute-specific checks are in Attr::setPrefix(). 787} 788 789bool Node::isDescendantOf(const Node* other) const 790{ 791 // Return true if other is an ancestor of this, otherwise false 792 if (!other || !other->hasChildNodes() || inDocument() != other->inDocument()) 793 return false; 794 if (other->isDocumentNode()) 795 return &document() == other && !isDocumentNode() && inDocument(); 796 for (const ContainerNode* n = parentNode(); n; n = n->parentNode()) { 797 if (n == other) 798 return true; 799 } 800 return false; 801} 802 803bool Node::isDescendantOrShadowDescendantOf(const Node* other) const 804{ 805 if (!other) 806 return false; 807 if (isDescendantOf(other)) 808 return true; 809 const Node* shadowAncestorNode = deprecatedShadowAncestorNode(); 810 if (!shadowAncestorNode) 811 return false; 812 return shadowAncestorNode == other || shadowAncestorNode->isDescendantOf(other); 813} 814 815bool Node::contains(const Node* node) const 816{ 817 if (!node) 818 return false; 819 return this == node || node->isDescendantOf(this); 820} 821 822bool Node::containsIncludingShadowDOM(const Node* node) const 823{ 824 for (; node; node = node->parentOrShadowHostNode()) { 825 if (node == this) 826 return true; 827 } 828 return false; 829} 830 831bool Node::containsIncludingHostElements(const Node* node) const 832{ 833#if ENABLE(TEMPLATE_ELEMENT) 834 while (node) { 835 if (node == this) 836 return true; 837 if (node->isDocumentFragment() && static_cast<const DocumentFragment*>(node)->isTemplateContent()) 838 node = static_cast<const TemplateContentDocumentFragment*>(node)->host(); 839 else 840 node = node->parentOrShadowHostNode(); 841 } 842 return false; 843#else 844 return containsIncludingShadowDOM(node); 845#endif 846} 847 848Node* Node::pseudoAwarePreviousSibling() const 849{ 850 Element* parentOrHost = isPseudoElement() ? toPseudoElement(this)->hostElement() : parentElement(); 851 if (parentOrHost && !previousSibling()) { 852 if (isAfterPseudoElement() && parentOrHost->lastChild()) 853 return parentOrHost->lastChild(); 854 if (!isBeforePseudoElement()) 855 return parentOrHost->beforePseudoElement(); 856 } 857 return previousSibling(); 858} 859 860Node* Node::pseudoAwareNextSibling() const 861{ 862 Element* parentOrHost = isPseudoElement() ? toPseudoElement(this)->hostElement() : parentElement(); 863 if (parentOrHost && !nextSibling()) { 864 if (isBeforePseudoElement() && parentOrHost->firstChild()) 865 return parentOrHost->firstChild(); 866 if (!isAfterPseudoElement()) 867 return parentOrHost->afterPseudoElement(); 868 } 869 return nextSibling(); 870} 871 872Node* Node::pseudoAwareFirstChild() const 873{ 874 if (isElementNode()) { 875 const Element* currentElement = toElement(this); 876 Node* first = currentElement->beforePseudoElement(); 877 if (first) 878 return first; 879 first = currentElement->firstChild(); 880 if (!first) 881 first = currentElement->afterPseudoElement(); 882 return first; 883 } 884 return firstChild(); 885} 886 887Node* Node::pseudoAwareLastChild() const 888{ 889 if (isElementNode()) { 890 const Element* currentElement = toElement(this); 891 Node* last = currentElement->afterPseudoElement(); 892 if (last) 893 return last; 894 last = currentElement->lastChild(); 895 if (!last) 896 last = currentElement->beforePseudoElement(); 897 return last; 898 } 899 return lastChild(); 900} 901 902RenderStyle* Node::computedStyle(PseudoId pseudoElementSpecifier) 903{ 904 for (Node* node = this; node; node = node->parentOrShadowHostNode()) { 905 if (node->isElementNode()) 906 return toElement(node)->computedStyle(pseudoElementSpecifier); 907 } 908 return nullptr; 909} 910 911int Node::maxCharacterOffset() const 912{ 913 ASSERT_NOT_REACHED(); 914 return 0; 915} 916 917// FIXME: Shouldn't these functions be in the editing code? Code that asks questions about HTML in the core DOM class 918// is obviously misplaced. 919bool Node::canStartSelection() const 920{ 921 if (hasEditableStyle()) 922 return true; 923 924 if (renderer()) { 925 const RenderStyle& style = renderer()->style(); 926 // We allow selections to begin within an element that has -webkit-user-select: none set, 927 // but if the element is draggable then dragging should take priority over selection. 928 if (style.userDrag() == DRAG_ELEMENT && style.userSelect() == SELECT_NONE) 929 return false; 930 } 931 return parentOrShadowHostNode() ? parentOrShadowHostNode()->canStartSelection() : true; 932} 933 934Element* Node::shadowHost() const 935{ 936 if (ShadowRoot* root = containingShadowRoot()) 937 return root->hostElement(); 938 return 0; 939} 940 941Node* Node::deprecatedShadowAncestorNode() const 942{ 943 if (ShadowRoot* root = containingShadowRoot()) 944 return root->hostElement(); 945 946 return const_cast<Node*>(this); 947} 948 949ShadowRoot* Node::containingShadowRoot() const 950{ 951 ContainerNode& root = treeScope().rootNode(); 952 return root.isShadowRoot() ? toShadowRoot(&root) : nullptr; 953} 954 955Node* Node::nonBoundaryShadowTreeRootNode() 956{ 957 ASSERT(!isShadowRoot()); 958 Node* root = this; 959 while (root) { 960 if (root->isShadowRoot()) 961 return root; 962 Node* parent = root->parentNodeGuaranteedHostFree(); 963 if (parent && parent->isShadowRoot()) 964 return root; 965 root = parent; 966 } 967 return 0; 968} 969 970ContainerNode* Node::nonShadowBoundaryParentNode() const 971{ 972 ContainerNode* parent = parentNode(); 973 return parent && !parent->isShadowRoot() ? parent : 0; 974} 975 976Element* Node::parentOrShadowHostElement() const 977{ 978 ContainerNode* parent = parentOrShadowHostNode(); 979 if (!parent) 980 return 0; 981 982 if (parent->isShadowRoot()) 983 return toShadowRoot(parent)->hostElement(); 984 985 if (!parent->isElementNode()) 986 return 0; 987 988 return toElement(parent); 989} 990 991Node* Node::insertionParentForBinding() const 992{ 993 return findInsertionPointOf(this); 994} 995 996Node::InsertionNotificationRequest Node::insertedInto(ContainerNode& insertionPoint) 997{ 998 ASSERT(insertionPoint.inDocument() || isContainerNode()); 999 if (insertionPoint.inDocument()) 1000 setFlag(InDocumentFlag); 1001 if (parentOrShadowHostNode()->isInShadowTree()) 1002 setFlag(IsInShadowTreeFlag); 1003 return InsertionDone; 1004} 1005 1006void Node::removedFrom(ContainerNode& insertionPoint) 1007{ 1008 ASSERT(insertionPoint.inDocument() || isContainerNode()); 1009 if (insertionPoint.inDocument()) 1010 clearFlag(InDocumentFlag); 1011 if (isInShadowTree() && !treeScope().rootNode().isShadowRoot()) 1012 clearFlag(IsInShadowTreeFlag); 1013} 1014 1015bool Node::isRootEditableElement() const 1016{ 1017 return hasEditableStyle() && isElementNode() && (!parentNode() || !parentNode()->hasEditableStyle() 1018 || !parentNode()->isElementNode() || hasTagName(bodyTag)); 1019} 1020 1021Element* Node::rootEditableElement(EditableType editableType) const 1022{ 1023 if (editableType == HasEditableAXRole) { 1024 if (AXObjectCache* cache = document().existingAXObjectCache()) 1025 return const_cast<Element*>(cache->rootAXEditableElement(this)); 1026 } 1027 1028 return rootEditableElement(); 1029} 1030 1031Element* Node::rootEditableElement() const 1032{ 1033 Element* result = 0; 1034 for (Node* n = const_cast<Node*>(this); n && n->hasEditableStyle(); n = n->parentNode()) { 1035 if (n->isElementNode()) 1036 result = toElement(n); 1037 if (n->hasTagName(bodyTag)) 1038 break; 1039 } 1040 return result; 1041} 1042 1043// FIXME: End of obviously misplaced HTML editing functions. Try to move these out of Node. 1044 1045Document* Node::ownerDocument() const 1046{ 1047 Document* document = &this->document(); 1048 return document == this ? nullptr : document; 1049} 1050 1051URL Node::baseURI() const 1052{ 1053 return parentNode() ? parentNode()->baseURI() : URL(); 1054} 1055 1056bool Node::isEqualNode(Node* other) const 1057{ 1058 if (!other) 1059 return false; 1060 1061 NodeType nodeType = this->nodeType(); 1062 if (nodeType != other->nodeType()) 1063 return false; 1064 1065 if (nodeName() != other->nodeName()) 1066 return false; 1067 1068 if (localName() != other->localName()) 1069 return false; 1070 1071 if (namespaceURI() != other->namespaceURI()) 1072 return false; 1073 1074 if (prefix() != other->prefix()) 1075 return false; 1076 1077 if (nodeValue() != other->nodeValue()) 1078 return false; 1079 1080 if (isElementNode() && !toElement(this)->hasEquivalentAttributes(toElement(other))) 1081 return false; 1082 1083 Node* child = firstChild(); 1084 Node* otherChild = other->firstChild(); 1085 1086 while (child) { 1087 if (!child->isEqualNode(otherChild)) 1088 return false; 1089 1090 child = child->nextSibling(); 1091 otherChild = otherChild->nextSibling(); 1092 } 1093 1094 if (otherChild) 1095 return false; 1096 1097 if (nodeType == DOCUMENT_TYPE_NODE) { 1098 const DocumentType* documentTypeThis = static_cast<const DocumentType*>(this); 1099 const DocumentType* documentTypeOther = static_cast<const DocumentType*>(other); 1100 1101 if (documentTypeThis->publicId() != documentTypeOther->publicId()) 1102 return false; 1103 1104 if (documentTypeThis->systemId() != documentTypeOther->systemId()) 1105 return false; 1106 1107 if (documentTypeThis->internalSubset() != documentTypeOther->internalSubset()) 1108 return false; 1109 1110 // FIXME: We don't compare entities or notations because currently both are always empty. 1111 } 1112 1113 return true; 1114} 1115 1116bool Node::isDefaultNamespace(const AtomicString& namespaceURIMaybeEmpty) const 1117{ 1118 const AtomicString& namespaceURI = namespaceURIMaybeEmpty.isEmpty() ? nullAtom : namespaceURIMaybeEmpty; 1119 1120 switch (nodeType()) { 1121 case ELEMENT_NODE: { 1122 const Element* elem = toElement(this); 1123 1124 if (elem->prefix().isNull()) 1125 return elem->namespaceURI() == namespaceURI; 1126 1127 if (elem->hasAttributes()) { 1128 for (const Attribute& attribute : elem->attributesIterator()) { 1129 if (attribute.localName() == xmlnsAtom) 1130 return attribute.value() == namespaceURI; 1131 } 1132 } 1133 1134 if (Element* ancestor = ancestorElement()) 1135 return ancestor->isDefaultNamespace(namespaceURI); 1136 1137 return false; 1138 } 1139 case DOCUMENT_NODE: 1140 if (Element* de = toDocument(this)->documentElement()) 1141 return de->isDefaultNamespace(namespaceURI); 1142 return false; 1143 case ENTITY_NODE: 1144 case NOTATION_NODE: 1145 case DOCUMENT_TYPE_NODE: 1146 case DOCUMENT_FRAGMENT_NODE: 1147 return false; 1148 case ATTRIBUTE_NODE: { 1149 const Attr* attr = static_cast<const Attr*>(this); 1150 if (attr->ownerElement()) 1151 return attr->ownerElement()->isDefaultNamespace(namespaceURI); 1152 return false; 1153 } 1154 default: 1155 if (Element* ancestor = ancestorElement()) 1156 return ancestor->isDefaultNamespace(namespaceURI); 1157 return false; 1158 } 1159} 1160 1161String Node::lookupPrefix(const AtomicString &namespaceURI) const 1162{ 1163 // Implemented according to 1164 // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#lookupNamespacePrefixAlgo 1165 1166 if (namespaceURI.isEmpty()) 1167 return String(); 1168 1169 switch (nodeType()) { 1170 case ELEMENT_NODE: 1171 return lookupNamespacePrefix(namespaceURI, static_cast<const Element *>(this)); 1172 case DOCUMENT_NODE: 1173 if (Element* de = toDocument(this)->documentElement()) 1174 return de->lookupPrefix(namespaceURI); 1175 return String(); 1176 case ENTITY_NODE: 1177 case NOTATION_NODE: 1178 case DOCUMENT_FRAGMENT_NODE: 1179 case DOCUMENT_TYPE_NODE: 1180 return String(); 1181 case ATTRIBUTE_NODE: { 1182 const Attr *attr = static_cast<const Attr *>(this); 1183 if (attr->ownerElement()) 1184 return attr->ownerElement()->lookupPrefix(namespaceURI); 1185 return String(); 1186 } 1187 default: 1188 if (Element* ancestor = ancestorElement()) 1189 return ancestor->lookupPrefix(namespaceURI); 1190 return String(); 1191 } 1192} 1193 1194String Node::lookupNamespaceURI(const String &prefix) const 1195{ 1196 // Implemented according to 1197 // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#lookupNamespaceURIAlgo 1198 1199 if (!prefix.isNull() && prefix.isEmpty()) 1200 return String(); 1201 1202 switch (nodeType()) { 1203 case ELEMENT_NODE: { 1204 const Element *elem = static_cast<const Element *>(this); 1205 1206 if (!elem->namespaceURI().isNull() && elem->prefix() == prefix) 1207 return elem->namespaceURI(); 1208 1209 if (elem->hasAttributes()) { 1210 for (const Attribute& attribute : elem->attributesIterator()) { 1211 1212 if (attribute.prefix() == xmlnsAtom && attribute.localName() == prefix) { 1213 if (!attribute.value().isEmpty()) 1214 return attribute.value(); 1215 1216 return String(); 1217 } 1218 if (attribute.localName() == xmlnsAtom && prefix.isNull()) { 1219 if (!attribute.value().isEmpty()) 1220 return attribute.value(); 1221 1222 return String(); 1223 } 1224 } 1225 } 1226 if (Element* ancestor = ancestorElement()) 1227 return ancestor->lookupNamespaceURI(prefix); 1228 return String(); 1229 } 1230 case DOCUMENT_NODE: 1231 if (Element* de = toDocument(this)->documentElement()) 1232 return de->lookupNamespaceURI(prefix); 1233 return String(); 1234 case ENTITY_NODE: 1235 case NOTATION_NODE: 1236 case DOCUMENT_TYPE_NODE: 1237 case DOCUMENT_FRAGMENT_NODE: 1238 return String(); 1239 case ATTRIBUTE_NODE: { 1240 const Attr *attr = static_cast<const Attr *>(this); 1241 1242 if (attr->ownerElement()) 1243 return attr->ownerElement()->lookupNamespaceURI(prefix); 1244 else 1245 return String(); 1246 } 1247 default: 1248 if (Element* ancestor = ancestorElement()) 1249 return ancestor->lookupNamespaceURI(prefix); 1250 return String(); 1251 } 1252} 1253 1254String Node::lookupNamespacePrefix(const AtomicString &_namespaceURI, const Element *originalElement) const 1255{ 1256 if (_namespaceURI.isNull()) 1257 return String(); 1258 1259 if (originalElement->lookupNamespaceURI(prefix()) == _namespaceURI) 1260 return prefix(); 1261 1262 ASSERT(isElementNode()); 1263 const Element* thisElement = toElement(this); 1264 if (thisElement->hasAttributes()) { 1265 for (const Attribute& attribute : thisElement->attributesIterator()) { 1266 if (attribute.prefix() == xmlnsAtom && attribute.value() == _namespaceURI 1267 && originalElement->lookupNamespaceURI(attribute.localName()) == _namespaceURI) 1268 return attribute.localName(); 1269 } 1270 } 1271 1272 if (Element* ancestor = ancestorElement()) 1273 return ancestor->lookupNamespacePrefix(_namespaceURI, originalElement); 1274 return String(); 1275} 1276 1277static void appendTextContent(const Node* node, bool convertBRsToNewlines, bool& isNullString, StringBuilder& content) 1278{ 1279 switch (node->nodeType()) { 1280 case Node::TEXT_NODE: 1281 case Node::CDATA_SECTION_NODE: 1282 case Node::COMMENT_NODE: 1283 isNullString = false; 1284 content.append(static_cast<const CharacterData*>(node)->data()); 1285 break; 1286 1287 case Node::PROCESSING_INSTRUCTION_NODE: 1288 isNullString = false; 1289 content.append(static_cast<const ProcessingInstruction*>(node)->data()); 1290 break; 1291 1292 case Node::ELEMENT_NODE: 1293 if (node->hasTagName(brTag) && convertBRsToNewlines) { 1294 isNullString = false; 1295 content.append('\n'); 1296 break; 1297 } 1298 FALLTHROUGH; 1299 case Node::ATTRIBUTE_NODE: 1300 case Node::ENTITY_NODE: 1301 case Node::ENTITY_REFERENCE_NODE: 1302 case Node::DOCUMENT_FRAGMENT_NODE: 1303 isNullString = false; 1304 for (Node* child = node->firstChild(); child; child = child->nextSibling()) { 1305 if (child->nodeType() == Node::COMMENT_NODE || child->nodeType() == Node::PROCESSING_INSTRUCTION_NODE) 1306 continue; 1307 appendTextContent(child, convertBRsToNewlines, isNullString, content); 1308 } 1309 break; 1310 1311 case Node::DOCUMENT_NODE: 1312 case Node::DOCUMENT_TYPE_NODE: 1313 case Node::NOTATION_NODE: 1314 case Node::XPATH_NAMESPACE_NODE: 1315 break; 1316 } 1317} 1318 1319String Node::textContent(bool convertBRsToNewlines) const 1320{ 1321 StringBuilder content; 1322 bool isNullString = true; 1323 appendTextContent(this, convertBRsToNewlines, isNullString, content); 1324 return isNullString ? String() : content.toString(); 1325} 1326 1327void Node::setTextContent(const String& text, ExceptionCode& ec) 1328{ 1329 switch (nodeType()) { 1330 case TEXT_NODE: 1331 case CDATA_SECTION_NODE: 1332 case COMMENT_NODE: 1333 case PROCESSING_INSTRUCTION_NODE: 1334 setNodeValue(text, ec); 1335 return; 1336 case ELEMENT_NODE: 1337 case ATTRIBUTE_NODE: 1338 case ENTITY_NODE: 1339 case ENTITY_REFERENCE_NODE: 1340 case DOCUMENT_FRAGMENT_NODE: { 1341 Ref<ContainerNode> container(*toContainerNode(this)); 1342 ChildListMutationScope mutation(container.get()); 1343 container->removeChildren(); 1344 if (!text.isEmpty()) 1345 container->appendChild(document().createTextNode(text), ec); 1346 return; 1347 } 1348 case DOCUMENT_NODE: 1349 case DOCUMENT_TYPE_NODE: 1350 case NOTATION_NODE: 1351 case XPATH_NAMESPACE_NODE: 1352 // Do nothing. 1353 return; 1354 } 1355 ASSERT_NOT_REACHED(); 1356} 1357 1358Element* Node::ancestorElement() const 1359{ 1360 // In theory, there can be EntityReference nodes between elements, but this is currently not supported. 1361 for (ContainerNode* n = parentNode(); n; n = n->parentNode()) { 1362 if (n->isElementNode()) 1363 return toElement(n); 1364 } 1365 return 0; 1366} 1367 1368bool Node::offsetInCharacters() const 1369{ 1370 return false; 1371} 1372 1373unsigned short Node::compareDocumentPosition(Node* otherNode) 1374{ 1375 // It is not clear what should be done if |otherNode| is 0. 1376 if (!otherNode) 1377 return DOCUMENT_POSITION_DISCONNECTED; 1378 1379 if (otherNode == this) 1380 return DOCUMENT_POSITION_EQUIVALENT; 1381 1382 Attr* attr1 = isAttributeNode() ? toAttr(this) : nullptr; 1383 Attr* attr2 = otherNode->isAttributeNode() ? toAttr(otherNode) : nullptr; 1384 1385 Node* start1 = attr1 ? attr1->ownerElement() : this; 1386 Node* start2 = attr2 ? attr2->ownerElement() : otherNode; 1387 1388 // If either of start1 or start2 is null, then we are disconnected, since one of the nodes is 1389 // an orphaned attribute node. 1390 if (!start1 || !start2) 1391 return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC; 1392 1393 Vector<Node*, 16> chain1; 1394 Vector<Node*, 16> chain2; 1395 if (attr1) 1396 chain1.append(attr1); 1397 if (attr2) 1398 chain2.append(attr2); 1399 1400 if (attr1 && attr2 && start1 == start2 && start1) { 1401 // We are comparing two attributes on the same node. Crawl our attribute map and see which one we hit first. 1402 Element* owner1 = attr1->ownerElement(); 1403 owner1->synchronizeAllAttributes(); 1404 for (const Attribute& attribute : owner1->attributesIterator()) { 1405 // If neither of the two determining nodes is a child node and nodeType is the same for both determining nodes, then an 1406 // implementation-dependent order between the determining nodes is returned. This order is stable as long as no nodes of 1407 // the same nodeType are inserted into or removed from the direct container. This would be the case, for example, 1408 // when comparing two attributes of the same element, and inserting or removing additional attributes might change 1409 // the order between existing attributes. 1410 if (attr1->qualifiedName() == attribute.name()) 1411 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_FOLLOWING; 1412 if (attr2->qualifiedName() == attribute.name()) 1413 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_PRECEDING; 1414 } 1415 1416 ASSERT_NOT_REACHED(); 1417 return DOCUMENT_POSITION_DISCONNECTED; 1418 } 1419 1420 // If one node is in the document and the other is not, we must be disconnected. 1421 // If the nodes have different owning documents, they must be disconnected. Note that we avoid 1422 // comparing Attr nodes here, since they return false from inDocument() all the time (which seems like a bug). 1423 if (start1->inDocument() != start2->inDocument() || 1424 &start1->treeScope() != &start2->treeScope()) 1425 return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC; 1426 1427 // We need to find a common ancestor container, and then compare the indices of the two immediate children. 1428 Node* current; 1429 for (current = start1; current; current = current->parentNode()) 1430 chain1.append(current); 1431 for (current = start2; current; current = current->parentNode()) 1432 chain2.append(current); 1433 1434 unsigned index1 = chain1.size(); 1435 unsigned index2 = chain2.size(); 1436 1437 // If the two elements don't have a common root, they're not in the same tree. 1438 if (chain1[index1 - 1] != chain2[index2 - 1]) 1439 return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC; 1440 1441 // Walk the two chains backwards and look for the first difference. 1442 for (unsigned i = std::min(index1, index2); i; --i) { 1443 Node* child1 = chain1[--index1]; 1444 Node* child2 = chain2[--index2]; 1445 if (child1 != child2) { 1446 // If one of the children is an attribute, it wins. 1447 if (child1->nodeType() == ATTRIBUTE_NODE) 1448 return DOCUMENT_POSITION_FOLLOWING; 1449 if (child2->nodeType() == ATTRIBUTE_NODE) 1450 return DOCUMENT_POSITION_PRECEDING; 1451 1452 if (!child2->nextSibling()) 1453 return DOCUMENT_POSITION_FOLLOWING; 1454 if (!child1->nextSibling()) 1455 return DOCUMENT_POSITION_PRECEDING; 1456 1457 // Otherwise we need to see which node occurs first. Crawl backwards from child2 looking for child1. 1458 for (Node* child = child2->previousSibling(); child; child = child->previousSibling()) { 1459 if (child == child1) 1460 return DOCUMENT_POSITION_FOLLOWING; 1461 } 1462 return DOCUMENT_POSITION_PRECEDING; 1463 } 1464 } 1465 1466 // There was no difference between the two parent chains, i.e., one was a subset of the other. The shorter 1467 // chain is the ancestor. 1468 return index1 < index2 ? 1469 DOCUMENT_POSITION_FOLLOWING | DOCUMENT_POSITION_CONTAINED_BY : 1470 DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_CONTAINS; 1471} 1472 1473FloatPoint Node::convertToPage(const FloatPoint& p) const 1474{ 1475 // If there is a renderer, just ask it to do the conversion 1476 if (renderer()) 1477 return renderer()->localToAbsolute(p, UseTransforms); 1478 1479 // Otherwise go up the tree looking for a renderer 1480 Element *parent = ancestorElement(); 1481 if (parent) 1482 return parent->convertToPage(p); 1483 1484 // No parent - no conversion needed 1485 return p; 1486} 1487 1488FloatPoint Node::convertFromPage(const FloatPoint& p) const 1489{ 1490 // If there is a renderer, just ask it to do the conversion 1491 if (renderer()) 1492 return renderer()->absoluteToLocal(p, UseTransforms); 1493 1494 // Otherwise go up the tree looking for a renderer 1495 Element *parent = ancestorElement(); 1496 if (parent) 1497 return parent->convertFromPage(p); 1498 1499 // No parent - no conversion needed 1500 return p; 1501} 1502 1503#ifndef NDEBUG 1504 1505static void appendAttributeDesc(const Node* node, StringBuilder& stringBuilder, const QualifiedName& name, const char* attrDesc) 1506{ 1507 if (!node->isElementNode()) 1508 return; 1509 1510 String attr = toElement(node)->getAttribute(name); 1511 if (attr.isEmpty()) 1512 return; 1513 1514 stringBuilder.append(attrDesc); 1515 stringBuilder.append(attr); 1516} 1517 1518void Node::showNode(const char* prefix) const 1519{ 1520 if (!prefix) 1521 prefix = ""; 1522 if (isTextNode()) { 1523 String value = nodeValue(); 1524 value.replaceWithLiteral('\\', "\\\\"); 1525 value.replaceWithLiteral('\n', "\\n"); 1526 fprintf(stderr, "%s%s\t%p \"%s\"\n", prefix, nodeName().utf8().data(), this, value.utf8().data()); 1527 } else { 1528 StringBuilder attrs; 1529 appendAttributeDesc(this, attrs, classAttr, " CLASS="); 1530 appendAttributeDesc(this, attrs, styleAttr, " STYLE="); 1531 fprintf(stderr, "%s%s\t%p (renderer %p) %s%s%s\n", prefix, nodeName().utf8().data(), this, renderer(), attrs.toString().utf8().data(), needsStyleRecalc() ? " (needs style recalc)" : "", childNeedsStyleRecalc() ? " (child needs style recalc)" : ""); 1532 } 1533} 1534 1535void Node::showTreeForThis() const 1536{ 1537 showTreeAndMark(this, "*"); 1538} 1539 1540void Node::showNodePathForThis() const 1541{ 1542 Vector<const Node*, 16> chain; 1543 const Node* node = this; 1544 while (node->parentOrShadowHostNode()) { 1545 chain.append(node); 1546 node = node->parentOrShadowHostNode(); 1547 } 1548 for (unsigned index = chain.size(); index > 0; --index) { 1549 const Node* node = chain[index - 1]; 1550 if (node->isShadowRoot()) { 1551 int count = 0; 1552 for (const ShadowRoot* shadowRoot = toShadowRoot(node); shadowRoot && shadowRoot != node; shadowRoot = shadowRoot->shadowRoot()) 1553 ++count; 1554 fprintf(stderr, "/#shadow-root[%d]", count); 1555 continue; 1556 } 1557 1558 switch (node->nodeType()) { 1559 case ELEMENT_NODE: { 1560 fprintf(stderr, "/%s", node->nodeName().utf8().data()); 1561 1562 const Element* element = toElement(node); 1563 const AtomicString& idattr = element->getIdAttribute(); 1564 bool hasIdAttr = !idattr.isNull() && !idattr.isEmpty(); 1565 if (node->previousSibling() || node->nextSibling()) { 1566 int count = 0; 1567 for (Node* previous = node->previousSibling(); previous; previous = previous->previousSibling()) 1568 if (previous->nodeName() == node->nodeName()) 1569 ++count; 1570 if (hasIdAttr) 1571 fprintf(stderr, "[@id=\"%s\" and position()=%d]", idattr.string().utf8().data(), count); 1572 else 1573 fprintf(stderr, "[%d]", count); 1574 } else if (hasIdAttr) 1575 fprintf(stderr, "[@id=\"%s\"]", idattr.string().utf8().data()); 1576 break; 1577 } 1578 case TEXT_NODE: 1579 fprintf(stderr, "/text()"); 1580 break; 1581 case ATTRIBUTE_NODE: 1582 fprintf(stderr, "/@%s", node->nodeName().utf8().data()); 1583 break; 1584 default: 1585 break; 1586 } 1587 } 1588 fprintf(stderr, "\n"); 1589} 1590 1591static void traverseTreeAndMark(const String& baseIndent, const Node* rootNode, const Node* markedNode1, const char* markedLabel1, const Node* markedNode2, const char* markedLabel2) 1592{ 1593 for (const Node* node = rootNode; node; node = NodeTraversal::next(node)) { 1594 if (node == markedNode1) 1595 fprintf(stderr, "%s", markedLabel1); 1596 if (node == markedNode2) 1597 fprintf(stderr, "%s", markedLabel2); 1598 1599 StringBuilder indent; 1600 indent.append(baseIndent); 1601 for (const Node* tmpNode = node; tmpNode && tmpNode != rootNode; tmpNode = tmpNode->parentOrShadowHostNode()) 1602 indent.append('\t'); 1603 fprintf(stderr, "%s", indent.toString().utf8().data()); 1604 node->showNode(); 1605 indent.append('\t'); 1606 if (!node->isShadowRoot()) { 1607 if (ShadowRoot* shadowRoot = node->shadowRoot()) 1608 traverseTreeAndMark(indent.toString(), shadowRoot, markedNode1, markedLabel1, markedNode2, markedLabel2); 1609 } 1610 } 1611} 1612 1613void Node::showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2, const char* markedLabel2) const 1614{ 1615 const Node* rootNode; 1616 const Node* node = this; 1617 while (node->parentOrShadowHostNode() && !node->hasTagName(bodyTag)) 1618 node = node->parentOrShadowHostNode(); 1619 rootNode = node; 1620 1621 String startingIndent; 1622 traverseTreeAndMark(startingIndent, rootNode, markedNode1, markedLabel1, markedNode2, markedLabel2); 1623} 1624 1625void Node::formatForDebugger(char* buffer, unsigned length) const 1626{ 1627 String result; 1628 String s; 1629 1630 s = nodeName(); 1631 if (s.isEmpty()) 1632 result = "<none>"; 1633 else 1634 result = s; 1635 1636 strncpy(buffer, result.utf8().data(), length - 1); 1637} 1638 1639static ContainerNode* parentOrShadowHostOrFrameOwner(const Node* node) 1640{ 1641 ContainerNode* parent = node->parentOrShadowHostNode(); 1642 if (!parent && node->document().frame()) 1643 parent = node->document().frame()->ownerElement(); 1644 return parent; 1645} 1646 1647static void showSubTreeAcrossFrame(const Node* node, const Node* markedNode, const String& indent) 1648{ 1649 if (node == markedNode) 1650 fputs("*", stderr); 1651 fputs(indent.utf8().data(), stderr); 1652 node->showNode(); 1653 if (!node->isShadowRoot()) { 1654 if (node->isFrameOwnerElement()) 1655 showSubTreeAcrossFrame(static_cast<const HTMLFrameOwnerElement*>(node)->contentDocument(), markedNode, indent + "\t"); 1656 if (ShadowRoot* shadowRoot = node->shadowRoot()) 1657 showSubTreeAcrossFrame(shadowRoot, markedNode, indent + "\t"); 1658 } 1659 for (Node* child = node->firstChild(); child; child = child->nextSibling()) 1660 showSubTreeAcrossFrame(child, markedNode, indent + "\t"); 1661} 1662 1663void Node::showTreeForThisAcrossFrame() const 1664{ 1665 Node* rootNode = const_cast<Node*>(this); 1666 while (parentOrShadowHostOrFrameOwner(rootNode)) 1667 rootNode = parentOrShadowHostOrFrameOwner(rootNode); 1668 showSubTreeAcrossFrame(rootNode, this, ""); 1669} 1670 1671#endif 1672 1673// -------- 1674 1675void NodeListsNodeData::invalidateCaches(const QualifiedName* attrName) 1676{ 1677 for (auto& atomicName : m_atomicNameCaches) 1678 atomicName.value->invalidateCacheForAttribute(attrName); 1679 1680 for (auto& name : m_nameCaches) 1681 name.value->invalidateCacheForAttribute(attrName); 1682 1683 for (auto& collection : m_cachedCollections) 1684 collection.value->invalidateCache(attrName); 1685 1686 if (attrName) 1687 return; 1688 1689 for (auto& tagNodeList : m_tagNodeListCacheNS) 1690 tagNodeList.value->invalidateCacheForAttribute(nullptr); 1691} 1692 1693void Node::getSubresourceURLs(ListHashSet<URL>& urls) const 1694{ 1695 addSubresourceAttributeURLs(urls); 1696} 1697 1698Element* Node::enclosingLinkEventParentOrSelf() 1699{ 1700 for (Node* node = this; node; node = node->parentOrShadowHostNode()) { 1701 // For imagemaps, the enclosing link element is the associated area element not the image itself. 1702 // So we don't let images be the enclosing link element, even though isLink sometimes returns 1703 // true for them. 1704 if (node->isLink() && !isHTMLImageElement(node)) 1705 return toElement(node); 1706 } 1707 1708 return 0; 1709} 1710 1711EventTargetInterface Node::eventTargetInterface() const 1712{ 1713 return NodeEventTargetInterfaceType; 1714} 1715 1716void Node::didMoveToNewDocument(Document* oldDocument) 1717{ 1718 TreeScopeAdopter::ensureDidMoveToNewDocumentWasCalled(oldDocument); 1719 1720 if (const EventTargetData* eventTargetData = this->eventTargetData()) { 1721 const EventListenerMap& listenerMap = eventTargetData->eventListenerMap; 1722 if (!listenerMap.isEmpty()) { 1723 Vector<AtomicString> types = listenerMap.eventTypes(); 1724 for (unsigned i = 0; i < types.size(); ++i) 1725 document().addListenerTypeIfNeeded(types[i]); 1726 } 1727 } 1728 1729 if (AXObjectCache::accessibilityEnabled() && oldDocument) 1730 if (AXObjectCache* cache = oldDocument->existingAXObjectCache()) 1731 cache->remove(this); 1732 1733 const EventListenerVector& mousewheelListeners = getEventListeners(eventNames().mousewheelEvent); 1734 for (size_t i = 0; i < mousewheelListeners.size(); ++i) { 1735 oldDocument->didRemoveWheelEventHandler(); 1736 document().didAddWheelEventHandler(); 1737 } 1738 1739 const EventListenerVector& wheelListeners = getEventListeners(eventNames().wheelEvent); 1740 for (size_t i = 0; i < wheelListeners.size(); ++i) { 1741 oldDocument->didRemoveWheelEventHandler(); 1742 document().didAddWheelEventHandler(); 1743 } 1744 1745 Vector<AtomicString> touchEventNames = eventNames().touchEventNames(); 1746 for (size_t i = 0; i < touchEventNames.size(); ++i) { 1747 const EventListenerVector& listeners = getEventListeners(touchEventNames[i]); 1748 for (size_t j = 0; j < listeners.size(); ++j) { 1749 oldDocument->didRemoveTouchEventHandler(this); 1750 document().didAddTouchEventHandler(this); 1751 } 1752 } 1753 1754 if (Vector<OwnPtr<MutationObserverRegistration>>* registry = mutationObserverRegistry()) { 1755 for (size_t i = 0; i < registry->size(); ++i) { 1756 document().addMutationObserverTypes(registry->at(i)->mutationTypes()); 1757 } 1758 } 1759 1760 if (HashSet<MutationObserverRegistration*>* transientRegistry = transientMutationObserverRegistry()) { 1761 for (HashSet<MutationObserverRegistration*>::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter) { 1762 document().addMutationObserverTypes((*iter)->mutationTypes()); 1763 } 1764 } 1765} 1766 1767static inline bool tryAddEventListener(Node* targetNode, const AtomicString& eventType, PassRefPtr<EventListener> prpListener, bool useCapture) 1768{ 1769 RefPtr<EventListener> listener = prpListener; 1770 1771 if (!targetNode->EventTarget::addEventListener(eventType, listener, useCapture)) 1772 return false; 1773 1774 targetNode->document().addListenerTypeIfNeeded(eventType); 1775 if (eventType == eventNames().wheelEvent || eventType == eventNames().mousewheelEvent) 1776 targetNode->document().didAddWheelEventHandler(); 1777 else if (eventNames().isTouchEventType(eventType)) 1778 targetNode->document().didAddTouchEventHandler(targetNode); 1779 1780#if PLATFORM(IOS) 1781 if (targetNode == &targetNode->document() && eventType == eventNames().scrollEvent) 1782 targetNode->document().domWindow()->incrementScrollEventListenersCount(); 1783 1784 // FIXME: Would it be sufficient to special-case this code for <body> and <frameset>? 1785 // 1786 // This code was added to address <rdar://problem/5846492> Onorientationchange event not working for document.body. 1787 // Forward this call to addEventListener() to the window since these are window-only events. 1788 if (eventType == eventNames().orientationchangeEvent || eventType == eventNames().resizeEvent) 1789 targetNode->document().domWindow()->addEventListener(eventType, listener, useCapture); 1790 1791#if ENABLE(TOUCH_EVENTS) 1792 if (eventNames().isTouchEventType(eventType)) 1793 targetNode->document().addTouchEventListener(targetNode); 1794#endif 1795#endif // PLATFORM(IOS) 1796 1797#if ENABLE(IOS_GESTURE_EVENTS) && ENABLE(TOUCH_EVENTS) 1798 if (eventType == eventNames().gesturestartEvent || eventType == eventNames().gesturechangeEvent || eventType == eventNames().gestureendEvent) 1799 targetNode->document().addTouchEventListener(targetNode); 1800#endif 1801 1802 return true; 1803} 1804 1805bool Node::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) 1806{ 1807 return tryAddEventListener(this, eventType, listener, useCapture); 1808} 1809 1810static inline bool tryRemoveEventListener(Node* targetNode, const AtomicString& eventType, EventListener* listener, bool useCapture) 1811{ 1812 if (!targetNode->EventTarget::removeEventListener(eventType, listener, useCapture)) 1813 return false; 1814 1815 // FIXME: Notify Document that the listener has vanished. We need to keep track of a number of 1816 // listeners for each type, not just a bool - see https://bugs.webkit.org/show_bug.cgi?id=33861 1817 if (eventType == eventNames().wheelEvent || eventType == eventNames().mousewheelEvent) 1818 targetNode->document().didRemoveWheelEventHandler(); 1819 else if (eventNames().isTouchEventType(eventType)) 1820 targetNode->document().didRemoveTouchEventHandler(targetNode); 1821 1822#if PLATFORM(IOS) 1823 if (targetNode == &targetNode->document() && eventType == eventNames().scrollEvent) 1824 targetNode->document().domWindow()->decrementScrollEventListenersCount(); 1825 1826 // FIXME: Would it be sufficient to special-case this code for <body> and <frameset>? See <rdar://problem/15647823>. 1827 // This code was added to address <rdar://problem/5846492> Onorientationchange event not working for document.body. 1828 // Forward this call to removeEventListener() to the window since these are window-only events. 1829 if (eventType == eventNames().orientationchangeEvent || eventType == eventNames().resizeEvent) 1830 targetNode->document().domWindow()->removeEventListener(eventType, listener, useCapture); 1831 1832#if ENABLE(TOUCH_EVENTS) 1833 if (eventNames().isTouchEventType(eventType)) 1834 targetNode->document().removeTouchEventListener(targetNode); 1835#endif 1836#endif // PLATFORM(IOS) 1837 1838#if ENABLE(IOS_GESTURE_EVENTS) && ENABLE(TOUCH_EVENTS) 1839 if (eventType == eventNames().gesturestartEvent || eventType == eventNames().gesturechangeEvent || eventType == eventNames().gestureendEvent) 1840 targetNode->document().removeTouchEventListener(targetNode); 1841#endif 1842 1843 return true; 1844} 1845 1846bool Node::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture) 1847{ 1848 return tryRemoveEventListener(this, eventType, listener, useCapture); 1849} 1850 1851typedef HashMap<Node*, OwnPtr<EventTargetData>> EventTargetDataMap; 1852 1853static EventTargetDataMap& eventTargetDataMap() 1854{ 1855 DEPRECATED_DEFINE_STATIC_LOCAL(EventTargetDataMap, map, ()); 1856 return map; 1857} 1858 1859EventTargetData* Node::eventTargetData() 1860{ 1861 return hasEventTargetData() ? eventTargetDataMap().get(this) : 0; 1862} 1863 1864EventTargetData& Node::ensureEventTargetData() 1865{ 1866 if (hasEventTargetData()) 1867 return *eventTargetDataMap().get(this); 1868 setHasEventTargetData(true); 1869 EventTargetData* data = new EventTargetData; 1870 eventTargetDataMap().set(this, adoptPtr(data)); 1871 return *data; 1872} 1873 1874void Node::clearEventTargetData() 1875{ 1876 eventTargetDataMap().remove(this); 1877} 1878 1879Vector<OwnPtr<MutationObserverRegistration>>* Node::mutationObserverRegistry() 1880{ 1881 if (!hasRareData()) 1882 return 0; 1883 NodeMutationObserverData* data = rareData()->mutationObserverData(); 1884 if (!data) 1885 return 0; 1886 return &data->registry; 1887} 1888 1889HashSet<MutationObserverRegistration*>* Node::transientMutationObserverRegistry() 1890{ 1891 if (!hasRareData()) 1892 return 0; 1893 NodeMutationObserverData* data = rareData()->mutationObserverData(); 1894 if (!data) 1895 return 0; 1896 return &data->transientRegistry; 1897} 1898 1899template<typename Registry> 1900static inline void collectMatchingObserversForMutation(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, Registry* registry, Node* target, MutationObserver::MutationType type, const QualifiedName* attributeName) 1901{ 1902 if (!registry) 1903 return; 1904 for (typename Registry::iterator iter = registry->begin(); iter != registry->end(); ++iter) { 1905 const MutationObserverRegistration& registration = **iter; 1906 if (registration.shouldReceiveMutationFrom(target, type, attributeName)) { 1907 MutationRecordDeliveryOptions deliveryOptions = registration.deliveryOptions(); 1908 HashMap<MutationObserver*, MutationRecordDeliveryOptions>::AddResult result = observers.add(registration.observer(), deliveryOptions); 1909 if (!result.isNewEntry) 1910 result.iterator->value |= deliveryOptions; 1911 } 1912 } 1913} 1914 1915void Node::getRegisteredMutationObserversOfType(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, MutationObserver::MutationType type, const QualifiedName* attributeName) 1916{ 1917 ASSERT((type == MutationObserver::Attributes && attributeName) || !attributeName); 1918 collectMatchingObserversForMutation(observers, mutationObserverRegistry(), this, type, attributeName); 1919 collectMatchingObserversForMutation(observers, transientMutationObserverRegistry(), this, type, attributeName); 1920 for (Node* node = parentNode(); node; node = node->parentNode()) { 1921 collectMatchingObserversForMutation(observers, node->mutationObserverRegistry(), this, type, attributeName); 1922 collectMatchingObserversForMutation(observers, node->transientMutationObserverRegistry(), this, type, attributeName); 1923 } 1924} 1925 1926void Node::registerMutationObserver(MutationObserver* observer, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter) 1927{ 1928 MutationObserverRegistration* registration = 0; 1929 Vector<OwnPtr<MutationObserverRegistration>>& registry = ensureRareData().ensureMutationObserverData().registry; 1930 for (size_t i = 0; i < registry.size(); ++i) { 1931 if (registry[i]->observer() == observer) { 1932 registration = registry[i].get(); 1933 registration->resetObservation(options, attributeFilter); 1934 } 1935 } 1936 1937 if (!registration) { 1938 registry.append(MutationObserverRegistration::create(observer, this, options, attributeFilter)); 1939 registration = registry.last().get(); 1940 } 1941 1942 document().addMutationObserverTypes(registration->mutationTypes()); 1943} 1944 1945void Node::unregisterMutationObserver(MutationObserverRegistration* registration) 1946{ 1947 Vector<OwnPtr<MutationObserverRegistration>>* registry = mutationObserverRegistry(); 1948 ASSERT(registry); 1949 if (!registry) 1950 return; 1951 1952 size_t index = registry->find(registration); 1953 ASSERT(index != notFound); 1954 if (index == notFound) 1955 return; 1956 1957 registry->remove(index); 1958} 1959 1960void Node::registerTransientMutationObserver(MutationObserverRegistration* registration) 1961{ 1962 ensureRareData().ensureMutationObserverData().transientRegistry.add(registration); 1963} 1964 1965void Node::unregisterTransientMutationObserver(MutationObserverRegistration* registration) 1966{ 1967 HashSet<MutationObserverRegistration*>* transientRegistry = transientMutationObserverRegistry(); 1968 ASSERT(transientRegistry); 1969 if (!transientRegistry) 1970 return; 1971 1972 ASSERT(transientRegistry->contains(registration)); 1973 transientRegistry->remove(registration); 1974} 1975 1976void Node::notifyMutationObserversNodeWillDetach() 1977{ 1978 if (!document().hasMutationObservers()) 1979 return; 1980 1981 for (Node* node = parentNode(); node; node = node->parentNode()) { 1982 if (Vector<OwnPtr<MutationObserverRegistration>>* registry = node->mutationObserverRegistry()) { 1983 const size_t size = registry->size(); 1984 for (size_t i = 0; i < size; ++i) 1985 registry->at(i)->observedSubtreeNodeWillDetach(this); 1986 } 1987 1988 if (HashSet<MutationObserverRegistration*>* transientRegistry = node->transientMutationObserverRegistry()) { 1989 for (HashSet<MutationObserverRegistration*>::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter) 1990 (*iter)->observedSubtreeNodeWillDetach(this); 1991 } 1992 } 1993} 1994 1995void Node::handleLocalEvents(Event& event) 1996{ 1997 if (!hasEventTargetData()) 1998 return; 1999 2000 if (isElementNode() && toElement(*this).isDisabledFormControl() && event.isMouseEvent()) 2001 return; 2002 2003 fireEventListeners(&event); 2004} 2005 2006void Node::dispatchScopedEvent(PassRefPtr<Event> event) 2007{ 2008 EventDispatcher::dispatchScopedEvent(*this, event); 2009} 2010 2011bool Node::dispatchEvent(PassRefPtr<Event> event) 2012{ 2013#if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS) 2014 if (event->isTouchEvent()) 2015 return dispatchTouchEvent(adoptRef(toTouchEvent(event.leakRef()))); 2016#endif 2017 return EventDispatcher::dispatchEvent(this, event); 2018} 2019 2020void Node::dispatchSubtreeModifiedEvent() 2021{ 2022 if (isInShadowTree()) 2023 return; 2024 2025 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); 2026 2027 if (!document().hasListenerType(Document::DOMSUBTREEMODIFIED_LISTENER)) 2028 return; 2029 const AtomicString& subtreeModifiedEventName = eventNames().DOMSubtreeModifiedEvent; 2030 if (!parentNode() && !hasEventListeners(subtreeModifiedEventName)) 2031 return; 2032 2033 dispatchScopedEvent(MutationEvent::create(subtreeModifiedEventName, true)); 2034} 2035 2036bool Node::dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEvent) 2037{ 2038 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); 2039 RefPtr<UIEvent> event = UIEvent::create(eventNames().DOMActivateEvent, true, true, document().defaultView(), detail); 2040 event->setUnderlyingEvent(underlyingEvent); 2041 dispatchScopedEvent(event); 2042 return event->defaultHandled(); 2043} 2044 2045#if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS) 2046bool Node::dispatchTouchEvent(PassRefPtr<TouchEvent> event) 2047{ 2048 return EventDispatcher::dispatchEvent(this, event); 2049} 2050#endif 2051 2052#if ENABLE(INDIE_UI) 2053bool Node::dispatchUIRequestEvent(PassRefPtr<UIRequestEvent> event) 2054{ 2055 EventDispatcher::dispatchEvent(this, event); 2056 return event->defaultHandled() || event->defaultPrevented(); 2057} 2058#endif 2059 2060bool Node::dispatchBeforeLoadEvent(const String& sourceURL) 2061{ 2062 if (!document().hasListenerType(Document::BEFORELOAD_LISTENER)) 2063 return true; 2064 2065 Ref<Node> protect(*this); 2066 RefPtr<BeforeLoadEvent> beforeLoadEvent = BeforeLoadEvent::create(sourceURL); 2067 dispatchEvent(beforeLoadEvent.get()); 2068 return !beforeLoadEvent->defaultPrevented(); 2069} 2070 2071void Node::dispatchInputEvent() 2072{ 2073 dispatchScopedEvent(Event::create(eventNames().inputEvent, true, false)); 2074} 2075 2076void Node::defaultEventHandler(Event* event) 2077{ 2078 if (event->target() != this) 2079 return; 2080 const AtomicString& eventType = event->type(); 2081 if (eventType == eventNames().keydownEvent || eventType == eventNames().keypressEvent) { 2082 if (event->isKeyboardEvent()) 2083 if (Frame* frame = document().frame()) 2084 frame->eventHandler().defaultKeyboardEventHandler(toKeyboardEvent(event)); 2085 } else if (eventType == eventNames().clickEvent) { 2086 int detail = event->isUIEvent() ? toUIEvent(event)->detail() : 0; 2087 if (dispatchDOMActivateEvent(detail, event)) 2088 event->setDefaultHandled(); 2089#if ENABLE(CONTEXT_MENUS) 2090 } else if (eventType == eventNames().contextmenuEvent) { 2091 if (Frame* frame = document().frame()) 2092 if (Page* page = frame->page()) 2093 page->contextMenuController().handleContextMenuEvent(event); 2094#endif 2095 } else if (eventType == eventNames().textInputEvent) { 2096 if (event->eventInterface() == TextEventInterfaceType) 2097 if (Frame* frame = document().frame()) 2098 frame->eventHandler().defaultTextInputEventHandler(toTextEvent(event)); 2099#if ENABLE(PAN_SCROLLING) 2100 } else if (eventType == eventNames().mousedownEvent && event->isMouseEvent()) { 2101 if (toMouseEvent(event)->button() == MiddleButton) { 2102 if (enclosingLinkEventParentOrSelf()) 2103 return; 2104 2105 RenderObject* renderer = this->renderer(); 2106 while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeScrolledAndHasScrollableArea())) 2107 renderer = renderer->parent(); 2108 2109 if (renderer) { 2110 if (Frame* frame = document().frame()) 2111 frame->eventHandler().startPanScrolling(toRenderBox(renderer)); 2112 } 2113 } 2114#endif 2115 } else if ((eventType == eventNames().wheelEvent || eventType == eventNames().mousewheelEvent) && event->eventInterface() == WheelEventInterfaceType) { 2116 2117 // If we don't have a renderer, send the wheel event to the first node we find with a renderer. 2118 // This is needed for <option> and <optgroup> elements so that <select>s get a wheel scroll. 2119 Node* startNode = this; 2120 while (startNode && !startNode->renderer()) 2121 startNode = startNode->parentOrShadowHostNode(); 2122 2123 if (startNode && startNode->renderer()) 2124 if (Frame* frame = document().frame()) 2125 frame->eventHandler().defaultWheelEventHandler(startNode, toWheelEvent(event)); 2126#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS) 2127 } else if (event->eventInterface() == TouchEventInterfaceType && eventNames().isTouchEventType(eventType)) { 2128 RenderObject* renderer = this->renderer(); 2129 while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeScrolledAndHasScrollableArea())) 2130 renderer = renderer->parent(); 2131 2132 if (renderer && renderer->node()) { 2133 if (Frame* frame = document().frame()) 2134 frame->eventHandler().defaultTouchEventHandler(renderer->node(), toTouchEvent(event)); 2135 } 2136#endif 2137 } else if (event->type() == eventNames().webkitEditableContentChangedEvent) { 2138 dispatchInputEvent(); 2139 } 2140} 2141 2142bool Node::willRespondToMouseMoveEvents() 2143{ 2144 // FIXME: Why is the iOS code path different from the non-iOS code path? 2145#if !PLATFORM(IOS) 2146 if (!isElementNode()) 2147 return false; 2148 if (toElement(this)->isDisabledFormControl()) 2149 return false; 2150#endif 2151 return hasEventListeners(eventNames().mousemoveEvent) || hasEventListeners(eventNames().mouseoverEvent) || hasEventListeners(eventNames().mouseoutEvent); 2152} 2153 2154bool Node::willRespondToMouseClickEvents() 2155{ 2156 // FIXME: Why is the iOS code path different from the non-iOS code path? 2157#if PLATFORM(IOS) 2158 return isContentEditable() || hasEventListeners(eventNames().mouseupEvent) || hasEventListeners(eventNames().mousedownEvent) || hasEventListeners(eventNames().clickEvent); 2159#else 2160 if (!isElementNode()) 2161 return false; 2162 if (toElement(this)->isDisabledFormControl()) 2163 return false; 2164 return isContentEditable(UserSelectAllIsAlwaysNonEditable) || hasEventListeners(eventNames().mouseupEvent) || hasEventListeners(eventNames().mousedownEvent) || hasEventListeners(eventNames().clickEvent) || hasEventListeners(eventNames().DOMActivateEvent); 2165#endif 2166} 2167 2168bool Node::willRespondToMouseWheelEvents() 2169{ 2170 return hasEventListeners(eventNames().mousewheelEvent); 2171} 2172 2173// It's important not to inline removedLastRef, because we don't want to inline the code to 2174// delete a Node at each deref call site. 2175void Node::removedLastRef() 2176{ 2177 // An explicit check for Document here is better than a virtual function since it is 2178 // faster for non-Document nodes, and because the call to removedLastRef that is inlined 2179 // at all deref call sites is smaller if it's a non-virtual function. 2180 if (isDocumentNode()) { 2181 toDocument(*this).removedLastRef(); 2182 return; 2183 } 2184 2185#ifndef NDEBUG 2186 m_deletionHasBegun = true; 2187#endif 2188 delete this; 2189} 2190 2191void Node::textRects(Vector<IntRect>& rects) const 2192{ 2193 RefPtr<Range> range = Range::create(document()); 2194 range->selectNodeContents(const_cast<Node*>(this), IGNORE_EXCEPTION); 2195 range->textRects(rects); 2196} 2197 2198unsigned Node::connectedSubframeCount() const 2199{ 2200 return hasRareData() ? rareData()->connectedSubframeCount() : 0; 2201} 2202 2203void Node::incrementConnectedSubframeCount(unsigned amount) 2204{ 2205 ASSERT(isContainerNode()); 2206 ensureRareData().incrementConnectedSubframeCount(amount); 2207} 2208 2209void Node::decrementConnectedSubframeCount(unsigned amount) 2210{ 2211 rareData()->decrementConnectedSubframeCount(amount); 2212} 2213 2214void Node::updateAncestorConnectedSubframeCountForRemoval() const 2215{ 2216 unsigned count = connectedSubframeCount(); 2217 2218 if (!count) 2219 return; 2220 2221 for (Node* node = parentOrShadowHostNode(); node; node = node->parentOrShadowHostNode()) 2222 node->decrementConnectedSubframeCount(count); 2223} 2224 2225void Node::updateAncestorConnectedSubframeCountForInsertion() const 2226{ 2227 unsigned count = connectedSubframeCount(); 2228 2229 if (!count) 2230 return; 2231 2232 for (Node* node = parentOrShadowHostNode(); node; node = node->parentOrShadowHostNode()) 2233 node->incrementConnectedSubframeCount(count); 2234} 2235 2236bool Node::inRenderedDocument() const 2237{ 2238 return inDocument() && document().hasLivingRenderTree(); 2239} 2240 2241} // namespace WebCore 2242 2243#ifndef NDEBUG 2244 2245void showTree(const WebCore::Node* node) 2246{ 2247 if (node) 2248 node->showTreeForThis(); 2249} 2250 2251void showNodePath(const WebCore::Node* node) 2252{ 2253 if (node) 2254 node->showNodePathForThis(); 2255} 2256 2257#endif 2258