1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org) 3 * (C) 1999 Antti Koivisto (koivisto (at) kde.org) 4 * (C) 2001 Dirk Mueller (mueller (at) kde.org) 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 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 "core/dom/Node.h" 27 28 #include "bindings/v8/ExceptionState.h" 29 #include "bindings/v8/ScriptCallStackFactory.h" 30 #include "core/HTMLNames.h" 31 #include "core/XMLNames.h" 32 #include "core/accessibility/AXObjectCache.h" 33 #include "core/dom/Attr.h" 34 #include "core/dom/Attribute.h" 35 #include "core/dom/ChildListMutationScope.h" 36 #include "core/dom/ChildNodeList.h" 37 #include "core/dom/DOMImplementation.h" 38 #include "core/dom/Document.h" 39 #include "core/dom/DocumentFragment.h" 40 #include "core/dom/DocumentMarkerController.h" 41 #include "core/dom/DocumentType.h" 42 #include "core/dom/Element.h" 43 #include "core/dom/ElementRareData.h" 44 #include "core/dom/ElementTraversal.h" 45 #include "core/dom/ExceptionCode.h" 46 #include "core/dom/LiveNodeList.h" 47 #include "core/dom/NoEventDispatchAssertion.h" 48 #include "core/dom/NodeRareData.h" 49 #include "core/dom/NodeRenderingTraversal.h" 50 #include "core/dom/NodeTraversal.h" 51 #include "core/dom/ProcessingInstruction.h" 52 #include "core/dom/Range.h" 53 #include "core/dom/StaticNodeList.h" 54 #include "core/dom/TemplateContentDocumentFragment.h" 55 #include "core/dom/Text.h" 56 #include "core/dom/TreeScopeAdopter.h" 57 #include "core/dom/UserActionElementSet.h" 58 #include "core/dom/WeakNodeMap.h" 59 #include "core/dom/shadow/ElementShadow.h" 60 #include "core/dom/shadow/InsertionPoint.h" 61 #include "core/dom/shadow/ShadowRoot.h" 62 #include "core/editing/htmlediting.h" 63 #include "core/editing/markup.h" 64 #include "core/events/Event.h" 65 #include "core/events/EventDispatchMediator.h" 66 #include "core/events/EventDispatcher.h" 67 #include "core/events/EventListener.h" 68 #include "core/events/GestureEvent.h" 69 #include "core/events/KeyboardEvent.h" 70 #include "core/events/MouseEvent.h" 71 #include "core/events/MutationEvent.h" 72 #include "core/events/TextEvent.h" 73 #include "core/events/TouchEvent.h" 74 #include "core/events/UIEvent.h" 75 #include "core/events/WheelEvent.h" 76 #include "core/frame/EventHandlerRegistry.h" 77 #include "core/frame/LocalFrame.h" 78 #include "core/html/HTMLAnchorElement.h" 79 #include "core/html/HTMLDialogElement.h" 80 #include "core/html/HTMLFrameOwnerElement.h" 81 #include "core/html/HTMLStyleElement.h" 82 #include "core/page/ContextMenuController.h" 83 #include "core/page/EventHandler.h" 84 #include "core/page/Page.h" 85 #include "core/frame/Settings.h" 86 #include "core/rendering/FlowThreadController.h" 87 #include "core/rendering/RenderBox.h" 88 #include "core/svg/graphics/SVGImage.h" 89 #include "platform/Partitions.h" 90 #include "platform/TraceEvent.h" 91 #include "platform/TracedValue.h" 92 #include "wtf/HashSet.h" 93 #include "wtf/PassOwnPtr.h" 94 #include "wtf/RefCountedLeakCounter.h" 95 #include "wtf/Vector.h" 96 #include "wtf/text/CString.h" 97 #include "wtf/text/StringBuilder.h" 98 99 namespace WebCore { 100 101 using namespace HTMLNames; 102 103 #if !ENABLE(OILPAN) 104 void* Node::operator new(size_t size) 105 { 106 ASSERT(isMainThread()); 107 return partitionAlloc(Partitions::getObjectModelPartition(), size); 108 } 109 110 void Node::operator delete(void* ptr) 111 { 112 ASSERT(isMainThread()); 113 partitionFree(ptr); 114 } 115 #endif 116 117 #if DUMP_NODE_STATISTICS 118 static HashSet<Node*>& liveNodeSet() 119 { 120 DEFINE_STATIC_LOCAL(HashSet<Node*>, s_liveNodeSet, ()); 121 return s_liveNodeSet; 122 } 123 #endif 124 125 void Node::dumpStatistics() 126 { 127 #if DUMP_NODE_STATISTICS 128 size_t nodesWithRareData = 0; 129 130 size_t elementNodes = 0; 131 size_t attrNodes = 0; 132 size_t textNodes = 0; 133 size_t cdataNodes = 0; 134 size_t commentNodes = 0; 135 size_t piNodes = 0; 136 size_t documentNodes = 0; 137 size_t docTypeNodes = 0; 138 size_t fragmentNodes = 0; 139 size_t shadowRootNodes = 0; 140 141 HashMap<String, size_t> perTagCount; 142 143 size_t attributes = 0; 144 size_t elementsWithAttributeStorage = 0; 145 size_t elementsWithRareData = 0; 146 size_t elementsWithNamedNodeMap = 0; 147 148 for (HashSet<Node*>::iterator it = liveNodeSet().begin(); it != liveNodeSet().end(); ++it) { 149 Node* node = *it; 150 151 if (node->hasRareData()) { 152 ++nodesWithRareData; 153 if (node->isElementNode()) { 154 ++elementsWithRareData; 155 if (toElement(node)->hasNamedNodeMap()) 156 ++elementsWithNamedNodeMap; 157 } 158 } 159 160 switch (node->nodeType()) { 161 case ELEMENT_NODE: { 162 ++elementNodes; 163 164 // Tag stats 165 Element* element = toElement(node); 166 HashMap<String, size_t>::AddResult result = perTagCount.add(element->tagName(), 1); 167 if (!result.isNewEntry) 168 result.storedValue->value++; 169 170 if (const ElementData* elementData = element->elementData()) { 171 attributes += elementData->length(); 172 ++elementsWithAttributeStorage; 173 } 174 break; 175 } 176 case ATTRIBUTE_NODE: { 177 ++attrNodes; 178 break; 179 } 180 case TEXT_NODE: { 181 ++textNodes; 182 break; 183 } 184 case CDATA_SECTION_NODE: { 185 ++cdataNodes; 186 break; 187 } 188 case COMMENT_NODE: { 189 ++commentNodes; 190 break; 191 } 192 case PROCESSING_INSTRUCTION_NODE: { 193 ++piNodes; 194 break; 195 } 196 case DOCUMENT_NODE: { 197 ++documentNodes; 198 break; 199 } 200 case DOCUMENT_TYPE_NODE: { 201 ++docTypeNodes; 202 break; 203 } 204 case DOCUMENT_FRAGMENT_NODE: { 205 if (node->isShadowRoot()) 206 ++shadowRootNodes; 207 else 208 ++fragmentNodes; 209 break; 210 } 211 } 212 } 213 214 printf("Number of Nodes: %d\n\n", liveNodeSet().size()); 215 printf("Number of Nodes with RareData: %zu\n\n", nodesWithRareData); 216 217 printf("NodeType distribution:\n"); 218 printf(" Number of Element nodes: %zu\n", elementNodes); 219 printf(" Number of Attribute nodes: %zu\n", attrNodes); 220 printf(" Number of Text nodes: %zu\n", textNodes); 221 printf(" Number of CDATASection nodes: %zu\n", cdataNodes); 222 printf(" Number of Comment nodes: %zu\n", commentNodes); 223 printf(" Number of ProcessingInstruction nodes: %zu\n", piNodes); 224 printf(" Number of Document nodes: %zu\n", documentNodes); 225 printf(" Number of DocumentType nodes: %zu\n", docTypeNodes); 226 printf(" Number of DocumentFragment nodes: %zu\n", fragmentNodes); 227 printf(" Number of ShadowRoot nodes: %zu\n", shadowRootNodes); 228 229 printf("Element tag name distibution:\n"); 230 for (HashMap<String, size_t>::iterator it = perTagCount.begin(); it != perTagCount.end(); ++it) 231 printf(" Number of <%s> tags: %zu\n", it->key.utf8().data(), it->value); 232 233 printf("Attributes:\n"); 234 printf(" Number of Attributes (non-Node and Node): %zu [%zu]\n", attributes, sizeof(Attribute)); 235 printf(" Number of Elements with attribute storage: %zu [%zu]\n", elementsWithAttributeStorage, sizeof(ElementData)); 236 printf(" Number of Elements with RareData: %zu\n", elementsWithRareData); 237 printf(" Number of Elements with NamedNodeMap: %zu [%zu]\n", elementsWithNamedNodeMap, sizeof(NamedNodeMap)); 238 #endif 239 } 240 241 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, nodeCounter, ("WebCoreNode")); 242 243 void Node::trackForDebugging() 244 { 245 #ifndef NDEBUG 246 nodeCounter.increment(); 247 #endif 248 249 #if DUMP_NODE_STATISTICS 250 liveNodeSet().add(this); 251 #endif 252 } 253 254 Node::Node(TreeScope* treeScope, ConstructionType type) 255 : m_nodeFlags(type) 256 , m_parentOrShadowHostNode(nullptr) 257 , m_treeScope(treeScope) 258 , m_previous(nullptr) 259 , m_next(nullptr) 260 { 261 ASSERT(m_treeScope || type == CreateDocument || type == CreateShadowRoot); 262 ScriptWrappable::init(this); 263 #if !ENABLE(OILPAN) 264 if (m_treeScope) 265 m_treeScope->guardRef(); 266 #endif 267 268 #if !defined(NDEBUG) || (defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS) 269 trackForDebugging(); 270 #endif 271 InspectorCounters::incrementCounter(InspectorCounters::NodeCounter); 272 } 273 274 Node::~Node() 275 { 276 #ifndef NDEBUG 277 nodeCounter.decrement(); 278 #endif 279 280 #if DUMP_NODE_STATISTICS 281 liveNodeSet().remove(this); 282 #endif 283 284 #if !ENABLE(OILPAN) 285 if (hasRareData()) 286 clearRareData(); 287 288 RELEASE_ASSERT(!renderer()); 289 290 if (!isContainerNode()) 291 willBeDeletedFromDocument(); 292 293 if (m_previous) 294 m_previous->setNextSibling(0); 295 if (m_next) 296 m_next->setPreviousSibling(0); 297 298 if (m_treeScope) 299 m_treeScope->guardDeref(); 300 #else 301 // With Oilpan, the rare data finalizer also asserts for 302 // this condition (we cannot directly access it here.) 303 RELEASE_ASSERT(hasRareData() || !renderer()); 304 #endif 305 306 InspectorCounters::decrementCounter(InspectorCounters::NodeCounter); 307 308 if (getFlag(HasWeakReferencesFlag)) 309 WeakNodeMap::notifyNodeDestroyed(this); 310 } 311 312 #if !ENABLE(OILPAN) 313 // With Oilpan all of this is handled with weak processing of the document. 314 void Node::willBeDeletedFromDocument() 315 { 316 if (!isTreeScopeInitialized()) 317 return; 318 319 Document& document = this->document(); 320 321 if (hasEventTargetData()) { 322 clearEventTargetData(); 323 document.didClearTouchEventHandlers(this); 324 if (document.frameHost()) 325 document.frameHost()->eventHandlerRegistry().didRemoveAllEventHandlers(*this); 326 } 327 328 if (AXObjectCache* cache = document.existingAXObjectCache()) 329 cache->remove(this); 330 331 document.markers().removeMarkers(this); 332 } 333 #endif 334 335 NodeRareData* Node::rareData() const 336 { 337 ASSERT_WITH_SECURITY_IMPLICATION(hasRareData()); 338 return static_cast<NodeRareData*>(m_data.m_rareData); 339 } 340 341 NodeRareData& Node::ensureRareData() 342 { 343 if (hasRareData()) 344 return *rareData(); 345 346 if (isElementNode()) 347 m_data.m_rareData = ElementRareData::create(m_data.m_renderer); 348 else 349 m_data.m_rareData = NodeRareData::create(m_data.m_renderer); 350 351 ASSERT(m_data.m_rareData); 352 353 setFlag(HasRareDataFlag); 354 return *rareData(); 355 } 356 357 #if !ENABLE(OILPAN) 358 void Node::clearRareData() 359 { 360 ASSERT(hasRareData()); 361 ASSERT(!transientMutationObserverRegistry() || transientMutationObserverRegistry()->isEmpty()); 362 363 RenderObject* renderer = m_data.m_rareData->renderer(); 364 if (isElementNode()) 365 delete static_cast<ElementRareData*>(m_data.m_rareData); 366 else 367 delete static_cast<NodeRareData*>(m_data.m_rareData); 368 m_data.m_renderer = renderer; 369 clearFlag(HasRareDataFlag); 370 } 371 #endif 372 373 Node* Node::toNode() 374 { 375 return this; 376 } 377 378 short Node::tabIndex() const 379 { 380 return 0; 381 } 382 383 String Node::nodeValue() const 384 { 385 return String(); 386 } 387 388 void Node::setNodeValue(const String&) 389 { 390 // By default, setting nodeValue has no effect. 391 } 392 393 PassRefPtrWillBeRawPtr<NodeList> Node::childNodes() 394 { 395 if (isContainerNode()) 396 return ensureRareData().ensureNodeLists().ensureChildNodeList(toContainerNode(*this)); 397 return ensureRareData().ensureNodeLists().ensureEmptyChildNodeList(*this); 398 } 399 400 Node& Node::lastDescendantOrSelf() const 401 { 402 Node* n = const_cast<Node*>(this); 403 while (n && n->lastChild()) 404 n = n->lastChild(); 405 ASSERT(n); 406 return *n; 407 } 408 409 Node* Node::pseudoAwarePreviousSibling() const 410 { 411 if (parentElement() && !previousSibling()) { 412 Element* parent = parentElement(); 413 if (isAfterPseudoElement() && parent->lastChild()) 414 return parent->lastChild(); 415 if (!isBeforePseudoElement()) 416 return parent->pseudoElement(BEFORE); 417 } 418 return previousSibling(); 419 } 420 421 Node* Node::pseudoAwareNextSibling() const 422 { 423 if (parentElement() && !nextSibling()) { 424 Element* parent = parentElement(); 425 if (isBeforePseudoElement() && parent->firstChild()) 426 return parent->firstChild(); 427 if (!isAfterPseudoElement()) 428 return parent->pseudoElement(AFTER); 429 } 430 return nextSibling(); 431 } 432 433 Node* Node::pseudoAwareFirstChild() const 434 { 435 if (isElementNode()) { 436 const Element* currentElement = toElement(this); 437 Node* first = currentElement->pseudoElement(BEFORE); 438 if (first) 439 return first; 440 first = currentElement->firstChild(); 441 if (!first) 442 first = currentElement->pseudoElement(AFTER); 443 return first; 444 } 445 446 return firstChild(); 447 } 448 449 Node* Node::pseudoAwareLastChild() const 450 { 451 if (isElementNode()) { 452 const Element* currentElement = toElement(this); 453 Node* last = currentElement->pseudoElement(AFTER); 454 if (last) 455 return last; 456 last = currentElement->lastChild(); 457 if (!last) 458 last = currentElement->pseudoElement(BEFORE); 459 return last; 460 } 461 462 return lastChild(); 463 } 464 465 void Node::insertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node* refChild, ExceptionState& exceptionState) 466 { 467 if (isContainerNode()) 468 toContainerNode(this)->insertBefore(newChild, refChild, exceptionState); 469 else 470 exceptionState.throwDOMException(HierarchyRequestError, "This node type does not support this method."); 471 } 472 473 void Node::replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, Node* oldChild, ExceptionState& exceptionState) 474 { 475 if (isContainerNode()) 476 toContainerNode(this)->replaceChild(newChild, oldChild, exceptionState); 477 else 478 exceptionState.throwDOMException(HierarchyRequestError, "This node type does not support this method."); 479 } 480 481 void Node::removeChild(Node* oldChild, ExceptionState& exceptionState) 482 { 483 if (isContainerNode()) 484 toContainerNode(this)->removeChild(oldChild, exceptionState); 485 else 486 exceptionState.throwDOMException(NotFoundError, "This node type does not support this method."); 487 } 488 489 void Node::appendChild(PassRefPtrWillBeRawPtr<Node> newChild, ExceptionState& exceptionState) 490 { 491 if (isContainerNode()) 492 toContainerNode(this)->appendChild(newChild, exceptionState); 493 else 494 exceptionState.throwDOMException(HierarchyRequestError, "This node type does not support this method."); 495 } 496 497 void Node::remove(ExceptionState& exceptionState) 498 { 499 if (ContainerNode* parent = parentNode()) 500 parent->removeChild(this, exceptionState); 501 } 502 503 void Node::normalize() 504 { 505 // Go through the subtree beneath us, normalizing all nodes. This means that 506 // any two adjacent text nodes are merged and any empty text nodes are removed. 507 508 RefPtrWillBeRawPtr<Node> node = this; 509 while (Node* firstChild = node->firstChild()) 510 node = firstChild; 511 while (node) { 512 if (node->isElementNode()) 513 toElement(node)->normalizeAttributes(); 514 515 if (node == this) 516 break; 517 518 if (node->nodeType() == TEXT_NODE) 519 node = toText(node)->mergeNextSiblingNodesIfPossible(); 520 else 521 node = NodeTraversal::nextPostOrder(*node); 522 } 523 } 524 525 const AtomicString& Node::localName() const 526 { 527 return nullAtom; 528 } 529 530 const AtomicString& Node::namespaceURI() const 531 { 532 return nullAtom; 533 } 534 535 bool Node::isContentEditable(UserSelectAllTreatment treatment) 536 { 537 document().updateRenderTreeIfNeeded(); 538 return rendererIsEditable(Editable, treatment); 539 } 540 541 bool Node::isContentRichlyEditable() 542 { 543 document().updateRenderTreeIfNeeded(); 544 return rendererIsEditable(RichlyEditable, UserSelectAllIsAlwaysNonEditable); 545 } 546 547 bool Node::rendererIsEditable(EditableLevel editableLevel, UserSelectAllTreatment treatment) const 548 { 549 if (isPseudoElement()) 550 return false; 551 552 // Ideally we'd call ASSERT(!needsStyleRecalc()) here, but 553 // ContainerNode::setFocus() calls setNeedsStyleRecalc(), so the assertion 554 // would fire in the middle of Document::setFocusedNode(). 555 556 for (const Node* node = this; node; node = node->parentNode()) { 557 if ((node->isHTMLElement() || node->isDocumentNode()) && node->renderer()) { 558 // Elements with user-select: all style are considered atomic 559 // therefore non editable. 560 if (Position::nodeIsUserSelectAll(node) && treatment == UserSelectAllIsAlwaysNonEditable) 561 return false; 562 switch (node->renderer()->style()->userModify()) { 563 case READ_ONLY: 564 return false; 565 case READ_WRITE: 566 return true; 567 case READ_WRITE_PLAINTEXT_ONLY: 568 return editableLevel != RichlyEditable; 569 } 570 ASSERT_NOT_REACHED(); 571 return false; 572 } 573 } 574 575 return false; 576 } 577 578 bool Node::isEditableToAccessibility(EditableLevel editableLevel) const 579 { 580 if (rendererIsEditable(editableLevel)) 581 return true; 582 583 // FIXME: Respect editableLevel for ARIA editable elements. 584 if (editableLevel == RichlyEditable) 585 return false; 586 587 ASSERT(AXObjectCache::accessibilityEnabled()); 588 ASSERT(document().existingAXObjectCache()); 589 590 if (AXObjectCache* cache = document().existingAXObjectCache()) 591 return cache->rootAXEditableElement(this); 592 593 return false; 594 } 595 596 bool Node::shouldUseInputMethod() 597 { 598 return isContentEditable(UserSelectAllIsAlwaysNonEditable); 599 } 600 601 RenderBox* Node::renderBox() const 602 { 603 RenderObject* renderer = this->renderer(); 604 return renderer && renderer->isBox() ? toRenderBox(renderer) : 0; 605 } 606 607 RenderBoxModelObject* Node::renderBoxModelObject() const 608 { 609 RenderObject* renderer = this->renderer(); 610 return renderer && renderer->isBoxModelObject() ? toRenderBoxModelObject(renderer) : 0; 611 } 612 613 LayoutRect Node::boundingBox() const 614 { 615 if (renderer()) 616 return renderer()->absoluteBoundingBoxRect(); 617 return LayoutRect(); 618 } 619 620 bool Node::hasNonEmptyBoundingBox() const 621 { 622 // Before calling absoluteRects, check for the common case where the renderer 623 // is non-empty, since this is a faster check and almost always returns true. 624 RenderBoxModelObject* box = renderBoxModelObject(); 625 if (!box) 626 return false; 627 if (!box->borderBoundingBox().isEmpty()) 628 return true; 629 630 Vector<IntRect> rects; 631 FloatPoint absPos = renderer()->localToAbsolute(); 632 renderer()->absoluteRects(rects, flooredLayoutPoint(absPos)); 633 size_t n = rects.size(); 634 for (size_t i = 0; i < n; ++i) 635 if (!rects[i].isEmpty()) 636 return true; 637 638 return false; 639 } 640 641 #ifndef NDEBUG 642 inline static ShadowRoot* oldestShadowRootFor(const Node* node) 643 { 644 if (!node->isElementNode()) 645 return 0; 646 if (ElementShadow* shadow = toElement(node)->shadow()) 647 return shadow->oldestShadowRoot(); 648 return 0; 649 } 650 #endif 651 652 void Node::recalcDistribution() 653 { 654 if (isElementNode()) { 655 if (ElementShadow* shadow = toElement(this)->shadow()) 656 shadow->distributeIfNeeded(); 657 } 658 659 for (Node* child = firstChild(); child; child = child->nextSibling()) { 660 if (child->childNeedsDistributionRecalc()) 661 child->recalcDistribution(); 662 } 663 664 for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) { 665 if (root->childNeedsDistributionRecalc()) 666 root->recalcDistribution(); 667 } 668 669 clearChildNeedsDistributionRecalc(); 670 } 671 672 void Node::setIsLink(bool isLink) 673 { 674 setFlag(isLink && !SVGImage::isInSVGImage(toElement(this)), IsLinkFlag); 675 } 676 677 void Node::setNeedsStyleInvalidation() 678 { 679 setFlag(NeedsStyleInvalidationFlag); 680 markAncestorsWithChildNeedsStyleInvalidation(); 681 } 682 683 void Node::markAncestorsWithChildNeedsStyleInvalidation() 684 { 685 for (Node* node = parentOrShadowHostNode(); node && !node->childNeedsStyleInvalidation(); node = node->parentOrShadowHostNode()) 686 node->setChildNeedsStyleInvalidation(); 687 document().scheduleRenderTreeUpdateIfNeeded(); 688 } 689 690 void Node::markAncestorsWithChildNeedsDistributionRecalc() 691 { 692 for (Node* node = this; node && !node->childNeedsDistributionRecalc(); node = node->parentOrShadowHostNode()) 693 node->setChildNeedsDistributionRecalc(); 694 document().scheduleRenderTreeUpdateIfNeeded(); 695 } 696 697 namespace { 698 699 PassRefPtr<JSONArray> jsStackAsJSONArray() 700 { 701 RefPtr<JSONArray> jsonArray = JSONArray::create(); 702 RefPtrWillBeRawPtr<ScriptCallStack> stack = createScriptCallStack(10); 703 if (!stack) 704 return jsonArray.release(); 705 for (size_t i = 0; i < stack->size(); i++) 706 jsonArray->pushString(stack->at(i).functionName()); 707 return jsonArray.release(); 708 } 709 710 PassRefPtr<JSONObject> jsonObjectForStyleInvalidation(unsigned nodeCount, const Node* rootNode) 711 { 712 RefPtr<JSONObject> jsonObject = JSONObject::create(); 713 jsonObject->setNumber("node_count", nodeCount); 714 jsonObject->setString("root_node", rootNode->debugName()); 715 jsonObject->setArray("js_stack", jsStackAsJSONArray()); 716 return jsonObject.release(); 717 } 718 719 } // anonymous namespace'd functions supporting traceStyleChange 720 721 unsigned Node::styledSubtreeSize() const 722 { 723 unsigned nodeCount = 0; 724 725 for (const Node* node = this; node; node = NodeTraversal::next(*node, this)) { 726 if (node->isTextNode() || node->isElementNode()) 727 nodeCount++; 728 for (ShadowRoot* root = node->youngestShadowRoot(); root; root = root->olderShadowRoot()) 729 nodeCount += root->styledSubtreeSize(); 730 } 731 732 return nodeCount; 733 } 734 735 void Node::traceStyleChange(StyleChangeType changeType) 736 { 737 static const unsigned kMinLoggedSize = 100; 738 unsigned nodeCount = styledSubtreeSize(); 739 if (nodeCount < kMinLoggedSize) 740 return; 741 742 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("style.debug"), 743 "Node::setNeedsStyleRecalc", 744 "data", TracedValue::fromJSONValue(jsonObjectForStyleInvalidation(nodeCount, this)) 745 ); 746 } 747 748 void Node::traceStyleChangeIfNeeded(StyleChangeType changeType) 749 { 750 // TRACE_EVENT_CATEGORY_GROUP_ENABLED macro loads a global static bool into our local bool. 751 bool styleTracingEnabled; 752 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("style.debug"), &styleTracingEnabled); 753 if (UNLIKELY(styleTracingEnabled)) 754 traceStyleChange(changeType); 755 } 756 757 inline void Node::setStyleChange(StyleChangeType changeType) 758 { 759 m_nodeFlags = (m_nodeFlags & ~StyleChangeMask) | changeType; 760 } 761 762 void Node::markAncestorsWithChildNeedsStyleRecalc() 763 { 764 for (ContainerNode* p = parentOrShadowHostNode(); p && !p->childNeedsStyleRecalc(); p = p->parentOrShadowHostNode()) 765 p->setChildNeedsStyleRecalc(); 766 document().scheduleRenderTreeUpdateIfNeeded(); 767 } 768 769 void Node::setNeedsStyleRecalc(StyleChangeType changeType) 770 { 771 ASSERT(changeType != NoStyleChange); 772 if (!inActiveDocument()) 773 return; 774 775 StyleChangeType existingChangeType = styleChangeType(); 776 if (changeType > existingChangeType) { 777 setStyleChange(changeType); 778 if (changeType >= SubtreeStyleChange) 779 traceStyleChangeIfNeeded(changeType); 780 } 781 782 if (existingChangeType == NoStyleChange) 783 markAncestorsWithChildNeedsStyleRecalc(); 784 785 if (isElementNode() && hasRareData()) 786 toElement(*this).setAnimationStyleChange(false); 787 } 788 789 void Node::clearNeedsStyleRecalc() 790 { 791 m_nodeFlags &= ~StyleChangeMask; 792 793 clearSVGFilterNeedsLayerUpdate(); 794 795 if (isElementNode() && hasRareData()) 796 toElement(*this).setAnimationStyleChange(false); 797 } 798 799 bool Node::inActiveDocument() const 800 { 801 return inDocument() && document().isActive(); 802 } 803 804 Node* Node::focusDelegate() 805 { 806 return this; 807 } 808 809 bool Node::shouldHaveFocusAppearance() const 810 { 811 ASSERT(focused()); 812 return true; 813 } 814 815 bool Node::isInert() const 816 { 817 const HTMLDialogElement* dialog = document().activeModalDialog(); 818 if (dialog && this != document() && !NodeRenderingTraversal::contains(dialog, this)) 819 return true; 820 return document().ownerElement() && document().ownerElement()->isInert(); 821 } 822 823 unsigned Node::nodeIndex() const 824 { 825 Node *_tempNode = previousSibling(); 826 unsigned count=0; 827 for ( count=0; _tempNode; count++ ) 828 _tempNode = _tempNode->previousSibling(); 829 return count; 830 } 831 832 void Node::invalidateNodeListCachesInAncestors(const QualifiedName* attrName, Element* attributeOwnerElement) 833 { 834 if (hasRareData() && (!attrName || isAttributeNode())) { 835 if (NodeListsNodeData* lists = rareData()->nodeLists()) 836 lists->clearChildNodeListCache(); 837 } 838 839 // Modifications to attributes that are not associated with an Element can't invalidate NodeList caches. 840 if (attrName && !attributeOwnerElement) 841 return; 842 843 if (!document().shouldInvalidateNodeListCaches(attrName)) 844 return; 845 846 document().invalidateNodeListCaches(attrName); 847 848 for (Node* node = this; node; node = node->parentNode()) { 849 if (NodeListsNodeData* lists = node->nodeLists()) 850 lists->invalidateCaches(attrName); 851 } 852 } 853 854 NodeListsNodeData* Node::nodeLists() 855 { 856 return hasRareData() ? rareData()->nodeLists() : 0; 857 } 858 859 void Node::clearNodeLists() 860 { 861 rareData()->clearNodeLists(); 862 } 863 864 bool Node::isDescendantOf(const Node *other) const 865 { 866 // Return true if other is an ancestor of this, otherwise false 867 if (!other || !other->hasChildren() || inDocument() != other->inDocument()) 868 return false; 869 if (other->treeScope() != treeScope()) 870 return false; 871 if (other->isTreeScope()) 872 return !isTreeScope(); 873 for (const ContainerNode* n = parentNode(); n; n = n->parentNode()) { 874 if (n == other) 875 return true; 876 } 877 return false; 878 } 879 880 bool Node::contains(const Node* node) const 881 { 882 if (!node) 883 return false; 884 return this == node || node->isDescendantOf(this); 885 } 886 887 bool Node::containsIncludingShadowDOM(const Node* node) const 888 { 889 if (!node) 890 return false; 891 892 if (this == node) 893 return true; 894 895 if (document() != node->document()) 896 return false; 897 898 if (inDocument() != node->inDocument()) 899 return false; 900 901 bool hasChildren = isContainerNode() && toContainerNode(this)->hasChildren(); 902 bool hasShadow = isElementNode() && toElement(this)->shadow(); 903 if (!hasChildren && !hasShadow) 904 return false; 905 906 for (; node; node = node->shadowHost()) { 907 if (treeScope() == node->treeScope()) 908 return contains(node); 909 } 910 911 return false; 912 } 913 914 bool Node::containsIncludingHostElements(const Node& node) const 915 { 916 const Node* current = &node; 917 do { 918 if (current == this) 919 return true; 920 if (current->isDocumentFragment() && toDocumentFragment(current)->isTemplateContent()) 921 current = static_cast<const TemplateContentDocumentFragment*>(current)->host(); 922 else 923 current = current->parentOrShadowHostNode(); 924 } while (current); 925 return false; 926 } 927 928 Node* Node::commonAncestor(const Node& other, Node* (*parent)(const Node&)) 929 { 930 if (this == other) 931 return this; 932 if (document() != other.document()) 933 return 0; 934 int thisDepth = 0; 935 for (Node* node = this; node; node = parent(*node)) { 936 if (node == &other) 937 return node; 938 thisDepth++; 939 } 940 int otherDepth = 0; 941 for (const Node* node = &other; node; node = parent(*node)) { 942 if (node == this) 943 return this; 944 otherDepth++; 945 } 946 Node* thisIterator = this; 947 const Node* otherIterator = &other; 948 if (thisDepth > otherDepth) { 949 for (int i = thisDepth; i > otherDepth; --i) 950 thisIterator = parent(*thisIterator); 951 } else if (otherDepth > thisDepth) { 952 for (int i = otherDepth; i > thisDepth; --i) 953 otherIterator = parent(*otherIterator); 954 } 955 while (thisIterator) { 956 if (thisIterator == otherIterator) 957 return thisIterator; 958 thisIterator = parent(*thisIterator); 959 otherIterator = parent(*otherIterator); 960 } 961 ASSERT(!otherIterator); 962 return 0; 963 } 964 965 void Node::reattach(const AttachContext& context) 966 { 967 AttachContext reattachContext(context); 968 reattachContext.performingReattach = true; 969 970 // We only need to detach if the node has already been through attach(). 971 if (styleChangeType() < NeedsReattachStyleChange) 972 detach(reattachContext); 973 attach(reattachContext); 974 } 975 976 void Node::attach(const AttachContext&) 977 { 978 ASSERT(document().inStyleRecalc() || isDocumentNode()); 979 ASSERT(needsAttach()); 980 ASSERT(!renderer() || (renderer()->style() && (renderer()->parent() || renderer()->isRenderView()))); 981 982 clearNeedsStyleRecalc(); 983 984 if (AXObjectCache* cache = document().axObjectCache()) 985 cache->updateCacheAfterNodeIsAttached(this); 986 } 987 988 #ifndef NDEBUG 989 static Node* detachingNode; 990 991 bool Node::inDetach() const 992 { 993 return detachingNode == this; 994 } 995 #endif 996 997 void Node::detach(const AttachContext& context) 998 { 999 ASSERT(document().lifecycle().stateAllowsDetach()); 1000 DocumentLifecycle::DetachScope willDetach(document().lifecycle()); 1001 1002 #ifndef NDEBUG 1003 ASSERT(!detachingNode); 1004 detachingNode = this; 1005 #endif 1006 1007 if (renderer()) 1008 renderer()->destroyAndCleanupAnonymousWrappers(); 1009 setRenderer(0); 1010 1011 // Do not remove the element's hovered and active status 1012 // if performing a reattach. 1013 if (!context.performingReattach) { 1014 Document& doc = document(); 1015 if (isUserActionElement()) { 1016 if (hovered()) 1017 doc.hoveredNodeDetached(this); 1018 if (inActiveChain()) 1019 doc.activeChainNodeDetached(this); 1020 doc.userActionElements().didDetach(this); 1021 } 1022 } 1023 1024 setStyleChange(NeedsReattachStyleChange); 1025 setChildNeedsStyleRecalc(); 1026 1027 if (StyleResolver* resolver = document().styleResolver()) 1028 resolver->ruleFeatureSet().styleInvalidator().clearInvalidation(*this); 1029 clearChildNeedsStyleInvalidation(); 1030 clearNeedsStyleInvalidation(); 1031 1032 #ifndef NDEBUG 1033 detachingNode = 0; 1034 #endif 1035 } 1036 1037 void Node::reattachWhitespaceSiblings(Text* start) 1038 { 1039 for (Node* sibling = start; sibling; sibling = sibling->nextSibling()) { 1040 if (sibling->isTextNode() && toText(sibling)->containsOnlyWhitespace()) { 1041 bool hadRenderer = !!sibling->renderer(); 1042 sibling->reattach(); 1043 // If the reattach didn't toggle the visibility of the whitespace we don't 1044 // need to continue reattaching siblings since they won't toggle visibility 1045 // either. 1046 if (hadRenderer == !!sibling->renderer()) 1047 return; 1048 } else if (sibling->renderer()) { 1049 return; 1050 } 1051 } 1052 } 1053 1054 // FIXME: This code is used by editing. Seems like it could move over there and not pollute Node. 1055 Node *Node::previousNodeConsideringAtomicNodes() const 1056 { 1057 if (previousSibling()) { 1058 Node *n = previousSibling(); 1059 while (!isAtomicNode(n) && n->lastChild()) 1060 n = n->lastChild(); 1061 return n; 1062 } 1063 else if (parentNode()) { 1064 return parentNode(); 1065 } 1066 else { 1067 return 0; 1068 } 1069 } 1070 1071 Node *Node::nextNodeConsideringAtomicNodes() const 1072 { 1073 if (!isAtomicNode(this) && firstChild()) 1074 return firstChild(); 1075 if (nextSibling()) 1076 return nextSibling(); 1077 const Node *n = this; 1078 while (n && !n->nextSibling()) 1079 n = n->parentNode(); 1080 if (n) 1081 return n->nextSibling(); 1082 return 0; 1083 } 1084 1085 Node *Node::previousLeafNode() const 1086 { 1087 Node *node = previousNodeConsideringAtomicNodes(); 1088 while (node) { 1089 if (isAtomicNode(node)) 1090 return node; 1091 node = node->previousNodeConsideringAtomicNodes(); 1092 } 1093 return 0; 1094 } 1095 1096 Node *Node::nextLeafNode() const 1097 { 1098 Node *node = nextNodeConsideringAtomicNodes(); 1099 while (node) { 1100 if (isAtomicNode(node)) 1101 return node; 1102 node = node->nextNodeConsideringAtomicNodes(); 1103 } 1104 return 0; 1105 } 1106 1107 RenderStyle* Node::virtualComputedStyle(PseudoId pseudoElementSpecifier) 1108 { 1109 return parentOrShadowHostNode() ? parentOrShadowHostNode()->computedStyle(pseudoElementSpecifier) : 0; 1110 } 1111 1112 int Node::maxCharacterOffset() const 1113 { 1114 ASSERT_NOT_REACHED(); 1115 return 0; 1116 } 1117 1118 // FIXME: Shouldn't these functions be in the editing code? Code that asks questions about HTML in the core DOM class 1119 // is obviously misplaced. 1120 bool Node::canStartSelection() const 1121 { 1122 if (rendererIsEditable()) 1123 return true; 1124 1125 if (renderer()) { 1126 RenderStyle* style = renderer()->style(); 1127 // We allow selections to begin within an element that has -webkit-user-select: none set, 1128 // but if the element is draggable then dragging should take priority over selection. 1129 if (style->userDrag() == DRAG_ELEMENT && style->userSelect() == SELECT_NONE) 1130 return false; 1131 } 1132 return parentOrShadowHostNode() ? parentOrShadowHostNode()->canStartSelection() : true; 1133 } 1134 1135 Element* Node::shadowHost() const 1136 { 1137 if (ShadowRoot* root = containingShadowRoot()) 1138 return root->host(); 1139 return 0; 1140 } 1141 1142 Node* Node::deprecatedShadowAncestorNode() const 1143 { 1144 if (ShadowRoot* root = containingShadowRoot()) 1145 return root->host(); 1146 1147 return const_cast<Node*>(this); 1148 } 1149 1150 ShadowRoot* Node::containingShadowRoot() const 1151 { 1152 Node& root = treeScope().rootNode(); 1153 return root.isShadowRoot() ? toShadowRoot(&root) : 0; 1154 } 1155 1156 Node* Node::nonBoundaryShadowTreeRootNode() 1157 { 1158 ASSERT(!isShadowRoot()); 1159 Node* root = this; 1160 while (root) { 1161 if (root->isShadowRoot()) 1162 return root; 1163 Node* parent = root->parentOrShadowHostNode(); 1164 if (parent && parent->isShadowRoot()) 1165 return root; 1166 root = parent; 1167 } 1168 return 0; 1169 } 1170 1171 ContainerNode* Node::nonShadowBoundaryParentNode() const 1172 { 1173 ContainerNode* parent = parentNode(); 1174 return parent && !parent->isShadowRoot() ? parent : 0; 1175 } 1176 1177 Element* Node::parentOrShadowHostElement() const 1178 { 1179 ContainerNode* parent = parentOrShadowHostNode(); 1180 if (!parent) 1181 return 0; 1182 1183 if (parent->isShadowRoot()) 1184 return toShadowRoot(parent)->host(); 1185 1186 if (!parent->isElementNode()) 1187 return 0; 1188 1189 return toElement(parent); 1190 } 1191 1192 ContainerNode* Node::parentOrShadowHostOrTemplateHostNode() const 1193 { 1194 if (isDocumentFragment() && toDocumentFragment(this)->isTemplateContent()) 1195 return static_cast<const TemplateContentDocumentFragment*>(this)->host(); 1196 return parentOrShadowHostNode(); 1197 } 1198 1199 bool Node::isBlockFlowElement() const 1200 { 1201 return isElementNode() && renderer() && renderer()->isRenderBlockFlow(); 1202 } 1203 1204 Element *Node::enclosingBlockFlowElement() const 1205 { 1206 Node *n = const_cast<Node *>(this); 1207 if (isBlockFlowElement()) 1208 return toElement(n); 1209 1210 while (1) { 1211 n = n->parentNode(); 1212 if (!n) 1213 break; 1214 if (n->isBlockFlowElement() || isHTMLBodyElement(*n)) 1215 return toElement(n); 1216 } 1217 return 0; 1218 } 1219 1220 bool Node::isRootEditableElement() const 1221 { 1222 return rendererIsEditable() && isElementNode() && (!parentNode() || !parentNode()->rendererIsEditable() 1223 || !parentNode()->isElementNode() || isHTMLBodyElement((*this))); 1224 } 1225 1226 Element* Node::rootEditableElement(EditableType editableType) const 1227 { 1228 if (editableType == HasEditableAXRole) { 1229 if (AXObjectCache* cache = document().existingAXObjectCache()) 1230 return const_cast<Element*>(cache->rootAXEditableElement(this)); 1231 } 1232 1233 return rootEditableElement(); 1234 } 1235 1236 Element* Node::rootEditableElement() const 1237 { 1238 Element* result = 0; 1239 for (Node* n = const_cast<Node*>(this); n && n->rendererIsEditable(); n = n->parentNode()) { 1240 if (n->isElementNode()) 1241 result = toElement(n); 1242 if (isHTMLBodyElement(*n)) 1243 break; 1244 } 1245 return result; 1246 } 1247 1248 bool Node::inSameContainingBlockFlowElement(Node *n) 1249 { 1250 return n ? enclosingBlockFlowElement() == n->enclosingBlockFlowElement() : false; 1251 } 1252 1253 // FIXME: End of obviously misplaced HTML editing functions. Try to move these out of Node. 1254 1255 Document* Node::ownerDocument() const 1256 { 1257 Document* doc = &document(); 1258 return doc == this ? 0 : doc; 1259 } 1260 1261 KURL Node::baseURI() const 1262 { 1263 return parentNode() ? parentNode()->baseURI() : KURL(); 1264 } 1265 1266 bool Node::isEqualNode(Node* other) const 1267 { 1268 if (!other) 1269 return false; 1270 1271 NodeType nodeType = this->nodeType(); 1272 if (nodeType != other->nodeType()) 1273 return false; 1274 1275 if (nodeName() != other->nodeName()) 1276 return false; 1277 1278 if (localName() != other->localName()) 1279 return false; 1280 1281 if (namespaceURI() != other->namespaceURI()) 1282 return false; 1283 1284 if (nodeValue() != other->nodeValue()) 1285 return false; 1286 1287 if (isElementNode() && !toElement(this)->hasEquivalentAttributes(toElement(other))) 1288 return false; 1289 1290 Node* child = firstChild(); 1291 Node* otherChild = other->firstChild(); 1292 1293 while (child) { 1294 if (!child->isEqualNode(otherChild)) 1295 return false; 1296 1297 child = child->nextSibling(); 1298 otherChild = otherChild->nextSibling(); 1299 } 1300 1301 if (otherChild) 1302 return false; 1303 1304 if (isDocumentTypeNode()) { 1305 const DocumentType* documentTypeThis = toDocumentType(this); 1306 const DocumentType* documentTypeOther = toDocumentType(other); 1307 1308 if (documentTypeThis->publicId() != documentTypeOther->publicId()) 1309 return false; 1310 1311 if (documentTypeThis->systemId() != documentTypeOther->systemId()) 1312 return false; 1313 } 1314 1315 return true; 1316 } 1317 1318 bool Node::isDefaultNamespace(const AtomicString& namespaceURIMaybeEmpty) const 1319 { 1320 const AtomicString& namespaceURI = namespaceURIMaybeEmpty.isEmpty() ? nullAtom : namespaceURIMaybeEmpty; 1321 1322 switch (nodeType()) { 1323 case ELEMENT_NODE: { 1324 const Element& element = toElement(*this); 1325 1326 if (element.prefix().isNull()) 1327 return element.namespaceURI() == namespaceURI; 1328 1329 if (element.hasAttributes()) { 1330 AttributeCollection attributes = element.attributes(); 1331 AttributeCollection::const_iterator end = attributes.end(); 1332 for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) { 1333 if (it->localName() == xmlnsAtom) 1334 return it->value() == namespaceURI; 1335 } 1336 } 1337 1338 if (Element* parent = parentElement()) 1339 return parent->isDefaultNamespace(namespaceURI); 1340 1341 return false; 1342 } 1343 case DOCUMENT_NODE: 1344 if (Element* de = toDocument(this)->documentElement()) 1345 return de->isDefaultNamespace(namespaceURI); 1346 return false; 1347 case DOCUMENT_TYPE_NODE: 1348 case DOCUMENT_FRAGMENT_NODE: 1349 return false; 1350 case ATTRIBUTE_NODE: { 1351 const Attr* attr = toAttr(this); 1352 if (attr->ownerElement()) 1353 return attr->ownerElement()->isDefaultNamespace(namespaceURI); 1354 return false; 1355 } 1356 default: 1357 if (Element* parent = parentElement()) 1358 return parent->isDefaultNamespace(namespaceURI); 1359 return false; 1360 } 1361 } 1362 1363 const AtomicString& Node::lookupPrefix(const AtomicString& namespaceURI) const 1364 { 1365 // Implemented according to 1366 // http://dom.spec.whatwg.org/#dom-node-lookupprefix 1367 1368 if (namespaceURI.isEmpty() || namespaceURI.isNull()) 1369 return nullAtom; 1370 1371 const Element* context; 1372 1373 switch (nodeType()) { 1374 case ELEMENT_NODE: 1375 context = toElement(this); 1376 break; 1377 case DOCUMENT_NODE: 1378 context = toDocument(this)->documentElement(); 1379 break; 1380 case DOCUMENT_FRAGMENT_NODE: 1381 case DOCUMENT_TYPE_NODE: 1382 context = 0; 1383 break; 1384 // FIXME: Remove this when Attr no longer extends Node (CR305105) 1385 case ATTRIBUTE_NODE: 1386 context = toAttr(this)->ownerElement(); 1387 break; 1388 default: 1389 context = parentElement(); 1390 break; 1391 } 1392 1393 if (!context) 1394 return nullAtom; 1395 1396 return context->locateNamespacePrefix(namespaceURI); 1397 } 1398 1399 const AtomicString& Node::lookupNamespaceURI(const String& prefix) const 1400 { 1401 // Implemented according to 1402 // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#lookupNamespaceURIAlgo 1403 1404 if (!prefix.isNull() && prefix.isEmpty()) 1405 return nullAtom; 1406 1407 switch (nodeType()) { 1408 case ELEMENT_NODE: { 1409 const Element& element = toElement(*this); 1410 1411 if (!element.namespaceURI().isNull() && element.prefix() == prefix) 1412 return element.namespaceURI(); 1413 1414 if (element.hasAttributes()) { 1415 AttributeCollection attributes = element.attributes(); 1416 AttributeCollection::const_iterator end = attributes.end(); 1417 for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) { 1418 if (it->prefix() == xmlnsAtom && it->localName() == prefix) { 1419 if (!it->value().isEmpty()) 1420 return it->value(); 1421 return nullAtom; 1422 } 1423 if (it->localName() == xmlnsAtom && prefix.isNull()) { 1424 if (!it->value().isEmpty()) 1425 return it->value(); 1426 return nullAtom; 1427 } 1428 } 1429 } 1430 if (Element* parent = parentElement()) 1431 return parent->lookupNamespaceURI(prefix); 1432 return nullAtom; 1433 } 1434 case DOCUMENT_NODE: 1435 if (Element* de = toDocument(this)->documentElement()) 1436 return de->lookupNamespaceURI(prefix); 1437 return nullAtom; 1438 case DOCUMENT_TYPE_NODE: 1439 case DOCUMENT_FRAGMENT_NODE: 1440 return nullAtom; 1441 case ATTRIBUTE_NODE: { 1442 const Attr *attr = toAttr(this); 1443 if (attr->ownerElement()) 1444 return attr->ownerElement()->lookupNamespaceURI(prefix); 1445 else 1446 return nullAtom; 1447 } 1448 default: 1449 if (Element* parent = parentElement()) 1450 return parent->lookupNamespaceURI(prefix); 1451 return nullAtom; 1452 } 1453 } 1454 1455 static void appendTextContent(const Node* node, bool convertBRsToNewlines, bool& isNullString, StringBuilder& content) 1456 { 1457 switch (node->nodeType()) { 1458 case Node::TEXT_NODE: 1459 case Node::CDATA_SECTION_NODE: 1460 case Node::COMMENT_NODE: 1461 isNullString = false; 1462 content.append(toCharacterData(node)->data()); 1463 break; 1464 1465 case Node::PROCESSING_INSTRUCTION_NODE: 1466 isNullString = false; 1467 content.append(toProcessingInstruction(node)->data()); 1468 break; 1469 1470 case Node::ELEMENT_NODE: 1471 if (isHTMLBRElement(*node) && convertBRsToNewlines) { 1472 isNullString = false; 1473 content.append('\n'); 1474 break; 1475 } 1476 // Fall through. 1477 case Node::ATTRIBUTE_NODE: 1478 case Node::DOCUMENT_FRAGMENT_NODE: 1479 isNullString = false; 1480 for (Node* child = toContainerNode(node)->firstChild(); child; child = child->nextSibling()) { 1481 Node::NodeType childNodeType = child->nodeType(); 1482 if (childNodeType == Node::COMMENT_NODE || childNodeType == Node::PROCESSING_INSTRUCTION_NODE) 1483 continue; 1484 appendTextContent(child, convertBRsToNewlines, isNullString, content); 1485 } 1486 break; 1487 1488 case Node::DOCUMENT_NODE: 1489 case Node::DOCUMENT_TYPE_NODE: 1490 break; 1491 } 1492 } 1493 1494 String Node::textContent(bool convertBRsToNewlines) const 1495 { 1496 StringBuilder content; 1497 bool isNullString = true; 1498 appendTextContent(this, convertBRsToNewlines, isNullString, content); 1499 return isNullString ? String() : content.toString(); 1500 } 1501 1502 void Node::setTextContent(const String& text) 1503 { 1504 switch (nodeType()) { 1505 case TEXT_NODE: 1506 case CDATA_SECTION_NODE: 1507 case COMMENT_NODE: 1508 case PROCESSING_INSTRUCTION_NODE: 1509 setNodeValue(text); 1510 return; 1511 case ELEMENT_NODE: 1512 case ATTRIBUTE_NODE: 1513 case DOCUMENT_FRAGMENT_NODE: { 1514 // FIXME: Merge this logic into replaceChildrenWithText. 1515 RefPtrWillBeRawPtr<ContainerNode> container = toContainerNode(this); 1516 // No need to do anything if the text is identical. 1517 if (container->hasOneTextChild() && toText(container->firstChild())->data() == text) 1518 return; 1519 ChildListMutationScope mutation(*this); 1520 container->removeChildren(); 1521 // Note: This API will not insert empty text nodes: 1522 // http://dom.spec.whatwg.org/#dom-node-textcontent 1523 if (!text.isEmpty()) 1524 container->appendChild(document().createTextNode(text), ASSERT_NO_EXCEPTION); 1525 return; 1526 } 1527 case DOCUMENT_NODE: 1528 case DOCUMENT_TYPE_NODE: 1529 // Do nothing. 1530 return; 1531 } 1532 ASSERT_NOT_REACHED(); 1533 } 1534 1535 bool Node::offsetInCharacters() const 1536 { 1537 return false; 1538 } 1539 1540 unsigned short Node::compareDocumentPosition(const Node* otherNode) const 1541 { 1542 return compareDocumentPositionInternal(otherNode, TreatShadowTreesAsDisconnected); 1543 } 1544 1545 unsigned short Node::compareDocumentPositionInternal(const Node* otherNode, ShadowTreesTreatment treatment) const 1546 { 1547 // It is not clear what should be done if |otherNode| is 0. 1548 if (!otherNode) 1549 return DOCUMENT_POSITION_DISCONNECTED; 1550 1551 if (otherNode == this) 1552 return DOCUMENT_POSITION_EQUIVALENT; 1553 1554 const Attr* attr1 = nodeType() == ATTRIBUTE_NODE ? toAttr(this) : 0; 1555 const Attr* attr2 = otherNode->nodeType() == ATTRIBUTE_NODE ? toAttr(otherNode) : 0; 1556 1557 const Node* start1 = attr1 ? attr1->ownerElement() : this; 1558 const Node* start2 = attr2 ? attr2->ownerElement() : otherNode; 1559 1560 // If either of start1 or start2 is null, then we are disconnected, since one of the nodes is 1561 // an orphaned attribute node. 1562 if (!start1 || !start2) { 1563 unsigned short direction = (this > otherNode) ? DOCUMENT_POSITION_PRECEDING : DOCUMENT_POSITION_FOLLOWING; 1564 return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | direction; 1565 } 1566 1567 Vector<const Node*, 16> chain1; 1568 Vector<const Node*, 16> chain2; 1569 if (attr1) 1570 chain1.append(attr1); 1571 if (attr2) 1572 chain2.append(attr2); 1573 1574 if (attr1 && attr2 && start1 == start2 && start1) { 1575 // We are comparing two attributes on the same node. Crawl our attribute map and see which one we hit first. 1576 const Element* owner1 = attr1->ownerElement(); 1577 owner1->synchronizeAllAttributes(); 1578 AttributeCollection attributes = owner1->attributes(); 1579 AttributeCollection::const_iterator end = attributes.end(); 1580 for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) { 1581 // If neither of the two determining nodes is a child node and nodeType is the same for both determining nodes, then an 1582 // implementation-dependent order between the determining nodes is returned. This order is stable as long as no nodes of 1583 // the same nodeType are inserted into or removed from the direct container. This would be the case, for example, 1584 // when comparing two attributes of the same element, and inserting or removing additional attributes might change 1585 // the order between existing attributes. 1586 if (attr1->qualifiedName() == it->name()) 1587 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_FOLLOWING; 1588 if (attr2->qualifiedName() == it->name()) 1589 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_PRECEDING; 1590 } 1591 1592 ASSERT_NOT_REACHED(); 1593 return DOCUMENT_POSITION_DISCONNECTED; 1594 } 1595 1596 // If one node is in the document and the other is not, we must be disconnected. 1597 // If the nodes have different owning documents, they must be disconnected. Note that we avoid 1598 // comparing Attr nodes here, since they return false from inDocument() all the time (which seems like a bug). 1599 if (start1->inDocument() != start2->inDocument() || (treatment == TreatShadowTreesAsDisconnected && start1->treeScope() != start2->treeScope())) { 1600 unsigned short direction = (this > otherNode) ? DOCUMENT_POSITION_PRECEDING : DOCUMENT_POSITION_FOLLOWING; 1601 return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | direction; 1602 } 1603 1604 // We need to find a common ancestor container, and then compare the indices of the two immediate children. 1605 const Node* current; 1606 for (current = start1; current; current = current->parentOrShadowHostNode()) 1607 chain1.append(current); 1608 for (current = start2; current; current = current->parentOrShadowHostNode()) 1609 chain2.append(current); 1610 1611 unsigned index1 = chain1.size(); 1612 unsigned index2 = chain2.size(); 1613 1614 // If the two elements don't have a common root, they're not in the same tree. 1615 if (chain1[index1 - 1] != chain2[index2 - 1]) { 1616 unsigned short direction = (this > otherNode) ? DOCUMENT_POSITION_PRECEDING : DOCUMENT_POSITION_FOLLOWING; 1617 return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | direction; 1618 } 1619 1620 unsigned connection = start1->treeScope() != start2->treeScope() ? DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC : 0; 1621 1622 // Walk the two chains backwards and look for the first difference. 1623 for (unsigned i = std::min(index1, index2); i; --i) { 1624 const Node* child1 = chain1[--index1]; 1625 const Node* child2 = chain2[--index2]; 1626 if (child1 != child2) { 1627 // If one of the children is an attribute, it wins. 1628 if (child1->nodeType() == ATTRIBUTE_NODE) 1629 return DOCUMENT_POSITION_FOLLOWING | connection; 1630 if (child2->nodeType() == ATTRIBUTE_NODE) 1631 return DOCUMENT_POSITION_PRECEDING | connection; 1632 1633 // If one of the children is a shadow root, 1634 if (child1->isShadowRoot() || child2->isShadowRoot()) { 1635 if (!child2->isShadowRoot()) 1636 return Node::DOCUMENT_POSITION_FOLLOWING | connection; 1637 if (!child1->isShadowRoot()) 1638 return Node::DOCUMENT_POSITION_PRECEDING | connection; 1639 1640 for (ShadowRoot* child = toShadowRoot(child2)->olderShadowRoot(); child; child = child->olderShadowRoot()) 1641 if (child == child1) 1642 return Node::DOCUMENT_POSITION_FOLLOWING | connection; 1643 1644 return Node::DOCUMENT_POSITION_PRECEDING | connection; 1645 } 1646 1647 if (!child2->nextSibling()) 1648 return DOCUMENT_POSITION_FOLLOWING | connection; 1649 if (!child1->nextSibling()) 1650 return DOCUMENT_POSITION_PRECEDING | connection; 1651 1652 // Otherwise we need to see which node occurs first. Crawl backwards from child2 looking for child1. 1653 for (Node* child = child2->previousSibling(); child; child = child->previousSibling()) { 1654 if (child == child1) 1655 return DOCUMENT_POSITION_FOLLOWING | connection; 1656 } 1657 return DOCUMENT_POSITION_PRECEDING | connection; 1658 } 1659 } 1660 1661 // There was no difference between the two parent chains, i.e., one was a subset of the other. The shorter 1662 // chain is the ancestor. 1663 return index1 < index2 ? 1664 DOCUMENT_POSITION_FOLLOWING | DOCUMENT_POSITION_CONTAINED_BY | connection : 1665 DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_CONTAINS | connection; 1666 } 1667 1668 FloatPoint Node::convertToPage(const FloatPoint& p) const 1669 { 1670 // If there is a renderer, just ask it to do the conversion 1671 if (renderer()) 1672 return renderer()->localToAbsolute(p, UseTransforms); 1673 1674 // Otherwise go up the tree looking for a renderer 1675 if (Element* parent = parentElement()) 1676 return parent->convertToPage(p); 1677 1678 // No parent - no conversion needed 1679 return p; 1680 } 1681 1682 FloatPoint Node::convertFromPage(const FloatPoint& p) const 1683 { 1684 // If there is a renderer, just ask it to do the conversion 1685 if (renderer()) 1686 return renderer()->absoluteToLocal(p, UseTransforms); 1687 1688 // Otherwise go up the tree looking for a renderer 1689 if (Element* parent = parentElement()) 1690 return parent->convertFromPage(p); 1691 1692 // No parent - no conversion needed 1693 return p; 1694 } 1695 1696 String Node::debugName() const 1697 { 1698 StringBuilder name; 1699 name.append(nodeName()); 1700 1701 if (hasID()) { 1702 name.appendLiteral(" id=\'"); 1703 name.append(toElement(this)->getIdAttribute()); 1704 name.append('\''); 1705 } 1706 1707 if (hasClass()) { 1708 name.appendLiteral(" class=\'"); 1709 for (size_t i = 0; i < toElement(this)->classNames().size(); ++i) { 1710 if (i > 0) 1711 name.append(' '); 1712 name.append(toElement(this)->classNames()[i]); 1713 } 1714 name.append('\''); 1715 } 1716 1717 return name.toString(); 1718 } 1719 1720 #ifndef NDEBUG 1721 1722 static void appendAttributeDesc(const Node* node, StringBuilder& stringBuilder, const QualifiedName& name, const char* attrDesc) 1723 { 1724 if (!node->isElementNode()) 1725 return; 1726 1727 String attr = toElement(node)->getAttribute(name); 1728 if (attr.isEmpty()) 1729 return; 1730 1731 stringBuilder.append(attrDesc); 1732 stringBuilder.append("=\""); 1733 stringBuilder.append(attr); 1734 stringBuilder.append("\""); 1735 } 1736 1737 void Node::showNode(const char* prefix) const 1738 { 1739 if (!prefix) 1740 prefix = ""; 1741 if (isTextNode()) { 1742 String value = nodeValue(); 1743 value.replaceWithLiteral('\\', "\\\\"); 1744 value.replaceWithLiteral('\n', "\\n"); 1745 fprintf(stderr, "%s%s\t%p \"%s\"\n", prefix, nodeName().utf8().data(), this, value.utf8().data()); 1746 } else { 1747 StringBuilder attrs; 1748 appendAttributeDesc(this, attrs, idAttr, " ID"); 1749 appendAttributeDesc(this, attrs, classAttr, " CLASS"); 1750 appendAttributeDesc(this, attrs, styleAttr, " STYLE"); 1751 fprintf(stderr, "%s%s\t%p%s\n", prefix, nodeName().utf8().data(), this, attrs.toString().utf8().data()); 1752 } 1753 } 1754 1755 void Node::showTreeForThis() const 1756 { 1757 showTreeAndMark(this, "*"); 1758 } 1759 1760 void Node::showNodePathForThis() const 1761 { 1762 Vector<const Node*, 16> chain; 1763 const Node* node = this; 1764 while (node->parentOrShadowHostNode()) { 1765 chain.append(node); 1766 node = node->parentOrShadowHostNode(); 1767 } 1768 for (unsigned index = chain.size(); index > 0; --index) { 1769 const Node* node = chain[index - 1]; 1770 if (node->isShadowRoot()) { 1771 int count = 0; 1772 for (ShadowRoot* shadowRoot = toShadowRoot(node)->olderShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) 1773 ++count; 1774 fprintf(stderr, "/#shadow-root[%d]", count); 1775 continue; 1776 } 1777 1778 switch (node->nodeType()) { 1779 case ELEMENT_NODE: { 1780 fprintf(stderr, "/%s", node->nodeName().utf8().data()); 1781 1782 const Element* element = toElement(node); 1783 const AtomicString& idattr = element->getIdAttribute(); 1784 bool hasIdAttr = !idattr.isNull() && !idattr.isEmpty(); 1785 if (node->previousSibling() || node->nextSibling()) { 1786 int count = 0; 1787 for (Node* previous = node->previousSibling(); previous; previous = previous->previousSibling()) 1788 if (previous->nodeName() == node->nodeName()) 1789 ++count; 1790 if (hasIdAttr) 1791 fprintf(stderr, "[@id=\"%s\" and position()=%d]", idattr.utf8().data(), count); 1792 else 1793 fprintf(stderr, "[%d]", count); 1794 } else if (hasIdAttr) { 1795 fprintf(stderr, "[@id=\"%s\"]", idattr.utf8().data()); 1796 } 1797 break; 1798 } 1799 case TEXT_NODE: 1800 fprintf(stderr, "/text()"); 1801 break; 1802 case ATTRIBUTE_NODE: 1803 fprintf(stderr, "/@%s", node->nodeName().utf8().data()); 1804 break; 1805 default: 1806 break; 1807 } 1808 } 1809 fprintf(stderr, "\n"); 1810 } 1811 1812 static void traverseTreeAndMark(const String& baseIndent, const Node* rootNode, const Node* markedNode1, const char* markedLabel1, const Node* markedNode2, const char* markedLabel2) 1813 { 1814 for (const Node* node = rootNode; node; node = NodeTraversal::next(*node)) { 1815 if (node == markedNode1) 1816 fprintf(stderr, "%s", markedLabel1); 1817 if (node == markedNode2) 1818 fprintf(stderr, "%s", markedLabel2); 1819 1820 StringBuilder indent; 1821 indent.append(baseIndent); 1822 for (const Node* tmpNode = node; tmpNode && tmpNode != rootNode; tmpNode = tmpNode->parentOrShadowHostNode()) 1823 indent.append('\t'); 1824 fprintf(stderr, "%s", indent.toString().utf8().data()); 1825 node->showNode(); 1826 indent.append('\t'); 1827 if (node->isShadowRoot()) { 1828 if (ShadowRoot* youngerShadowRoot = toShadowRoot(node)->youngerShadowRoot()) 1829 traverseTreeAndMark(indent.toString(), youngerShadowRoot, markedNode1, markedLabel1, markedNode2, markedLabel2); 1830 } else if (ShadowRoot* oldestShadowRoot = oldestShadowRootFor(node)) 1831 traverseTreeAndMark(indent.toString(), oldestShadowRoot, markedNode1, markedLabel1, markedNode2, markedLabel2); 1832 } 1833 } 1834 1835 void Node::showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2, const char* markedLabel2) const 1836 { 1837 const Node* rootNode; 1838 const Node* node = this; 1839 while (node->parentOrShadowHostNode() && !isHTMLBodyElement(*node)) 1840 node = node->parentOrShadowHostNode(); 1841 rootNode = node; 1842 1843 String startingIndent; 1844 traverseTreeAndMark(startingIndent, rootNode, markedNode1, markedLabel1, markedNode2, markedLabel2); 1845 } 1846 1847 void Node::formatForDebugger(char* buffer, unsigned length) const 1848 { 1849 String result; 1850 String s; 1851 1852 s = nodeName(); 1853 if (s.isEmpty()) 1854 result = "<none>"; 1855 else 1856 result = s; 1857 1858 strncpy(buffer, result.utf8().data(), length - 1); 1859 } 1860 1861 static ContainerNode* parentOrShadowHostOrFrameOwner(const Node* node) 1862 { 1863 ContainerNode* parent = node->parentOrShadowHostNode(); 1864 if (!parent && node->document().frame()) 1865 parent = node->document().frame()->deprecatedLocalOwner(); 1866 return parent; 1867 } 1868 1869 static void showSubTreeAcrossFrame(const Node* node, const Node* markedNode, const String& indent) 1870 { 1871 if (node == markedNode) 1872 fputs("*", stderr); 1873 fputs(indent.utf8().data(), stderr); 1874 node->showNode(); 1875 if (node->isShadowRoot()) { 1876 if (ShadowRoot* youngerShadowRoot = toShadowRoot(node)->youngerShadowRoot()) 1877 showSubTreeAcrossFrame(youngerShadowRoot, markedNode, indent + "\t"); 1878 } else { 1879 if (node->isFrameOwnerElement()) 1880 showSubTreeAcrossFrame(toHTMLFrameOwnerElement(node)->contentDocument(), markedNode, indent + "\t"); 1881 if (ShadowRoot* oldestShadowRoot = oldestShadowRootFor(node)) 1882 showSubTreeAcrossFrame(oldestShadowRoot, markedNode, indent + "\t"); 1883 } 1884 for (Node* child = node->firstChild(); child; child = child->nextSibling()) 1885 showSubTreeAcrossFrame(child, markedNode, indent + "\t"); 1886 } 1887 1888 void Node::showTreeForThisAcrossFrame() const 1889 { 1890 Node* rootNode = const_cast<Node*>(this); 1891 while (parentOrShadowHostOrFrameOwner(rootNode)) 1892 rootNode = parentOrShadowHostOrFrameOwner(rootNode); 1893 showSubTreeAcrossFrame(rootNode, this, ""); 1894 } 1895 1896 #endif 1897 1898 // -------- 1899 1900 Node* Node::enclosingLinkEventParentOrSelf() 1901 { 1902 for (Node* node = this; node; node = NodeRenderingTraversal::parent(node)) { 1903 // For imagemaps, the enclosing link node is the associated area element not the image itself. 1904 // So we don't let images be the enclosingLinkNode, even though isLink sometimes returns true 1905 // for them. 1906 if (node->isLink() && !isHTMLImageElement(*node)) 1907 return node; 1908 } 1909 1910 return 0; 1911 } 1912 1913 const AtomicString& Node::interfaceName() const 1914 { 1915 return EventTargetNames::Node; 1916 } 1917 1918 ExecutionContext* Node::executionContext() const 1919 { 1920 return document().contextDocument().get(); 1921 } 1922 1923 void Node::didMoveToNewDocument(Document& oldDocument) 1924 { 1925 TreeScopeAdopter::ensureDidMoveToNewDocumentWasCalled(oldDocument); 1926 1927 if (const EventTargetData* eventTargetData = this->eventTargetData()) { 1928 const EventListenerMap& listenerMap = eventTargetData->eventListenerMap; 1929 if (!listenerMap.isEmpty()) { 1930 Vector<AtomicString> types = listenerMap.eventTypes(); 1931 for (unsigned i = 0; i < types.size(); ++i) 1932 document().addListenerTypeIfNeeded(types[i]); 1933 } 1934 } 1935 1936 if (AXObjectCache::accessibilityEnabled()) { 1937 if (AXObjectCache* cache = oldDocument.existingAXObjectCache()) 1938 cache->remove(this); 1939 } 1940 1941 oldDocument.markers().removeMarkers(this); 1942 oldDocument.updateRangesAfterNodeMovedToAnotherDocument(*this); 1943 1944 if (const TouchEventTargetSet* touchHandlers = oldDocument.touchEventTargets()) { 1945 while (touchHandlers->contains(this)) { 1946 oldDocument.didRemoveTouchEventHandler(this); 1947 document().didAddTouchEventHandler(this); 1948 } 1949 } 1950 if (oldDocument.frameHost() != document().frameHost()) { 1951 if (oldDocument.frameHost()) 1952 oldDocument.frameHost()->eventHandlerRegistry().didMoveOutOfFrameHost(*this); 1953 if (document().frameHost()) 1954 document().frameHost()->eventHandlerRegistry().didMoveIntoFrameHost(*this); 1955 } 1956 1957 if (WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* registry = mutationObserverRegistry()) { 1958 for (size_t i = 0; i < registry->size(); ++i) { 1959 document().addMutationObserverTypes(registry->at(i)->mutationTypes()); 1960 } 1961 } 1962 1963 if (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* transientRegistry = transientMutationObserverRegistry()) { 1964 for (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter) { 1965 document().addMutationObserverTypes((*iter)->mutationTypes()); 1966 } 1967 } 1968 } 1969 1970 static inline bool tryAddEventListener(Node* targetNode, const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) 1971 { 1972 if (!targetNode->EventTarget::addEventListener(eventType, listener, useCapture)) 1973 return false; 1974 1975 Document& document = targetNode->document(); 1976 document.addListenerTypeIfNeeded(eventType); 1977 if (isTouchEventType(eventType)) 1978 document.didAddTouchEventHandler(targetNode); 1979 if (document.frameHost()) 1980 document.frameHost()->eventHandlerRegistry().didAddEventHandler(*targetNode, eventType); 1981 1982 return true; 1983 } 1984 1985 bool Node::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) 1986 { 1987 return tryAddEventListener(this, eventType, listener, useCapture); 1988 } 1989 1990 static inline bool tryRemoveEventListener(Node* targetNode, const AtomicString& eventType, EventListener* listener, bool useCapture) 1991 { 1992 if (!targetNode->EventTarget::removeEventListener(eventType, listener, useCapture)) 1993 return false; 1994 1995 // FIXME: Notify Document that the listener has vanished. We need to keep track of a number of 1996 // listeners for each type, not just a bool - see https://bugs.webkit.org/show_bug.cgi?id=33861 1997 Document& document = targetNode->document(); 1998 if (isTouchEventType(eventType)) 1999 document.didRemoveTouchEventHandler(targetNode); 2000 if (document.frameHost()) 2001 document.frameHost()->eventHandlerRegistry().didRemoveEventHandler(*targetNode, eventType); 2002 2003 return true; 2004 } 2005 2006 bool Node::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture) 2007 { 2008 return tryRemoveEventListener(this, eventType, listener, useCapture); 2009 } 2010 2011 void Node::removeAllEventListeners() 2012 { 2013 if (hasEventListeners() && document().frameHost()) 2014 document().frameHost()->eventHandlerRegistry().didRemoveAllEventHandlers(*this); 2015 EventTarget::removeAllEventListeners(); 2016 document().didClearTouchEventHandlers(this); 2017 } 2018 2019 void Node::removeAllEventListenersRecursively() 2020 { 2021 for (Node* node = this; node; node = NodeTraversal::next(*node)) { 2022 node->removeAllEventListeners(); 2023 for (ShadowRoot* root = node->youngestShadowRoot(); root; root = root->olderShadowRoot()) 2024 root->removeAllEventListenersRecursively(); 2025 } 2026 } 2027 2028 typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<Node>, OwnPtr<EventTargetData> > EventTargetDataMap; 2029 2030 static EventTargetDataMap& eventTargetDataMap() 2031 { 2032 #if ENABLE(OILPAN) 2033 DEFINE_STATIC_LOCAL(Persistent<EventTargetDataMap>, map, (new EventTargetDataMap())); 2034 return *map; 2035 #else 2036 DEFINE_STATIC_LOCAL(EventTargetDataMap, map, ()); 2037 return map; 2038 #endif 2039 } 2040 2041 EventTargetData* Node::eventTargetData() 2042 { 2043 return hasEventTargetData() ? eventTargetDataMap().get(this) : 0; 2044 } 2045 2046 EventTargetData& Node::ensureEventTargetData() 2047 { 2048 if (hasEventTargetData()) 2049 return *eventTargetDataMap().get(this); 2050 setHasEventTargetData(true); 2051 EventTargetData* data = new EventTargetData; 2052 eventTargetDataMap().set(this, adoptPtr(data)); 2053 return *data; 2054 } 2055 2056 #if !ENABLE(OILPAN) 2057 void Node::clearEventTargetData() 2058 { 2059 eventTargetDataMap().remove(this); 2060 } 2061 #endif 2062 2063 WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* Node::mutationObserverRegistry() 2064 { 2065 if (!hasRareData()) 2066 return 0; 2067 NodeMutationObserverData* data = rareData()->mutationObserverData(); 2068 if (!data) 2069 return 0; 2070 return &data->registry; 2071 } 2072 2073 WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* Node::transientMutationObserverRegistry() 2074 { 2075 if (!hasRareData()) 2076 return 0; 2077 NodeMutationObserverData* data = rareData()->mutationObserverData(); 2078 if (!data) 2079 return 0; 2080 return &data->transientRegistry; 2081 } 2082 2083 template<typename Registry> 2084 static inline void collectMatchingObserversForMutation(WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>& observers, Registry* registry, Node& target, MutationObserver::MutationType type, const QualifiedName* attributeName) 2085 { 2086 if (!registry) 2087 return; 2088 for (typename Registry::iterator iter = registry->begin(); iter != registry->end(); ++iter) { 2089 const MutationObserverRegistration& registration = **iter; 2090 if (registration.shouldReceiveMutationFrom(target, type, attributeName)) { 2091 MutationRecordDeliveryOptions deliveryOptions = registration.deliveryOptions(); 2092 WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>::AddResult result = observers.add(®istration.observer(), deliveryOptions); 2093 if (!result.isNewEntry) 2094 result.storedValue->value |= deliveryOptions; 2095 } 2096 } 2097 } 2098 2099 void Node::getRegisteredMutationObserversOfType(WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>& observers, MutationObserver::MutationType type, const QualifiedName* attributeName) 2100 { 2101 ASSERT((type == MutationObserver::Attributes && attributeName) || !attributeName); 2102 collectMatchingObserversForMutation(observers, mutationObserverRegistry(), *this, type, attributeName); 2103 collectMatchingObserversForMutation(observers, transientMutationObserverRegistry(), *this, type, attributeName); 2104 for (Node* node = parentNode(); node; node = node->parentNode()) { 2105 collectMatchingObserversForMutation(observers, node->mutationObserverRegistry(), *this, type, attributeName); 2106 collectMatchingObserversForMutation(observers, node->transientMutationObserverRegistry(), *this, type, attributeName); 2107 } 2108 } 2109 2110 void Node::registerMutationObserver(MutationObserver& observer, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter) 2111 { 2112 MutationObserverRegistration* registration = 0; 2113 WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >& registry = ensureRareData().ensureMutationObserverData().registry; 2114 for (size_t i = 0; i < registry.size(); ++i) { 2115 if (®istry[i]->observer() == &observer) { 2116 registration = registry[i].get(); 2117 registration->resetObservation(options, attributeFilter); 2118 } 2119 } 2120 2121 if (!registration) { 2122 registry.append(MutationObserverRegistration::create(observer, this, options, attributeFilter)); 2123 registration = registry.last().get(); 2124 } 2125 2126 document().addMutationObserverTypes(registration->mutationTypes()); 2127 } 2128 2129 void Node::unregisterMutationObserver(MutationObserverRegistration* registration) 2130 { 2131 WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* registry = mutationObserverRegistry(); 2132 ASSERT(registry); 2133 if (!registry) 2134 return; 2135 2136 size_t index = registry->find(registration); 2137 ASSERT(index != kNotFound); 2138 if (index == kNotFound) 2139 return; 2140 2141 // Deleting the registration may cause this node to be derefed, so we must make sure the Vector operation completes 2142 // before that, in case |this| is destroyed (see MutationObserverRegistration::m_registrationNodeKeepAlive). 2143 // FIXME: Simplify the registration/transient registration logic to make this understandable by humans. 2144 RefPtrWillBeRawPtr<Node> protect(this); 2145 #if ENABLE(OILPAN) 2146 // The explicit dispose() is needed to have the registration 2147 // object unregister itself promptly. 2148 registration->dispose(); 2149 #endif 2150 registry->remove(index); 2151 } 2152 2153 void Node::registerTransientMutationObserver(MutationObserverRegistration* registration) 2154 { 2155 ensureRareData().ensureMutationObserverData().transientRegistry.add(registration); 2156 } 2157 2158 void Node::unregisterTransientMutationObserver(MutationObserverRegistration* registration) 2159 { 2160 WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* transientRegistry = transientMutationObserverRegistry(); 2161 ASSERT(transientRegistry); 2162 if (!transientRegistry) 2163 return; 2164 2165 ASSERT(transientRegistry->contains(registration)); 2166 transientRegistry->remove(registration); 2167 } 2168 2169 void Node::notifyMutationObserversNodeWillDetach() 2170 { 2171 if (!document().hasMutationObservers()) 2172 return; 2173 2174 for (Node* node = parentNode(); node; node = node->parentNode()) { 2175 if (WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* registry = node->mutationObserverRegistry()) { 2176 const size_t size = registry->size(); 2177 for (size_t i = 0; i < size; ++i) 2178 registry->at(i)->observedSubtreeNodeWillDetach(*this); 2179 } 2180 2181 if (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* transientRegistry = node->transientMutationObserverRegistry()) { 2182 for (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter) 2183 (*iter)->observedSubtreeNodeWillDetach(*this); 2184 } 2185 } 2186 } 2187 2188 void Node::handleLocalEvents(Event* event) 2189 { 2190 if (!hasEventTargetData()) 2191 return; 2192 2193 if (isDisabledFormControl(this) && event->isMouseEvent()) 2194 return; 2195 2196 fireEventListeners(event); 2197 } 2198 2199 void Node::dispatchScopedEvent(PassRefPtrWillBeRawPtr<Event> event) 2200 { 2201 dispatchScopedEventDispatchMediator(EventDispatchMediator::create(event)); 2202 } 2203 2204 void Node::dispatchScopedEventDispatchMediator(PassRefPtrWillBeRawPtr<EventDispatchMediator> eventDispatchMediator) 2205 { 2206 EventDispatcher::dispatchScopedEvent(this, eventDispatchMediator); 2207 } 2208 2209 bool Node::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event) 2210 { 2211 if (event->isMouseEvent()) 2212 return EventDispatcher::dispatchEvent(this, MouseEventDispatchMediator::create(static_pointer_cast<MouseEvent>(event), MouseEventDispatchMediator::SyntheticMouseEvent)); 2213 if (event->isTouchEvent()) 2214 return dispatchTouchEvent(static_pointer_cast<TouchEvent>(event)); 2215 return EventDispatcher::dispatchEvent(this, EventDispatchMediator::create(event)); 2216 } 2217 2218 void Node::dispatchSubtreeModifiedEvent() 2219 { 2220 if (isInShadowTree()) 2221 return; 2222 2223 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); 2224 2225 if (!document().hasListenerType(Document::DOMSUBTREEMODIFIED_LISTENER)) 2226 return; 2227 2228 dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMSubtreeModified, true)); 2229 } 2230 2231 bool Node::dispatchDOMActivateEvent(int detail, PassRefPtrWillBeRawPtr<Event> underlyingEvent) 2232 { 2233 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); 2234 RefPtrWillBeRawPtr<UIEvent> event = UIEvent::create(EventTypeNames::DOMActivate, true, true, document().domWindow(), detail); 2235 event->setUnderlyingEvent(underlyingEvent); 2236 dispatchScopedEvent(event); 2237 return event->defaultHandled(); 2238 } 2239 2240 bool Node::dispatchKeyEvent(const PlatformKeyboardEvent& event) 2241 { 2242 return EventDispatcher::dispatchEvent(this, KeyboardEventDispatchMediator::create(KeyboardEvent::create(event, document().domWindow()))); 2243 } 2244 2245 bool Node::dispatchMouseEvent(const PlatformMouseEvent& event, const AtomicString& eventType, 2246 int detail, Node* relatedTarget) 2247 { 2248 return EventDispatcher::dispatchEvent(this, MouseEventDispatchMediator::create(MouseEvent::create(eventType, document().domWindow(), event, detail, relatedTarget))); 2249 } 2250 2251 bool Node::dispatchGestureEvent(const PlatformGestureEvent& event) 2252 { 2253 RefPtrWillBeRawPtr<GestureEvent> gestureEvent = GestureEvent::create(document().domWindow(), event); 2254 if (!gestureEvent.get()) 2255 return false; 2256 return EventDispatcher::dispatchEvent(this, GestureEventDispatchMediator::create(gestureEvent)); 2257 } 2258 2259 bool Node::dispatchTouchEvent(PassRefPtrWillBeRawPtr<TouchEvent> event) 2260 { 2261 return EventDispatcher::dispatchEvent(this, TouchEventDispatchMediator::create(event)); 2262 } 2263 2264 void Node::dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions eventOptions) 2265 { 2266 EventDispatcher::dispatchSimulatedClick(this, underlyingEvent, eventOptions); 2267 } 2268 2269 bool Node::dispatchWheelEvent(const PlatformWheelEvent& event) 2270 { 2271 return EventDispatcher::dispatchEvent(this, WheelEventDispatchMediator::create(event, document().domWindow())); 2272 } 2273 2274 void Node::dispatchInputEvent() 2275 { 2276 dispatchScopedEvent(Event::createBubble(EventTypeNames::input)); 2277 } 2278 2279 void Node::defaultEventHandler(Event* event) 2280 { 2281 if (event->target() != this) 2282 return; 2283 const AtomicString& eventType = event->type(); 2284 if (eventType == EventTypeNames::keydown || eventType == EventTypeNames::keypress) { 2285 if (event->isKeyboardEvent()) { 2286 if (LocalFrame* frame = document().frame()) 2287 frame->eventHandler().defaultKeyboardEventHandler(toKeyboardEvent(event)); 2288 } 2289 } else if (eventType == EventTypeNames::click) { 2290 int detail = event->isUIEvent() ? static_cast<UIEvent*>(event)->detail() : 0; 2291 if (dispatchDOMActivateEvent(detail, event)) 2292 event->setDefaultHandled(); 2293 } else if (eventType == EventTypeNames::contextmenu) { 2294 if (Page* page = document().page()) 2295 page->contextMenuController().handleContextMenuEvent(event); 2296 } else if (eventType == EventTypeNames::textInput) { 2297 if (event->hasInterface(EventNames::TextEvent)) { 2298 if (LocalFrame* frame = document().frame()) 2299 frame->eventHandler().defaultTextInputEventHandler(toTextEvent(event)); 2300 } 2301 #if OS(WIN) 2302 } else if (eventType == EventTypeNames::mousedown && event->isMouseEvent()) { 2303 MouseEvent* mouseEvent = toMouseEvent(event); 2304 if (mouseEvent->button() == MiddleButton) { 2305 if (enclosingLinkEventParentOrSelf()) 2306 return; 2307 2308 RenderObject* renderer = this->renderer(); 2309 while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeScrolledAndHasScrollableArea())) 2310 renderer = renderer->parent(); 2311 2312 if (renderer) { 2313 if (LocalFrame* frame = document().frame()) 2314 frame->eventHandler().startPanScrolling(renderer); 2315 } 2316 } 2317 #endif 2318 } else if ((eventType == EventTypeNames::wheel || eventType == EventTypeNames::mousewheel) && event->hasInterface(EventNames::WheelEvent)) { 2319 WheelEvent* wheelEvent = toWheelEvent(event); 2320 2321 // If we don't have a renderer, send the wheel event to the first node we find with a renderer. 2322 // This is needed for <option> and <optgroup> elements so that <select>s get a wheel scroll. 2323 Node* startNode = this; 2324 while (startNode && !startNode->renderer()) 2325 startNode = startNode->parentOrShadowHostNode(); 2326 2327 if (startNode && startNode->renderer()) { 2328 if (LocalFrame* frame = document().frame()) 2329 frame->eventHandler().defaultWheelEventHandler(startNode, wheelEvent); 2330 } 2331 } else if (event->type() == EventTypeNames::webkitEditableContentChanged) { 2332 dispatchInputEvent(); 2333 } 2334 } 2335 2336 void Node::willCallDefaultEventHandler(const Event&) 2337 { 2338 } 2339 2340 bool Node::willRespondToMouseMoveEvents() 2341 { 2342 if (isDisabledFormControl(this)) 2343 return false; 2344 return hasEventListeners(EventTypeNames::mousemove) || hasEventListeners(EventTypeNames::mouseover) || hasEventListeners(EventTypeNames::mouseout); 2345 } 2346 2347 bool Node::willRespondToMouseClickEvents() 2348 { 2349 if (isDisabledFormControl(this)) 2350 return false; 2351 return isContentEditable(UserSelectAllIsAlwaysNonEditable) || hasEventListeners(EventTypeNames::mouseup) || hasEventListeners(EventTypeNames::mousedown) || hasEventListeners(EventTypeNames::click) || hasEventListeners(EventTypeNames::DOMActivate); 2352 } 2353 2354 bool Node::willRespondToTouchEvents() 2355 { 2356 if (isDisabledFormControl(this)) 2357 return false; 2358 return hasEventListeners(EventTypeNames::touchstart) || hasEventListeners(EventTypeNames::touchmove) || hasEventListeners(EventTypeNames::touchcancel) || hasEventListeners(EventTypeNames::touchend); 2359 } 2360 2361 #if !ENABLE(OILPAN) 2362 // This is here for inlining 2363 inline void TreeScope::removedLastRefToScope() 2364 { 2365 ASSERT_WITH_SECURITY_IMPLICATION(!deletionHasBegun()); 2366 if (m_guardRefCount) { 2367 // If removing a child removes the last self-only ref, we don't 2368 // want the scope to be destructed until after 2369 // removeDetachedChildren returns, so we guard ourselves with an 2370 // extra self-only ref. 2371 guardRef(); 2372 dispose(); 2373 #if ASSERT_ENABLED 2374 // We need to do this right now since guardDeref() can delete this. 2375 rootNode().m_inRemovedLastRefFunction = false; 2376 #endif 2377 guardDeref(); 2378 } else { 2379 #if ASSERT_ENABLED 2380 rootNode().m_inRemovedLastRefFunction = false; 2381 #endif 2382 #if SECURITY_ASSERT_ENABLED 2383 beginDeletion(); 2384 #endif 2385 delete this; 2386 } 2387 } 2388 2389 // It's important not to inline removedLastRef, because we don't want to inline the code to 2390 // delete a Node at each deref call site. 2391 void Node::removedLastRef() 2392 { 2393 // An explicit check for Document here is better than a virtual function since it is 2394 // faster for non-Document nodes, and because the call to removedLastRef that is inlined 2395 // at all deref call sites is smaller if it's a non-virtual function. 2396 if (isTreeScope()) { 2397 treeScope().removedLastRefToScope(); 2398 return; 2399 } 2400 2401 #if SECURITY_ASSERT_ENABLED 2402 m_deletionHasBegun = true; 2403 #endif 2404 delete this; 2405 } 2406 #endif 2407 2408 unsigned Node::connectedSubframeCount() const 2409 { 2410 return hasRareData() ? rareData()->connectedSubframeCount() : 0; 2411 } 2412 2413 void Node::incrementConnectedSubframeCount(unsigned amount) 2414 { 2415 ASSERT(isContainerNode()); 2416 ensureRareData().incrementConnectedSubframeCount(amount); 2417 } 2418 2419 void Node::decrementConnectedSubframeCount(unsigned amount) 2420 { 2421 rareData()->decrementConnectedSubframeCount(amount); 2422 } 2423 2424 void Node::updateAncestorConnectedSubframeCountForRemoval() const 2425 { 2426 unsigned count = connectedSubframeCount(); 2427 2428 if (!count) 2429 return; 2430 2431 for (Node* node = parentOrShadowHostNode(); node; node = node->parentOrShadowHostNode()) 2432 node->decrementConnectedSubframeCount(count); 2433 } 2434 2435 void Node::updateAncestorConnectedSubframeCountForInsertion() const 2436 { 2437 unsigned count = connectedSubframeCount(); 2438 2439 if (!count) 2440 return; 2441 2442 for (Node* node = parentOrShadowHostNode(); node; node = node->parentOrShadowHostNode()) 2443 node->incrementConnectedSubframeCount(count); 2444 } 2445 2446 PassRefPtrWillBeRawPtr<StaticNodeList> Node::getDestinationInsertionPoints() 2447 { 2448 document().updateDistributionForNodeIfNeeded(this); 2449 WillBeHeapVector<RawPtrWillBeMember<InsertionPoint>, 8> insertionPoints; 2450 collectDestinationInsertionPoints(*this, insertionPoints); 2451 WillBeHeapVector<RefPtrWillBeMember<Node> > filteredInsertionPoints; 2452 for (size_t i = 0; i < insertionPoints.size(); ++i) { 2453 InsertionPoint* insertionPoint = insertionPoints[i]; 2454 ASSERT(insertionPoint->containingShadowRoot()); 2455 if (insertionPoint->containingShadowRoot()->type() != ShadowRoot::UserAgentShadowRoot) 2456 filteredInsertionPoints.append(insertionPoint); 2457 } 2458 return StaticNodeList::adopt(filteredInsertionPoints); 2459 } 2460 2461 void Node::setFocus(bool flag) 2462 { 2463 document().userActionElements().setFocused(this, flag); 2464 } 2465 2466 void Node::setActive(bool flag) 2467 { 2468 document().userActionElements().setActive(this, flag); 2469 } 2470 2471 void Node::setHovered(bool flag) 2472 { 2473 document().userActionElements().setHovered(this, flag); 2474 } 2475 2476 bool Node::isUserActionElementActive() const 2477 { 2478 ASSERT(isUserActionElement()); 2479 return document().userActionElements().isActive(this); 2480 } 2481 2482 bool Node::isUserActionElementInActiveChain() const 2483 { 2484 ASSERT(isUserActionElement()); 2485 return document().userActionElements().isInActiveChain(this); 2486 } 2487 2488 bool Node::isUserActionElementHovered() const 2489 { 2490 ASSERT(isUserActionElement()); 2491 return document().userActionElements().isHovered(this); 2492 } 2493 2494 bool Node::isUserActionElementFocused() const 2495 { 2496 ASSERT(isUserActionElement()); 2497 return document().userActionElements().isFocused(this); 2498 } 2499 2500 void Node::setCustomElementState(CustomElementState newState) 2501 { 2502 CustomElementState oldState = customElementState(); 2503 2504 switch (newState) { 2505 case NotCustomElement: 2506 ASSERT_NOT_REACHED(); // Everything starts in this state 2507 return; 2508 2509 case WaitingForUpgrade: 2510 ASSERT(NotCustomElement == oldState); 2511 break; 2512 2513 case Upgraded: 2514 ASSERT(WaitingForUpgrade == oldState); 2515 break; 2516 } 2517 2518 ASSERT(isHTMLElement() || isSVGElement()); 2519 setFlag(CustomElementFlag); 2520 setFlag(newState == Upgraded, CustomElementUpgradedFlag); 2521 2522 if (oldState == NotCustomElement || newState == Upgraded) 2523 setNeedsStyleRecalc(SubtreeStyleChange); // :unresolved has changed 2524 } 2525 2526 void Node::trace(Visitor* visitor) 2527 { 2528 visitor->trace(m_parentOrShadowHostNode); 2529 visitor->trace(m_previous); 2530 visitor->trace(m_next); 2531 if (hasRareData()) 2532 visitor->trace(rareData()); 2533 visitor->trace(m_treeScope); 2534 EventTarget::trace(visitor); 2535 } 2536 2537 unsigned Node::lengthOfContents() const 2538 { 2539 // This switch statement must be consistent with that of Range::processContentsBetweenOffsets. 2540 switch (nodeType()) { 2541 case Node::TEXT_NODE: 2542 case Node::CDATA_SECTION_NODE: 2543 case Node::COMMENT_NODE: 2544 return toCharacterData(this)->length(); 2545 case Node::PROCESSING_INSTRUCTION_NODE: 2546 return toProcessingInstruction(this)->data().length(); 2547 case Node::ELEMENT_NODE: 2548 case Node::ATTRIBUTE_NODE: 2549 case Node::DOCUMENT_NODE: 2550 case Node::DOCUMENT_FRAGMENT_NODE: 2551 return toContainerNode(this)->countChildren(); 2552 case Node::DOCUMENT_TYPE_NODE: 2553 return 0; 2554 } 2555 ASSERT_NOT_REACHED(); 2556 return 0; 2557 } 2558 2559 } // namespace WebCore 2560 2561 #ifndef NDEBUG 2562 2563 void showNode(const WebCore::Node* node) 2564 { 2565 if (node) 2566 node->showNode(""); 2567 } 2568 2569 void showTree(const WebCore::Node* node) 2570 { 2571 if (node) 2572 node->showTreeForThis(); 2573 } 2574 2575 void showNodePath(const WebCore::Node* node) 2576 { 2577 if (node) 2578 node->showNodePathForThis(); 2579 } 2580 2581 #endif 2582