| 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 |