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, 2014 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.
28 #include "AXObjectCache.h"
30 #include "BeforeLoadEvent.h"
31 #include "ChildListMutationScope.h"
32 #include "ComposedTreeAncestorIterator.h"
33 #include "ContainerNodeAlgorithms.h"
34 #include "ContextMenuController.h"
35 #include "DataTransfer.h"
36 #include "DocumentType.h"
37 #include "ElementIterator.h"
38 #include "ElementRareData.h"
39 #include "ElementTraversal.h"
40 #include "EventDispatcher.h"
41 #include "EventHandler.h"
42 #include "FrameView.h"
43 #include "HTMLBodyElement.h"
44 #include "HTMLCollection.h"
45 #include "HTMLElement.h"
46 #include "HTMLImageElement.h"
47 #include "HTMLSlotElement.h"
48 #include "HTMLStyleElement.h"
49 #include "InputEvent.h"
50 #include "InspectorController.h"
51 #include "KeyboardEvent.h"
53 #include "MutationEvent.h"
54 #include "NoEventDispatchAssertion.h"
55 #include "NodeRenderStyle.h"
56 #include "ProcessingInstruction.h"
57 #include "ProgressEvent.h"
59 #include "RenderBlock.h"
60 #include "RenderBox.h"
61 #include "RenderTextControl.h"
62 #include "RenderView.h"
63 #include "ScopedEventQueue.h"
64 #include "StorageEvent.h"
65 #include "StyleResolver.h"
66 #include "StyleSheetContents.h"
67 #include "TemplateContentDocumentFragment.h"
68 #include "TextEvent.h"
69 #include "TouchEvent.h"
70 #include "WheelEvent.h"
71 #include "XMLNSNames.h"
73 #include <wtf/RefCountedLeakCounter.h>
75 #include <wtf/Variant.h>
76 #include <wtf/text/CString.h>
77 #include <wtf/text/StringBuilder.h>
81 using namespace HTMLNames;
83 #if DUMP_NODE_STATISTICS
84 static HashSet<Node*> liveNodeSet;
87 void Node::dumpStatistics()
89 #if DUMP_NODE_STATISTICS
90 size_t nodesWithRareData = 0;
92 size_t elementNodes = 0;
95 size_t cdataNodes = 0;
96 size_t commentNodes = 0;
97 size_t entityNodes = 0;
99 size_t documentNodes = 0;
100 size_t docTypeNodes = 0;
101 size_t fragmentNodes = 0;
102 size_t shadowRootNodes = 0;
104 HashMap<String, size_t> perTagCount;
106 size_t attributes = 0;
107 size_t attributesWithAttr = 0;
108 size_t elementsWithAttributeStorage = 0;
109 size_t elementsWithRareData = 0;
110 size_t elementsWithNamedNodeMap = 0;
112 for (auto* node : liveNodeSet) {
113 if (node->hasRareData()) {
115 if (is<Element>(*node)) {
116 ++elementsWithRareData;
117 if (downcast<Element>(*node).hasNamedNodeMap())
118 ++elementsWithNamedNodeMap;
122 switch (node->nodeType()) {
127 Element& element = downcast<Element>(*node);
128 HashMap<String, size_t>::AddResult result = perTagCount.add(element.tagName(), 1);
129 if (!result.isNewEntry)
130 result.iterator->value++;
132 if (const ElementData* elementData = element.elementData()) {
133 unsigned length = elementData->length();
134 attributes += length;
135 ++elementsWithAttributeStorage;
136 for (unsigned i = 0; i < length; ++i) {
137 const Attribute& attr = elementData->attributeAt(i);
139 ++attributesWithAttr;
144 case ATTRIBUTE_NODE: {
152 case CDATA_SECTION_NODE: {
164 case PROCESSING_INSTRUCTION_NODE: {
168 case DOCUMENT_NODE: {
172 case DOCUMENT_TYPE_NODE: {
176 case DOCUMENT_FRAGMENT_NODE: {
177 if (node->isShadowRoot())
186 printf("Number of Nodes: %d\n\n", liveNodeSet.size());
187 printf("Number of Nodes with RareData: %zu\n\n", nodesWithRareData);
189 printf("NodeType distribution:\n");
190 printf(" Number of Element nodes: %zu\n", elementNodes);
191 printf(" Number of Attribute nodes: %zu\n", attrNodes);
192 printf(" Number of Text nodes: %zu\n", textNodes);
193 printf(" Number of CDATASection nodes: %zu\n", cdataNodes);
194 printf(" Number of Comment nodes: %zu\n", commentNodes);
195 printf(" Number of Entity nodes: %zu\n", entityNodes);
196 printf(" Number of ProcessingInstruction nodes: %zu\n", piNodes);
197 printf(" Number of Document nodes: %zu\n", documentNodes);
198 printf(" Number of DocumentType nodes: %zu\n", docTypeNodes);
199 printf(" Number of DocumentFragment nodes: %zu\n", fragmentNodes);
200 printf(" Number of ShadowRoot nodes: %zu\n", shadowRootNodes);
202 printf("Element tag name distibution:\n");
203 for (auto& stringSizePair : perTagCount)
204 printf(" Number of <%s> tags: %zu\n", stringSizePair.key.utf8().data(), stringSizePair.value);
206 printf("Attributes:\n");
207 printf(" Number of Attributes (non-Node and Node): %zu [%zu]\n", attributes, sizeof(Attribute));
208 printf(" Number of Attributes with an Attr: %zu\n", attributesWithAttr);
209 printf(" Number of Elements with attribute storage: %zu [%zu]\n", elementsWithAttributeStorage, sizeof(ElementData));
210 printf(" Number of Elements with RareData: %zu\n", elementsWithRareData);
211 printf(" Number of Elements with NamedNodeMap: %zu [%zu]\n", elementsWithNamedNodeMap, sizeof(NamedNodeMap));
215 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, nodeCounter, ("WebCoreNode"));
218 static bool shouldIgnoreLeaks = false;
220 static HashSet<Node*>& ignoreSet()
222 static NeverDestroyed<HashSet<Node*>> ignore;
229 void Node::startIgnoringLeaks()
232 shouldIgnoreLeaks = true;
236 void Node::stopIgnoringLeaks()
239 shouldIgnoreLeaks = false;
243 void Node::trackForDebugging()
246 if (shouldIgnoreLeaks)
247 ignoreSet().add(this);
249 nodeCounter.increment();
252 #if DUMP_NODE_STATISTICS
253 liveNodeSet.add(this);
257 Node::Node(Document& document, ConstructionType type)
260 , m_treeScope(&document)
262 ASSERT(isMainThread());
264 document.incrementReferencingNodeCount();
266 #if !defined(NDEBUG) || (defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS)
273 ASSERT(isMainThread());
275 ASSERT(m_deletionHasBegun);
276 ASSERT(!m_adoptionIsRequired);
279 if (!ignoreSet().remove(this))
280 nodeCounter.decrement();
283 #if DUMP_NODE_STATISTICS
284 liveNodeSet.remove(this);
287 RELEASE_ASSERT(!renderer());
288 ASSERT(!parentNode());
295 if (!isContainerNode())
296 willBeDeletedFrom(document());
298 if (hasEventTargetData())
299 clearEventTargetData();
301 document().decrementReferencingNodeCount();
303 #if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS) && (!ASSERT_DISABLED || ENABLE(SECURITY_ASSERTIONS))
304 for (auto* document : Document::allDocuments()) {
305 ASSERT_WITH_SECURITY_IMPLICATION(!document->touchEventListenersContain(*this));
306 ASSERT_WITH_SECURITY_IMPLICATION(!document->touchEventHandlersContain(*this));
307 ASSERT_WITH_SECURITY_IMPLICATION(!document->touchEventTargetsContain(*this));
312 void Node::willBeDeletedFrom(Document& document)
314 if (hasEventTargetData()) {
315 document.didRemoveWheelEventHandler(*this, EventHandlerRemoval::All);
316 #if ENABLE(TOUCH_EVENTS)
318 document.removeTouchEventListener(*this, EventHandlerRemoval::All);
320 document.didRemoveTouchEventHandler(*this, EventHandlerRemoval::All);
324 #if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS)
325 document.removeTouchEventHandler(*this, EventHandlerRemoval::All);
328 if (AXObjectCache* cache = document.existingAXObjectCache())
332 void Node::materializeRareData()
335 if (is<Element>(*this))
336 data = std::make_unique<ElementRareData>(downcast<RenderElement>(m_data.m_renderer)).release();
338 data = std::make_unique<NodeRareData>(m_data.m_renderer).release();
341 m_data.m_rareData = data;
342 setFlag(HasRareDataFlag);
345 void Node::clearRareData()
347 ASSERT(hasRareData());
348 ASSERT(!transientMutationObserverRegistry() || transientMutationObserverRegistry()->isEmpty());
350 RenderObject* renderer = m_data.m_rareData->renderer();
352 delete static_cast<ElementRareData*>(m_data.m_rareData);
354 delete static_cast<NodeRareData*>(m_data.m_rareData);
355 m_data.m_renderer = renderer;
356 clearFlag(HasRareDataFlag);
359 RefPtr<Node> Node::toNode()
364 String Node::nodeValue() const
369 ExceptionOr<void> Node::setNodeValue(const String&)
371 // By default, setting nodeValue has no effect.
375 RefPtr<NodeList> Node::childNodes()
377 if (is<ContainerNode>(*this))
378 return ensureRareData().ensureNodeLists().ensureChildNodeList(downcast<ContainerNode>(*this));
379 return ensureRareData().ensureNodeLists().ensureEmptyChildNodeList(*this);
382 Node *Node::lastDescendant() const
384 Node *n = const_cast<Node *>(this);
385 while (n && n->lastChild())
390 Node* Node::firstDescendant() const
392 Node *n = const_cast<Node *>(this);
393 while (n && n->firstChild())
398 Element* Node::previousElementSibling() const
400 return ElementTraversal::previousSibling(*this);
403 Element* Node::nextElementSibling() const
405 return ElementTraversal::nextSibling(*this);
408 ExceptionOr<void> Node::insertBefore(Node& newChild, Node* refChild)
410 if (!is<ContainerNode>(*this))
411 return Exception { HierarchyRequestError };
412 return downcast<ContainerNode>(*this).insertBefore(newChild, refChild);
415 ExceptionOr<void> Node::replaceChild(Node& newChild, Node& oldChild)
417 if (!is<ContainerNode>(*this))
418 return Exception { HierarchyRequestError };
419 return downcast<ContainerNode>(*this).replaceChild(newChild, oldChild);
422 ExceptionOr<void> Node::removeChild(Node& oldChild)
424 if (!is<ContainerNode>(*this))
425 return Exception { NotFoundError };
426 return downcast<ContainerNode>(*this).removeChild(oldChild);
429 ExceptionOr<void> Node::appendChild(Node& newChild)
431 if (!is<ContainerNode>(*this))
432 return Exception { HierarchyRequestError };
433 return downcast<ContainerNode>(*this).appendChild(newChild);
436 static HashSet<RefPtr<Node>> nodeSetPreTransformedFromNodeOrStringVector(const Vector<NodeOrString>& vector)
438 HashSet<RefPtr<Node>> nodeSet;
439 for (const auto& variant : vector) {
440 WTF::switchOn(variant,
441 [&] (const RefPtr<Node>& node) { nodeSet.add(const_cast<Node*>(node.get())); },
442 [] (const String&) { }
448 static RefPtr<Node> firstPrecedingSiblingNotInNodeSet(Node& context, const HashSet<RefPtr<Node>>& nodeSet)
450 for (auto* sibling = context.previousSibling(); sibling; sibling = sibling->previousSibling()) {
451 if (!nodeSet.contains(sibling))
457 static RefPtr<Node> firstFollowingSiblingNotInNodeSet(Node& context, const HashSet<RefPtr<Node>>& nodeSet)
459 for (auto* sibling = context.nextSibling(); sibling; sibling = sibling->nextSibling()) {
460 if (!nodeSet.contains(sibling))
466 ExceptionOr<RefPtr<Node>> Node::convertNodesOrStringsIntoNode(Vector<NodeOrString>&& nodeOrStringVector)
468 if (nodeOrStringVector.isEmpty())
471 Vector<Ref<Node>> nodes;
472 nodes.reserveInitialCapacity(nodeOrStringVector.size());
473 for (auto& variant : nodeOrStringVector) {
474 WTF::switchOn(variant,
475 [&](RefPtr<Node>& node) { nodes.uncheckedAppend(*node.get()); },
476 [&](String& string) { nodes.uncheckedAppend(Text::create(document(), string)); }
480 if (nodes.size() == 1)
481 return RefPtr<Node> { WTFMove(nodes.first()) };
483 auto nodeToReturn = DocumentFragment::create(document());
484 for (auto& node : nodes) {
485 auto appendResult = nodeToReturn->appendChild(node);
486 if (appendResult.hasException())
487 return appendResult.releaseException();
489 return RefPtr<Node> { WTFMove(nodeToReturn) };
492 ExceptionOr<void> Node::before(Vector<NodeOrString>&& nodeOrStringVector)
494 RefPtr<ContainerNode> parent = parentNode();
498 auto nodeSet = nodeSetPreTransformedFromNodeOrStringVector(nodeOrStringVector);
499 auto viablePreviousSibling = firstPrecedingSiblingNotInNodeSet(*this, nodeSet);
501 auto result = convertNodesOrStringsIntoNode(WTFMove(nodeOrStringVector));
502 if (result.hasException())
503 return result.releaseException();
504 auto node = result.releaseReturnValue();
508 if (viablePreviousSibling)
509 viablePreviousSibling = viablePreviousSibling->nextSibling();
511 viablePreviousSibling = parent->firstChild();
513 return parent->insertBefore(*node, viablePreviousSibling.get());
516 ExceptionOr<void> Node::after(Vector<NodeOrString>&& nodeOrStringVector)
518 RefPtr<ContainerNode> parent = parentNode();
522 auto nodeSet = nodeSetPreTransformedFromNodeOrStringVector(nodeOrStringVector);
523 auto viableNextSibling = firstFollowingSiblingNotInNodeSet(*this, nodeSet);
525 auto result = convertNodesOrStringsIntoNode(WTFMove(nodeOrStringVector));
526 if (result.hasException())
527 return result.releaseException();
528 auto node = result.releaseReturnValue();
532 return parent->insertBefore(*node, viableNextSibling.get());
535 ExceptionOr<void> Node::replaceWith(Vector<NodeOrString>&& nodeOrStringVector)
537 RefPtr<ContainerNode> parent = parentNode();
541 auto nodeSet = nodeSetPreTransformedFromNodeOrStringVector(nodeOrStringVector);
542 auto viableNextSibling = firstFollowingSiblingNotInNodeSet(*this, nodeSet);
544 auto result = convertNodesOrStringsIntoNode(WTFMove(nodeOrStringVector));
545 if (result.hasException())
546 return result.releaseException();
548 if (parentNode() == parent) {
549 if (auto node = result.releaseReturnValue())
550 return parent->replaceChild(*node, *this);
551 return parent->removeChild(*this);
554 if (auto node = result.releaseReturnValue())
555 return parent->insertBefore(*node, viableNextSibling.get());
559 ExceptionOr<void> Node::remove()
561 auto* parent = parentNode();
564 return parent->removeChild(*this);
567 void Node::normalize()
569 // Go through the subtree beneath us, normalizing all nodes. This means that
570 // any two adjacent text nodes are merged and any empty text nodes are removed.
572 RefPtr<Node> node = this;
573 while (Node* firstChild = node->firstChild())
576 NodeType type = node->nodeType();
577 if (type == ELEMENT_NODE)
578 downcast<Element>(*node).normalizeAttributes();
583 if (type != TEXT_NODE) {
584 node = NodeTraversal::nextPostOrder(*node);
588 RefPtr<Text> text = downcast<Text>(node.get());
590 // Remove empty text nodes.
591 if (!text->length()) {
592 // Care must be taken to get the next node before removing the current node.
593 node = NodeTraversal::nextPostOrder(*node);
599 while (Node* nextSibling = node->nextSibling()) {
600 if (nextSibling->nodeType() != TEXT_NODE)
602 RefPtr<Text> nextText = downcast<Text>(nextSibling);
604 // Remove empty text nodes.
605 if (!nextText->length()) {
610 // Both non-empty text nodes. Merge them.
611 unsigned offset = text->length();
612 text->appendData(nextText->data());
613 document().textNodesMerged(nextText.get(), offset);
617 node = NodeTraversal::nextPostOrder(*node);
621 ExceptionOr<Ref<Node>> Node::cloneNodeForBindings(bool deep)
623 if (UNLIKELY(isShadowRoot()))
624 return Exception { NotSupportedError };
625 return cloneNode(deep);
628 const AtomicString& Node::prefix() const
630 // For nodes other than elements and attributes, the prefix is always null
634 ExceptionOr<void> Node::setPrefix(const AtomicString&)
636 // The spec says that for nodes other than elements and attributes, prefix is always null.
637 // It does not say what to do when the user tries to set the prefix on another type of
638 // node, however Mozilla throws a NamespaceError exception.
639 return Exception { NamespaceError };
642 const AtomicString& Node::localName() const
647 const AtomicString& Node::namespaceURI() const
652 bool Node::isContentEditable()
654 return computeEditability(UserSelectAllDoesNotAffectEditability, ShouldUpdateStyle::Update) != Editability::ReadOnly;
657 bool Node::isContentRichlyEditable()
659 return computeEditability(UserSelectAllIsAlwaysNonEditable, ShouldUpdateStyle::Update) == Editability::CanEditRichly;
664 if (document().page())
665 document().page()->inspectorController().inspect(this);
668 static Node::Editability computeEditabilityFromComputedStyle(const Node& startNode, Node::UserSelectAllTreatment treatment)
670 // Ideally we'd call ASSERT(!needsStyleRecalc()) here, but
671 // ContainerNode::setFocus() calls invalidateStyleForSubtree(), so the assertion
672 // would fire in the middle of Document::setFocusedElement().
674 for (const Node* node = &startNode; node; node = node->parentNode()) {
675 auto* style = node->isDocumentNode() ? node->renderStyle() : const_cast<Node*>(node)->computedStyle();
678 if (style->display() == NONE)
680 #if ENABLE(USERSELECT_ALL)
681 // Elements with user-select: all style are considered atomic
682 // therefore non editable.
683 if (treatment == Node::UserSelectAllIsAlwaysNonEditable && style->userSelect() == SELECT_ALL)
684 return Node::Editability::ReadOnly;
686 UNUSED_PARAM(treatment);
688 switch (style->userModify()) {
690 return Node::Editability::ReadOnly;
692 return Node::Editability::CanEditRichly;
693 case READ_WRITE_PLAINTEXT_ONLY:
694 return Node::Editability::CanEditPlainText;
696 ASSERT_NOT_REACHED();
697 return Node::Editability::ReadOnly;
699 return Node::Editability::ReadOnly;
702 Node::Editability Node::computeEditability(UserSelectAllTreatment treatment, ShouldUpdateStyle shouldUpdateStyle) const
704 if (!document().hasLivingRenderTree() || isPseudoElement())
705 return Editability::ReadOnly;
707 if (isInShadowTree())
708 return HTMLElement::editabilityFromContentEditableAttr(*this);
710 if (document().frame() && document().frame()->page() && document().frame()->page()->isEditable())
711 return Editability::CanEditRichly;
713 if (shouldUpdateStyle == ShouldUpdateStyle::Update && document().needsStyleRecalc()) {
714 if (!document().usesStyleBasedEditability())
715 return HTMLElement::editabilityFromContentEditableAttr(*this);
716 document().updateStyleIfNeeded();
718 return computeEditabilityFromComputedStyle(*this, treatment);
721 RenderBox* Node::renderBox() const
723 RenderObject* renderer = this->renderer();
724 return is<RenderBox>(renderer) ? downcast<RenderBox>(renderer) : nullptr;
727 RenderBoxModelObject* Node::renderBoxModelObject() const
729 RenderObject* renderer = this->renderer();
730 return is<RenderBoxModelObject>(renderer) ? downcast<RenderBoxModelObject>(renderer) : nullptr;
733 LayoutRect Node::renderRect(bool* isReplaced)
735 RenderObject* hitRenderer = this->renderer();
737 RenderObject* renderer = hitRenderer;
738 while (renderer && !renderer->isBody() && !renderer->isDocumentElementRenderer()) {
739 if (renderer->isRenderBlock() || renderer->isInlineBlockOrInlineTable() || renderer->isReplaced()) {
740 *isReplaced = renderer->isReplaced();
741 return renderer->absoluteBoundingBoxRect();
743 renderer = renderer->parent();
748 void Node::refEventTarget()
753 void Node::derefEventTarget()
758 void Node::adjustStyleValidity(Style::Validity validity, Style::InvalidationMode mode)
760 if (validity > styleValidity()) {
761 m_nodeFlags &= ~StyleValidityMask;
762 m_nodeFlags |= static_cast<unsigned>(validity) << StyleValidityShift;
764 if (mode == Style::InvalidationMode::RecompositeLayer)
765 setFlag(StyleResolutionShouldRecompositeLayerFlag);
768 inline void Node::updateAncestorsForStyleRecalc()
770 auto composedAncestors = composedTreeAncestors(*this);
771 auto it = composedAncestors.begin();
772 auto end = composedAncestors.end();
774 it->setDirectChildNeedsStyleRecalc();
776 if (it->childrenAffectedByPropertyBasedBackwardPositionalRules())
777 it->adjustStyleValidity(Style::Validity::SubtreeInvalid, Style::InvalidationMode::Normal);
779 for (; it != end; ++it) {
780 // Iterator skips over shadow roots.
781 if (auto* shadowRoot = it->shadowRoot())
782 shadowRoot->setChildNeedsStyleRecalc();
783 if (it->childNeedsStyleRecalc())
785 it->setChildNeedsStyleRecalc();
789 auto* documentElement = document().documentElement();
790 if (!documentElement)
792 if (!documentElement->childNeedsStyleRecalc() && !documentElement->needsStyleRecalc())
794 document().setChildNeedsStyleRecalc();
795 document().scheduleStyleRecalc();
798 void Node::invalidateStyle(Style::Validity validity, Style::InvalidationMode mode)
800 ASSERT(validity != Style::Validity::Valid);
801 if (!inRenderedDocument())
804 // FIXME: This should eventually be an ASSERT.
805 if (document().inRenderTreeUpdate())
808 // FIXME: Why the second condition?
809 bool markAncestors = styleValidity() == Style::Validity::Valid || validity == Style::Validity::SubtreeAndRenderersInvalid;
811 adjustStyleValidity(validity, mode);
814 updateAncestorsForStyleRecalc();
817 unsigned Node::computeNodeIndex() const
820 for (Node* sibling = previousSibling(); sibling; sibling = sibling->previousSibling())
825 template<unsigned type>
826 bool shouldInvalidateNodeListCachesForAttr(const unsigned nodeListCounts[], const QualifiedName& attrName)
828 if (nodeListCounts[type] && shouldInvalidateTypeOnAttributeChange(static_cast<NodeListInvalidationType>(type), attrName))
830 return shouldInvalidateNodeListCachesForAttr<type + 1>(nodeListCounts, attrName);
834 bool shouldInvalidateNodeListCachesForAttr<numNodeListInvalidationTypes>(const unsigned[], const QualifiedName&)
839 inline bool Document::shouldInvalidateNodeListAndCollectionCaches() const
841 for (int type = 0; type < numNodeListInvalidationTypes; ++type) {
842 if (m_nodeListAndCollectionCounts[type])
848 inline bool Document::shouldInvalidateNodeListAndCollectionCachesForAttribute(const QualifiedName& attrName) const
850 return shouldInvalidateNodeListCachesForAttr<DoNotInvalidateOnAttributeChanges + 1>(m_nodeListAndCollectionCounts, attrName);
853 template <typename InvalidationFunction>
854 void Document::invalidateNodeListAndCollectionCaches(InvalidationFunction invalidate)
856 for (auto* list : copyToVectorSpecialization<Vector<LiveNodeList*, 8>>(m_listsInvalidatedAtDocument))
859 for (auto* collection : copyToVectorSpecialization<Vector<HTMLCollection*, 8>>(m_collectionsInvalidatedAtDocument))
860 invalidate(*collection);
863 void Node::invalidateNodeListAndCollectionCachesInAncestors()
866 if (auto* lists = rareData()->nodeLists())
867 lists->clearChildNodeListCache();
870 if (!document().shouldInvalidateNodeListAndCollectionCaches())
873 document().invalidateNodeListAndCollectionCaches([](auto& list) {
874 list.invalidateCache();
877 for (auto* node = this; node; node = node->parentNode()) {
878 if (!node->hasRareData())
881 if (auto* lists = node->rareData()->nodeLists())
882 lists->invalidateCaches();
886 void Node::invalidateNodeListAndCollectionCachesInAncestorsForAttribute(const QualifiedName& attrName)
888 ASSERT(is<Element>(*this));
890 if (!document().shouldInvalidateNodeListAndCollectionCachesForAttribute(attrName))
893 document().invalidateNodeListAndCollectionCaches([&attrName](auto& list) {
894 list.invalidateCacheForAttribute(attrName);
897 for (auto* node = this; node; node = node->parentNode()) {
898 if (!node->hasRareData())
901 if (auto* lists = node->rareData()->nodeLists())
902 lists->invalidateCachesForAttribute(attrName);
906 NodeListsNodeData* Node::nodeLists()
908 return hasRareData() ? rareData()->nodeLists() : nullptr;
911 void Node::clearNodeLists()
913 rareData()->clearNodeLists();
916 ExceptionOr<void> Node::checkSetPrefix(const AtomicString& prefix)
918 // Perform error checking as required by spec for setting Node.prefix. Used by
919 // Element::setPrefix() and Attr::setPrefix()
921 if (!prefix.isEmpty() && !Document::isValidName(prefix))
922 return Exception { InvalidCharacterError };
924 // FIXME: Raise NamespaceError if prefix is malformed per the Namespaces in XML specification.
926 auto& namespaceURI = this->namespaceURI();
927 if (namespaceURI.isEmpty() && !prefix.isEmpty())
928 return Exception { NamespaceError };
929 if (prefix == xmlAtom() && namespaceURI != XMLNames::xmlNamespaceURI)
930 return Exception { NamespaceError };
932 // Attribute-specific checks are in Attr::setPrefix().
937 bool Node::isDescendantOf(const Node& other) const
939 // Return true if other is an ancestor of this, otherwise false
940 if (!other.hasChildNodes() || isConnected() != other.isConnected())
942 if (other.isDocumentNode())
943 return &document() == &other && !isDocumentNode() && isConnected();
944 for (const auto* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
945 if (ancestor == &other)
951 bool Node::isDescendantOrShadowDescendantOf(const Node* other) const
955 if (isDescendantOf(*other))
957 const Node* shadowAncestorNode = deprecatedShadowAncestorNode();
958 if (!shadowAncestorNode)
960 return shadowAncestorNode == other || shadowAncestorNode->isDescendantOf(*other);
963 bool Node::contains(const Node* node) const
967 return this == node || node->isDescendantOf(*this);
970 bool Node::containsIncludingShadowDOM(const Node* node) const
972 for (; node; node = node->parentOrShadowHostNode()) {
979 bool Node::containsIncludingHostElements(const Node* node) const
984 if (node->isDocumentFragment() && static_cast<const DocumentFragment*>(node)->isTemplateContent())
985 node = static_cast<const TemplateContentDocumentFragment*>(node)->host();
987 node = node->parentOrShadowHostNode();
992 Node* Node::pseudoAwarePreviousSibling() const
994 Element* parentOrHost = is<PseudoElement>(*this) ? downcast<PseudoElement>(*this).hostElement() : parentElement();
995 if (parentOrHost && !previousSibling()) {
996 if (isAfterPseudoElement() && parentOrHost->lastChild())
997 return parentOrHost->lastChild();
998 if (!isBeforePseudoElement())
999 return parentOrHost->beforePseudoElement();
1001 return previousSibling();
1004 Node* Node::pseudoAwareNextSibling() const
1006 Element* parentOrHost = is<PseudoElement>(*this) ? downcast<PseudoElement>(*this).hostElement() : parentElement();
1007 if (parentOrHost && !nextSibling()) {
1008 if (isBeforePseudoElement() && parentOrHost->firstChild())
1009 return parentOrHost->firstChild();
1010 if (!isAfterPseudoElement())
1011 return parentOrHost->afterPseudoElement();
1013 return nextSibling();
1016 Node* Node::pseudoAwareFirstChild() const
1018 if (is<Element>(*this)) {
1019 const Element& currentElement = downcast<Element>(*this);
1020 Node* first = currentElement.beforePseudoElement();
1023 first = currentElement.firstChild();
1025 first = currentElement.afterPseudoElement();
1028 return firstChild();
1031 Node* Node::pseudoAwareLastChild() const
1033 if (is<Element>(*this)) {
1034 const Element& currentElement = downcast<Element>(*this);
1035 Node* last = currentElement.afterPseudoElement();
1038 last = currentElement.lastChild();
1040 last = currentElement.beforePseudoElement();
1046 const RenderStyle* Node::computedStyle(PseudoId pseudoElementSpecifier)
1048 auto* composedParent = composedTreeAncestors(*this).first();
1049 if (!composedParent)
1051 return composedParent->computedStyle(pseudoElementSpecifier);
1054 int Node::maxCharacterOffset() const
1056 ASSERT_NOT_REACHED();
1060 // FIXME: Shouldn't these functions be in the editing code? Code that asks questions about HTML in the core DOM class
1061 // is obviously misplaced.
1062 bool Node::canStartSelection() const
1064 if (hasEditableStyle())
1068 const RenderStyle& style = renderer()->style();
1069 // We allow selections to begin within an element that has -webkit-user-select: none set,
1070 // but if the element is draggable then dragging should take priority over selection.
1071 if (style.userDrag() == DRAG_ELEMENT && style.userSelect() == SELECT_NONE)
1074 return parentOrShadowHostNode() ? parentOrShadowHostNode()->canStartSelection() : true;
1077 Element* Node::shadowHost() const
1079 if (ShadowRoot* root = containingShadowRoot())
1080 return root->host();
1084 Node* Node::deprecatedShadowAncestorNode() const
1086 if (ShadowRoot* root = containingShadowRoot())
1087 return root->host();
1089 return const_cast<Node*>(this);
1092 ShadowRoot* Node::containingShadowRoot() const
1094 ContainerNode& root = treeScope().rootNode();
1095 return is<ShadowRoot>(root) ? downcast<ShadowRoot>(&root) : nullptr;
1098 #if !ASSERT_DISABLED
1099 // https://dom.spec.whatwg.org/#concept-closed-shadow-hidden
1100 static bool isClosedShadowHiddenUsingSpecDefinition(const Node& A, const Node& B)
1102 return A.isInShadowTree()
1103 && !A.rootNode().containsIncludingShadowDOM(&B)
1104 && (A.containingShadowRoot()->mode() != ShadowRootMode::Open || isClosedShadowHiddenUsingSpecDefinition(*A.shadowHost(), B));
1108 // http://w3c.github.io/webcomponents/spec/shadow/#dfn-unclosed-node
1109 bool Node::isClosedShadowHidden(const Node& otherNode) const
1111 // Use Vector instead of HashSet since we expect the number of ancestor tree scopes to be small.
1112 Vector<TreeScope*, 8> ancestorScopesOfThisNode;
1114 for (auto* scope = &treeScope(); scope; scope = scope->parentTreeScope())
1115 ancestorScopesOfThisNode.append(scope);
1117 for (auto* treeScopeThatCanAccessOtherNode = &otherNode.treeScope(); treeScopeThatCanAccessOtherNode; treeScopeThatCanAccessOtherNode = treeScopeThatCanAccessOtherNode->parentTreeScope()) {
1118 for (auto* scope : ancestorScopesOfThisNode) {
1119 if (scope == treeScopeThatCanAccessOtherNode) {
1120 ASSERT(!isClosedShadowHiddenUsingSpecDefinition(otherNode, *this));
1121 return false; // treeScopeThatCanAccessOtherNode is a shadow-including inclusive ancestor of this node.
1124 auto& root = treeScopeThatCanAccessOtherNode->rootNode();
1125 if (is<ShadowRoot>(root) && downcast<ShadowRoot>(root).mode() != ShadowRootMode::Open)
1129 ASSERT(isClosedShadowHiddenUsingSpecDefinition(otherNode, *this));
1133 static inline ShadowRoot* parentShadowRoot(const Node& node)
1135 if (auto* parent = node.parentElement())
1136 return parent->shadowRoot();
1140 HTMLSlotElement* Node::assignedSlot() const
1142 if (auto* shadowRoot = parentShadowRoot(*this))
1143 return shadowRoot->findAssignedSlot(*this);
1147 HTMLSlotElement* Node::assignedSlotForBindings() const
1149 auto* shadowRoot = parentShadowRoot(*this);
1150 if (shadowRoot && shadowRoot->mode() == ShadowRootMode::Open)
1151 return shadowRoot->findAssignedSlot(*this);
1155 ContainerNode* Node::parentInComposedTree() const
1157 ASSERT(isMainThreadOrGCThread());
1158 if (auto* slot = assignedSlot())
1160 if (is<ShadowRoot>(*this))
1161 return downcast<ShadowRoot>(*this).host();
1162 return parentNode();
1165 Element* Node::parentElementInComposedTree() const
1167 if (auto* slot = assignedSlot())
1169 if (auto* parent = parentNode()) {
1170 if (is<ShadowRoot>(*parent))
1171 return downcast<ShadowRoot>(*parent).host();
1172 if (is<Element>(*parent))
1173 return downcast<Element>(parent);
1178 bool Node::isInUserAgentShadowTree() const
1180 auto* shadowRoot = containingShadowRoot();
1181 return shadowRoot && shadowRoot->mode() == ShadowRootMode::UserAgent;
1184 Node* Node::nonBoundaryShadowTreeRootNode()
1186 ASSERT(!isShadowRoot());
1189 if (root->isShadowRoot())
1191 Node* parent = root->parentNodeGuaranteedHostFree();
1192 if (parent && parent->isShadowRoot())
1199 ContainerNode* Node::nonShadowBoundaryParentNode() const
1201 ContainerNode* parent = parentNode();
1202 return parent && !parent->isShadowRoot() ? parent : nullptr;
1205 Element* Node::parentOrShadowHostElement() const
1207 ContainerNode* parent = parentOrShadowHostNode();
1211 if (is<ShadowRoot>(*parent))
1212 return downcast<ShadowRoot>(*parent).host();
1214 if (!is<Element>(*parent))
1217 return downcast<Element>(parent);
1220 Node& Node::traverseToRootNode() const
1222 Node* node = const_cast<Node*>(this);
1223 Node* highest = node;
1224 for (; node; node = node->parentNode())
1229 // https://dom.spec.whatwg.org/#concept-shadow-including-root
1230 Node& Node::shadowIncludingRoot() const
1232 auto& root = rootNode();
1233 if (!is<ShadowRoot>(root))
1235 auto* host = downcast<ShadowRoot>(root).host();
1236 return host ? host->shadowIncludingRoot() : root;
1239 Node& Node::getRootNode(const GetRootNodeOptions& options) const
1241 return options.composed ? shadowIncludingRoot() : rootNode();
1244 Node::InsertedIntoAncestorResult Node::insertedIntoAncestor(InsertionType insertionType, ContainerNode& parentOfInsertedTree)
1246 if (insertionType.connectedToDocument)
1247 setFlag(IsConnectedFlag);
1248 if (parentOfInsertedTree.isInShadowTree())
1249 setFlag(IsInShadowTreeFlag);
1251 invalidateStyle(Style::Validity::SubtreeAndRenderersInvalid);
1253 return InsertedIntoAncestorResult::Done;
1256 void Node::removedFromAncestor(RemovalType removalType, ContainerNode&)
1258 if (removalType.disconnectedFromDocument)
1259 clearFlag(IsConnectedFlag);
1260 if (isInShadowTree() && !treeScope().rootNode().isShadowRoot())
1261 clearFlag(IsInShadowTreeFlag);
1264 bool Node::isRootEditableElement() const
1266 return hasEditableStyle() && isElementNode() && (!parentNode() || !parentNode()->hasEditableStyle()
1267 || !parentNode()->isElementNode() || hasTagName(bodyTag));
1270 Element* Node::rootEditableElement() const
1272 Element* result = nullptr;
1273 for (Node* node = const_cast<Node*>(this); node && node->hasEditableStyle(); node = node->parentNode()) {
1274 if (is<Element>(*node))
1275 result = downcast<Element>(node);
1276 if (is<HTMLBodyElement>(*node))
1282 // FIXME: End of obviously misplaced HTML editing functions. Try to move these out of Node.
1284 Document* Node::ownerDocument() const
1286 Document* document = &this->document();
1287 return document == this ? nullptr : document;
1290 const URL& Node::baseURI() const
1292 auto& url = document().baseURL();
1293 return url.isNull() ? blankURL() : url;
1296 bool Node::isEqualNode(Node* other) const
1301 NodeType nodeType = this->nodeType();
1302 if (nodeType != other->nodeType())
1306 case Node::DOCUMENT_TYPE_NODE: {
1307 auto& thisDocType = downcast<DocumentType>(*this);
1308 auto& otherDocType = downcast<DocumentType>(*other);
1309 if (thisDocType.name() != otherDocType.name())
1311 if (thisDocType.publicId() != otherDocType.publicId())
1313 if (thisDocType.systemId() != otherDocType.systemId())
1317 case Node::ELEMENT_NODE: {
1318 auto& thisElement = downcast<Element>(*this);
1319 auto& otherElement = downcast<Element>(*other);
1320 if (thisElement.tagQName() != otherElement.tagQName())
1322 if (!thisElement.hasEquivalentAttributes(&otherElement))
1326 case Node::PROCESSING_INSTRUCTION_NODE: {
1327 auto& thisProcessingInstruction = downcast<ProcessingInstruction>(*this);
1328 auto& otherProcessingInstruction = downcast<ProcessingInstruction>(*other);
1329 if (thisProcessingInstruction.target() != otherProcessingInstruction.target())
1331 if (thisProcessingInstruction.data() != otherProcessingInstruction.data())
1335 case Node::CDATA_SECTION_NODE:
1336 case Node::TEXT_NODE:
1337 case Node::COMMENT_NODE: {
1338 auto& thisCharacterData = downcast<CharacterData>(*this);
1339 auto& otherCharacterData = downcast<CharacterData>(*other);
1340 if (thisCharacterData.data() != otherCharacterData.data())
1344 case Node::ATTRIBUTE_NODE: {
1345 auto& thisAttribute = downcast<Attr>(*this);
1346 auto& otherAttribute = downcast<Attr>(*other);
1347 if (thisAttribute.qualifiedName() != otherAttribute.qualifiedName())
1349 if (thisAttribute.value() != otherAttribute.value())
1353 case Node::DOCUMENT_NODE:
1354 case Node::DOCUMENT_FRAGMENT_NODE:
1358 Node* child = firstChild();
1359 Node* otherChild = other->firstChild();
1362 if (!child->isEqualNode(otherChild))
1365 child = child->nextSibling();
1366 otherChild = otherChild->nextSibling();
1375 // https://dom.spec.whatwg.org/#locate-a-namespace
1376 static const AtomicString& locateDefaultNamespace(const Node& node, const AtomicString& prefix)
1378 switch (node.nodeType()) {
1379 case Node::ELEMENT_NODE: {
1380 auto& element = downcast<Element>(node);
1381 auto& namespaceURI = element.namespaceURI();
1382 if (!namespaceURI.isNull() && element.prefix() == prefix)
1383 return namespaceURI;
1385 if (element.hasAttributes()) {
1386 for (auto& attribute : element.attributesIterator()) {
1387 if (attribute.namespaceURI() != XMLNSNames::xmlnsNamespaceURI)
1390 if ((prefix.isNull() && attribute.prefix().isNull() && attribute.localName() == xmlnsAtom()) || (attribute.prefix() == xmlnsAtom() && attribute.localName() == prefix)) {
1391 auto& result = attribute.value();
1392 return result.isEmpty() ? nullAtom() : result;
1396 auto* parent = node.parentElement();
1397 return parent ? locateDefaultNamespace(*parent, prefix) : nullAtom();
1399 case Node::DOCUMENT_NODE:
1400 if (auto* documentElement = downcast<Document>(node).documentElement())
1401 return locateDefaultNamespace(*documentElement, prefix);
1403 case Node::DOCUMENT_TYPE_NODE:
1404 case Node::DOCUMENT_FRAGMENT_NODE:
1406 case Node::ATTRIBUTE_NODE:
1407 if (auto* ownerElement = downcast<Attr>(node).ownerElement())
1408 return locateDefaultNamespace(*ownerElement, prefix);
1411 if (auto* parent = node.parentElement())
1412 return locateDefaultNamespace(*parent, prefix);
1417 // https://dom.spec.whatwg.org/#dom-node-isdefaultnamespace
1418 bool Node::isDefaultNamespace(const AtomicString& potentiallyEmptyNamespace) const
1420 const AtomicString& namespaceURI = potentiallyEmptyNamespace.isEmpty() ? nullAtom() : potentiallyEmptyNamespace;
1421 return locateDefaultNamespace(*this, nullAtom()) == namespaceURI;
1424 // https://dom.spec.whatwg.org/#dom-node-lookupnamespaceuri
1425 const AtomicString& Node::lookupNamespaceURI(const AtomicString& potentiallyEmptyPrefix) const
1427 const AtomicString& prefix = potentiallyEmptyPrefix.isEmpty() ? nullAtom() : potentiallyEmptyPrefix;
1428 return locateDefaultNamespace(*this, prefix);
1431 // https://dom.spec.whatwg.org/#locate-a-namespace-prefix
1432 static const AtomicString& locateNamespacePrefix(const Element& element, const AtomicString& namespaceURI)
1434 if (element.namespaceURI() == namespaceURI)
1435 return element.prefix();
1437 if (element.hasAttributes()) {
1438 for (auto& attribute : element.attributesIterator()) {
1439 if (attribute.prefix() == xmlnsAtom() && attribute.value() == namespaceURI)
1440 return attribute.localName();
1443 auto* parent = element.parentElement();
1444 return parent ? locateNamespacePrefix(*parent, namespaceURI) : nullAtom();
1447 // https://dom.spec.whatwg.org/#dom-node-lookupprefix
1448 const AtomicString& Node::lookupPrefix(const AtomicString& namespaceURI) const
1450 if (namespaceURI.isEmpty())
1453 switch (nodeType()) {
1455 return locateNamespacePrefix(downcast<Element>(*this), namespaceURI);
1457 if (auto* documentElement = downcast<Document>(*this).documentElement())
1458 return locateNamespacePrefix(*documentElement, namespaceURI);
1460 case DOCUMENT_FRAGMENT_NODE:
1461 case DOCUMENT_TYPE_NODE:
1463 case ATTRIBUTE_NODE:
1464 if (auto* ownerElement = downcast<Attr>(*this).ownerElement())
1465 return locateNamespacePrefix(*ownerElement, namespaceURI);
1468 if (auto* parent = parentElement())
1469 return locateNamespacePrefix(*parent, namespaceURI);
1474 static void appendTextContent(const Node* node, bool convertBRsToNewlines, bool& isNullString, StringBuilder& content)
1476 switch (node->nodeType()) {
1477 case Node::TEXT_NODE:
1478 case Node::CDATA_SECTION_NODE:
1479 case Node::COMMENT_NODE:
1480 isNullString = false;
1481 content.append(downcast<CharacterData>(*node).data());
1484 case Node::PROCESSING_INSTRUCTION_NODE:
1485 isNullString = false;
1486 content.append(downcast<ProcessingInstruction>(*node).data());
1489 case Node::ATTRIBUTE_NODE:
1490 isNullString = false;
1491 content.append(downcast<Attr>(*node).value());
1494 case Node::ELEMENT_NODE:
1495 if (node->hasTagName(brTag) && convertBRsToNewlines) {
1496 isNullString = false;
1497 content.append('\n');
1501 case Node::DOCUMENT_FRAGMENT_NODE:
1502 isNullString = false;
1503 for (Node* child = node->firstChild(); child; child = child->nextSibling()) {
1504 if (child->nodeType() == Node::COMMENT_NODE || child->nodeType() == Node::PROCESSING_INSTRUCTION_NODE)
1506 appendTextContent(child, convertBRsToNewlines, isNullString, content);
1510 case Node::DOCUMENT_NODE:
1511 case Node::DOCUMENT_TYPE_NODE:
1516 String Node::textContent(bool convertBRsToNewlines) const
1518 StringBuilder content;
1519 bool isNullString = true;
1520 appendTextContent(this, convertBRsToNewlines, isNullString, content);
1521 return isNullString ? String() : content.toString();
1524 ExceptionOr<void> Node::setTextContent(const String& text)
1526 switch (nodeType()) {
1527 case ATTRIBUTE_NODE:
1529 case CDATA_SECTION_NODE:
1531 case PROCESSING_INSTRUCTION_NODE:
1532 return setNodeValue(text);
1534 case DOCUMENT_FRAGMENT_NODE: {
1535 auto& container = downcast<ContainerNode>(*this);
1537 container.replaceAllChildren(nullptr);
1539 container.replaceAllChildren(document().createTextNode(text));
1543 case DOCUMENT_TYPE_NODE:
1547 ASSERT_NOT_REACHED();
1551 bool Node::offsetInCharacters() const
1556 static SHA1::Digest hashPointer(void* pointer)
1559 sha1.addBytes(reinterpret_cast<const uint8_t*>(&pointer), sizeof(pointer));
1560 SHA1::Digest digest;
1561 sha1.computeHash(digest);
1565 static inline unsigned short compareDetachedElementsPosition(Node& firstNode, Node& secondNode)
1567 // If the 2 nodes are not in the same tree, return the result of adding DOCUMENT_POSITION_DISCONNECTED,
1568 // DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC, and either DOCUMENT_POSITION_PRECEDING or
1569 // DOCUMENT_POSITION_FOLLOWING, with the constraint that this is to be consistent. Whether to return
1570 // DOCUMENT_POSITION_PRECEDING or DOCUMENT_POSITION_FOLLOWING is implemented by comparing cryptographic
1571 // hashes of Node pointers.
1572 // See step 3 in https://dom.spec.whatwg.org/#dom-node-comparedocumentposition
1573 SHA1::Digest firstHash = hashPointer(&firstNode);
1574 SHA1::Digest secondHash = hashPointer(&secondNode);
1576 unsigned short direction = memcmp(firstHash.data(), secondHash.data(), SHA1::hashSize) > 0 ? Node::DOCUMENT_POSITION_PRECEDING : Node::DOCUMENT_POSITION_FOLLOWING;
1578 return Node::DOCUMENT_POSITION_DISCONNECTED | Node::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | direction;
1581 unsigned short Node::compareDocumentPosition(Node& otherNode)
1583 if (&otherNode == this)
1584 return DOCUMENT_POSITION_EQUIVALENT;
1586 Attr* attr1 = is<Attr>(*this) ? downcast<Attr>(this) : nullptr;
1587 Attr* attr2 = is<Attr>(otherNode) ? &downcast<Attr>(otherNode) : nullptr;
1589 Node* start1 = attr1 ? attr1->ownerElement() : this;
1590 Node* start2 = attr2 ? attr2->ownerElement() : &otherNode;
1592 // If either of start1 or start2 is null, then we are disconnected, since one of the nodes is
1593 // an orphaned attribute node.
1594 if (!start1 || !start2)
1595 return compareDetachedElementsPosition(*this, otherNode);
1597 Vector<Node*, 16> chain1;
1598 Vector<Node*, 16> chain2;
1600 chain1.append(attr1);
1602 chain2.append(attr2);
1604 if (attr1 && attr2 && start1 == start2 && start1) {
1605 // We are comparing two attributes on the same node. Crawl our attribute map and see which one we hit first.
1606 Element* owner1 = attr1->ownerElement();
1607 owner1->synchronizeAllAttributes();
1608 for (const Attribute& attribute : owner1->attributesIterator()) {
1609 // If neither of the two determining nodes is a child node and nodeType is the same for both determining nodes, then an
1610 // implementation-dependent order between the determining nodes is returned. This order is stable as long as no nodes of
1611 // the same nodeType are inserted into or removed from the direct container. This would be the case, for example,
1612 // when comparing two attributes of the same element, and inserting or removing additional attributes might change
1613 // the order between existing attributes.
1614 if (attr1->qualifiedName() == attribute.name())
1615 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_FOLLOWING;
1616 if (attr2->qualifiedName() == attribute.name())
1617 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_PRECEDING;
1620 ASSERT_NOT_REACHED();
1621 return DOCUMENT_POSITION_DISCONNECTED;
1624 // If one node is in the document and the other is not, we must be disconnected.
1625 // If the nodes have different owning documents, they must be disconnected. Note that we avoid
1626 // comparing Attr nodes here, since they return false from isConnected() all the time (which seems like a bug).
1627 if (start1->isConnected() != start2->isConnected() || &start1->treeScope() != &start2->treeScope())
1628 return compareDetachedElementsPosition(*this, otherNode);
1630 // We need to find a common ancestor container, and then compare the indices of the two immediate children.
1632 for (current = start1; current; current = current->parentNode())
1633 chain1.append(current);
1634 for (current = start2; current; current = current->parentNode())
1635 chain2.append(current);
1637 unsigned index1 = chain1.size();
1638 unsigned index2 = chain2.size();
1640 // If the two elements don't have a common root, they're not in the same tree.
1641 if (chain1[index1 - 1] != chain2[index2 - 1])
1642 return compareDetachedElementsPosition(*this, otherNode);
1644 // Walk the two chains backwards and look for the first difference.
1645 for (unsigned i = std::min(index1, index2); i; --i) {
1646 Node* child1 = chain1[--index1];
1647 Node* child2 = chain2[--index2];
1648 if (child1 != child2) {
1649 // If one of the children is an attribute, it wins.
1650 if (child1->nodeType() == ATTRIBUTE_NODE)
1651 return DOCUMENT_POSITION_FOLLOWING;
1652 if (child2->nodeType() == ATTRIBUTE_NODE)
1653 return DOCUMENT_POSITION_PRECEDING;
1655 if (!child2->nextSibling())
1656 return DOCUMENT_POSITION_FOLLOWING;
1657 if (!child1->nextSibling())
1658 return DOCUMENT_POSITION_PRECEDING;
1660 // Otherwise we need to see which node occurs first. Crawl backwards from child2 looking for child1.
1661 for (Node* child = child2->previousSibling(); child; child = child->previousSibling()) {
1662 if (child == child1)
1663 return DOCUMENT_POSITION_FOLLOWING;
1665 return DOCUMENT_POSITION_PRECEDING;
1669 // There was no difference between the two parent chains, i.e., one was a subset of the other. The shorter
1670 // chain is the ancestor.
1671 return index1 < index2 ?
1672 DOCUMENT_POSITION_FOLLOWING | DOCUMENT_POSITION_CONTAINED_BY :
1673 DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_CONTAINS;
1676 FloatPoint Node::convertToPage(const FloatPoint& p) const
1678 // If there is a renderer, just ask it to do the conversion
1680 return renderer()->localToAbsolute(p, UseTransforms);
1682 // Otherwise go up the tree looking for a renderer
1683 if (auto* parent = parentElement())
1684 return parent->convertToPage(p);
1686 // No parent - no conversion needed
1690 FloatPoint Node::convertFromPage(const FloatPoint& p) const
1692 // If there is a renderer, just ask it to do the conversion
1694 return renderer()->absoluteToLocal(p, UseTransforms);
1696 // Otherwise go up the tree looking for a renderer
1697 if (auto* parent = parentElement())
1698 return parent->convertFromPage(p);
1700 // No parent - no conversion needed
1704 #if ENABLE(TREE_DEBUGGING)
1706 static void appendAttributeDesc(const Node* node, StringBuilder& stringBuilder, const QualifiedName& name, const char* attrDesc)
1708 if (!is<Element>(*node))
1711 const AtomicString& attr = downcast<Element>(*node).getAttribute(name);
1715 stringBuilder.append(attrDesc);
1716 stringBuilder.append(attr);
1719 void Node::showNode(const char* prefix) const
1724 String value = nodeValue();
1725 value.replaceWithLiteral('\\', "\\\\");
1726 value.replaceWithLiteral('\n', "\\n");
1727 fprintf(stderr, "%s%s\t%p \"%s\"\n", prefix, nodeName().utf8().data(), this, value.utf8().data());
1729 StringBuilder attrs;
1730 appendAttributeDesc(this, attrs, classAttr, " CLASS=");
1731 appendAttributeDesc(this, attrs, styleAttr, " STYLE=");
1732 fprintf(stderr, "%s%s\t%p (renderer %p) %s%s%s\n", prefix, nodeName().utf8().data(), this, renderer(), attrs.toString().utf8().data(), needsStyleRecalc() ? " (needs style recalc)" : "", childNeedsStyleRecalc() ? " (child needs style recalc)" : "");
1736 void Node::showTreeForThis() const
1738 showTreeAndMark(this, "*");
1741 void Node::showNodePathForThis() const
1743 Vector<const Node*, 16> chain;
1744 const Node* node = this;
1745 while (node->parentOrShadowHostNode()) {
1747 node = node->parentOrShadowHostNode();
1749 for (unsigned index = chain.size(); index > 0; --index) {
1750 const Node* node = chain[index - 1];
1751 if (is<ShadowRoot>(*node)) {
1753 for (const ShadowRoot* shadowRoot = downcast<ShadowRoot>(node); shadowRoot && shadowRoot != node; shadowRoot = shadowRoot->shadowRoot())
1755 fprintf(stderr, "/#shadow-root[%d]", count);
1759 switch (node->nodeType()) {
1760 case ELEMENT_NODE: {
1761 fprintf(stderr, "/%s", node->nodeName().utf8().data());
1763 const Element& element = downcast<Element>(*node);
1764 const AtomicString& idattr = element.getIdAttribute();
1765 bool hasIdAttr = !idattr.isNull() && !idattr.isEmpty();
1766 if (node->previousSibling() || node->nextSibling()) {
1768 for (Node* previous = node->previousSibling(); previous; previous = previous->previousSibling())
1769 if (previous->nodeName() == node->nodeName())
1772 fprintf(stderr, "[@id=\"%s\" and position()=%d]", idattr.string().utf8().data(), count);
1774 fprintf(stderr, "[%d]", count);
1775 } else if (hasIdAttr)
1776 fprintf(stderr, "[@id=\"%s\"]", idattr.string().utf8().data());
1780 fprintf(stderr, "/text()");
1782 case ATTRIBUTE_NODE:
1783 fprintf(stderr, "/@%s", node->nodeName().utf8().data());
1789 fprintf(stderr, "\n");
1792 static void traverseTreeAndMark(const String& baseIndent, const Node* rootNode, const Node* markedNode1, const char* markedLabel1, const Node* markedNode2, const char* markedLabel2)
1794 for (const Node* node = rootNode; node; node = NodeTraversal::next(*node)) {
1795 if (node == markedNode1)
1796 fprintf(stderr, "%s", markedLabel1);
1797 if (node == markedNode2)
1798 fprintf(stderr, "%s", markedLabel2);
1800 StringBuilder indent;
1801 indent.append(baseIndent);
1802 for (const Node* tmpNode = node; tmpNode && tmpNode != rootNode; tmpNode = tmpNode->parentOrShadowHostNode())
1803 indent.append('\t');
1804 fprintf(stderr, "%s", indent.toString().utf8().data());
1806 indent.append('\t');
1807 if (!node->isShadowRoot()) {
1808 if (ShadowRoot* shadowRoot = node->shadowRoot())
1809 traverseTreeAndMark(indent.toString(), shadowRoot, markedNode1, markedLabel1, markedNode2, markedLabel2);
1814 void Node::showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2, const char* markedLabel2) const
1816 const Node* rootNode;
1817 const Node* node = this;
1818 while (node->parentOrShadowHostNode() && !node->hasTagName(bodyTag))
1819 node = node->parentOrShadowHostNode();
1822 String startingIndent;
1823 traverseTreeAndMark(startingIndent, rootNode, markedNode1, markedLabel1, markedNode2, markedLabel2);
1826 void Node::formatForDebugger(char* buffer, unsigned length) const
1837 strncpy(buffer, result.utf8().data(), length - 1);
1840 static ContainerNode* parentOrShadowHostOrFrameOwner(const Node* node)
1842 ContainerNode* parent = node->parentOrShadowHostNode();
1843 if (!parent && node->document().frame())
1844 parent = node->document().frame()->ownerElement();
1848 static void showSubTreeAcrossFrame(const Node* node, const Node* markedNode, const String& indent)
1850 if (node == markedNode)
1852 fputs(indent.utf8().data(), stderr);
1854 if (!node->isShadowRoot()) {
1855 if (node->isFrameOwnerElement())
1856 showSubTreeAcrossFrame(static_cast<const HTMLFrameOwnerElement*>(node)->contentDocument(), markedNode, indent + "\t");
1857 if (ShadowRoot* shadowRoot = node->shadowRoot())
1858 showSubTreeAcrossFrame(shadowRoot, markedNode, indent + "\t");
1860 for (Node* child = node->firstChild(); child; child = child->nextSibling())
1861 showSubTreeAcrossFrame(child, markedNode, indent + "\t");
1864 void Node::showTreeForThisAcrossFrame() const
1866 Node* rootNode = const_cast<Node*>(this);
1867 while (parentOrShadowHostOrFrameOwner(rootNode))
1868 rootNode = parentOrShadowHostOrFrameOwner(rootNode);
1869 showSubTreeAcrossFrame(rootNode, this, "");
1872 #endif // ENABLE(TREE_DEBUGGING)
1876 void NodeListsNodeData::invalidateCaches()
1878 for (auto& atomicName : m_atomicNameCaches)
1879 atomicName.value->invalidateCache();
1881 for (auto& collection : m_cachedCollections)
1882 collection.value->invalidateCache();
1884 for (auto& tagCollection : m_tagCollectionNSCache)
1885 tagCollection.value->invalidateCache();
1888 void NodeListsNodeData::invalidateCachesForAttribute(const QualifiedName& attrName)
1890 for (auto& atomicName : m_atomicNameCaches)
1891 atomicName.value->invalidateCacheForAttribute(attrName);
1893 for (auto& collection : m_cachedCollections)
1894 collection.value->invalidateCacheForAttribute(attrName);
1897 void Node::getSubresourceURLs(ListHashSet<URL>& urls) const
1899 addSubresourceAttributeURLs(urls);
1902 Element* Node::enclosingLinkEventParentOrSelf()
1904 for (Node* node = this; node; node = node->parentInComposedTree()) {
1905 // For imagemaps, the enclosing link element is the associated area element not the image itself.
1906 // So we don't let images be the enclosing link element, even though isLink sometimes returns
1908 if (node->isLink() && !is<HTMLImageElement>(*node))
1909 return downcast<Element>(node);
1915 EventTargetInterface Node::eventTargetInterface() const
1917 return NodeEventTargetInterfaceType;
1920 #if !ASSERT_DISABLED || ENABLE(SECURITY_ASSERTIONS)
1921 class DidMoveToNewDocumentAssertionScope {
1923 DidMoveToNewDocumentAssertionScope(Node& node, Document& oldDocument, Document& newDocument)
1925 , m_oldDocument(oldDocument)
1926 , m_newDocument(newDocument)
1927 , m_previousScope(s_scope)
1932 ~DidMoveToNewDocumentAssertionScope()
1934 RELEASE_ASSERT(m_called);
1935 s_scope = m_previousScope;
1938 static void didRecieveCall(Node& node, Document& oldDocument, Document& newDocument)
1940 RELEASE_ASSERT(s_scope);
1941 RELEASE_ASSERT(!s_scope->m_called);
1942 RELEASE_ASSERT(&s_scope->m_node == &node);
1943 RELEASE_ASSERT(&s_scope->m_oldDocument == &oldDocument);
1944 RELEASE_ASSERT(&s_scope->m_newDocument == &newDocument);
1945 s_scope->m_called = true;
1950 Document& m_oldDocument;
1951 Document& m_newDocument;
1952 bool m_called { false };
1953 DidMoveToNewDocumentAssertionScope* m_previousScope;
1955 static DidMoveToNewDocumentAssertionScope* s_scope;
1958 DidMoveToNewDocumentAssertionScope* DidMoveToNewDocumentAssertionScope::s_scope = nullptr;
1961 class DidMoveToNewDocumentAssertionScope {
1963 DidMoveToNewDocumentAssertionScope(Node&, Document&, Document&) { }
1964 static void didRecieveCall(Node&, Document&, Document&) { }
1968 static ALWAYS_INLINE void moveNodeToNewDocument(Node& node, Document& oldDocument, Document& newDocument)
1970 ASSERT(!node.isConnected() || &oldDocument != &newDocument);
1971 DidMoveToNewDocumentAssertionScope scope(node, oldDocument, newDocument);
1972 node.didMoveToNewDocument(oldDocument, newDocument);
1973 RELEASE_ASSERT(&node.document() == &newDocument);
1976 template <typename MoveNodeFunction, typename MoveShadowRootFunction>
1977 static void traverseSubtreeToUpdateTreeScope(Node& root, MoveNodeFunction moveNode, MoveShadowRootFunction moveShadowRoot)
1979 for (Node* node = &root; node; node = NodeTraversal::next(*node, &root)) {
1982 if (!is<Element>(*node))
1984 Element& element = downcast<Element>(*node);
1986 if (element.hasSyntheticAttrChildNodes()) {
1987 for (auto& attr : element.attrNodeList())
1991 if (auto* shadow = element.shadowRoot())
1992 moveShadowRoot(*shadow);
1996 static void moveShadowTreeToNewDocument(ShadowRoot& shadowRoot, Document& oldDocument, Document& newDocument)
1998 traverseSubtreeToUpdateTreeScope(shadowRoot, [&oldDocument, &newDocument](Node& node) {
1999 moveNodeToNewDocument(node, oldDocument, newDocument);
2000 }, [&oldDocument, &newDocument](ShadowRoot& innerShadowRoot) {
2001 RELEASE_ASSERT(&innerShadowRoot.document() == &oldDocument);
2002 moveShadowTreeToNewDocument(innerShadowRoot, oldDocument, newDocument);
2006 void Node::moveTreeToNewScope(Node& root, TreeScope& oldScope, TreeScope& newScope)
2008 ASSERT(&oldScope != &newScope);
2009 RELEASE_ASSERT(&root.treeScope() == &oldScope);
2011 Document& oldDocument = oldScope.documentScope();
2012 Document& newDocument = newScope.documentScope();
2013 if (&oldDocument != &newDocument) {
2014 oldDocument.incrementReferencingNodeCount();
2015 traverseSubtreeToUpdateTreeScope(root, [&](Node& node) {
2016 ASSERT(!node.isTreeScope());
2017 RELEASE_ASSERT(&node.treeScope() == &oldScope);
2018 RELEASE_ASSERT(&node.document() == &oldDocument);
2019 node.setTreeScope(newScope);
2020 moveNodeToNewDocument(node, oldDocument, newDocument);
2021 }, [&](ShadowRoot& shadowRoot) {
2022 ASSERT_WITH_SECURITY_IMPLICATION(&shadowRoot.document() == &oldDocument);
2023 shadowRoot.setParentTreeScope(newScope);
2024 moveShadowTreeToNewDocument(shadowRoot, oldDocument, newDocument);
2026 oldDocument.decrementReferencingNodeCount();
2028 traverseSubtreeToUpdateTreeScope(root, [&](Node& node) {
2029 ASSERT(!node.isTreeScope());
2030 RELEASE_ASSERT(&node.treeScope() == &oldScope);
2031 node.setTreeScope(newScope);
2032 if (!node.hasRareData())
2034 if (auto* nodeLists = node.rareData()->nodeLists())
2035 nodeLists->adoptTreeScope();
2036 }, [&newScope](ShadowRoot& shadowRoot) {
2037 shadowRoot.setParentTreeScope(newScope);
2042 void Node::didMoveToNewDocument(Document& oldDocument, Document& newDocument)
2044 RELEASE_ASSERT(&document() == &newDocument);
2045 DidMoveToNewDocumentAssertionScope::didRecieveCall(*this, oldDocument, newDocument);
2047 newDocument.incrementReferencingNodeCount();
2048 oldDocument.decrementReferencingNodeCount();
2050 if (hasRareData()) {
2051 if (auto* nodeLists = rareData()->nodeLists())
2052 nodeLists->adoptDocument(oldDocument, newDocument);
2055 oldDocument.moveNodeIteratorsToNewDocument(*this, newDocument);
2057 if (auto* eventTargetData = this->eventTargetData()) {
2058 if (!eventTargetData->eventListenerMap.isEmpty()) {
2059 for (auto& type : eventTargetData->eventListenerMap.eventTypes())
2060 newDocument.addListenerTypeIfNeeded(type);
2064 if (AXObjectCache::accessibilityEnabled()) {
2065 if (auto* cache = oldDocument.existingAXObjectCache())
2066 cache->remove(this);
2069 unsigned numWheelEventHandlers = eventListeners(eventNames().mousewheelEvent).size() + eventListeners(eventNames().wheelEvent).size();
2070 for (unsigned i = 0; i < numWheelEventHandlers; ++i) {
2071 oldDocument.didRemoveWheelEventHandler(*this);
2072 newDocument.didAddWheelEventHandler(*this);
2075 unsigned numTouchEventListeners = 0;
2076 for (auto& name : eventNames().touchEventNames())
2077 numTouchEventListeners += eventListeners(name).size();
2079 for (unsigned i = 0; i < numTouchEventListeners; ++i) {
2080 oldDocument.didRemoveTouchEventHandler(*this);
2081 newDocument.didAddTouchEventHandler(*this);
2083 #if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS)
2084 oldDocument.removeTouchEventListener(*this);
2085 newDocument.addTouchEventListener(*this);
2089 #if ENABLE(TOUCH_EVENTS) && ENABLE(IOS_GESTURE_EVENTS)
2090 unsigned numGestureEventListeners = 0;
2091 for (auto& name : eventNames().gestureEventNames())
2092 numGestureEventListeners += eventListeners(name).size();
2094 for (unsigned i = 0; i < numGestureEventListeners; ++i) {
2095 oldDocument.removeTouchEventHandler(*this);
2096 newDocument.addTouchEventHandler(*this);
2100 if (auto* registry = mutationObserverRegistry()) {
2101 for (auto& registration : *registry)
2102 newDocument.addMutationObserverTypes(registration->mutationTypes());
2105 if (auto* transientRegistry = transientMutationObserverRegistry()) {
2106 for (auto& registration : *transientRegistry)
2107 newDocument.addMutationObserverTypes(registration->mutationTypes());
2110 #if !ASSERT_DISABLED || ENABLE(SECURITY_ASSERTIONS)
2111 #if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS)
2112 ASSERT_WITH_SECURITY_IMPLICATION(!oldDocument.touchEventListenersContain(*this));
2113 ASSERT_WITH_SECURITY_IMPLICATION(!oldDocument.touchEventHandlersContain(*this));
2115 #if ENABLE(TOUCH_EVENTS) && ENABLE(IOS_GESTURE_EVENTS)
2116 ASSERT_WITH_SECURITY_IMPLICATION(!oldDocument.touchEventTargetsContain(*this));
2121 static inline bool tryAddEventListener(Node* targetNode, const AtomicString& eventType, Ref<EventListener>&& listener, const EventTarget::AddEventListenerOptions& options)
2123 if (!targetNode->EventTarget::addEventListener(eventType, listener.copyRef(), options))
2126 targetNode->document().addListenerTypeIfNeeded(eventType);
2127 if (eventNames().isWheelEventType(eventType))
2128 targetNode->document().didAddWheelEventHandler(*targetNode);
2129 else if (eventNames().isTouchEventType(eventType))
2130 targetNode->document().didAddTouchEventHandler(*targetNode);
2133 if (targetNode == &targetNode->document() && eventType == eventNames().scrollEvent)
2134 targetNode->document().domWindow()->incrementScrollEventListenersCount();
2136 // FIXME: Would it be sufficient to special-case this code for <body> and <frameset>?
2138 // This code was added to address <rdar://problem/5846492> Onorientationchange event not working for document.body.
2139 // Forward this call to addEventListener() to the window since these are window-only events.
2140 if (eventType == eventNames().orientationchangeEvent || eventType == eventNames().resizeEvent)
2141 targetNode->document().domWindow()->addEventListener(eventType, WTFMove(listener), options);
2143 #if ENABLE(TOUCH_EVENTS)
2144 if (eventNames().isTouchEventType(eventType))
2145 targetNode->document().addTouchEventListener(*targetNode);
2147 #endif // PLATFORM(IOS)
2149 #if ENABLE(IOS_GESTURE_EVENTS) && ENABLE(TOUCH_EVENTS)
2150 if (eventNames().isGestureEventType(eventType))
2151 targetNode->document().addTouchEventHandler(*targetNode);
2157 bool Node::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, const AddEventListenerOptions& options)
2159 return tryAddEventListener(this, eventType, WTFMove(listener), options);
2162 static inline bool tryRemoveEventListener(Node* targetNode, const AtomicString& eventType, EventListener& listener, const EventTarget::ListenerOptions& options)
2164 if (!targetNode->EventTarget::removeEventListener(eventType, listener, options))
2167 // FIXME: Notify Document that the listener has vanished. We need to keep track of a number of
2168 // listeners for each type, not just a bool - see https://bugs.webkit.org/show_bug.cgi?id=33861
2169 if (eventNames().isWheelEventType(eventType))
2170 targetNode->document().didRemoveWheelEventHandler(*targetNode);
2171 else if (eventNames().isTouchEventType(eventType))
2172 targetNode->document().didRemoveTouchEventHandler(*targetNode);
2175 if (targetNode == &targetNode->document() && eventType == eventNames().scrollEvent)
2176 targetNode->document().domWindow()->decrementScrollEventListenersCount();
2178 // FIXME: Would it be sufficient to special-case this code for <body> and <frameset>? See <rdar://problem/15647823>.
2179 // This code was added to address <rdar://problem/5846492> Onorientationchange event not working for document.body.
2180 // Forward this call to removeEventListener() to the window since these are window-only events.
2181 if (eventType == eventNames().orientationchangeEvent || eventType == eventNames().resizeEvent)
2182 targetNode->document().domWindow()->removeEventListener(eventType, listener, options);
2184 #if ENABLE(TOUCH_EVENTS)
2185 if (eventNames().isTouchEventType(eventType))
2186 targetNode->document().removeTouchEventListener(*targetNode);
2188 #endif // PLATFORM(IOS)
2190 #if ENABLE(IOS_GESTURE_EVENTS) && ENABLE(TOUCH_EVENTS)
2191 if (eventNames().isGestureEventType(eventType))
2192 targetNode->document().removeTouchEventHandler(*targetNode);
2198 bool Node::removeEventListener(const AtomicString& eventType, EventListener& listener, const ListenerOptions& options)
2200 return tryRemoveEventListener(this, eventType, listener, options);
2203 typedef HashMap<Node*, std::unique_ptr<EventTargetData>> EventTargetDataMap;
2205 static EventTargetDataMap& eventTargetDataMap()
2207 static NeverDestroyed<EventTargetDataMap> map;
2212 static StaticLock s_eventTargetDataMapLock;
2214 EventTargetData* Node::eventTargetData()
2216 return hasEventTargetData() ? eventTargetDataMap().get(this) : nullptr;
2219 EventTargetData* Node::eventTargetDataConcurrently()
2221 auto locker = holdLock(s_eventTargetDataMapLock);
2222 return hasEventTargetData() ? eventTargetDataMap().get(this) : nullptr;
2225 EventTargetData& Node::ensureEventTargetData()
2227 if (hasEventTargetData())
2228 return *eventTargetDataMap().get(this);
2230 auto locker = holdLock(s_eventTargetDataMapLock);
2231 setHasEventTargetData(true);
2232 return *eventTargetDataMap().add(this, std::make_unique<EventTargetData>()).iterator->value;
2235 void Node::clearEventTargetData()
2237 auto locker = holdLock(s_eventTargetDataMapLock);
2238 eventTargetDataMap().remove(this);
2241 Vector<std::unique_ptr<MutationObserverRegistration>>* Node::mutationObserverRegistry()
2245 auto* data = rareData()->mutationObserverData();
2248 return &data->registry;
2251 HashSet<MutationObserverRegistration*>* Node::transientMutationObserverRegistry()
2255 auto* data = rareData()->mutationObserverData();
2258 return &data->transientRegistry;
2261 template<typename Registry> static inline void collectMatchingObserversForMutation(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, Registry* registry, Node& target, MutationObserver::MutationType type, const QualifiedName* attributeName)
2266 for (auto& registration : *registry) {
2267 if (registration->shouldReceiveMutationFrom(target, type, attributeName)) {
2268 auto deliveryOptions = registration->deliveryOptions();
2269 auto result = observers.add(®istration->observer(), deliveryOptions);
2270 if (!result.isNewEntry)
2271 result.iterator->value |= deliveryOptions;
2276 HashMap<MutationObserver*, MutationRecordDeliveryOptions> Node::registeredMutationObservers(MutationObserver::MutationType type, const QualifiedName* attributeName)
2278 HashMap<MutationObserver*, MutationRecordDeliveryOptions> result;
2279 ASSERT((type == MutationObserver::Attributes && attributeName) || !attributeName);
2280 collectMatchingObserversForMutation(result, mutationObserverRegistry(), *this, type, attributeName);
2281 collectMatchingObserversForMutation(result, transientMutationObserverRegistry(), *this, type, attributeName);
2282 for (Node* node = parentNode(); node; node = node->parentNode()) {
2283 collectMatchingObserversForMutation(result, node->mutationObserverRegistry(), *this, type, attributeName);
2284 collectMatchingObserversForMutation(result, node->transientMutationObserverRegistry(), *this, type, attributeName);
2289 void Node::registerMutationObserver(MutationObserver& observer, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
2291 MutationObserverRegistration* registration = nullptr;
2292 auto& registry = ensureRareData().ensureMutationObserverData().registry;
2294 for (auto& candidateRegistration : registry) {
2295 if (&candidateRegistration->observer() == &observer) {
2296 registration = candidateRegistration.get();
2297 registration->resetObservation(options, attributeFilter);
2301 if (!registration) {
2302 registry.append(std::make_unique<MutationObserverRegistration>(observer, *this, options, attributeFilter));
2303 registration = registry.last().get();
2306 document().addMutationObserverTypes(registration->mutationTypes());
2309 void Node::unregisterMutationObserver(MutationObserverRegistration& registration)
2311 auto* registry = mutationObserverRegistry();
2316 registry->removeFirstMatching([®istration] (auto& current) {
2317 return current.get() == ®istration;
2321 void Node::registerTransientMutationObserver(MutationObserverRegistration& registration)
2323 ensureRareData().ensureMutationObserverData().transientRegistry.add(®istration);
2326 void Node::unregisterTransientMutationObserver(MutationObserverRegistration& registration)
2328 auto* transientRegistry = transientMutationObserverRegistry();
2329 ASSERT(transientRegistry);
2330 if (!transientRegistry)
2333 ASSERT(transientRegistry->contains(®istration));
2334 transientRegistry->remove(®istration);
2337 void Node::notifyMutationObserversNodeWillDetach()
2339 if (!document().hasMutationObservers())
2342 for (Node* node = parentNode(); node; node = node->parentNode()) {
2343 if (auto* registry = node->mutationObserverRegistry()) {
2344 for (auto& registration : *registry)
2345 registration->observedSubtreeNodeWillDetach(*this);
2347 if (auto* transientRegistry = node->transientMutationObserverRegistry()) {
2348 for (auto* registration : *transientRegistry)
2349 registration->observedSubtreeNodeWillDetach(*this);
2354 void Node::handleLocalEvents(Event& event)
2356 if (!hasEventTargetData())
2359 // FIXME: Should we deliver wheel events to disabled form controls or not?
2360 if (is<Element>(*this) && downcast<Element>(*this).isDisabledFormControl() && event.isMouseEvent() && !event.isWheelEvent())
2363 fireEventListeners(event);
2366 void Node::dispatchScopedEvent(Event& event)
2368 EventDispatcher::dispatchScopedEvent(*this, event);
2371 bool Node::dispatchEvent(Event& event)
2373 #if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS)
2374 if (is<TouchEvent>(event))
2375 return dispatchTouchEvent(downcast<TouchEvent>(event));
2377 return EventDispatcher::dispatchEvent(*this, event);
2380 void Node::dispatchSubtreeModifiedEvent()
2382 if (isInShadowTree())
2385 RELEASE_ASSERT(NoEventDispatchAssertion::isEventDispatchAllowedInSubtree(*this));
2387 if (!document().hasListenerType(Document::DOMSUBTREEMODIFIED_LISTENER))
2389 const AtomicString& subtreeModifiedEventName = eventNames().DOMSubtreeModifiedEvent;
2390 if (!parentNode() && !hasEventListeners(subtreeModifiedEventName))
2393 dispatchScopedEvent(MutationEvent::create(subtreeModifiedEventName, true));
2396 bool Node::dispatchDOMActivateEvent(int detail, Event& underlyingEvent)
2398 RELEASE_ASSERT(NoEventDispatchAssertion::isEventAllowedInMainThread());
2399 Ref<UIEvent> event = UIEvent::create(eventNames().DOMActivateEvent, true, true, document().defaultView(), detail);
2400 event->setUnderlyingEvent(&underlyingEvent);
2401 dispatchScopedEvent(event);
2402 return event->defaultHandled();
2405 #if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS)
2406 bool Node::dispatchTouchEvent(TouchEvent& event)
2408 return EventDispatcher::dispatchEvent(*this, event);
2412 bool Node::dispatchBeforeLoadEvent(const String& sourceURL)
2414 if (!document().hasListenerType(Document::BEFORELOAD_LISTENER))
2417 Ref<Node> protectedThis(*this);
2418 Ref<BeforeLoadEvent> beforeLoadEvent = BeforeLoadEvent::create(sourceURL);
2419 dispatchEvent(beforeLoadEvent);
2420 return !beforeLoadEvent->defaultPrevented();
2423 void Node::dispatchInputEvent()
2425 dispatchScopedEvent(Event::create(eventNames().inputEvent, true, false));
2428 void Node::defaultEventHandler(Event& event)
2430 if (event.target() != this)
2432 const AtomicString& eventType = event.type();
2433 if (eventType == eventNames().keydownEvent || eventType == eventNames().keypressEvent) {
2434 if (is<KeyboardEvent>(event)) {
2435 if (Frame* frame = document().frame())
2436 frame->eventHandler().defaultKeyboardEventHandler(downcast<KeyboardEvent>(event));
2438 } else if (eventType == eventNames().clickEvent) {
2439 int detail = is<UIEvent>(event) ? downcast<UIEvent>(event).detail() : 0;
2440 if (dispatchDOMActivateEvent(detail, event))
2441 event.setDefaultHandled();
2442 #if ENABLE(CONTEXT_MENUS)
2443 } else if (eventType == eventNames().contextmenuEvent) {
2444 if (Frame* frame = document().frame())
2445 if (Page* page = frame->page())
2446 page->contextMenuController().handleContextMenuEvent(event);
2448 } else if (eventType == eventNames().textInputEvent) {
2449 if (is<TextEvent>(event)) {
2450 if (Frame* frame = document().frame())
2451 frame->eventHandler().defaultTextInputEventHandler(downcast<TextEvent>(event));
2453 #if ENABLE(PAN_SCROLLING)
2454 } else if (eventType == eventNames().mousedownEvent && is<MouseEvent>(event)) {
2455 if (downcast<MouseEvent>(event).button() == MiddleButton) {
2456 if (enclosingLinkEventParentOrSelf())
2459 RenderObject* renderer = this->renderer();
2460 while (renderer && (!is<RenderBox>(*renderer) || !downcast<RenderBox>(*renderer).canBeScrolledAndHasScrollableArea()))
2461 renderer = renderer->parent();
2464 if (Frame* frame = document().frame())
2465 frame->eventHandler().startPanScrolling(downcast<RenderBox>(*renderer));
2469 } else if (eventNames().isWheelEventType(eventType) && is<WheelEvent>(event)) {
2470 // If we don't have a renderer, send the wheel event to the first node we find with a renderer.
2471 // This is needed for <option> and <optgroup> elements so that <select>s get a wheel scroll.
2472 Node* startNode = this;
2473 while (startNode && !startNode->renderer())
2474 startNode = startNode->parentOrShadowHostNode();
2476 if (startNode && startNode->renderer())
2477 if (Frame* frame = document().frame())
2478 frame->eventHandler().defaultWheelEventHandler(startNode, downcast<WheelEvent>(event));
2479 #if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS)
2480 } else if (is<TouchEvent>(event) && eventNames().isTouchEventType(eventType)) {
2481 RenderObject* renderer = this->renderer();
2482 while (renderer && (!is<RenderBox>(*renderer) || !downcast<RenderBox>(*renderer).canBeScrolledAndHasScrollableArea()))
2483 renderer = renderer->parent();
2485 if (renderer && renderer->node()) {
2486 if (Frame* frame = document().frame())
2487 frame->eventHandler().defaultTouchEventHandler(*renderer->node(), downcast<TouchEvent>(event));
2493 bool Node::willRespondToMouseMoveEvents()
2495 // FIXME: Why is the iOS code path different from the non-iOS code path?
2497 if (!is<Element>(*this))
2499 if (downcast<Element>(*this).isDisabledFormControl())
2502 return hasEventListeners(eventNames().mousemoveEvent) || hasEventListeners(eventNames().mouseoverEvent) || hasEventListeners(eventNames().mouseoutEvent);
2505 bool Node::willRespondToMouseClickEvents()
2507 // FIXME: Why is the iOS code path different from the non-iOS code path?
2509 return isContentEditable() || hasEventListeners(eventNames().mouseupEvent) || hasEventListeners(eventNames().mousedownEvent) || hasEventListeners(eventNames().clickEvent);
2511 if (!is<Element>(*this))
2513 if (downcast<Element>(*this).isDisabledFormControl())
2515 return computeEditability(UserSelectAllIsAlwaysNonEditable, ShouldUpdateStyle::Update) != Editability::ReadOnly
2516 || hasEventListeners(eventNames().mouseupEvent) || hasEventListeners(eventNames().mousedownEvent) || hasEventListeners(eventNames().clickEvent) || hasEventListeners(eventNames().DOMActivateEvent);
2520 bool Node::willRespondToMouseWheelEvents()
2522 return hasEventListeners(eventNames().mousewheelEvent);
2525 // It's important not to inline removedLastRef, because we don't want to inline the code to
2526 // delete a Node at each deref call site.
2527 void Node::removedLastRef()
2529 // An explicit check for Document here is better than a virtual function since it is
2530 // faster for non-Document nodes, and because the call to removedLastRef that is inlined
2531 // at all deref call sites is smaller if it's a non-virtual function.
2532 if (is<Document>(*this)) {
2533 downcast<Document>(*this).removedLastRef();
2538 m_deletionHasBegun = true;
2543 void Node::textRects(Vector<IntRect>& rects) const
2545 auto range = Range::create(document());
2546 range->selectNodeContents(const_cast<Node&>(*this));
2547 range->absoluteTextRects(rects);
2550 unsigned Node::connectedSubframeCount() const
2552 return hasRareData() ? rareData()->connectedSubframeCount() : 0;
2555 void Node::incrementConnectedSubframeCount(unsigned amount)
2557 ASSERT(isContainerNode());
2558 ensureRareData().incrementConnectedSubframeCount(amount);
2561 void Node::decrementConnectedSubframeCount(unsigned amount)
2563 rareData()->decrementConnectedSubframeCount(amount);
2566 void Node::updateAncestorConnectedSubframeCountForRemoval() const
2568 unsigned count = connectedSubframeCount();
2573 for (Node* node = parentOrShadowHostNode(); node; node = node->parentOrShadowHostNode())
2574 node->decrementConnectedSubframeCount(count);
2577 void Node::updateAncestorConnectedSubframeCountForInsertion() const
2579 unsigned count = connectedSubframeCount();
2584 for (Node* node = parentOrShadowHostNode(); node; node = node->parentOrShadowHostNode())
2585 node->incrementConnectedSubframeCount(count);
2588 bool Node::inRenderedDocument() const
2590 return isConnected() && document().hasLivingRenderTree();
2593 void* Node::opaqueRootSlow() const
2595 const Node* node = this;
2597 const Node* nextNode = node->parentOrShadowHostNode();
2602 return const_cast<void*>(static_cast<const void*>(node));
2605 } // namespace WebCore
2607 #if ENABLE(TREE_DEBUGGING)
2609 void showTree(const WebCore::Node* node)
2612 node->showTreeForThis();
2615 void showNodePath(const WebCore::Node* node)
2618 node->showNodePathForThis();
2621 #endif // ENABLE(TREE_DEBUGGING)