OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ights reserved. | 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All |
| 6 * rights reserved. |
6 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 7 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) | 8 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. |
| 9 * (http://www.torchmobile.com/) |
8 * | 10 * |
9 * This library is free software; you can redistribute it and/or | 11 * This library is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU Library General Public | 12 * modify it under the terms of the GNU Library General Public |
11 * License as published by the Free Software Foundation; either | 13 * License as published by the Free Software Foundation; either |
12 * version 2 of the License, or (at your option) any later version. | 14 * version 2 of the License, or (at your option) any later version. |
13 * | 15 * |
14 * This library is distributed in the hope that it will be useful, | 16 * This library is distributed in the hope that it will be useful, |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 * Library General Public License for more details. | 19 * Library General Public License for more details. |
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 | 535 |
534 void Node::remove(ExceptionState& exceptionState) { | 536 void Node::remove(ExceptionState& exceptionState) { |
535 if (ContainerNode* parent = parentNode()) | 537 if (ContainerNode* parent = parentNode()) |
536 parent->removeChild(this, exceptionState); | 538 parent->removeChild(this, exceptionState); |
537 } | 539 } |
538 | 540 |
539 void Node::normalize() { | 541 void Node::normalize() { |
540 updateDistribution(); | 542 updateDistribution(); |
541 | 543 |
542 // Go through the subtree beneath us, normalizing all nodes. This means that | 544 // Go through the subtree beneath us, normalizing all nodes. This means that |
543 // any two adjacent text nodes are merged and any empty text nodes are removed
. | 545 // any two adjacent text nodes are merged and any empty text nodes are |
| 546 // removed. |
544 | 547 |
545 Node* node = this; | 548 Node* node = this; |
546 while (Node* firstChild = node->firstChild()) | 549 while (Node* firstChild = node->firstChild()) |
547 node = firstChild; | 550 node = firstChild; |
548 while (node) { | 551 while (node) { |
549 if (node == this) | 552 if (node == this) |
550 break; | 553 break; |
551 | 554 |
552 if (node->getNodeType() == kTextNode) | 555 if (node->getNodeType() == kTextNode) |
553 node = toText(node)->mergeNextSiblingNodesIfPossible(); | 556 node = toText(node)->mergeNextSiblingNodesIfPossible(); |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
860 otherIterator = parent(*otherIterator); | 863 otherIterator = parent(*otherIterator); |
861 } | 864 } |
862 DCHECK(!otherIterator); | 865 DCHECK(!otherIterator); |
863 return nullptr; | 866 return nullptr; |
864 } | 867 } |
865 | 868 |
866 void Node::reattachLayoutTree(const AttachContext& context) { | 869 void Node::reattachLayoutTree(const AttachContext& context) { |
867 AttachContext reattachContext(context); | 870 AttachContext reattachContext(context); |
868 reattachContext.performingReattach = true; | 871 reattachContext.performingReattach = true; |
869 | 872 |
870 // We only need to detach if the node has already been through attachLayoutTre
e(). | 873 // We only need to detach if the node has already been through |
| 874 // attachLayoutTree(). |
871 if (getStyleChangeType() < NeedsReattachStyleChange) | 875 if (getStyleChangeType() < NeedsReattachStyleChange) |
872 detachLayoutTree(reattachContext); | 876 detachLayoutTree(reattachContext); |
873 attachLayoutTree(reattachContext); | 877 attachLayoutTree(reattachContext); |
874 } | 878 } |
875 | 879 |
876 void Node::attachLayoutTree(const AttachContext&) { | 880 void Node::attachLayoutTree(const AttachContext&) { |
877 DCHECK(document().inStyleRecalc() || isDocumentNode()); | 881 DCHECK(document().inStyleRecalc() || isDocumentNode()); |
878 DCHECK(!document().lifecycle().inDetach()); | 882 DCHECK(!document().lifecycle().inDetach()); |
879 DCHECK(needsAttach()); | 883 DCHECK(needsAttach()); |
880 DCHECK(!layoutObject() || | 884 DCHECK(!layoutObject() || |
(...skipping 16 matching lines...) Expand all Loading... |
897 setStyleChange(NeedsReattachStyleChange); | 901 setStyleChange(NeedsReattachStyleChange); |
898 clearChildNeedsStyleInvalidation(); | 902 clearChildNeedsStyleInvalidation(); |
899 } | 903 } |
900 | 904 |
901 void Node::reattachWhitespaceSiblingsIfNeeded(Text* start) { | 905 void Node::reattachWhitespaceSiblingsIfNeeded(Text* start) { |
902 ScriptForbiddenScope forbidScriptDuringRawIteration; | 906 ScriptForbiddenScope forbidScriptDuringRawIteration; |
903 for (Node* sibling = start; sibling; sibling = sibling->nextSibling()) { | 907 for (Node* sibling = start; sibling; sibling = sibling->nextSibling()) { |
904 if (sibling->isTextNode() && toText(sibling)->containsOnlyWhitespace()) { | 908 if (sibling->isTextNode() && toText(sibling)->containsOnlyWhitespace()) { |
905 bool hadLayoutObject = !!sibling->layoutObject(); | 909 bool hadLayoutObject = !!sibling->layoutObject(); |
906 toText(sibling)->reattachLayoutTreeIfNeeded(); | 910 toText(sibling)->reattachLayoutTreeIfNeeded(); |
907 // If sibling's layout object status didn't change we don't need to contin
ue checking | 911 // If sibling's layout object status didn't change we don't need to |
908 // other siblings since their layout object status won't change either. | 912 // continue checking other siblings since their layout object status won't |
| 913 // change either. |
909 if (!!sibling->layoutObject() == hadLayoutObject) | 914 if (!!sibling->layoutObject() == hadLayoutObject) |
910 return; | 915 return; |
911 } else if (sibling->layoutObject()) { | 916 } else if (sibling->layoutObject()) { |
912 return; | 917 return; |
913 } | 918 } |
914 } | 919 } |
915 } | 920 } |
916 | 921 |
917 const ComputedStyle* Node::virtualEnsureComputedStyle( | 922 const ComputedStyle* Node::virtualEnsureComputedStyle( |
918 PseudoId pseudoElementSpecifier) { | 923 PseudoId pseudoElementSpecifier) { |
919 return parentOrShadowHostNode() | 924 return parentOrShadowHostNode() |
920 ? parentOrShadowHostNode()->ensureComputedStyle( | 925 ? parentOrShadowHostNode()->ensureComputedStyle( |
921 pseudoElementSpecifier) | 926 pseudoElementSpecifier) |
922 : nullptr; | 927 : nullptr; |
923 } | 928 } |
924 | 929 |
925 int Node::maxCharacterOffset() const { | 930 int Node::maxCharacterOffset() const { |
926 ASSERT_NOT_REACHED(); | 931 ASSERT_NOT_REACHED(); |
927 return 0; | 932 return 0; |
928 } | 933 } |
929 | 934 |
930 // FIXME: Shouldn't these functions be in the editing code? Code that asks ques
tions about HTML in the core DOM class | 935 // FIXME: Shouldn't these functions be in the editing code? Code that asks |
931 // is obviously misplaced. | 936 // questions about HTML in the core DOM class is obviously misplaced. |
932 bool Node::canStartSelection() const { | 937 bool Node::canStartSelection() const { |
933 if (isDisabledFormControl(this)) | 938 if (isDisabledFormControl(this)) |
934 return false; | 939 return false; |
935 | 940 |
936 if (hasEditableStyle(*this)) | 941 if (hasEditableStyle(*this)) |
937 return true; | 942 return true; |
938 | 943 |
939 if (layoutObject()) { | 944 if (layoutObject()) { |
940 const ComputedStyle& style = layoutObject()->styleRef(); | 945 const ComputedStyle& style = layoutObject()->styleRef(); |
941 // We allow selections to begin within an element that has -webkit-user-sele
ct: none set, | 946 // We allow selections to begin within an element that has |
942 // but if the element is draggable then dragging should take priority over s
election. | 947 // -webkit-user-select: none set, but if the element is draggable then |
| 948 // dragging should take priority over selection. |
943 if (style.userDrag() == DRAG_ELEMENT && style.userSelect() == SELECT_NONE) | 949 if (style.userDrag() == DRAG_ELEMENT && style.userSelect() == SELECT_NONE) |
944 return false; | 950 return false; |
945 } | 951 } |
946 ContainerNode* parent = FlatTreeTraversal::parent(*this); | 952 ContainerNode* parent = FlatTreeTraversal::parent(*this); |
947 return parent ? parent->canStartSelection() : true; | 953 return parent ? parent->canStartSelection() : true; |
948 } | 954 } |
949 | 955 |
950 // StyledElements allow inline style (style="border: 1px"), presentational attri
butes (ex. color), | 956 // StyledElements allow inline style (style="border: 1px"), presentational |
951 // class names (ex. class="foo bar") and other non-basic styling features. They
also control | 957 // attributes (ex. color), class names (ex. class="foo bar") and other non-basic |
952 // if this element can participate in style sharing. | 958 // styling features. They also control if this element can participate in style |
| 959 // sharing. |
953 // | 960 // |
954 // FIXME: The only things that ever go through StyleResolver that aren't StyledE
lements are | 961 // FIXME: The only things that ever go through StyleResolver that aren't |
955 // PseudoElements and VTTElements. It's possible we can just eliminate all the c
hecks | 962 // StyledElements are PseudoElements and VTTElements. It's possible we can just |
956 // since those elements will never have class names, inline style, or other thin
gs that | 963 // eliminate all the checks since those elements will never have class names, |
957 // this apparently guards against. | 964 // inline style, or other things that this apparently guards against. |
958 bool Node::isStyledElement() const { | 965 bool Node::isStyledElement() const { |
959 return isHTMLElement() || isSVGElement() || | 966 return isHTMLElement() || isSVGElement() || |
960 (isElementNode() && | 967 (isElementNode() && |
961 toElement(this)->namespaceURI() == MathMLNames::mathmlNamespaceURI); | 968 toElement(this)->namespaceURI() == MathMLNames::mathmlNamespaceURI); |
962 } | 969 } |
963 | 970 |
964 bool Node::canParticipateInFlatTree() const { | 971 bool Node::canParticipateInFlatTree() const { |
965 // TODO(hayato): Return false for pseudo elements. | 972 // TODO(hayato): Return false for pseudo elements. |
966 return !isShadowRoot() && !isSlotOrActiveInsertionPoint(); | 973 return !isShadowRoot() && !isSlotOrActiveInsertionPoint(); |
967 } | 974 } |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1324 if (otherNode == this) | 1331 if (otherNode == this) |
1325 return kDocumentPositionEquivalent; | 1332 return kDocumentPositionEquivalent; |
1326 | 1333 |
1327 const Attr* attr1 = getNodeType() == kAttributeNode ? toAttr(this) : nullptr; | 1334 const Attr* attr1 = getNodeType() == kAttributeNode ? toAttr(this) : nullptr; |
1328 const Attr* attr2 = | 1335 const Attr* attr2 = |
1329 otherNode->getNodeType() == kAttributeNode ? toAttr(otherNode) : nullptr; | 1336 otherNode->getNodeType() == kAttributeNode ? toAttr(otherNode) : nullptr; |
1330 | 1337 |
1331 const Node* start1 = attr1 ? attr1->ownerElement() : this; | 1338 const Node* start1 = attr1 ? attr1->ownerElement() : this; |
1332 const Node* start2 = attr2 ? attr2->ownerElement() : otherNode; | 1339 const Node* start2 = attr2 ? attr2->ownerElement() : otherNode; |
1333 | 1340 |
1334 // If either of start1 or start2 is null, then we are disconnected, since one
of the nodes is | 1341 // If either of start1 or start2 is null, then we are disconnected, since one |
1335 // an orphaned attribute node. | 1342 // of the nodes is an orphaned attribute node. |
1336 if (!start1 || !start2) { | 1343 if (!start1 || !start2) { |
1337 unsigned short direction = (this > otherNode) ? kDocumentPositionPreceding | 1344 unsigned short direction = (this > otherNode) ? kDocumentPositionPreceding |
1338 : kDocumentPositionFollowing; | 1345 : kDocumentPositionFollowing; |
1339 return kDocumentPositionDisconnected | | 1346 return kDocumentPositionDisconnected | |
1340 kDocumentPositionImplementationSpecific | direction; | 1347 kDocumentPositionImplementationSpecific | direction; |
1341 } | 1348 } |
1342 | 1349 |
1343 HeapVector<Member<const Node>, 16> chain1; | 1350 HeapVector<Member<const Node>, 16> chain1; |
1344 HeapVector<Member<const Node>, 16> chain2; | 1351 HeapVector<Member<const Node>, 16> chain2; |
1345 if (attr1) | 1352 if (attr1) |
1346 chain1.append(attr1); | 1353 chain1.append(attr1); |
1347 if (attr2) | 1354 if (attr2) |
1348 chain2.append(attr2); | 1355 chain2.append(attr2); |
1349 | 1356 |
1350 if (attr1 && attr2 && start1 == start2 && start1) { | 1357 if (attr1 && attr2 && start1 == start2 && start1) { |
1351 // We are comparing two attributes on the same node. Crawl our attribute map
and see which one we hit first. | 1358 // We are comparing two attributes on the same node. Crawl our attribute map |
| 1359 // and see which one we hit first. |
1352 const Element* owner1 = attr1->ownerElement(); | 1360 const Element* owner1 = attr1->ownerElement(); |
1353 AttributeCollection attributes = owner1->attributes(); | 1361 AttributeCollection attributes = owner1->attributes(); |
1354 for (const Attribute& attr : attributes) { | 1362 for (const Attribute& attr : attributes) { |
1355 // If neither of the two determining nodes is a child node and nodeType is
the same for both determining nodes, then an | 1363 // If neither of the two determining nodes is a child node and nodeType is |
1356 // implementation-dependent order between the determining nodes is returne
d. This order is stable as long as no nodes of | 1364 // the same for both determining nodes, then an implementation-dependent |
1357 // the same nodeType are inserted into or removed from the direct containe
r. This would be the case, for example, | 1365 // order between the determining nodes is returned. This order is stable |
1358 // when comparing two attributes of the same element, and inserting or rem
oving additional attributes might change | 1366 // as long as no nodes of the same nodeType are inserted into or removed |
1359 // the order between existing attributes. | 1367 // from the direct container. This would be the case, for example, when |
| 1368 // comparing two attributes of the same element, and inserting or removing |
| 1369 // additional attributes might change the order between existing |
| 1370 // attributes. |
1360 if (attr1->getQualifiedName() == attr.name()) | 1371 if (attr1->getQualifiedName() == attr.name()) |
1361 return kDocumentPositionImplementationSpecific | | 1372 return kDocumentPositionImplementationSpecific | |
1362 kDocumentPositionFollowing; | 1373 kDocumentPositionFollowing; |
1363 if (attr2->getQualifiedName() == attr.name()) | 1374 if (attr2->getQualifiedName() == attr.name()) |
1364 return kDocumentPositionImplementationSpecific | | 1375 return kDocumentPositionImplementationSpecific | |
1365 kDocumentPositionPreceding; | 1376 kDocumentPositionPreceding; |
1366 } | 1377 } |
1367 | 1378 |
1368 ASSERT_NOT_REACHED(); | 1379 ASSERT_NOT_REACHED(); |
1369 return kDocumentPositionDisconnected; | 1380 return kDocumentPositionDisconnected; |
1370 } | 1381 } |
1371 | 1382 |
1372 // If one node is in the document and the other is not, we must be disconnecte
d. | 1383 // If one node is in the document and the other is not, we must be |
1373 // If the nodes have different owning documents, they must be disconnected. N
ote that we avoid | 1384 // disconnected. If the nodes have different owning documents, they must be |
1374 // comparing Attr nodes here, since they return false from isConnected() all t
he time (which seems like a bug). | 1385 // disconnected. Note that we avoid comparing Attr nodes here, since they |
| 1386 // return false from isConnected() all the time (which seems like a bug). |
1375 if (start1->isConnected() != start2->isConnected() || | 1387 if (start1->isConnected() != start2->isConnected() || |
1376 (treatment == TreatShadowTreesAsDisconnected && | 1388 (treatment == TreatShadowTreesAsDisconnected && |
1377 start1->treeScope() != start2->treeScope())) { | 1389 start1->treeScope() != start2->treeScope())) { |
1378 unsigned short direction = (this > otherNode) ? kDocumentPositionPreceding | 1390 unsigned short direction = (this > otherNode) ? kDocumentPositionPreceding |
1379 : kDocumentPositionFollowing; | 1391 : kDocumentPositionFollowing; |
1380 return kDocumentPositionDisconnected | | 1392 return kDocumentPositionDisconnected | |
1381 kDocumentPositionImplementationSpecific | direction; | 1393 kDocumentPositionImplementationSpecific | direction; |
1382 } | 1394 } |
1383 | 1395 |
1384 // We need to find a common ancestor container, and then compare the indices o
f the two immediate children. | 1396 // We need to find a common ancestor container, and then compare the indices |
| 1397 // of the two immediate children. |
1385 const Node* current; | 1398 const Node* current; |
1386 for (current = start1; current; current = current->parentOrShadowHostNode()) | 1399 for (current = start1; current; current = current->parentOrShadowHostNode()) |
1387 chain1.append(current); | 1400 chain1.append(current); |
1388 for (current = start2; current; current = current->parentOrShadowHostNode()) | 1401 for (current = start2; current; current = current->parentOrShadowHostNode()) |
1389 chain2.append(current); | 1402 chain2.append(current); |
1390 | 1403 |
1391 unsigned index1 = chain1.size(); | 1404 unsigned index1 = chain1.size(); |
1392 unsigned index2 = chain2.size(); | 1405 unsigned index2 = chain2.size(); |
1393 | 1406 |
1394 // If the two elements don't have a common root, they're not in the same tree. | 1407 // If the two elements don't have a common root, they're not in the same tree. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1430 } | 1443 } |
1431 | 1444 |
1432 return Node::kDocumentPositionPreceding | connection; | 1445 return Node::kDocumentPositionPreceding | connection; |
1433 } | 1446 } |
1434 | 1447 |
1435 if (!child2->nextSibling()) | 1448 if (!child2->nextSibling()) |
1436 return kDocumentPositionFollowing | connection; | 1449 return kDocumentPositionFollowing | connection; |
1437 if (!child1->nextSibling()) | 1450 if (!child1->nextSibling()) |
1438 return kDocumentPositionPreceding | connection; | 1451 return kDocumentPositionPreceding | connection; |
1439 | 1452 |
1440 // Otherwise we need to see which node occurs first. Crawl backwards from
child2 looking for child1. | 1453 // Otherwise we need to see which node occurs first. Crawl backwards from |
| 1454 // child2 looking for child1. |
1441 for (const Node* child = child2->previousSibling(); child; | 1455 for (const Node* child = child2->previousSibling(); child; |
1442 child = child->previousSibling()) { | 1456 child = child->previousSibling()) { |
1443 if (child == child1) | 1457 if (child == child1) |
1444 return kDocumentPositionFollowing | connection; | 1458 return kDocumentPositionFollowing | connection; |
1445 } | 1459 } |
1446 return kDocumentPositionPreceding | connection; | 1460 return kDocumentPositionPreceding | connection; |
1447 } | 1461 } |
1448 } | 1462 } |
1449 | 1463 |
1450 // There was no difference between the two parent chains, i.e., one was a subs
et of the other. The shorter | 1464 // There was no difference between the two parent chains, i.e., one was a |
1451 // chain is the ancestor. | 1465 // subset of the other. The shorter chain is the ancestor. |
1452 return index1 < index2 | 1466 return index1 < index2 |
1453 ? kDocumentPositionFollowing | kDocumentPositionContainedBy | | 1467 ? kDocumentPositionFollowing | kDocumentPositionContainedBy | |
1454 connection | 1468 connection |
1455 : kDocumentPositionPreceding | kDocumentPositionContains | | 1469 : kDocumentPositionPreceding | kDocumentPositionContains | |
1456 connection; | 1470 connection; |
1457 } | 1471 } |
1458 | 1472 |
1459 String Node::debugName() const { | 1473 String Node::debugName() const { |
1460 StringBuilder name; | 1474 StringBuilder name; |
1461 name.append(debugNodeName()); | 1475 name.append(debugNodeName()); |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1749 LOG(INFO) << "\n" << stream.str(); | 1763 LOG(INFO) << "\n" << stream.str(); |
1750 } | 1764 } |
1751 | 1765 |
1752 #endif | 1766 #endif |
1753 | 1767 |
1754 // -------- | 1768 // -------- |
1755 | 1769 |
1756 Element* Node::enclosingLinkEventParentOrSelf() const { | 1770 Element* Node::enclosingLinkEventParentOrSelf() const { |
1757 const Node* result = nullptr; | 1771 const Node* result = nullptr; |
1758 for (const Node* node = this; node; node = FlatTreeTraversal::parent(*node)) { | 1772 for (const Node* node = this; node; node = FlatTreeTraversal::parent(*node)) { |
1759 // For imagemaps, the enclosing link node is the associated area element not
the image itself. | 1773 // For imagemaps, the enclosing link node is the associated area element not |
1760 // So we don't let images be the enclosingLinkNode, even though isLink somet
imes returns true | 1774 // the image itself. So we don't let images be the enclosingLinkNode, even |
1761 // for them. | 1775 // though isLink sometimes returns true for them. |
1762 if (node->isLink() && !isHTMLImageElement(*node)) { | 1776 if (node->isLink() && !isHTMLImageElement(*node)) { |
1763 // Casting to Element is safe because only HTMLAnchorElement, HTMLImageEle
ment and | 1777 // Casting to Element is safe because only HTMLAnchorElement, |
1764 // SVGAElement can return true for isLink(). | 1778 // HTMLImageElement and SVGAElement can return true for isLink(). |
1765 result = node; | 1779 result = node; |
1766 break; | 1780 break; |
1767 } | 1781 } |
1768 } | 1782 } |
1769 | 1783 |
1770 return toElement(const_cast<Node*>(result)); | 1784 return toElement(const_cast<Node*>(result)); |
1771 } | 1785 } |
1772 | 1786 |
1773 const AtomicString& Node::interfaceName() const { | 1787 const AtomicString& Node::interfaceName() const { |
1774 return EventTargetNames::Node; | 1788 return EventTargetNames::Node; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1820 document().addListenerTypeIfNeeded(eventType); | 1834 document().addListenerTypeIfNeeded(eventType); |
1821 if (FrameHost* frameHost = document().frameHost()) | 1835 if (FrameHost* frameHost = document().frameHost()) |
1822 frameHost->eventHandlerRegistry().didAddEventHandler( | 1836 frameHost->eventHandlerRegistry().didAddEventHandler( |
1823 *this, eventType, registeredListener.options()); | 1837 *this, eventType, registeredListener.options()); |
1824 } | 1838 } |
1825 | 1839 |
1826 void Node::removedEventListener( | 1840 void Node::removedEventListener( |
1827 const AtomicString& eventType, | 1841 const AtomicString& eventType, |
1828 const RegisteredEventListener& registeredListener) { | 1842 const RegisteredEventListener& registeredListener) { |
1829 EventTarget::removedEventListener(eventType, registeredListener); | 1843 EventTarget::removedEventListener(eventType, registeredListener); |
1830 // FIXME: Notify Document that the listener has vanished. We need to keep trac
k of a number of | 1844 // FIXME: Notify Document that the listener has vanished. We need to keep |
1831 // listeners for each type, not just a bool - see https://bugs.webkit.org/show
_bug.cgi?id=33861 | 1845 // track of a number of listeners for each type, not just a bool - see |
| 1846 // https://bugs.webkit.org/show_bug.cgi?id=33861 |
1832 if (FrameHost* frameHost = document().frameHost()) | 1847 if (FrameHost* frameHost = document().frameHost()) |
1833 frameHost->eventHandlerRegistry().didRemoveEventHandler( | 1848 frameHost->eventHandlerRegistry().didRemoveEventHandler( |
1834 *this, eventType, registeredListener.options()); | 1849 *this, eventType, registeredListener.options()); |
1835 } | 1850 } |
1836 | 1851 |
1837 void Node::removeAllEventListeners() { | 1852 void Node::removeAllEventListeners() { |
1838 if (hasEventListeners() && document().frameHost()) | 1853 if (hasEventListeners() && document().frameHost()) |
1839 document().frameHost()->eventHandlerRegistry().didRemoveAllEventHandlers( | 1854 document().frameHost()->eventHandlerRegistry().didRemoveAllEventHandlers( |
1840 *this); | 1855 *this); |
1841 EventTarget::removeAllEventListeners(); | 1856 EventTarget::removeAllEventListeners(); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1968 mutationObserverRegistry(); | 1983 mutationObserverRegistry(); |
1969 DCHECK(registry); | 1984 DCHECK(registry); |
1970 if (!registry) | 1985 if (!registry) |
1971 return; | 1986 return; |
1972 | 1987 |
1973 size_t index = registry->find(registration); | 1988 size_t index = registry->find(registration); |
1974 DCHECK_NE(index, kNotFound); | 1989 DCHECK_NE(index, kNotFound); |
1975 if (index == kNotFound) | 1990 if (index == kNotFound) |
1976 return; | 1991 return; |
1977 | 1992 |
1978 // FIXME: Simplify the registration/transient registration logic to make this
understandable by humans. | 1993 // FIXME: Simplify the registration/transient registration logic to make this |
1979 // The explicit dispose() is needed to have the registration | 1994 // understandable by humans. The explicit dispose() is needed to have the |
1980 // object unregister itself promptly. | 1995 // registration object unregister itself promptly. |
1981 registration->dispose(); | 1996 registration->dispose(); |
1982 registry->remove(index); | 1997 registry->remove(index); |
1983 } | 1998 } |
1984 | 1999 |
1985 void Node::registerTransientMutationObserver( | 2000 void Node::registerTransientMutationObserver( |
1986 MutationObserverRegistration* registration) { | 2001 MutationObserverRegistration* registration) { |
1987 ensureRareData().ensureMutationObserverData().transientRegistry.add( | 2002 ensureRareData().ensureMutationObserverData().transientRegistry.add( |
1988 registration); | 2003 registration); |
1989 } | 2004 } |
1990 | 2005 |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2320 DCHECK(isHTMLElement() || isSVGElement()); | 2335 DCHECK(isHTMLElement() || isSVGElement()); |
2321 DCHECK(CustomElementState::Custom != getCustomElementState()); | 2336 DCHECK(CustomElementState::Custom != getCustomElementState()); |
2322 setFlag(V0CustomElementFlag); | 2337 setFlag(V0CustomElementFlag); |
2323 setFlag(newState == V0Upgraded, V0CustomElementUpgradedFlag); | 2338 setFlag(newState == V0Upgraded, V0CustomElementUpgradedFlag); |
2324 | 2339 |
2325 if (oldState == V0NotCustomElement || newState == V0Upgraded) | 2340 if (oldState == V0NotCustomElement || newState == V0Upgraded) |
2326 toElement(this)->pseudoStateChanged(CSSSelector::PseudoUnresolved); | 2341 toElement(this)->pseudoStateChanged(CSSSelector::PseudoUnresolved); |
2327 } | 2342 } |
2328 | 2343 |
2329 void Node::checkSlotChange() { | 2344 void Node::checkSlotChange() { |
2330 // Common check logic is used in both cases, "after inserted" and "before remo
ved". | 2345 // Common check logic is used in both cases, "after inserted" and "before |
| 2346 // removed". |
2331 if (!isSlotable()) | 2347 if (!isSlotable()) |
2332 return; | 2348 return; |
2333 if (ShadowRoot* root = v1ShadowRootOfParent()) { | 2349 if (ShadowRoot* root = v1ShadowRootOfParent()) { |
2334 // Relevant DOM Standard: | 2350 // Relevant DOM Standard: |
2335 // https://dom.spec.whatwg.org/#concept-node-insert | 2351 // https://dom.spec.whatwg.org/#concept-node-insert |
2336 // - 6.1.2: If parent is a shadow host and node is a slotable, then assign a
slot for node. | 2352 // - 6.1.2: If parent is a shadow host and node is a slotable, then assign a |
| 2353 // slot for node. |
2337 // https://dom.spec.whatwg.org/#concept-node-remove | 2354 // https://dom.spec.whatwg.org/#concept-node-remove |
2338 // - 10. If node is assigned, then run assign slotables for node’s assigned
slot. | 2355 // - 10. If node is assigned, then run assign slotables for node’s assigned |
| 2356 // slot. |
2339 | 2357 |
2340 // Although DOM Standard requires "assign a slot for node / run assign slota
bles" at this timing, | 2358 // Although DOM Standard requires "assign a slot for node / run assign |
2341 // we skip it as an optimization. | 2359 // slotables" at this timing, we skip it as an optimization. |
2342 if (HTMLSlotElement* slot = root->ensureSlotAssignment().findSlot(*this)) | 2360 if (HTMLSlotElement* slot = root->ensureSlotAssignment().findSlot(*this)) |
2343 slot->enqueueSlotChangeEvent(); | 2361 slot->enqueueSlotChangeEvent(); |
2344 } else { | 2362 } else { |
2345 // Relevant DOM Standard: | 2363 // Relevant DOM Standard: |
2346 // https://dom.spec.whatwg.org/#concept-node-insert | 2364 // https://dom.spec.whatwg.org/#concept-node-insert |
2347 // - 6.1.3: If parent is a slot whose assigned nodes is the empty list, then
run signal a slot change for parent. | 2365 // - 6.1.3: If parent is a slot whose assigned nodes is the empty list, then |
| 2366 // run signal a slot change for parent. |
2348 // https://dom.spec.whatwg.org/#concept-node-remove | 2367 // https://dom.spec.whatwg.org/#concept-node-remove |
2349 // - 11. If parent is a slot whose assigned nodes is the empty list, then ru
n signal a slot change for parent. | 2368 // - 11. If parent is a slot whose assigned nodes is the empty list, then |
| 2369 // run signal a slot change for parent. |
2350 Element* parent = parentElement(); | 2370 Element* parent = parentElement(); |
2351 if (parent && isHTMLSlotElement(parent)) { | 2371 if (parent && isHTMLSlotElement(parent)) { |
2352 HTMLSlotElement& parentSlot = toHTMLSlotElement(*parent); | 2372 HTMLSlotElement& parentSlot = toHTMLSlotElement(*parent); |
2353 if (ShadowRoot* root = containingShadowRoot()) { | 2373 if (ShadowRoot* root = containingShadowRoot()) { |
2354 if (root && root->isV1() && !parentSlot.hasAssignedNodesSlow()) | 2374 if (root && root->isV1() && !parentSlot.hasAssignedNodesSlow()) |
2355 parentSlot.enqueueSlotChangeEvent(); | 2375 parentSlot.enqueueSlotChangeEvent(); |
2356 } | 2376 } |
2357 } | 2377 } |
2358 } | 2378 } |
2359 } | 2379 } |
(...skipping 14 matching lines...) Expand all Loading... |
2374 DEFINE_TRACE_WRAPPERS(Node) { | 2394 DEFINE_TRACE_WRAPPERS(Node) { |
2375 visitor->traceWrappers(parentOrShadowHostOrTemplateHostNode()); | 2395 visitor->traceWrappers(parentOrShadowHostOrTemplateHostNode()); |
2376 visitor->traceWrappers(m_previous); | 2396 visitor->traceWrappers(m_previous); |
2377 visitor->traceWrappers(m_next); | 2397 visitor->traceWrappers(m_next); |
2378 if (hasRareData()) | 2398 if (hasRareData()) |
2379 visitor->traceWrappers(rareData()); | 2399 visitor->traceWrappers(rareData()); |
2380 EventTarget::traceWrappers(visitor); | 2400 EventTarget::traceWrappers(visitor); |
2381 } | 2401 } |
2382 | 2402 |
2383 unsigned Node::lengthOfContents() const { | 2403 unsigned Node::lengthOfContents() const { |
2384 // This switch statement must be consistent with that of Range::processContent
sBetweenOffsets. | 2404 // This switch statement must be consistent with that of |
| 2405 // Range::processContentsBetweenOffsets. |
2385 switch (getNodeType()) { | 2406 switch (getNodeType()) { |
2386 case Node::kTextNode: | 2407 case Node::kTextNode: |
2387 case Node::kCdataSectionNode: | 2408 case Node::kCdataSectionNode: |
2388 case Node::kCommentNode: | 2409 case Node::kCommentNode: |
2389 case Node::kProcessingInstructionNode: | 2410 case Node::kProcessingInstructionNode: |
2390 return toCharacterData(this)->length(); | 2411 return toCharacterData(this)->length(); |
2391 case Node::kElementNode: | 2412 case Node::kElementNode: |
2392 case Node::kDocumentNode: | 2413 case Node::kDocumentNode: |
2393 case Node::kDocumentFragmentNode: | 2414 case Node::kDocumentFragmentNode: |
2394 return toContainerNode(this)->countChildren(); | 2415 return toContainerNode(this)->countChildren(); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2443 if (node) { | 2464 if (node) { |
2444 std::stringstream stream; | 2465 std::stringstream stream; |
2445 node->printNodePathTo(stream); | 2466 node->printNodePathTo(stream); |
2446 LOG(INFO) << stream.str(); | 2467 LOG(INFO) << stream.str(); |
2447 } else { | 2468 } else { |
2448 LOG(INFO) << "Cannot showNodePath for <null>"; | 2469 LOG(INFO) << "Cannot showNodePath for <null>"; |
2449 } | 2470 } |
2450 } | 2471 } |
2451 | 2472 |
2452 #endif | 2473 #endif |
OLD | NEW |