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