2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
6 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
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.
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.
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.
26 #include "core/dom/Node.h"
28 #include "HTMLNames.h"
30 #include "bindings/v8/ExceptionState.h"
31 #include "bindings/v8/ScriptCallStackFactory.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/NodeRareData.h"
48 #include "core/dom/NodeRenderingTraversal.h"
49 #include "core/dom/NodeTraversal.h"
50 #include "core/dom/ProcessingInstruction.h"
51 #include "core/dom/Range.h"
52 #include "core/dom/StaticNodeList.h"
53 #include "core/dom/TemplateContentDocumentFragment.h"
54 #include "core/dom/Text.h"
55 #include "core/dom/TreeScopeAdopter.h"
56 #include "core/dom/UserActionElementSet.h"
57 #include "core/dom/WheelController.h"
58 #include "core/dom/shadow/ElementShadow.h"
59 #include "core/dom/shadow/InsertionPoint.h"
60 #include "core/dom/shadow/ShadowRoot.h"
61 #include "core/editing/htmlediting.h"
62 #include "core/editing/markup.h"
63 #include "core/events/Event.h"
64 #include "core/events/EventDispatchMediator.h"
65 #include "core/events/EventDispatcher.h"
66 #include "core/events/EventListener.h"
67 #include "core/events/GestureEvent.h"
68 #include "core/events/KeyboardEvent.h"
69 #include "core/events/MouseEvent.h"
70 #include "core/events/MutationEvent.h"
71 #include "core/events/TextEvent.h"
72 #include "core/events/TouchEvent.h"
73 #include "core/events/UIEvent.h"
74 #include "core/events/WheelEvent.h"
75 #include "core/frame/LocalFrame.h"
76 #include "core/html/HTMLAnchorElement.h"
77 #include "core/html/HTMLDialogElement.h"
78 #include "core/html/HTMLFrameOwnerElement.h"
79 #include "core/html/HTMLStyleElement.h"
80 #include "core/page/ContextMenuController.h"
81 #include "core/page/EventHandler.h"
82 #include "core/page/Page.h"
83 #include "core/frame/Settings.h"
84 #include "core/rendering/FlowThreadController.h"
85 #include "core/rendering/RenderBox.h"
86 #include "core/svg/graphics/SVGImage.h"
87 #include "platform/Partitions.h"
88 #include "wtf/HashSet.h"
89 #include "wtf/PassOwnPtr.h"
90 #include "wtf/RefCountedLeakCounter.h"
91 #include "wtf/Vector.h"
92 #include "wtf/text/CString.h"
93 #include "wtf/text/StringBuilder.h"
99 using namespace HTMLNames;
101 void* Node::operator new(size_t size)
103 ASSERT(isMainThread());
104 return partitionAlloc(Partitions::getObjectModelPartition(), size);
107 void Node::operator delete(void* ptr)
109 ASSERT(isMainThread());
113 #if DUMP_NODE_STATISTICS
114 static HashSet<Node*> liveNodeSet;
117 void Node::dumpStatistics()
119 #if DUMP_NODE_STATISTICS
120 size_t nodesWithRareData = 0;
122 size_t elementNodes = 0;
123 size_t attrNodes = 0;
124 size_t textNodes = 0;
125 size_t cdataNodes = 0;
126 size_t commentNodes = 0;
128 size_t documentNodes = 0;
129 size_t docTypeNodes = 0;
130 size_t fragmentNodes = 0;
131 size_t shadowRootNodes = 0;
133 HashMap<String, size_t> perTagCount;
135 size_t attributes = 0;
136 size_t attributesWithAttr = 0;
137 size_t elementsWithAttributeStorage = 0;
138 size_t elementsWithRareData = 0;
139 size_t elementsWithNamedNodeMap = 0;
141 for (HashSet<Node*>::iterator it = liveNodeSet.begin(); it != liveNodeSet.end(); ++it) {
144 if (node->hasRareData()) {
146 if (node->isElementNode()) {
147 ++elementsWithRareData;
148 if (toElement(node)->hasNamedNodeMap())
149 ++elementsWithNamedNodeMap;
153 switch (node->nodeType()) {
158 Element* element = toElement(node);
159 HashMap<String, size_t>::AddResult result = perTagCount.add(element->tagName(), 1);
160 if (!result.isNewEntry)
161 result.storedValue->value++;
163 if (ElementData* elementData = element->elementData()) {
164 attributes += elementData->length();
165 ++elementsWithAttributeStorage;
166 for (unsigned i = 0; i < elementData->length(); ++i) {
167 Attribute* attr = elementData->attributeItem(i);
169 ++attributesWithAttr;
174 case ATTRIBUTE_NODE: {
182 case CDATA_SECTION_NODE: {
190 case PROCESSING_INSTRUCTION_NODE: {
194 case DOCUMENT_NODE: {
198 case DOCUMENT_TYPE_NODE: {
202 case DOCUMENT_FRAGMENT_NODE: {
203 if (node->isShadowRoot())
212 printf("Number of Nodes: %d\n\n", liveNodeSet.size());
213 printf("Number of Nodes with RareData: %zu\n\n", nodesWithRareData);
215 printf("NodeType distribution:\n");
216 printf(" Number of Element nodes: %zu\n", elementNodes);
217 printf(" Number of Attribute nodes: %zu\n", attrNodes);
218 printf(" Number of Text nodes: %zu\n", textNodes);
219 printf(" Number of CDATASection nodes: %zu\n", cdataNodes);
220 printf(" Number of Comment nodes: %zu\n", commentNodes);
221 printf(" Number of ProcessingInstruction nodes: %zu\n", piNodes);
222 printf(" Number of Document nodes: %zu\n", documentNodes);
223 printf(" Number of DocumentType nodes: %zu\n", docTypeNodes);
224 printf(" Number of DocumentFragment nodes: %zu\n", fragmentNodes);
225 printf(" Number of ShadowRoot nodes: %zu\n", shadowRootNodes);
227 printf("Element tag name distibution:\n");
228 for (HashMap<String, size_t>::iterator it = perTagCount.begin(); it != perTagCount.end(); ++it)
229 printf(" Number of <%s> tags: %zu\n", it->key.utf8().data(), it->value);
231 printf("Attributes:\n");
232 printf(" Number of Attributes (non-Node and Node): %zu [%zu]\n", attributes, sizeof(Attribute));
233 printf(" Number of Attributes with an Attr: %zu\n", attributesWithAttr);
234 printf(" Number of Elements with attribute storage: %zu [%zu]\n", elementsWithAttributeStorage, sizeof(ElementData));
235 printf(" Number of Elements with RareData: %zu\n", elementsWithRareData);
236 printf(" Number of Elements with NamedNodeMap: %zu [%zu]\n", elementsWithNamedNodeMap, sizeof(NamedNodeMap));
240 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, nodeCounter, ("WebCoreNode"));
242 void Node::trackForDebugging()
245 nodeCounter.increment();
248 #if DUMP_NODE_STATISTICS
249 liveNodeSet.add(this);
256 nodeCounter.decrement();
259 #if DUMP_NODE_STATISTICS
260 liveNodeSet.remove(this);
266 RELEASE_ASSERT(!renderer());
268 if (!isContainerNode())
269 willBeDeletedFromDocument();
272 m_previous->setNextSibling(0);
274 m_next->setPreviousSibling(0);
277 m_treeScope->guardDeref();
279 InspectorCounters::decrementCounter(InspectorCounters::NodeCounter);
282 void Node::willBeDeletedFromDocument()
284 if (!isTreeScopeInitialized())
287 Document& document = this->document();
289 if (hasEventTargetData()) {
290 clearEventTargetData();
291 document.didClearTouchEventHandlers(this);
294 if (AXObjectCache* cache = document.existingAXObjectCache())
297 document.markers().removeMarkers(this);
300 NodeRareData* Node::rareData() const
302 ASSERT_WITH_SECURITY_IMPLICATION(hasRareData());
303 return static_cast<NodeRareData*>(m_data.m_rareData);
306 NodeRareData& Node::ensureRareData()
313 data = ElementRareData::create(m_data.m_renderer).leakPtr();
315 data = NodeRareData::create(m_data.m_renderer).leakPtr();
318 m_data.m_rareData = data;
319 setFlag(HasRareDataFlag);
323 void Node::clearRareData()
325 ASSERT(hasRareData());
326 ASSERT(!transientMutationObserverRegistry() || transientMutationObserverRegistry()->isEmpty());
328 RenderObject* renderer = m_data.m_rareData->renderer();
330 delete static_cast<ElementRareData*>(m_data.m_rareData);
332 delete static_cast<NodeRareData*>(m_data.m_rareData);
333 m_data.m_renderer = renderer;
334 clearFlag(HasRareDataFlag);
342 short Node::tabIndex() const
347 String Node::nodeValue() const
352 void Node::setNodeValue(const String&)
354 // By default, setting nodeValue has no effect.
357 PassRefPtr<NodeList> Node::childNodes()
359 if (isContainerNode())
360 return ensureRareData().ensureNodeLists().ensureChildNodeList(toContainerNode(*this));
361 return ensureRareData().ensureNodeLists().ensureEmptyChildNodeList(*this);
364 Node& Node::lastDescendant() const
366 Node* n = const_cast<Node*>(this);
367 while (n && n->lastChild())
373 Node* Node::pseudoAwarePreviousSibling() const
375 if (parentElement() && !previousSibling()) {
376 Element* parent = parentElement();
377 if (isAfterPseudoElement() && parent->lastChild())
378 return parent->lastChild();
379 if (!isBeforePseudoElement())
380 return parent->pseudoElement(BEFORE);
382 return previousSibling();
385 Node* Node::pseudoAwareNextSibling() const
387 if (parentElement() && !nextSibling()) {
388 Element* parent = parentElement();
389 if (isBeforePseudoElement() && parent->firstChild())
390 return parent->firstChild();
391 if (!isAfterPseudoElement())
392 return parent->pseudoElement(AFTER);
394 return nextSibling();
397 Node* Node::pseudoAwareFirstChild() const
399 if (isElementNode()) {
400 const Element* currentElement = toElement(this);
401 Node* first = currentElement->pseudoElement(BEFORE);
404 first = currentElement->firstChild();
406 first = currentElement->pseudoElement(AFTER);
413 Node* Node::pseudoAwareLastChild() const
415 if (isElementNode()) {
416 const Element* currentElement = toElement(this);
417 Node* last = currentElement->pseudoElement(AFTER);
420 last = currentElement->lastChild();
422 last = currentElement->pseudoElement(BEFORE);
429 void Node::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& exceptionState)
431 if (isContainerNode())
432 toContainerNode(this)->insertBefore(newChild, refChild, exceptionState);
434 exceptionState.throwDOMException(HierarchyRequestError, "This node type does not support this method.");
437 void Node::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& exceptionState)
439 if (isContainerNode())
440 toContainerNode(this)->replaceChild(newChild, oldChild, exceptionState);
442 exceptionState.throwDOMException(HierarchyRequestError, "This node type does not support this method.");
445 void Node::removeChild(Node* oldChild, ExceptionState& exceptionState)
447 if (isContainerNode())
448 toContainerNode(this)->removeChild(oldChild, exceptionState);
450 exceptionState.throwDOMException(NotFoundError, "This node type does not support this method.");
453 void Node::appendChild(PassRefPtr<Node> newChild, ExceptionState& exceptionState)
455 if (isContainerNode())
456 toContainerNode(this)->appendChild(newChild, exceptionState);
458 exceptionState.throwDOMException(HierarchyRequestError, "This node type does not support this method.");
461 void Node::remove(ExceptionState& exceptionState)
463 if (ContainerNode* parent = parentNode())
464 parent->removeChild(this, exceptionState);
467 void Node::normalize()
469 // Go through the subtree beneath us, normalizing all nodes. This means that
470 // any two adjacent text nodes are merged and any empty text nodes are removed.
472 RefPtr<Node> node = this;
473 while (Node* firstChild = node->firstChild())
476 NodeType type = node->nodeType();
477 if (type == ELEMENT_NODE)
478 toElement(node)->normalizeAttributes();
483 if (type == TEXT_NODE)
484 node = toText(node)->mergeNextSiblingNodesIfPossible();
486 node = NodeTraversal::nextPostOrder(*node);
490 const AtomicString& Node::localName() const
495 const AtomicString& Node::namespaceURI() const
500 bool Node::isContentEditable(UserSelectAllTreatment treatment)
502 document().updateRenderTreeIfNeeded();
503 return rendererIsEditable(Editable, treatment);
506 bool Node::isContentRichlyEditable()
508 document().updateRenderTreeIfNeeded();
509 return rendererIsEditable(RichlyEditable, UserSelectAllIsAlwaysNonEditable);
512 bool Node::rendererIsEditable(EditableLevel editableLevel, UserSelectAllTreatment treatment) const
514 if (isPseudoElement())
517 // Ideally we'd call ASSERT(!needsStyleRecalc()) here, but
518 // ContainerNode::setFocus() calls setNeedsStyleRecalc(), so the assertion
519 // would fire in the middle of Document::setFocusedNode().
521 for (const Node* node = this; node; node = node->parentNode()) {
522 if ((node->isHTMLElement() || node->isDocumentNode()) && node->renderer()) {
523 // Elements with user-select: all style are considered atomic
524 // therefore non editable.
525 if (Position::nodeIsUserSelectAll(node) && treatment == UserSelectAllIsAlwaysNonEditable)
527 switch (node->renderer()->style()->userModify()) {
532 case READ_WRITE_PLAINTEXT_ONLY:
533 return editableLevel != RichlyEditable;
535 ASSERT_NOT_REACHED();
543 bool Node::isEditableToAccessibility(EditableLevel editableLevel) const
545 if (rendererIsEditable(editableLevel))
548 // FIXME: Respect editableLevel for ARIA editable elements.
549 if (editableLevel == RichlyEditable)
552 ASSERT(AXObjectCache::accessibilityEnabled());
553 ASSERT(document().existingAXObjectCache());
555 if (AXObjectCache* cache = document().existingAXObjectCache())
556 return cache->rootAXEditableElement(this);
561 bool Node::shouldUseInputMethod()
563 return isContentEditable(UserSelectAllIsAlwaysNonEditable);
566 RenderBox* Node::renderBox() const
568 RenderObject* renderer = this->renderer();
569 return renderer && renderer->isBox() ? toRenderBox(renderer) : 0;
572 RenderBoxModelObject* Node::renderBoxModelObject() const
574 RenderObject* renderer = this->renderer();
575 return renderer && renderer->isBoxModelObject() ? toRenderBoxModelObject(renderer) : 0;
578 LayoutRect Node::boundingBox() const
581 return renderer()->absoluteBoundingBoxRect();
585 bool Node::hasNonEmptyBoundingBox() const
587 // Before calling absoluteRects, check for the common case where the renderer
588 // is non-empty, since this is a faster check and almost always returns true.
589 RenderBoxModelObject* box = renderBoxModelObject();
592 if (!box->borderBoundingBox().isEmpty())
595 Vector<IntRect> rects;
596 FloatPoint absPos = renderer()->localToAbsolute();
597 renderer()->absoluteRects(rects, flooredLayoutPoint(absPos));
598 size_t n = rects.size();
599 for (size_t i = 0; i < n; ++i)
600 if (!rects[i].isEmpty())
607 inline static ShadowRoot* oldestShadowRootFor(const Node* node)
609 if (!node->isElementNode())
611 if (ElementShadow* shadow = toElement(node)->shadow())
612 return shadow->oldestShadowRoot();
617 void Node::recalcDistribution()
619 if (isElementNode()) {
620 if (ElementShadow* shadow = toElement(this)->shadow())
621 shadow->distributeIfNeeded();
624 for (Node* child = firstChild(); child; child = child->nextSibling()) {
625 if (child->childNeedsDistributionRecalc())
626 child->recalcDistribution();
629 for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
630 if (root->childNeedsDistributionRecalc())
631 root->recalcDistribution();
634 clearChildNeedsDistributionRecalc();
637 void Node::setIsLink(bool isLink)
639 setFlag(isLink && !SVGImage::isInSVGImage(toElement(this)), IsLinkFlag);
642 void Node::setNeedsStyleInvalidation()
644 setFlag(NeedsStyleInvalidation);
645 markAncestorsWithChildNeedsStyleInvalidation();
648 void Node::markAncestorsWithChildNeedsStyleInvalidation()
650 for (Node* node = parentOrShadowHostNode(); node && !node->childNeedsStyleInvalidation(); node = node->parentOrShadowHostNode())
651 node->setChildNeedsStyleInvalidation();
652 if (document().childNeedsStyleInvalidation())
653 document().scheduleRenderTreeUpdate();
656 void Node::markAncestorsWithChildNeedsDistributionRecalc()
658 for (Node* node = this; node && !node->childNeedsDistributionRecalc(); node = node->parentOrShadowHostNode())
659 node->setChildNeedsDistributionRecalc();
660 if (document().childNeedsDistributionRecalc())
661 document().scheduleRenderTreeUpdate();
666 unsigned styledSubtreeSize(const Node*);
668 unsigned styledSubtreeSizeIgnoringSelfAndShadowRoots(const Node* rootNode)
670 unsigned nodeCount = 0;
671 for (Node* child = rootNode->firstChild(); child; child = child->nextSibling())
672 nodeCount += styledSubtreeSize(child);
676 unsigned styledSubtreeSize(const Node* rootNode)
678 if (rootNode->isTextNode())
680 if (!rootNode->isElementNode())
683 // FIXME: We should use a shadow-tree aware node-iterator when such exists.
684 unsigned nodeCount = 1 + styledSubtreeSizeIgnoringSelfAndShadowRoots(rootNode);
686 // ShadowRoots don't have style (so don't count them), but their children might.
687 for (ShadowRoot* shadowRoot = rootNode->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot())
688 nodeCount += styledSubtreeSizeIgnoringSelfAndShadowRoots(shadowRoot);
693 PassRefPtr<JSONArray> jsStackAsJSONArray()
695 RefPtr<JSONArray> jsonArray = JSONArray::create();
696 RefPtr<ScriptCallStack> stack = createScriptCallStack(10);
698 return jsonArray.release();
699 for (size_t i = 0; i < stack->size(); i++)
700 jsonArray->pushString(stack->at(i).functionName());
701 return jsonArray.release();
704 PassRefPtr<JSONObject> jsonObjectForStyleInvalidation(unsigned nodeCount, const Node* rootNode)
706 RefPtr<JSONObject> jsonObject = JSONObject::create();
707 jsonObject->setNumber("node_count", nodeCount);
708 jsonObject->setString("root_node", rootNode->debugName());
709 jsonObject->setArray("js_stack", jsStackAsJSONArray());
710 return jsonObject.release();
713 } // anonymous namespace'd functions supporting traceStyleChange
715 void Node::traceStyleChange(StyleChangeType changeType)
717 static const unsigned kMinLoggedSize = 100;
718 unsigned nodeCount = styledSubtreeSize(this);
719 if (nodeCount < kMinLoggedSize)
722 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("style.debug"),
723 "Node::setNeedsStyleRecalc",
724 "data", jsonObjectForStyleInvalidation(nodeCount, this)->toJSONString().ascii()
728 void Node::traceStyleChangeIfNeeded(StyleChangeType changeType)
730 // TRACE_EVENT_CATEGORY_GROUP_ENABLED macro loads a global static bool into our local bool.
731 bool styleTracingEnabled;
732 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("style.debug"), &styleTracingEnabled);
733 if (UNLIKELY(styleTracingEnabled))
734 traceStyleChange(changeType);
737 inline void Node::setStyleChange(StyleChangeType changeType)
739 m_nodeFlags = (m_nodeFlags & ~StyleChangeMask) | changeType;
742 void Node::markAncestorsWithChildNeedsStyleRecalc()
744 for (ContainerNode* p = parentOrShadowHostNode(); p && !p->childNeedsStyleRecalc(); p = p->parentOrShadowHostNode())
745 p->setChildNeedsStyleRecalc();
747 if (document().needsStyleRecalc() || document().childNeedsStyleRecalc())
748 document().scheduleRenderTreeUpdate();
751 void Node::setNeedsStyleRecalc(StyleChangeType changeType)
753 ASSERT(changeType != NoStyleChange);
754 if (!inActiveDocument())
757 StyleChangeType existingChangeType = styleChangeType();
758 if (changeType > existingChangeType) {
759 setStyleChange(changeType);
760 if (changeType >= SubtreeStyleChange)
761 traceStyleChangeIfNeeded(changeType);
764 if (existingChangeType == NoStyleChange)
765 markAncestorsWithChildNeedsStyleRecalc();
767 if (isElementNode() && hasRareData())
768 toElement(*this).setAnimationStyleChange(false);
771 void Node::clearNeedsStyleRecalc()
773 m_nodeFlags &= ~StyleChangeMask;
775 clearNeedsLayerUpdate();
777 if (isElementNode() && hasRareData())
778 toElement(*this).setAnimationStyleChange(false);
781 bool Node::inActiveDocument() const
783 return inDocument() && document().isActive();
786 Node* Node::focusDelegate()
791 bool Node::shouldHaveFocusAppearance() const
797 bool Node::isInert() const
799 const HTMLDialogElement* dialog = document().activeModalDialog();
800 if (dialog && this != document() && !NodeRenderingTraversal::contains(dialog, this))
802 return document().ownerElement() && document().ownerElement()->isInert();
805 unsigned Node::nodeIndex() const
807 Node *_tempNode = previousSibling();
809 for ( count=0; _tempNode; count++ )
810 _tempNode = _tempNode->previousSibling();
814 void Node::invalidateNodeListCachesInAncestors(const QualifiedName* attrName, Element* attributeOwnerElement)
816 if (hasRareData() && (!attrName || isAttributeNode())) {
817 if (NodeListsNodeData* lists = rareData()->nodeLists())
818 lists->clearChildNodeListCache();
821 // Modifications to attributes that are not associated with an Element can't invalidate NodeList caches.
822 if (attrName && !attributeOwnerElement)
825 if (!document().shouldInvalidateNodeListCaches(attrName))
828 document().invalidateNodeListCaches(attrName);
830 for (Node* node = this; node; node = node->parentNode()) {
831 if (NodeListsNodeData* lists = node->nodeLists())
832 lists->invalidateCaches(attrName);
836 NodeListsNodeData* Node::nodeLists()
838 return hasRareData() ? rareData()->nodeLists() : 0;
841 void Node::clearNodeLists()
843 rareData()->clearNodeLists();
846 bool Node::isDescendantOf(const Node *other) const
848 // Return true if other is an ancestor of this, otherwise false
849 if (!other || !other->hasChildren() || inDocument() != other->inDocument())
851 if (other->treeScope() != treeScope())
853 if (other->isTreeScope())
854 return !isTreeScope();
855 for (const ContainerNode* n = parentNode(); n; n = n->parentNode()) {
862 bool Node::contains(const Node* node) const
866 return this == node || node->isDescendantOf(this);
869 bool Node::containsIncludingShadowDOM(const Node* node) const
877 if (document() != node->document())
880 if (inDocument() != node->inDocument())
883 bool hasChildren = isContainerNode() && toContainerNode(this)->hasChildren();
884 bool hasShadow = isElementNode() && toElement(this)->shadow();
885 if (!hasChildren && !hasShadow)
888 for (; node; node = node->shadowHost()) {
889 if (treeScope() == node->treeScope())
890 return contains(node);
896 bool Node::containsIncludingHostElements(const Node& node) const
898 const Node* current = &node;
902 if (current->isDocumentFragment() && toDocumentFragment(current)->isTemplateContent())
903 current = static_cast<const TemplateContentDocumentFragment*>(current)->host();
905 current = current->parentOrShadowHostNode();
910 Node* Node::commonAncestor(const Node& other, Node* (*parent)(const Node&))
914 if (document() != other.document())
917 for (Node* node = this; node; node = parent(*node)) {
923 for (const Node* node = &other; node; node = parent(*node)) {
928 Node* thisIterator = this;
929 const Node* otherIterator = &other;
930 if (thisDepth > otherDepth) {
931 for (int i = thisDepth; i > otherDepth; --i)
932 thisIterator = parent(*thisIterator);
933 } else if (otherDepth > thisDepth) {
934 for (int i = otherDepth; i > thisDepth; --i)
935 otherIterator = parent(*otherIterator);
937 while (thisIterator) {
938 if (thisIterator == otherIterator)
940 thisIterator = parent(*thisIterator);
941 otherIterator = parent(*otherIterator);
943 ASSERT(!otherIterator);
947 void Node::reattach(const AttachContext& context)
949 AttachContext reattachContext(context);
950 reattachContext.performingReattach = true;
952 // We only need to detach if the node has already been through attach().
953 if (styleChangeType() < NeedsReattachStyleChange)
954 detach(reattachContext);
955 attach(reattachContext);
958 void Node::attach(const AttachContext&)
960 ASSERT(document().inStyleRecalc() || isDocumentNode());
961 ASSERT(needsAttach());
962 ASSERT(!renderer() || (renderer()->style() && (renderer()->parent() || renderer()->isRenderView())));
964 clearNeedsStyleRecalc();
966 if (AXObjectCache* cache = document().axObjectCache())
967 cache->updateCacheAfterNodeIsAttached(this);
971 static Node* detachingNode;
973 bool Node::inDetach() const
975 return detachingNode == this;
979 void Node::detach(const AttachContext& context)
982 ASSERT(!detachingNode);
983 detachingNode = this;
987 renderer()->destroyAndCleanupAnonymousWrappers();
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()) {
996 doc.hoveredNodeDetached(this);
998 doc.activeChainNodeDetached(this);
999 doc.userActionElements().didDetach(this);
1003 setStyleChange(NeedsReattachStyleChange);
1004 setChildNeedsStyleRecalc();
1006 if (StyleResolver* resolver = document().styleResolver())
1007 resolver->ruleFeatureSet().clearStyleInvalidation(this);
1014 void Node::reattachWhitespaceSiblings(Text* start)
1016 for (Node* sibling = start; sibling; sibling = sibling->nextSibling()) {
1017 if (sibling->isTextNode() && toText(sibling)->containsOnlyWhitespace()) {
1018 bool hadRenderer = sibling->hasRenderer();
1019 sibling->reattach();
1020 // If the reattach didn't toggle the visibility of the whitespace we don't
1021 // need to continue reattaching siblings since they won't toggle visibility
1023 if (hadRenderer == sibling->hasRenderer())
1025 } else if (sibling->renderer()) {
1031 // FIXME: This code is used by editing. Seems like it could move over there and not pollute Node.
1032 Node *Node::previousNodeConsideringAtomicNodes() const
1034 if (previousSibling()) {
1035 Node *n = previousSibling();
1036 while (!isAtomicNode(n) && n->lastChild())
1040 else if (parentNode()) {
1041 return parentNode();
1048 Node *Node::nextNodeConsideringAtomicNodes() const
1050 if (!isAtomicNode(this) && firstChild())
1051 return firstChild();
1053 return nextSibling();
1054 const Node *n = this;
1055 while (n && !n->nextSibling())
1056 n = n->parentNode();
1058 return n->nextSibling();
1062 Node *Node::previousLeafNode() const
1064 Node *node = previousNodeConsideringAtomicNodes();
1066 if (isAtomicNode(node))
1068 node = node->previousNodeConsideringAtomicNodes();
1073 Node *Node::nextLeafNode() const
1075 Node *node = nextNodeConsideringAtomicNodes();
1077 if (isAtomicNode(node))
1079 node = node->nextNodeConsideringAtomicNodes();
1084 RenderStyle* Node::virtualComputedStyle(PseudoId pseudoElementSpecifier)
1086 return parentOrShadowHostNode() ? parentOrShadowHostNode()->computedStyle(pseudoElementSpecifier) : 0;
1089 int Node::maxCharacterOffset() const
1091 ASSERT_NOT_REACHED();
1095 // FIXME: Shouldn't these functions be in the editing code? Code that asks questions about HTML in the core DOM class
1096 // is obviously misplaced.
1097 bool Node::canStartSelection() const
1099 if (rendererIsEditable())
1103 RenderStyle* style = renderer()->style();
1104 // We allow selections to begin within an element that has -webkit-user-select: none set,
1105 // but if the element is draggable then dragging should take priority over selection.
1106 if (style->userDrag() == DRAG_ELEMENT && style->userSelect() == SELECT_NONE)
1109 return parentOrShadowHostNode() ? parentOrShadowHostNode()->canStartSelection() : true;
1112 Element* Node::shadowHost() const
1114 if (ShadowRoot* root = containingShadowRoot())
1115 return root->host();
1119 Node* Node::deprecatedShadowAncestorNode() const
1121 if (ShadowRoot* root = containingShadowRoot())
1122 return root->host();
1124 return const_cast<Node*>(this);
1127 ShadowRoot* Node::containingShadowRoot() const
1129 Node& root = treeScope().rootNode();
1130 return root.isShadowRoot() ? toShadowRoot(&root) : 0;
1133 Node* Node::nonBoundaryShadowTreeRootNode()
1135 ASSERT(!isShadowRoot());
1138 if (root->isShadowRoot())
1140 Node* parent = root->parentOrShadowHostNode();
1141 if (parent && parent->isShadowRoot())
1148 ContainerNode* Node::nonShadowBoundaryParentNode() const
1150 ContainerNode* parent = parentNode();
1151 return parent && !parent->isShadowRoot() ? parent : 0;
1154 Element* Node::parentOrShadowHostElement() const
1156 ContainerNode* parent = parentOrShadowHostNode();
1160 if (parent->isShadowRoot())
1161 return toShadowRoot(parent)->host();
1163 if (!parent->isElementNode())
1166 return toElement(parent);
1169 ContainerNode* Node::parentOrShadowHostOrTemplateHostNode() const
1171 if (isDocumentFragment() && toDocumentFragment(this)->isTemplateContent())
1172 return static_cast<const TemplateContentDocumentFragment*>(this)->host();
1173 return parentOrShadowHostNode();
1176 bool Node::isBlockFlowElement() const
1178 return isElementNode() && renderer() && renderer()->isRenderBlockFlow();
1181 Element *Node::enclosingBlockFlowElement() const
1183 Node *n = const_cast<Node *>(this);
1184 if (isBlockFlowElement())
1185 return toElement(n);
1188 n = n->parentNode();
1191 if (n->isBlockFlowElement() || isHTMLBodyElement(*n))
1192 return toElement(n);
1197 bool Node::isRootEditableElement() const
1199 return rendererIsEditable() && isElementNode() && (!parentNode() || !parentNode()->rendererIsEditable()
1200 || !parentNode()->isElementNode() || isHTMLBodyElement((*this)));
1203 Element* Node::rootEditableElement(EditableType editableType) const
1205 if (editableType == HasEditableAXRole) {
1206 if (AXObjectCache* cache = document().existingAXObjectCache())
1207 return const_cast<Element*>(cache->rootAXEditableElement(this));
1210 return rootEditableElement();
1213 Element* Node::rootEditableElement() const
1215 Element* result = 0;
1216 for (Node* n = const_cast<Node*>(this); n && n->rendererIsEditable(); n = n->parentNode()) {
1217 if (n->isElementNode())
1218 result = toElement(n);
1219 if (isHTMLBodyElement(*n))
1225 bool Node::inSameContainingBlockFlowElement(Node *n)
1227 return n ? enclosingBlockFlowElement() == n->enclosingBlockFlowElement() : false;
1230 // FIXME: End of obviously misplaced HTML editing functions. Try to move these out of Node.
1232 Document* Node::ownerDocument() const
1234 Document* doc = &document();
1235 return doc == this ? 0 : doc;
1238 KURL Node::baseURI() const
1240 return parentNode() ? parentNode()->baseURI() : KURL();
1243 bool Node::isEqualNode(Node* other) const
1248 NodeType nodeType = this->nodeType();
1249 if (nodeType != other->nodeType())
1252 if (nodeName() != other->nodeName())
1255 if (localName() != other->localName())
1258 if (namespaceURI() != other->namespaceURI())
1261 if (nodeValue() != other->nodeValue())
1264 if (isElementNode() && !toElement(this)->hasEquivalentAttributes(toElement(other)))
1267 Node* child = firstChild();
1268 Node* otherChild = other->firstChild();
1271 if (!child->isEqualNode(otherChild))
1274 child = child->nextSibling();
1275 otherChild = otherChild->nextSibling();
1281 if (isDocumentTypeNode()) {
1282 const DocumentType* documentTypeThis = toDocumentType(this);
1283 const DocumentType* documentTypeOther = toDocumentType(other);
1285 if (documentTypeThis->publicId() != documentTypeOther->publicId())
1288 if (documentTypeThis->systemId() != documentTypeOther->systemId())
1291 if (documentTypeThis->internalSubset() != documentTypeOther->internalSubset())
1298 bool Node::isDefaultNamespace(const AtomicString& namespaceURIMaybeEmpty) const
1300 const AtomicString& namespaceURI = namespaceURIMaybeEmpty.isEmpty() ? nullAtom : namespaceURIMaybeEmpty;
1302 switch (nodeType()) {
1303 case ELEMENT_NODE: {
1304 const Element* elem = toElement(this);
1306 if (elem->prefix().isNull())
1307 return elem->namespaceURI() == namespaceURI;
1309 if (elem->hasAttributes()) {
1310 unsigned attributeCount = elem->attributeCount();
1311 for (unsigned i = 0; i < attributeCount; ++i) {
1312 const Attribute& attr = elem->attributeItem(i);
1314 if (attr.localName() == xmlnsAtom)
1315 return attr.value() == namespaceURI;
1319 if (Element* parent = parentElement())
1320 return parent->isDefaultNamespace(namespaceURI);
1325 if (Element* de = toDocument(this)->documentElement())
1326 return de->isDefaultNamespace(namespaceURI);
1328 case DOCUMENT_TYPE_NODE:
1329 case DOCUMENT_FRAGMENT_NODE:
1331 case ATTRIBUTE_NODE: {
1332 const Attr* attr = toAttr(this);
1333 if (attr->ownerElement())
1334 return attr->ownerElement()->isDefaultNamespace(namespaceURI);
1338 if (Element* parent = parentElement())
1339 return parent->isDefaultNamespace(namespaceURI);
1344 const AtomicString& Node::lookupPrefix(const AtomicString& namespaceURI) const
1346 // Implemented according to
1347 // http://dom.spec.whatwg.org/#dom-node-lookupprefix
1349 if (namespaceURI.isEmpty() || namespaceURI.isNull())
1352 const Element* context;
1354 switch (nodeType()) {
1356 context = toElement(this);
1359 context = toDocument(this)->documentElement();
1361 case DOCUMENT_FRAGMENT_NODE:
1362 case DOCUMENT_TYPE_NODE:
1365 // FIXME: Remove this when Attr no longer extends Node (CR305105)
1366 case ATTRIBUTE_NODE:
1367 context = toAttr(this)->ownerElement();
1370 context = parentElement();
1377 return context->locateNamespacePrefix(namespaceURI);
1380 const AtomicString& Node::lookupNamespaceURI(const String& prefix) const
1382 // Implemented according to
1383 // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#lookupNamespaceURIAlgo
1385 if (!prefix.isNull() && prefix.isEmpty())
1388 switch (nodeType()) {
1389 case ELEMENT_NODE: {
1390 const Element *elem = toElement(this);
1392 if (!elem->namespaceURI().isNull() && elem->prefix() == prefix)
1393 return elem->namespaceURI();
1395 if (elem->hasAttributes()) {
1396 unsigned attributeCount = elem->attributeCount();
1397 for (unsigned i = 0; i < attributeCount; ++i) {
1398 const Attribute& attr = elem->attributeItem(i);
1400 if (attr.prefix() == xmlnsAtom && attr.localName() == prefix) {
1401 if (!attr.value().isEmpty())
1402 return attr.value();
1406 if (attr.localName() == xmlnsAtom && prefix.isNull()) {
1407 if (!attr.value().isEmpty())
1408 return attr.value();
1414 if (Element* parent = parentElement())
1415 return parent->lookupNamespaceURI(prefix);
1419 if (Element* de = toDocument(this)->documentElement())
1420 return de->lookupNamespaceURI(prefix);
1422 case DOCUMENT_TYPE_NODE:
1423 case DOCUMENT_FRAGMENT_NODE:
1425 case ATTRIBUTE_NODE: {
1426 const Attr *attr = toAttr(this);
1427 if (attr->ownerElement())
1428 return attr->ownerElement()->lookupNamespaceURI(prefix);
1433 if (Element* parent = parentElement())
1434 return parent->lookupNamespaceURI(prefix);
1439 static void appendTextContent(const Node* node, bool convertBRsToNewlines, bool& isNullString, StringBuilder& content)
1441 switch (node->nodeType()) {
1442 case Node::TEXT_NODE:
1443 case Node::CDATA_SECTION_NODE:
1444 case Node::COMMENT_NODE:
1445 isNullString = false;
1446 content.append(toCharacterData(node)->data());
1449 case Node::PROCESSING_INSTRUCTION_NODE:
1450 isNullString = false;
1451 content.append(toProcessingInstruction(node)->data());
1454 case Node::ELEMENT_NODE:
1455 if (isHTMLBRElement(*node) && convertBRsToNewlines) {
1456 isNullString = false;
1457 content.append('\n');
1461 case Node::ATTRIBUTE_NODE:
1462 case Node::DOCUMENT_FRAGMENT_NODE:
1463 isNullString = false;
1464 for (Node* child = node->firstChild(); child; child = child->nextSibling()) {
1465 if (child->nodeType() == Node::COMMENT_NODE || child->nodeType() == Node::PROCESSING_INSTRUCTION_NODE)
1467 appendTextContent(child, convertBRsToNewlines, isNullString, content);
1471 case Node::DOCUMENT_NODE:
1472 case Node::DOCUMENT_TYPE_NODE:
1477 String Node::textContent(bool convertBRsToNewlines) const
1479 StringBuilder content;
1480 bool isNullString = true;
1481 appendTextContent(this, convertBRsToNewlines, isNullString, content);
1482 return isNullString ? String() : content.toString();
1485 void Node::setTextContent(const String& text)
1487 switch (nodeType()) {
1489 case CDATA_SECTION_NODE:
1491 case PROCESSING_INSTRUCTION_NODE:
1495 case ATTRIBUTE_NODE:
1496 case DOCUMENT_FRAGMENT_NODE: {
1497 // FIXME: Merge this logic into replaceChildrenWithText.
1498 RefPtr<ContainerNode> container = toContainerNode(this);
1499 // No need to do anything if the text is identical.
1500 if (container->hasOneTextChild() && toText(container->firstChild())->data() == text)
1502 ChildListMutationScope mutation(*this);
1503 container->removeChildren();
1504 // Note: This API will not insert empty text nodes:
1505 // http://dom.spec.whatwg.org/#dom-node-textcontent
1506 if (!text.isEmpty())
1507 container->appendChild(document().createTextNode(text), ASSERT_NO_EXCEPTION);
1511 case DOCUMENT_TYPE_NODE:
1515 ASSERT_NOT_REACHED();
1518 bool Node::offsetInCharacters() const
1523 unsigned short Node::compareDocumentPosition(const Node* otherNode) const
1525 return compareDocumentPositionInternal(otherNode, TreatShadowTreesAsDisconnected);
1528 unsigned short Node::compareDocumentPositionInternal(const Node* otherNode, ShadowTreesTreatment treatment) const
1530 // It is not clear what should be done if |otherNode| is 0.
1532 return DOCUMENT_POSITION_DISCONNECTED;
1534 if (otherNode == this)
1535 return DOCUMENT_POSITION_EQUIVALENT;
1537 const Attr* attr1 = nodeType() == ATTRIBUTE_NODE ? toAttr(this) : 0;
1538 const Attr* attr2 = otherNode->nodeType() == ATTRIBUTE_NODE ? toAttr(otherNode) : 0;
1540 const Node* start1 = attr1 ? attr1->ownerElement() : this;
1541 const Node* start2 = attr2 ? attr2->ownerElement() : otherNode;
1543 // If either of start1 or start2 is null, then we are disconnected, since one of the nodes is
1544 // an orphaned attribute node.
1545 if (!start1 || !start2) {
1546 unsigned short direction = (this > otherNode) ? DOCUMENT_POSITION_PRECEDING : DOCUMENT_POSITION_FOLLOWING;
1547 return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | direction;
1550 Vector<const Node*, 16> chain1;
1551 Vector<const Node*, 16> chain2;
1553 chain1.append(attr1);
1555 chain2.append(attr2);
1557 if (attr1 && attr2 && start1 == start2 && start1) {
1558 // We are comparing two attributes on the same node. Crawl our attribute map and see which one we hit first.
1559 const Element* owner1 = attr1->ownerElement();
1560 owner1->synchronizeAllAttributes();
1561 unsigned length = owner1->attributeCount();
1562 for (unsigned i = 0; i < length; ++i) {
1563 // If neither of the two determining nodes is a child node and nodeType is the same for both determining nodes, then an
1564 // implementation-dependent order between the determining nodes is returned. This order is stable as long as no nodes of
1565 // the same nodeType are inserted into or removed from the direct container. This would be the case, for example,
1566 // when comparing two attributes of the same element, and inserting or removing additional attributes might change
1567 // the order between existing attributes.
1568 const Attribute& attribute = owner1->attributeItem(i);
1569 if (attr1->qualifiedName() == attribute.name())
1570 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_FOLLOWING;
1571 if (attr2->qualifiedName() == attribute.name())
1572 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_PRECEDING;
1575 ASSERT_NOT_REACHED();
1576 return DOCUMENT_POSITION_DISCONNECTED;
1579 // If one node is in the document and the other is not, we must be disconnected.
1580 // If the nodes have different owning documents, they must be disconnected. Note that we avoid
1581 // comparing Attr nodes here, since they return false from inDocument() all the time (which seems like a bug).
1582 if (start1->inDocument() != start2->inDocument() || (treatment == TreatShadowTreesAsDisconnected && start1->treeScope() != start2->treeScope())) {
1583 unsigned short direction = (this > otherNode) ? DOCUMENT_POSITION_PRECEDING : DOCUMENT_POSITION_FOLLOWING;
1584 return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | direction;
1587 // We need to find a common ancestor container, and then compare the indices of the two immediate children.
1588 const Node* current;
1589 for (current = start1; current; current = current->parentOrShadowHostNode())
1590 chain1.append(current);
1591 for (current = start2; current; current = current->parentOrShadowHostNode())
1592 chain2.append(current);
1594 unsigned index1 = chain1.size();
1595 unsigned index2 = chain2.size();
1597 // If the two elements don't have a common root, they're not in the same tree.
1598 if (chain1[index1 - 1] != chain2[index2 - 1]) {
1599 unsigned short direction = (this > otherNode) ? DOCUMENT_POSITION_PRECEDING : DOCUMENT_POSITION_FOLLOWING;
1600 return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | direction;
1603 unsigned connection = start1->treeScope() != start2->treeScope() ? DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC : 0;
1605 // Walk the two chains backwards and look for the first difference.
1606 for (unsigned i = min(index1, index2); i; --i) {
1607 const Node* child1 = chain1[--index1];
1608 const Node* child2 = chain2[--index2];
1609 if (child1 != child2) {
1610 // If one of the children is an attribute, it wins.
1611 if (child1->nodeType() == ATTRIBUTE_NODE)
1612 return DOCUMENT_POSITION_FOLLOWING | connection;
1613 if (child2->nodeType() == ATTRIBUTE_NODE)
1614 return DOCUMENT_POSITION_PRECEDING | connection;
1616 // If one of the children is a shadow root,
1617 if (child1->isShadowRoot() || child2->isShadowRoot()) {
1618 if (!child2->isShadowRoot())
1619 return Node::DOCUMENT_POSITION_FOLLOWING | connection;
1620 if (!child1->isShadowRoot())
1621 return Node::DOCUMENT_POSITION_PRECEDING | connection;
1623 for (ShadowRoot* child = toShadowRoot(child2)->olderShadowRoot(); child; child = child->olderShadowRoot())
1624 if (child == child1)
1625 return Node::DOCUMENT_POSITION_FOLLOWING | connection;
1627 return Node::DOCUMENT_POSITION_PRECEDING | connection;
1630 if (!child2->nextSibling())
1631 return DOCUMENT_POSITION_FOLLOWING | connection;
1632 if (!child1->nextSibling())
1633 return DOCUMENT_POSITION_PRECEDING | connection;
1635 // Otherwise we need to see which node occurs first. Crawl backwards from child2 looking for child1.
1636 for (Node* child = child2->previousSibling(); child; child = child->previousSibling()) {
1637 if (child == child1)
1638 return DOCUMENT_POSITION_FOLLOWING | connection;
1640 return DOCUMENT_POSITION_PRECEDING | connection;
1644 // There was no difference between the two parent chains, i.e., one was a subset of the other. The shorter
1645 // chain is the ancestor.
1646 return index1 < index2 ?
1647 DOCUMENT_POSITION_FOLLOWING | DOCUMENT_POSITION_CONTAINED_BY | connection :
1648 DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_CONTAINS | connection;
1651 FloatPoint Node::convertToPage(const FloatPoint& p) const
1653 // If there is a renderer, just ask it to do the conversion
1655 return renderer()->localToAbsolute(p, UseTransforms);
1657 // Otherwise go up the tree looking for a renderer
1658 if (Element* parent = parentElement())
1659 return parent->convertToPage(p);
1661 // No parent - no conversion needed
1665 FloatPoint Node::convertFromPage(const FloatPoint& p) const
1667 // If there is a renderer, just ask it to do the conversion
1669 return renderer()->absoluteToLocal(p, UseTransforms);
1671 // Otherwise go up the tree looking for a renderer
1672 if (Element* parent = parentElement())
1673 return parent->convertFromPage(p);
1675 // No parent - no conversion needed
1679 String Node::debugName() const
1682 name.append(nodeName());
1685 name.appendLiteral(" id=\'");
1686 name.append(toElement(this)->getIdAttribute());
1691 name.appendLiteral(" class=\'");
1692 for (size_t i = 0; i < toElement(this)->classNames().size(); ++i) {
1695 name.append(toElement(this)->classNames()[i]);
1700 return name.toString();
1705 static void appendAttributeDesc(const Node* node, StringBuilder& stringBuilder, const QualifiedName& name, const char* attrDesc)
1707 if (!node->isElementNode())
1710 String attr = toElement(node)->getAttribute(name);
1714 stringBuilder.append(attrDesc);
1715 stringBuilder.append("=\"");
1716 stringBuilder.append(attr);
1717 stringBuilder.append("\"");
1720 void Node::showNode(const char* prefix) const
1725 String value = nodeValue();
1726 value.replaceWithLiteral('\\', "\\\\");
1727 value.replaceWithLiteral('\n', "\\n");
1728 fprintf(stderr, "%s%s\t%p \"%s\"\n", prefix, nodeName().utf8().data(), this, value.utf8().data());
1730 StringBuilder attrs;
1731 appendAttributeDesc(this, attrs, idAttr, " ID");
1732 appendAttributeDesc(this, attrs, classAttr, " CLASS");
1733 appendAttributeDesc(this, attrs, styleAttr, " STYLE");
1734 fprintf(stderr, "%s%s\t%p%s\n", prefix, nodeName().utf8().data(), this, attrs.toString().utf8().data());
1738 void Node::showTreeForThis() const
1740 showTreeAndMark(this, "*");
1743 void Node::showNodePathForThis() const
1745 Vector<const Node*, 16> chain;
1746 const Node* node = this;
1747 while (node->parentOrShadowHostNode()) {
1749 node = node->parentOrShadowHostNode();
1751 for (unsigned index = chain.size(); index > 0; --index) {
1752 const Node* node = chain[index - 1];
1753 if (node->isShadowRoot()) {
1755 for (ShadowRoot* shadowRoot = toShadowRoot(node)->olderShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot())
1757 fprintf(stderr, "/#shadow-root[%d]", count);
1761 switch (node->nodeType()) {
1762 case ELEMENT_NODE: {
1763 fprintf(stderr, "/%s", node->nodeName().utf8().data());
1765 const Element* element = toElement(node);
1766 const AtomicString& idattr = element->getIdAttribute();
1767 bool hasIdAttr = !idattr.isNull() && !idattr.isEmpty();
1768 if (node->previousSibling() || node->nextSibling()) {
1770 for (Node* previous = node->previousSibling(); previous; previous = previous->previousSibling())
1771 if (previous->nodeName() == node->nodeName())
1774 fprintf(stderr, "[@id=\"%s\" and position()=%d]", idattr.utf8().data(), count);
1776 fprintf(stderr, "[%d]", count);
1777 } else if (hasIdAttr) {
1778 fprintf(stderr, "[@id=\"%s\"]", idattr.utf8().data());
1783 fprintf(stderr, "/text()");
1785 case ATTRIBUTE_NODE:
1786 fprintf(stderr, "/@%s", node->nodeName().utf8().data());
1792 fprintf(stderr, "\n");
1795 static void traverseTreeAndMark(const String& baseIndent, const Node* rootNode, const Node* markedNode1, const char* markedLabel1, const Node* markedNode2, const char* markedLabel2)
1797 for (const Node* node = rootNode; node; node = NodeTraversal::next(*node)) {
1798 if (node == markedNode1)
1799 fprintf(stderr, "%s", markedLabel1);
1800 if (node == markedNode2)
1801 fprintf(stderr, "%s", markedLabel2);
1803 StringBuilder indent;
1804 indent.append(baseIndent);
1805 for (const Node* tmpNode = node; tmpNode && tmpNode != rootNode; tmpNode = tmpNode->parentOrShadowHostNode())
1806 indent.append('\t');
1807 fprintf(stderr, "%s", indent.toString().utf8().data());
1809 indent.append('\t');
1810 if (node->isShadowRoot()) {
1811 if (ShadowRoot* youngerShadowRoot = toShadowRoot(node)->youngerShadowRoot())
1812 traverseTreeAndMark(indent.toString(), youngerShadowRoot, markedNode1, markedLabel1, markedNode2, markedLabel2);
1813 } else if (ShadowRoot* oldestShadowRoot = oldestShadowRootFor(node))
1814 traverseTreeAndMark(indent.toString(), oldestShadowRoot, markedNode1, markedLabel1, markedNode2, markedLabel2);
1818 void Node::showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2, const char* markedLabel2) const
1820 const Node* rootNode;
1821 const Node* node = this;
1822 while (node->parentOrShadowHostNode() && !isHTMLBodyElement(*node))
1823 node = node->parentOrShadowHostNode();
1826 String startingIndent;
1827 traverseTreeAndMark(startingIndent, rootNode, markedNode1, markedLabel1, markedNode2, markedLabel2);
1830 void Node::formatForDebugger(char* buffer, unsigned length) const
1841 strncpy(buffer, result.utf8().data(), length - 1);
1844 static ContainerNode* parentOrShadowHostOrFrameOwner(const Node* node)
1846 ContainerNode* parent = node->parentOrShadowHostNode();
1847 if (!parent && node->document().frame())
1848 parent = node->document().frame()->ownerElement();
1852 static void showSubTreeAcrossFrame(const Node* node, const Node* markedNode, const String& indent)
1854 if (node == markedNode)
1856 fputs(indent.utf8().data(), stderr);
1858 if (node->isShadowRoot()) {
1859 if (ShadowRoot* youngerShadowRoot = toShadowRoot(node)->youngerShadowRoot())
1860 showSubTreeAcrossFrame(youngerShadowRoot, markedNode, indent + "\t");
1862 if (node->isFrameOwnerElement())
1863 showSubTreeAcrossFrame(toHTMLFrameOwnerElement(node)->contentDocument(), markedNode, indent + "\t");
1864 if (ShadowRoot* oldestShadowRoot = oldestShadowRootFor(node))
1865 showSubTreeAcrossFrame(oldestShadowRoot, markedNode, indent + "\t");
1867 for (Node* child = node->firstChild(); child; child = child->nextSibling())
1868 showSubTreeAcrossFrame(child, markedNode, indent + "\t");
1871 void Node::showTreeForThisAcrossFrame() const
1873 Node* rootNode = const_cast<Node*>(this);
1874 while (parentOrShadowHostOrFrameOwner(rootNode))
1875 rootNode = parentOrShadowHostOrFrameOwner(rootNode);
1876 showSubTreeAcrossFrame(rootNode, this, "");
1883 Node* Node::enclosingLinkEventParentOrSelf()
1885 for (Node* node = this; node; node = node->parentOrShadowHostNode()) {
1886 // For imagemaps, the enclosing link node is the associated area element not the image itself.
1887 // So we don't let images be the enclosingLinkNode, even though isLink sometimes returns true
1889 if (node->isLink() && !isHTMLImageElement(*node))
1896 const AtomicString& Node::interfaceName() const
1898 return EventTargetNames::Node;
1901 ExecutionContext* Node::executionContext() const
1903 return document().contextDocument().get();
1906 void Node::didMoveToNewDocument(Document& oldDocument)
1908 TreeScopeAdopter::ensureDidMoveToNewDocumentWasCalled(oldDocument);
1910 if (const EventTargetData* eventTargetData = this->eventTargetData()) {
1911 const EventListenerMap& listenerMap = eventTargetData->eventListenerMap;
1912 if (!listenerMap.isEmpty()) {
1913 Vector<AtomicString> types = listenerMap.eventTypes();
1914 for (unsigned i = 0; i < types.size(); ++i)
1915 document().addListenerTypeIfNeeded(types[i]);
1919 if (AXObjectCache::accessibilityEnabled()) {
1920 if (AXObjectCache* cache = oldDocument.existingAXObjectCache())
1921 cache->remove(this);
1924 const EventListenerVector& mousewheelListeners = getEventListeners(EventTypeNames::mousewheel);
1925 WheelController* oldController = WheelController::from(oldDocument);
1926 WheelController* newController = WheelController::from(document());
1927 for (size_t i = 0; i < mousewheelListeners.size(); ++i) {
1928 oldController->didRemoveWheelEventHandler(oldDocument);
1929 newController->didAddWheelEventHandler(document());
1932 const EventListenerVector& wheelListeners = getEventListeners(EventTypeNames::wheel);
1933 for (size_t i = 0; i < wheelListeners.size(); ++i) {
1934 oldController->didRemoveWheelEventHandler(oldDocument);
1935 newController->didAddWheelEventHandler(document());
1938 if (const TouchEventTargetSet* touchHandlers = oldDocument.touchEventTargets()) {
1939 while (touchHandlers->contains(this)) {
1940 oldDocument.didRemoveTouchEventHandler(this);
1941 document().didAddTouchEventHandler(this);
1945 if (Vector<OwnPtr<MutationObserverRegistration> >* registry = mutationObserverRegistry()) {
1946 for (size_t i = 0; i < registry->size(); ++i) {
1947 document().addMutationObserverTypes(registry->at(i)->mutationTypes());
1951 if (HashSet<MutationObserverRegistration*>* transientRegistry = transientMutationObserverRegistry()) {
1952 for (HashSet<MutationObserverRegistration*>::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter) {
1953 document().addMutationObserverTypes((*iter)->mutationTypes());
1958 static inline bool tryAddEventListener(Node* targetNode, const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
1960 if (!targetNode->EventTarget::addEventListener(eventType, listener, useCapture))
1963 Document& document = targetNode->document();
1964 document.addListenerTypeIfNeeded(eventType);
1965 if (eventType == EventTypeNames::wheel || eventType == EventTypeNames::mousewheel)
1966 WheelController::from(document)->didAddWheelEventHandler(document);
1967 else if (isTouchEventType(eventType))
1968 document.didAddTouchEventHandler(targetNode);
1973 bool Node::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
1975 return tryAddEventListener(this, eventType, listener, useCapture);
1978 static inline bool tryRemoveEventListener(Node* targetNode, const AtomicString& eventType, EventListener* listener, bool useCapture)
1980 if (!targetNode->EventTarget::removeEventListener(eventType, listener, useCapture))
1983 // FIXME: Notify Document that the listener has vanished. We need to keep track of a number of
1984 // listeners for each type, not just a bool - see https://bugs.webkit.org/show_bug.cgi?id=33861
1985 Document& document = targetNode->document();
1986 if (eventType == EventTypeNames::wheel || eventType == EventTypeNames::mousewheel)
1987 WheelController::from(document)->didRemoveWheelEventHandler(document);
1988 else if (isTouchEventType(eventType))
1989 document.didRemoveTouchEventHandler(targetNode);
1994 bool Node::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
1996 return tryRemoveEventListener(this, eventType, listener, useCapture);
1999 void Node::removeAllEventListeners()
2001 EventTarget::removeAllEventListeners();
2002 document().didClearTouchEventHandlers(this);
2005 typedef HashMap<Node*, OwnPtr<EventTargetData> > EventTargetDataMap;
2007 static EventTargetDataMap& eventTargetDataMap()
2009 DEFINE_STATIC_LOCAL(EventTargetDataMap, map, ());
2013 EventTargetData* Node::eventTargetData()
2015 return hasEventTargetData() ? eventTargetDataMap().get(this) : 0;
2018 EventTargetData& Node::ensureEventTargetData()
2020 if (hasEventTargetData())
2021 return *eventTargetDataMap().get(this);
2022 setHasEventTargetData(true);
2023 EventTargetData* data = new EventTargetData;
2024 eventTargetDataMap().set(this, adoptPtr(data));
2028 void Node::clearEventTargetData()
2030 eventTargetDataMap().remove(this);
2033 Vector<OwnPtr<MutationObserverRegistration> >* Node::mutationObserverRegistry()
2037 NodeMutationObserverData* data = rareData()->mutationObserverData();
2040 return &data->registry;
2043 HashSet<MutationObserverRegistration*>* Node::transientMutationObserverRegistry()
2047 NodeMutationObserverData* data = rareData()->mutationObserverData();
2050 return &data->transientRegistry;
2053 template<typename Registry>
2054 static inline void collectMatchingObserversForMutation(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, Registry* registry, Node& target, MutationObserver::MutationType type, const QualifiedName* attributeName)
2058 for (typename Registry::iterator iter = registry->begin(); iter != registry->end(); ++iter) {
2059 const MutationObserverRegistration& registration = **iter;
2060 if (registration.shouldReceiveMutationFrom(target, type, attributeName)) {
2061 MutationRecordDeliveryOptions deliveryOptions = registration.deliveryOptions();
2062 HashMap<MutationObserver*, MutationRecordDeliveryOptions>::AddResult result = observers.add(®istration.observer(), deliveryOptions);
2063 if (!result.isNewEntry)
2064 result.storedValue->value |= deliveryOptions;
2069 void Node::getRegisteredMutationObserversOfType(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, MutationObserver::MutationType type, const QualifiedName* attributeName)
2071 ASSERT((type == MutationObserver::Attributes && attributeName) || !attributeName);
2072 collectMatchingObserversForMutation(observers, mutationObserverRegistry(), *this, type, attributeName);
2073 collectMatchingObserversForMutation(observers, transientMutationObserverRegistry(), *this, type, attributeName);
2074 for (Node* node = parentNode(); node; node = node->parentNode()) {
2075 collectMatchingObserversForMutation(observers, node->mutationObserverRegistry(), *this, type, attributeName);
2076 collectMatchingObserversForMutation(observers, node->transientMutationObserverRegistry(), *this, type, attributeName);
2080 void Node::registerMutationObserver(MutationObserver& observer, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
2082 MutationObserverRegistration* registration = 0;
2083 Vector<OwnPtr<MutationObserverRegistration> >& registry = ensureRareData().ensureMutationObserverData().registry;
2084 for (size_t i = 0; i < registry.size(); ++i) {
2085 if (®istry[i]->observer() == &observer) {
2086 registration = registry[i].get();
2087 registration->resetObservation(options, attributeFilter);
2091 if (!registration) {
2092 registry.append(MutationObserverRegistration::create(observer, *this, options, attributeFilter));
2093 registration = registry.last().get();
2096 document().addMutationObserverTypes(registration->mutationTypes());
2099 void Node::unregisterMutationObserver(MutationObserverRegistration* registration)
2101 Vector<OwnPtr<MutationObserverRegistration> >* registry = mutationObserverRegistry();
2106 size_t index = registry->find(registration);
2107 ASSERT(index != kNotFound);
2108 if (index == kNotFound)
2111 // Deleting the registration may cause this node to be derefed, so we must make sure the Vector operation completes
2112 // before that, in case |this| is destroyed (see MutationObserverRegistration::m_registrationNodeKeepAlive).
2113 // FIXME: Simplify the registration/transient registration logic to make this understandable by humans.
2114 RefPtr<Node> protect(this);
2115 registry->remove(index);
2118 void Node::registerTransientMutationObserver(MutationObserverRegistration* registration)
2120 ensureRareData().ensureMutationObserverData().transientRegistry.add(registration);
2123 void Node::unregisterTransientMutationObserver(MutationObserverRegistration* registration)
2125 HashSet<MutationObserverRegistration*>* transientRegistry = transientMutationObserverRegistry();
2126 ASSERT(transientRegistry);
2127 if (!transientRegistry)
2130 ASSERT(transientRegistry->contains(registration));
2131 transientRegistry->remove(registration);
2134 void Node::notifyMutationObserversNodeWillDetach()
2136 if (!document().hasMutationObservers())
2139 for (Node* node = parentNode(); node; node = node->parentNode()) {
2140 if (Vector<OwnPtr<MutationObserverRegistration> >* registry = node->mutationObserverRegistry()) {
2141 const size_t size = registry->size();
2142 for (size_t i = 0; i < size; ++i)
2143 registry->at(i)->observedSubtreeNodeWillDetach(*this);
2146 if (HashSet<MutationObserverRegistration*>* transientRegistry = node->transientMutationObserverRegistry()) {
2147 for (HashSet<MutationObserverRegistration*>::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter)
2148 (*iter)->observedSubtreeNodeWillDetach(*this);
2153 void Node::handleLocalEvents(Event* event)
2155 if (!hasEventTargetData())
2158 if (isDisabledFormControl(this) && event->isMouseEvent())
2161 fireEventListeners(event);
2164 void Node::dispatchScopedEvent(PassRefPtr<Event> event)
2166 dispatchScopedEventDispatchMediator(EventDispatchMediator::create(event));
2169 void Node::dispatchScopedEventDispatchMediator(PassRefPtr<EventDispatchMediator> eventDispatchMediator)
2171 EventDispatcher::dispatchScopedEvent(this, eventDispatchMediator);
2174 bool Node::dispatchEvent(PassRefPtr<Event> event)
2176 if (event->isMouseEvent())
2177 return EventDispatcher::dispatchEvent(this, MouseEventDispatchMediator::create(static_pointer_cast<MouseEvent>(event), MouseEventDispatchMediator::SyntheticMouseEvent));
2178 if (event->isTouchEvent())
2179 return dispatchTouchEvent(static_pointer_cast<TouchEvent>(event));
2180 return EventDispatcher::dispatchEvent(this, EventDispatchMediator::create(event));
2183 void Node::dispatchSubtreeModifiedEvent()
2185 if (isInShadowTree())
2188 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
2190 if (!document().hasListenerType(Document::DOMSUBTREEMODIFIED_LISTENER))
2193 dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMSubtreeModified, true));
2196 bool Node::dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEvent)
2198 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
2199 RefPtr<UIEvent> event = UIEvent::create(EventTypeNames::DOMActivate, true, true, document().domWindow(), detail);
2200 event->setUnderlyingEvent(underlyingEvent);
2201 dispatchScopedEvent(event);
2202 return event->defaultHandled();
2205 bool Node::dispatchKeyEvent(const PlatformKeyboardEvent& event)
2207 return EventDispatcher::dispatchEvent(this, KeyboardEventDispatchMediator::create(KeyboardEvent::create(event, document().domWindow())));
2210 bool Node::dispatchMouseEvent(const PlatformMouseEvent& event, const AtomicString& eventType,
2211 int detail, Node* relatedTarget)
2213 return EventDispatcher::dispatchEvent(this, MouseEventDispatchMediator::create(MouseEvent::create(eventType, document().domWindow(), event, detail, relatedTarget)));
2216 bool Node::dispatchGestureEvent(const PlatformGestureEvent& event)
2218 RefPtr<GestureEvent> gestureEvent = GestureEvent::create(document().domWindow(), event);
2219 if (!gestureEvent.get())
2221 return EventDispatcher::dispatchEvent(this, GestureEventDispatchMediator::create(gestureEvent));
2224 bool Node::dispatchTouchEvent(PassRefPtr<TouchEvent> event)
2226 return EventDispatcher::dispatchEvent(this, TouchEventDispatchMediator::create(event));
2229 void Node::dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions eventOptions)
2231 EventDispatcher::dispatchSimulatedClick(this, underlyingEvent, eventOptions);
2234 bool Node::dispatchWheelEvent(const PlatformWheelEvent& event)
2236 return EventDispatcher::dispatchEvent(this, WheelEventDispatchMediator::create(event, document().domWindow()));
2239 void Node::dispatchInputEvent()
2241 dispatchScopedEvent(Event::createBubble(EventTypeNames::input));
2244 void Node::defaultEventHandler(Event* event)
2246 if (event->target() != this)
2248 const AtomicString& eventType = event->type();
2249 if (eventType == EventTypeNames::keydown || eventType == EventTypeNames::keypress) {
2250 if (event->isKeyboardEvent()) {
2251 if (LocalFrame* frame = document().frame())
2252 frame->eventHandler().defaultKeyboardEventHandler(toKeyboardEvent(event));
2254 } else if (eventType == EventTypeNames::click) {
2255 int detail = event->isUIEvent() ? static_cast<UIEvent*>(event)->detail() : 0;
2256 if (dispatchDOMActivateEvent(detail, event))
2257 event->setDefaultHandled();
2258 } else if (eventType == EventTypeNames::contextmenu) {
2259 if (Page* page = document().page())
2260 page->contextMenuController().handleContextMenuEvent(event);
2261 } else if (eventType == EventTypeNames::textInput) {
2262 if (event->hasInterface(EventNames::TextEvent)) {
2263 if (LocalFrame* frame = document().frame())
2264 frame->eventHandler().defaultTextInputEventHandler(toTextEvent(event));
2267 } else if (eventType == EventTypeNames::mousedown && event->isMouseEvent()) {
2268 MouseEvent* mouseEvent = toMouseEvent(event);
2269 if (mouseEvent->button() == MiddleButton) {
2270 if (enclosingLinkEventParentOrSelf())
2273 RenderObject* renderer = this->renderer();
2274 while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeScrolledAndHasScrollableArea()))
2275 renderer = renderer->parent();
2278 if (LocalFrame* frame = document().frame())
2279 frame->eventHandler().startPanScrolling(renderer);
2283 } else if ((eventType == EventTypeNames::wheel || eventType == EventTypeNames::mousewheel) && event->hasInterface(EventNames::WheelEvent)) {
2284 WheelEvent* wheelEvent = toWheelEvent(event);
2286 // If we don't have a renderer, send the wheel event to the first node we find with a renderer.
2287 // This is needed for <option> and <optgroup> elements so that <select>s get a wheel scroll.
2288 Node* startNode = this;
2289 while (startNode && !startNode->renderer())
2290 startNode = startNode->parentOrShadowHostNode();
2292 if (startNode && startNode->renderer()) {
2293 if (LocalFrame* frame = document().frame())
2294 frame->eventHandler().defaultWheelEventHandler(startNode, wheelEvent);
2296 } else if (event->type() == EventTypeNames::webkitEditableContentChanged) {
2297 dispatchInputEvent();
2301 void Node::willCallDefaultEventHandler(const Event&)
2305 bool Node::willRespondToMouseMoveEvents()
2307 if (isDisabledFormControl(this))
2309 return hasEventListeners(EventTypeNames::mousemove) || hasEventListeners(EventTypeNames::mouseover) || hasEventListeners(EventTypeNames::mouseout);
2312 bool Node::willRespondToMouseClickEvents()
2314 if (isDisabledFormControl(this))
2316 return isContentEditable(UserSelectAllIsAlwaysNonEditable) || hasEventListeners(EventTypeNames::mouseup) || hasEventListeners(EventTypeNames::mousedown) || hasEventListeners(EventTypeNames::click) || hasEventListeners(EventTypeNames::DOMActivate);
2319 bool Node::willRespondToTouchEvents()
2321 if (isDisabledFormControl(this))
2323 return hasEventListeners(EventTypeNames::touchstart) || hasEventListeners(EventTypeNames::touchmove) || hasEventListeners(EventTypeNames::touchcancel) || hasEventListeners(EventTypeNames::touchend);
2326 // This is here for inlining
2327 inline void TreeScope::removedLastRefToScope()
2329 ASSERT_WITH_SECURITY_IMPLICATION(!deletionHasBegun());
2330 if (m_guardRefCount) {
2331 // If removing a child removes the last self-only ref, we don't
2332 // want the scope to be destructed until after
2333 // removeDetachedChildren returns, so we guard ourselves with an
2334 // extra self-only ref.
2337 #if !ASSERT_DISABLED
2338 // We need to do this right now since guardDeref() can delete this.
2339 rootNode().m_inRemovedLastRefFunction = false;
2343 #if !ASSERT_DISABLED
2344 rootNode().m_inRemovedLastRefFunction = false;
2346 #if SECURITY_ASSERT_ENABLED
2353 // It's important not to inline removedLastRef, because we don't want to inline the code to
2354 // delete a Node at each deref call site.
2355 void Node::removedLastRef()
2357 // An explicit check for Document here is better than a virtual function since it is
2358 // faster for non-Document nodes, and because the call to removedLastRef that is inlined
2359 // at all deref call sites is smaller if it's a non-virtual function.
2360 if (isTreeScope()) {
2361 treeScope().removedLastRefToScope();
2365 #if SECURITY_ASSERT_ENABLED
2366 m_deletionHasBegun = true;
2371 unsigned Node::connectedSubframeCount() const
2373 return hasRareData() ? rareData()->connectedSubframeCount() : 0;
2376 void Node::incrementConnectedSubframeCount(unsigned amount)
2378 ASSERT(isContainerNode());
2379 ensureRareData().incrementConnectedSubframeCount(amount);
2382 void Node::decrementConnectedSubframeCount(unsigned amount)
2384 rareData()->decrementConnectedSubframeCount(amount);
2387 void Node::updateAncestorConnectedSubframeCountForRemoval() const
2389 unsigned count = connectedSubframeCount();
2394 for (Node* node = parentOrShadowHostNode(); node; node = node->parentOrShadowHostNode())
2395 node->decrementConnectedSubframeCount(count);
2398 void Node::updateAncestorConnectedSubframeCountForInsertion() const
2400 unsigned count = connectedSubframeCount();
2405 for (Node* node = parentOrShadowHostNode(); node; node = node->parentOrShadowHostNode())
2406 node->incrementConnectedSubframeCount(count);
2409 PassRefPtr<NodeList> Node::getDestinationInsertionPoints()
2411 document().updateDistributionForNodeIfNeeded(this);
2412 Vector<InsertionPoint*, 8> insertionPoints;
2413 collectDestinationInsertionPoints(*this, insertionPoints);
2414 Vector<RefPtr<Node> > filteredInsertionPoints;
2415 for (size_t i = 0; i < insertionPoints.size(); ++i) {
2416 InsertionPoint* insertionPoint = insertionPoints[i];
2417 ASSERT(insertionPoint->containingShadowRoot());
2418 if (insertionPoint->containingShadowRoot()->type() != ShadowRoot::UserAgentShadowRoot)
2419 filteredInsertionPoints.append(insertionPoint);
2421 return StaticNodeList::adopt(filteredInsertionPoints);
2424 void Node::registerScopedHTMLStyleChild()
2426 setHasScopedHTMLStyleChild(true);
2429 void Node::unregisterScopedHTMLStyleChild()
2431 ASSERT(hasScopedHTMLStyleChild());
2432 setHasScopedHTMLStyleChild(numberOfScopedHTMLStyleChildren());
2435 size_t Node::numberOfScopedHTMLStyleChildren() const
2438 for (HTMLStyleElement* style = Traversal<HTMLStyleElement>::firstChild(*this); style; style = Traversal<HTMLStyleElement>::nextSibling(*style)) {
2439 if (style->isRegisteredAsScoped())
2446 void Node::setFocus(bool flag)
2448 document().userActionElements().setFocused(this, flag);
2451 void Node::setActive(bool flag)
2453 document().userActionElements().setActive(this, flag);
2456 void Node::setHovered(bool flag)
2458 document().userActionElements().setHovered(this, flag);
2461 bool Node::isUserActionElementActive() const
2463 ASSERT(isUserActionElement());
2464 return document().userActionElements().isActive(this);
2467 bool Node::isUserActionElementInActiveChain() const
2469 ASSERT(isUserActionElement());
2470 return document().userActionElements().isInActiveChain(this);
2473 bool Node::isUserActionElementHovered() const
2475 ASSERT(isUserActionElement());
2476 return document().userActionElements().isHovered(this);
2479 bool Node::isUserActionElementFocused() const
2481 ASSERT(isUserActionElement());
2482 return document().userActionElements().isFocused(this);
2485 void Node::setCustomElementState(CustomElementState newState)
2487 CustomElementState oldState = customElementState();
2490 case NotCustomElement:
2491 ASSERT_NOT_REACHED(); // Everything starts in this state
2494 case WaitingForUpgrade:
2495 ASSERT(NotCustomElement == oldState);
2499 ASSERT(WaitingForUpgrade == oldState);
2503 ASSERT(isHTMLElement() || isSVGElement());
2504 setFlag(CustomElement);
2505 setFlag(newState == Upgraded, CustomElementUpgraded);
2507 if (oldState == NotCustomElement || newState == Upgraded)
2508 setNeedsStyleRecalc(SubtreeStyleChange); // :unresolved has changed
2511 } // namespace WebCore
2515 void showNode(const WebCore::Node* node)
2521 void showTree(const WebCore::Node* node)
2524 node->showTreeForThis();
2527 void showNodePath(const WebCore::Node* node)
2530 node->showNodePathForThis();