| 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 r
ights reserved. |
| 6 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 6 * 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/) | 7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) |
| 8 * | 8 * |
| 9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 if (node->hasRareData()) { | 150 if (node->hasRareData()) { |
| 151 ++nodesWithRareData; | 151 ++nodesWithRareData; |
| 152 if (node->isElementNode()) { | 152 if (node->isElementNode()) { |
| 153 ++elementsWithRareData; | 153 ++elementsWithRareData; |
| 154 if (toElement(node)->hasNamedNodeMap()) | 154 if (toElement(node)->hasNamedNodeMap()) |
| 155 ++elementsWithNamedNodeMap; | 155 ++elementsWithNamedNodeMap; |
| 156 } | 156 } |
| 157 } | 157 } |
| 158 | 158 |
| 159 switch (node->getNodeType()) { | 159 switch (node->getNodeType()) { |
| 160 case ELEMENT_NODE: { | 160 case kElementNode: { |
| 161 ++elementNodes; | 161 ++elementNodes; |
| 162 | 162 |
| 163 // Tag stats | 163 // Tag stats |
| 164 Element* element = toElement(node); | 164 Element* element = toElement(node); |
| 165 HashMap<String, size_t>::AddResult result = perTagCount.add(elem
ent->tagName(), 1); | 165 HashMap<String, size_t>::AddResult result = perTagCount.add(elem
ent->tagName(), 1); |
| 166 if (!result.isNewEntry) | 166 if (!result.isNewEntry) |
| 167 result.storedValue->value++; | 167 result.storedValue->value++; |
| 168 | 168 |
| 169 size_t attributeCount = element->attributesWithoutUpdate().size(
); | 169 size_t attributeCount = element->attributesWithoutUpdate().size(
); |
| 170 if (attributeCount) { | 170 if (attributeCount) { |
| 171 attributes += attributeCount; | 171 attributes += attributeCount; |
| 172 ++elementsWithAttributeStorage; | 172 ++elementsWithAttributeStorage; |
| 173 } | 173 } |
| 174 break; | 174 break; |
| 175 } | 175 } |
| 176 case ATTRIBUTE_NODE: { | 176 case kAttributeNode: { |
| 177 ++attrNodes; | 177 ++attrNodes; |
| 178 break; | 178 break; |
| 179 } | 179 } |
| 180 case TEXT_NODE: { | 180 case kTextNode: { |
| 181 ++textNodes; | 181 ++textNodes; |
| 182 break; | 182 break; |
| 183 } | 183 } |
| 184 case CDATA_SECTION_NODE: { | 184 case kCdataSectionNode: { |
| 185 ++cdataNodes; | 185 ++cdataNodes; |
| 186 break; | 186 break; |
| 187 } | 187 } |
| 188 case COMMENT_NODE: { | 188 case kCommentNode: { |
| 189 ++commentNodes; | 189 ++commentNodes; |
| 190 break; | 190 break; |
| 191 } | 191 } |
| 192 case PROCESSING_INSTRUCTION_NODE: { | 192 case kProcessingInstructionNode: { |
| 193 ++piNodes; | 193 ++piNodes; |
| 194 break; | 194 break; |
| 195 } | 195 } |
| 196 case DOCUMENT_NODE: { | 196 case kDocumentNode: { |
| 197 ++documentNodes; | 197 ++documentNodes; |
| 198 break; | 198 break; |
| 199 } | 199 } |
| 200 case DOCUMENT_TYPE_NODE: { | 200 case kDocumentTypeNode: { |
| 201 ++docTypeNodes; | 201 ++docTypeNodes; |
| 202 break; | 202 break; |
| 203 } | 203 } |
| 204 case DOCUMENT_FRAGMENT_NODE: { | 204 case kDocumentFragmentNode: { |
| 205 if (node->isShadowRoot()) | 205 if (node->isShadowRoot()) |
| 206 ++shadowRootNodes; | 206 ++shadowRootNodes; |
| 207 else | 207 else |
| 208 ++fragmentNodes; | 208 ++fragmentNodes; |
| 209 break; | 209 break; |
| 210 } | 210 } |
| 211 } | 211 } |
| 212 } | 212 } |
| 213 } | 213 } |
| 214 | 214 |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 // Go through the subtree beneath us, normalizing all nodes. This means that | 527 // Go through the subtree beneath us, normalizing all nodes. This means that |
| 528 // any two adjacent text nodes are merged and any empty text nodes are remov
ed. | 528 // any two adjacent text nodes are merged and any empty text nodes are remov
ed. |
| 529 | 529 |
| 530 Node* node = this; | 530 Node* node = this; |
| 531 while (Node* firstChild = node->firstChild()) | 531 while (Node* firstChild = node->firstChild()) |
| 532 node = firstChild; | 532 node = firstChild; |
| 533 while (node) { | 533 while (node) { |
| 534 if (node == this) | 534 if (node == this) |
| 535 break; | 535 break; |
| 536 | 536 |
| 537 if (node->getNodeType() == TEXT_NODE) | 537 if (node->getNodeType() == kTextNode) |
| 538 node = toText(node)->mergeNextSiblingNodesIfPossible(); | 538 node = toText(node)->mergeNextSiblingNodesIfPossible(); |
| 539 else | 539 else |
| 540 node = NodeTraversal::nextPostOrder(*node); | 540 node = NodeTraversal::nextPostOrder(*node); |
| 541 } | 541 } |
| 542 } | 542 } |
| 543 | 543 |
| 544 LayoutBox* Node::layoutBox() const | 544 LayoutBox* Node::layoutBox() const |
| 545 { | 545 { |
| 546 LayoutObject* layoutObject = this->layoutObject(); | 546 LayoutObject* layoutObject = this->layoutObject(); |
| 547 return layoutObject && layoutObject->isBox() ? toLayoutBox(layoutObject) : n
ullptr; | 547 return layoutObject && layoutObject->isBox() ? toLayoutBox(layoutObject) : n
ullptr; |
| (...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1123 } | 1123 } |
| 1124 | 1124 |
| 1125 return true; | 1125 return true; |
| 1126 } | 1126 } |
| 1127 | 1127 |
| 1128 bool Node::isDefaultNamespace(const AtomicString& namespaceURIMaybeEmpty) const | 1128 bool Node::isDefaultNamespace(const AtomicString& namespaceURIMaybeEmpty) const |
| 1129 { | 1129 { |
| 1130 const AtomicString& namespaceURI = namespaceURIMaybeEmpty.isEmpty() ? nullAt
om : namespaceURIMaybeEmpty; | 1130 const AtomicString& namespaceURI = namespaceURIMaybeEmpty.isEmpty() ? nullAt
om : namespaceURIMaybeEmpty; |
| 1131 | 1131 |
| 1132 switch (getNodeType()) { | 1132 switch (getNodeType()) { |
| 1133 case ELEMENT_NODE: { | 1133 case kElementNode: { |
| 1134 const Element& element = toElement(*this); | 1134 const Element& element = toElement(*this); |
| 1135 | 1135 |
| 1136 if (element.prefix().isNull()) | 1136 if (element.prefix().isNull()) |
| 1137 return element.namespaceURI() == namespaceURI; | 1137 return element.namespaceURI() == namespaceURI; |
| 1138 | 1138 |
| 1139 AttributeCollection attributes = element.attributes(); | 1139 AttributeCollection attributes = element.attributes(); |
| 1140 for (const Attribute& attr : attributes) { | 1140 for (const Attribute& attr : attributes) { |
| 1141 if (attr.localName() == xmlnsAtom) | 1141 if (attr.localName() == xmlnsAtom) |
| 1142 return attr.value() == namespaceURI; | 1142 return attr.value() == namespaceURI; |
| 1143 } | 1143 } |
| 1144 | 1144 |
| 1145 if (Element* parent = parentElement()) | 1145 if (Element* parent = parentElement()) |
| 1146 return parent->isDefaultNamespace(namespaceURI); | 1146 return parent->isDefaultNamespace(namespaceURI); |
| 1147 | 1147 |
| 1148 return false; | 1148 return false; |
| 1149 } | 1149 } |
| 1150 case DOCUMENT_NODE: | 1150 case kDocumentNode: |
| 1151 if (Element* de = toDocument(this)->documentElement()) | 1151 if (Element* de = toDocument(this)->documentElement()) |
| 1152 return de->isDefaultNamespace(namespaceURI); | 1152 return de->isDefaultNamespace(namespaceURI); |
| 1153 return false; | 1153 return false; |
| 1154 case DOCUMENT_TYPE_NODE: | 1154 case kDocumentTypeNode: |
| 1155 case DOCUMENT_FRAGMENT_NODE: | 1155 case kDocumentFragmentNode: |
| 1156 return false; | 1156 return false; |
| 1157 case ATTRIBUTE_NODE: { | 1157 case kAttributeNode: { |
| 1158 const Attr* attr = toAttr(this); | 1158 const Attr* attr = toAttr(this); |
| 1159 if (attr->ownerElement()) | 1159 if (attr->ownerElement()) |
| 1160 return attr->ownerElement()->isDefaultNamespace(namespaceURI); | 1160 return attr->ownerElement()->isDefaultNamespace(namespaceURI); |
| 1161 return false; | 1161 return false; |
| 1162 } | 1162 } |
| 1163 default: | 1163 default: |
| 1164 if (Element* parent = parentElement()) | 1164 if (Element* parent = parentElement()) |
| 1165 return parent->isDefaultNamespace(namespaceURI); | 1165 return parent->isDefaultNamespace(namespaceURI); |
| 1166 return false; | 1166 return false; |
| 1167 } | 1167 } |
| 1168 } | 1168 } |
| 1169 | 1169 |
| 1170 const AtomicString& Node::lookupPrefix(const AtomicString& namespaceURI) const | 1170 const AtomicString& Node::lookupPrefix(const AtomicString& namespaceURI) const |
| 1171 { | 1171 { |
| 1172 // Implemented according to | 1172 // Implemented according to |
| 1173 // https://dom.spec.whatwg.org/#dom-node-lookupprefix | 1173 // https://dom.spec.whatwg.org/#dom-node-lookupprefix |
| 1174 | 1174 |
| 1175 if (namespaceURI.isEmpty() || namespaceURI.isNull()) | 1175 if (namespaceURI.isEmpty() || namespaceURI.isNull()) |
| 1176 return nullAtom; | 1176 return nullAtom; |
| 1177 | 1177 |
| 1178 const Element* context; | 1178 const Element* context; |
| 1179 | 1179 |
| 1180 switch (getNodeType()) { | 1180 switch (getNodeType()) { |
| 1181 case ELEMENT_NODE: | 1181 case kElementNode: |
| 1182 context = toElement(this); | 1182 context = toElement(this); |
| 1183 break; | 1183 break; |
| 1184 case DOCUMENT_NODE: | 1184 case kDocumentNode: |
| 1185 context = toDocument(this)->documentElement(); | 1185 context = toDocument(this)->documentElement(); |
| 1186 break; | 1186 break; |
| 1187 case DOCUMENT_FRAGMENT_NODE: | 1187 case kDocumentFragmentNode: |
| 1188 case DOCUMENT_TYPE_NODE: | 1188 case kDocumentTypeNode: |
| 1189 context = nullptr; | 1189 context = nullptr; |
| 1190 break; | 1190 break; |
| 1191 // FIXME: Remove this when Attr no longer extends Node (CR305105) | 1191 // FIXME: Remove this when Attr no longer extends Node (CR305105) |
| 1192 case ATTRIBUTE_NODE: | 1192 case kAttributeNode: |
| 1193 context = toAttr(this)->ownerElement(); | 1193 context = toAttr(this)->ownerElement(); |
| 1194 break; | 1194 break; |
| 1195 default: | 1195 default: |
| 1196 context = parentElement(); | 1196 context = parentElement(); |
| 1197 break; | 1197 break; |
| 1198 } | 1198 } |
| 1199 | 1199 |
| 1200 if (!context) | 1200 if (!context) |
| 1201 return nullAtom; | 1201 return nullAtom; |
| 1202 | 1202 |
| 1203 return context->locateNamespacePrefix(namespaceURI); | 1203 return context->locateNamespacePrefix(namespaceURI); |
| 1204 } | 1204 } |
| 1205 | 1205 |
| 1206 const AtomicString& Node::lookupNamespaceURI(const String& prefix) const | 1206 const AtomicString& Node::lookupNamespaceURI(const String& prefix) const |
| 1207 { | 1207 { |
| 1208 // Implemented according to | 1208 // Implemented according to |
| 1209 // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algori
thms.html#lookupNamespaceURIAlgo | 1209 // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algori
thms.html#lookupNamespaceURIAlgo |
| 1210 | 1210 |
| 1211 if (!prefix.isNull() && prefix.isEmpty()) | 1211 if (!prefix.isNull() && prefix.isEmpty()) |
| 1212 return nullAtom; | 1212 return nullAtom; |
| 1213 | 1213 |
| 1214 switch (getNodeType()) { | 1214 switch (getNodeType()) { |
| 1215 case ELEMENT_NODE: { | 1215 case kElementNode: { |
| 1216 const Element& element = toElement(*this); | 1216 const Element& element = toElement(*this); |
| 1217 | 1217 |
| 1218 if (!element.namespaceURI().isNull() && element.prefix() == prefix) | 1218 if (!element.namespaceURI().isNull() && element.prefix() == prefix) |
| 1219 return element.namespaceURI(); | 1219 return element.namespaceURI(); |
| 1220 | 1220 |
| 1221 AttributeCollection attributes = element.attributes(); | 1221 AttributeCollection attributes = element.attributes(); |
| 1222 for (const Attribute& attr : attributes) { | 1222 for (const Attribute& attr : attributes) { |
| 1223 if (attr.prefix() == xmlnsAtom && attr.localName() == prefix) { | 1223 if (attr.prefix() == xmlnsAtom && attr.localName() == prefix) { |
| 1224 if (!attr.value().isEmpty()) | 1224 if (!attr.value().isEmpty()) |
| 1225 return attr.value(); | 1225 return attr.value(); |
| 1226 return nullAtom; | 1226 return nullAtom; |
| 1227 } | 1227 } |
| 1228 if (attr.localName() == xmlnsAtom && prefix.isNull()) { | 1228 if (attr.localName() == xmlnsAtom && prefix.isNull()) { |
| 1229 if (!attr.value().isEmpty()) | 1229 if (!attr.value().isEmpty()) |
| 1230 return attr.value(); | 1230 return attr.value(); |
| 1231 return nullAtom; | 1231 return nullAtom; |
| 1232 } | 1232 } |
| 1233 } | 1233 } |
| 1234 | 1234 |
| 1235 if (Element* parent = parentElement()) | 1235 if (Element* parent = parentElement()) |
| 1236 return parent->lookupNamespaceURI(prefix); | 1236 return parent->lookupNamespaceURI(prefix); |
| 1237 return nullAtom; | 1237 return nullAtom; |
| 1238 } | 1238 } |
| 1239 case DOCUMENT_NODE: | 1239 case kDocumentNode: |
| 1240 if (Element* de = toDocument(this)->documentElement()) | 1240 if (Element* de = toDocument(this)->documentElement()) |
| 1241 return de->lookupNamespaceURI(prefix); | 1241 return de->lookupNamespaceURI(prefix); |
| 1242 return nullAtom; | 1242 return nullAtom; |
| 1243 case DOCUMENT_TYPE_NODE: | 1243 case kDocumentTypeNode: |
| 1244 case DOCUMENT_FRAGMENT_NODE: | 1244 case kDocumentFragmentNode: |
| 1245 return nullAtom; | 1245 return nullAtom; |
| 1246 case ATTRIBUTE_NODE: { | 1246 case kAttributeNode: { |
| 1247 const Attr *attr = toAttr(this); | 1247 const Attr *attr = toAttr(this); |
| 1248 if (attr->ownerElement()) | 1248 if (attr->ownerElement()) |
| 1249 return attr->ownerElement()->lookupNamespaceURI(prefix); | 1249 return attr->ownerElement()->lookupNamespaceURI(prefix); |
| 1250 return nullAtom; | 1250 return nullAtom; |
| 1251 } | 1251 } |
| 1252 default: | 1252 default: |
| 1253 if (Element* parent = parentElement()) | 1253 if (Element* parent = parentElement()) |
| 1254 return parent->lookupNamespaceURI(prefix); | 1254 return parent->lookupNamespaceURI(prefix); |
| 1255 return nullAtom; | 1255 return nullAtom; |
| 1256 } | 1256 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1276 } else if (node.isTextNode()) { | 1276 } else if (node.isTextNode()) { |
| 1277 content.append(toText(node).data()); | 1277 content.append(toText(node).data()); |
| 1278 } | 1278 } |
| 1279 } | 1279 } |
| 1280 return content.toString(); | 1280 return content.toString(); |
| 1281 } | 1281 } |
| 1282 | 1282 |
| 1283 void Node::setTextContent(const String& text) | 1283 void Node::setTextContent(const String& text) |
| 1284 { | 1284 { |
| 1285 switch (getNodeType()) { | 1285 switch (getNodeType()) { |
| 1286 case TEXT_NODE: | 1286 case kTextNode: |
| 1287 case CDATA_SECTION_NODE: | 1287 case kCdataSectionNode: |
| 1288 case COMMENT_NODE: | 1288 case kCommentNode: |
| 1289 case PROCESSING_INSTRUCTION_NODE: | 1289 case kProcessingInstructionNode: |
| 1290 setNodeValue(text); | 1290 setNodeValue(text); |
| 1291 return; | 1291 return; |
| 1292 case ELEMENT_NODE: | 1292 case kElementNode: |
| 1293 case DOCUMENT_FRAGMENT_NODE: { | 1293 case kDocumentFragmentNode: { |
| 1294 // FIXME: Merge this logic into replaceChildrenWithText. | 1294 // FIXME: Merge this logic into replaceChildrenWithText. |
| 1295 ContainerNode* container = toContainerNode(this); | 1295 ContainerNode* container = toContainerNode(this); |
| 1296 | 1296 |
| 1297 // Note: This is an intentional optimization. | 1297 // Note: This is an intentional optimization. |
| 1298 // See crbug.com/352836 also. | 1298 // See crbug.com/352836 also. |
| 1299 // No need to do anything if the text is identical. | 1299 // No need to do anything if the text is identical. |
| 1300 if (container->hasOneTextChild() && toText(container->firstChild())->dat
a() == text) | 1300 if (container->hasOneTextChild() && toText(container->firstChild())->dat
a() == text) |
| 1301 return; | 1301 return; |
| 1302 | 1302 |
| 1303 ChildListMutationScope mutation(*this); | 1303 ChildListMutationScope mutation(*this); |
| 1304 // Note: This API will not insert empty text nodes: | 1304 // Note: This API will not insert empty text nodes: |
| 1305 // https://dom.spec.whatwg.org/#dom-node-textcontent | 1305 // https://dom.spec.whatwg.org/#dom-node-textcontent |
| 1306 if (text.isEmpty()) { | 1306 if (text.isEmpty()) { |
| 1307 container->removeChildren(DispatchSubtreeModifiedEvent); | 1307 container->removeChildren(DispatchSubtreeModifiedEvent); |
| 1308 } else { | 1308 } else { |
| 1309 container->removeChildren(OmitSubtreeModifiedEvent); | 1309 container->removeChildren(OmitSubtreeModifiedEvent); |
| 1310 container->appendChild(document().createTextNode(text), ASSERT_NO_EX
CEPTION); | 1310 container->appendChild(document().createTextNode(text), ASSERT_NO_EX
CEPTION); |
| 1311 } | 1311 } |
| 1312 return; | 1312 return; |
| 1313 } | 1313 } |
| 1314 case ATTRIBUTE_NODE: | 1314 case kAttributeNode: |
| 1315 case DOCUMENT_NODE: | 1315 case kDocumentNode: |
| 1316 case DOCUMENT_TYPE_NODE: | 1316 case kDocumentTypeNode: |
| 1317 // Do nothing. | 1317 // Do nothing. |
| 1318 return; | 1318 return; |
| 1319 } | 1319 } |
| 1320 ASSERT_NOT_REACHED(); | 1320 ASSERT_NOT_REACHED(); |
| 1321 } | 1321 } |
| 1322 | 1322 |
| 1323 bool Node::offsetInCharacters() const | 1323 bool Node::offsetInCharacters() const |
| 1324 { | 1324 { |
| 1325 return isCharacterDataNode(); | 1325 return isCharacterDataNode(); |
| 1326 } | 1326 } |
| 1327 | 1327 |
| 1328 unsigned short Node::compareDocumentPosition(const Node* otherNode, ShadowTreesT
reatment treatment) const | 1328 unsigned short Node::compareDocumentPosition(const Node* otherNode, ShadowTreesT
reatment treatment) const |
| 1329 { | 1329 { |
| 1330 if (otherNode == this) | 1330 if (otherNode == this) |
| 1331 return DOCUMENT_POSITION_EQUIVALENT; | 1331 return kDocumentPositionEquivalent; |
| 1332 | 1332 |
| 1333 const Attr* attr1 = getNodeType() == ATTRIBUTE_NODE ? toAttr(this) : nullptr
; | 1333 const Attr* attr1 = getNodeType() == kAttributeNode ? toAttr(this) : nullptr
; |
| 1334 const Attr* attr2 = otherNode->getNodeType() == ATTRIBUTE_NODE ? toAttr(othe
rNode) : nullptr; | 1334 const Attr* attr2 = otherNode->getNodeType() == kAttributeNode ? toAttr(othe
rNode) : nullptr; |
| 1335 | 1335 |
| 1336 const Node* start1 = attr1 ? attr1->ownerElement() : this; | 1336 const Node* start1 = attr1 ? attr1->ownerElement() : this; |
| 1337 const Node* start2 = attr2 ? attr2->ownerElement() : otherNode; | 1337 const Node* start2 = attr2 ? attr2->ownerElement() : otherNode; |
| 1338 | 1338 |
| 1339 // If either of start1 or start2 is null, then we are disconnected, since on
e of the nodes is | 1339 // If either of start1 or start2 is null, then we are disconnected, since on
e of the nodes is |
| 1340 // an orphaned attribute node. | 1340 // an orphaned attribute node. |
| 1341 if (!start1 || !start2) { | 1341 if (!start1 || !start2) { |
| 1342 unsigned short direction = (this > otherNode) ? DOCUMENT_POSITION_PRECED
ING : DOCUMENT_POSITION_FOLLOWING; | 1342 unsigned short direction = (this > otherNode) ? kDocumentPositionPrecedi
ng : kDocumentPositionFollowing; |
| 1343 return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION
_SPECIFIC | direction; | 1343 return kDocumentPositionDisconnected | kDocumentPositionImplementationSp
ecific | direction; |
| 1344 } | 1344 } |
| 1345 | 1345 |
| 1346 HeapVector<Member<const Node>, 16> chain1; | 1346 HeapVector<Member<const Node>, 16> chain1; |
| 1347 HeapVector<Member<const Node>, 16> chain2; | 1347 HeapVector<Member<const Node>, 16> chain2; |
| 1348 if (attr1) | 1348 if (attr1) |
| 1349 chain1.append(attr1); | 1349 chain1.append(attr1); |
| 1350 if (attr2) | 1350 if (attr2) |
| 1351 chain2.append(attr2); | 1351 chain2.append(attr2); |
| 1352 | 1352 |
| 1353 if (attr1 && attr2 && start1 == start2 && start1) { | 1353 if (attr1 && attr2 && start1 == start2 && start1) { |
| 1354 // We are comparing two attributes on the same node. Crawl our attribute
map and see which one we hit first. | 1354 // We are comparing two attributes on the same node. Crawl our attribute
map and see which one we hit first. |
| 1355 const Element* owner1 = attr1->ownerElement(); | 1355 const Element* owner1 = attr1->ownerElement(); |
| 1356 AttributeCollection attributes = owner1->attributes(); | 1356 AttributeCollection attributes = owner1->attributes(); |
| 1357 for (const Attribute& attr : attributes) { | 1357 for (const Attribute& attr : attributes) { |
| 1358 // If neither of the two determining nodes is a child node and nodeT
ype is the same for both determining nodes, then an | 1358 // If neither of the two determining nodes is a child node and nodeT
ype is the same for both determining nodes, then an |
| 1359 // implementation-dependent order between the determining nodes is r
eturned. This order is stable as long as no nodes of | 1359 // implementation-dependent order between the determining nodes is r
eturned. This order is stable as long as no nodes of |
| 1360 // the same nodeType are inserted into or removed from the direct co
ntainer. This would be the case, for example, | 1360 // the same nodeType are inserted into or removed from the direct co
ntainer. This would be the case, for example, |
| 1361 // when comparing two attributes of the same element, and inserting
or removing additional attributes might change | 1361 // when comparing two attributes of the same element, and inserting
or removing additional attributes might change |
| 1362 // the order between existing attributes. | 1362 // the order between existing attributes. |
| 1363 if (attr1->getQualifiedName() == attr.name()) | 1363 if (attr1->getQualifiedName() == attr.name()) |
| 1364 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSI
TION_FOLLOWING; | 1364 return kDocumentPositionImplementationSpecific | kDocumentPositi
onFollowing; |
| 1365 if (attr2->getQualifiedName() == attr.name()) | 1365 if (attr2->getQualifiedName() == attr.name()) |
| 1366 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSI
TION_PRECEDING; | 1366 return kDocumentPositionImplementationSpecific | kDocumentPositi
onPreceding; |
| 1367 } | 1367 } |
| 1368 | 1368 |
| 1369 ASSERT_NOT_REACHED(); | 1369 ASSERT_NOT_REACHED(); |
| 1370 return DOCUMENT_POSITION_DISCONNECTED; | 1370 return kDocumentPositionDisconnected; |
| 1371 } | 1371 } |
| 1372 | 1372 |
| 1373 // If one node is in the document and the other is not, we must be disconnec
ted. | 1373 // If one node is in the document and the other is not, we must be disconnec
ted. |
| 1374 // If the nodes have different owning documents, they must be disconnected.
Note that we avoid | 1374 // If the nodes have different owning documents, they must be disconnected.
Note that we avoid |
| 1375 // comparing Attr nodes here, since they return false from isConnected() all
the time (which seems like a bug). | 1375 // comparing Attr nodes here, since they return false from isConnected() all
the time (which seems like a bug). |
| 1376 if (start1->isConnected() != start2->isConnected() || (treatment == TreatSha
dowTreesAsDisconnected && start1->treeScope() != start2->treeScope())) { | 1376 if (start1->isConnected() != start2->isConnected() || (treatment == TreatSha
dowTreesAsDisconnected && start1->treeScope() != start2->treeScope())) { |
| 1377 unsigned short direction = (this > otherNode) ? DOCUMENT_POSITION_PRECED
ING : DOCUMENT_POSITION_FOLLOWING; | 1377 unsigned short direction = (this > otherNode) ? kDocumentPositionPrecedi
ng : kDocumentPositionFollowing; |
| 1378 return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION
_SPECIFIC | direction; | 1378 return kDocumentPositionDisconnected | kDocumentPositionImplementationSp
ecific | direction; |
| 1379 } | 1379 } |
| 1380 | 1380 |
| 1381 // We need to find a common ancestor container, and then compare the indices
of the two immediate children. | 1381 // We need to find a common ancestor container, and then compare the indices
of the two immediate children. |
| 1382 const Node* current; | 1382 const Node* current; |
| 1383 for (current = start1; current; current = current->parentOrShadowHostNode()) | 1383 for (current = start1; current; current = current->parentOrShadowHostNode()) |
| 1384 chain1.append(current); | 1384 chain1.append(current); |
| 1385 for (current = start2; current; current = current->parentOrShadowHostNode()) | 1385 for (current = start2; current; current = current->parentOrShadowHostNode()) |
| 1386 chain2.append(current); | 1386 chain2.append(current); |
| 1387 | 1387 |
| 1388 unsigned index1 = chain1.size(); | 1388 unsigned index1 = chain1.size(); |
| 1389 unsigned index2 = chain2.size(); | 1389 unsigned index2 = chain2.size(); |
| 1390 | 1390 |
| 1391 // If the two elements don't have a common root, they're not in the same tre
e. | 1391 // If the two elements don't have a common root, they're not in the same tre
e. |
| 1392 if (chain1[index1 - 1] != chain2[index2 - 1]) { | 1392 if (chain1[index1 - 1] != chain2[index2 - 1]) { |
| 1393 unsigned short direction = (this > otherNode) ? DOCUMENT_POSITION_PRECED
ING : DOCUMENT_POSITION_FOLLOWING; | 1393 unsigned short direction = (this > otherNode) ? kDocumentPositionPrecedi
ng : kDocumentPositionFollowing; |
| 1394 return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION
_SPECIFIC | direction; | 1394 return kDocumentPositionDisconnected | kDocumentPositionImplementationSp
ecific | direction; |
| 1395 } | 1395 } |
| 1396 | 1396 |
| 1397 unsigned connection = start1->treeScope() != start2->treeScope() ? DOCUMENT_
POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC : 0; | 1397 unsigned connection = start1->treeScope() != start2->treeScope() ? kDocument
PositionDisconnected | kDocumentPositionImplementationSpecific : 0; |
| 1398 | 1398 |
| 1399 // Walk the two chains backwards and look for the first difference. | 1399 // Walk the two chains backwards and look for the first difference. |
| 1400 for (unsigned i = std::min(index1, index2); i; --i) { | 1400 for (unsigned i = std::min(index1, index2); i; --i) { |
| 1401 const Node* child1 = chain1[--index1]; | 1401 const Node* child1 = chain1[--index1]; |
| 1402 const Node* child2 = chain2[--index2]; | 1402 const Node* child2 = chain2[--index2]; |
| 1403 if (child1 != child2) { | 1403 if (child1 != child2) { |
| 1404 // If one of the children is an attribute, it wins. | 1404 // If one of the children is an attribute, it wins. |
| 1405 if (child1->getNodeType() == ATTRIBUTE_NODE) | 1405 if (child1->getNodeType() == kAttributeNode) |
| 1406 return DOCUMENT_POSITION_FOLLOWING | connection; | 1406 return kDocumentPositionFollowing | connection; |
| 1407 if (child2->getNodeType() == ATTRIBUTE_NODE) | 1407 if (child2->getNodeType() == kAttributeNode) |
| 1408 return DOCUMENT_POSITION_PRECEDING | connection; | 1408 return kDocumentPositionPreceding | connection; |
| 1409 | 1409 |
| 1410 // If one of the children is a shadow root, | 1410 // If one of the children is a shadow root, |
| 1411 if (child1->isShadowRoot() || child2->isShadowRoot()) { | 1411 if (child1->isShadowRoot() || child2->isShadowRoot()) { |
| 1412 if (!child2->isShadowRoot()) | 1412 if (!child2->isShadowRoot()) |
| 1413 return Node::DOCUMENT_POSITION_FOLLOWING | connection; | 1413 return Node::kDocumentPositionFollowing | connection; |
| 1414 if (!child1->isShadowRoot()) | 1414 if (!child1->isShadowRoot()) |
| 1415 return Node::DOCUMENT_POSITION_PRECEDING | connection; | 1415 return Node::kDocumentPositionPreceding | connection; |
| 1416 | 1416 |
| 1417 for (const ShadowRoot* child = toShadowRoot(child2)->olderShadow
Root(); child; child = child->olderShadowRoot()) { | 1417 for (const ShadowRoot* child = toShadowRoot(child2)->olderShadow
Root(); child; child = child->olderShadowRoot()) { |
| 1418 if (child == child1) { | 1418 if (child == child1) { |
| 1419 return Node::DOCUMENT_POSITION_FOLLOWING | connection; | 1419 return Node::kDocumentPositionFollowing | connection; |
| 1420 } | 1420 } |
| 1421 } | 1421 } |
| 1422 | 1422 |
| 1423 return Node::DOCUMENT_POSITION_PRECEDING | connection; | 1423 return Node::kDocumentPositionPreceding | connection; |
| 1424 } | 1424 } |
| 1425 | 1425 |
| 1426 if (!child2->nextSibling()) | 1426 if (!child2->nextSibling()) |
| 1427 return DOCUMENT_POSITION_FOLLOWING | connection; | 1427 return kDocumentPositionFollowing | connection; |
| 1428 if (!child1->nextSibling()) | 1428 if (!child1->nextSibling()) |
| 1429 return DOCUMENT_POSITION_PRECEDING | connection; | 1429 return kDocumentPositionPreceding | connection; |
| 1430 | 1430 |
| 1431 // Otherwise we need to see which node occurs first. Crawl backward
s from child2 looking for child1. | 1431 // Otherwise we need to see which node occurs first. Crawl backward
s from child2 looking for child1. |
| 1432 for (const Node* child = child2->previousSibling(); child; child = c
hild->previousSibling()) { | 1432 for (const Node* child = child2->previousSibling(); child; child = c
hild->previousSibling()) { |
| 1433 if (child == child1) | 1433 if (child == child1) |
| 1434 return DOCUMENT_POSITION_FOLLOWING | connection; | 1434 return kDocumentPositionFollowing | connection; |
| 1435 } | 1435 } |
| 1436 return DOCUMENT_POSITION_PRECEDING | connection; | 1436 return kDocumentPositionPreceding | connection; |
| 1437 } | 1437 } |
| 1438 } | 1438 } |
| 1439 | 1439 |
| 1440 // There was no difference between the two parent chains, i.e., one was a su
bset of the other. The shorter | 1440 // There was no difference between the two parent chains, i.e., one was a su
bset of the other. The shorter |
| 1441 // chain is the ancestor. | 1441 // chain is the ancestor. |
| 1442 return index1 < index2 ? | 1442 return index1 < index2 ? |
| 1443 DOCUMENT_POSITION_FOLLOWING | DOCUMENT_POSITION_CONTAINED_BY | connectio
n : | 1443 kDocumentPositionFollowing | kDocumentPositionContainedBy | connection : |
| 1444 DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_CONTAINS | connection; | 1444 kDocumentPositionPreceding | kDocumentPositionContains | connection; |
| 1445 } | 1445 } |
| 1446 | 1446 |
| 1447 String Node::debugName() const | 1447 String Node::debugName() const |
| 1448 { | 1448 { |
| 1449 StringBuilder name; | 1449 StringBuilder name; |
| 1450 name.append(debugNodeName()); | 1450 name.append(debugNodeName()); |
| 1451 if (isElementNode()) { | 1451 if (isElementNode()) { |
| 1452 const Element& thisElement = toElement(*this); | 1452 const Element& thisElement = toElement(*this); |
| 1453 if (thisElement.hasID()) { | 1453 if (thisElement.hasID()) { |
| 1454 name.append(" id=\'"); | 1454 name.append(" id=\'"); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1525 { | 1525 { |
| 1526 if (!prefix) | 1526 if (!prefix) |
| 1527 prefix = ""; | 1527 prefix = ""; |
| 1528 if (isTextNode()) { | 1528 if (isTextNode()) { |
| 1529 String value = nodeValue(); | 1529 String value = nodeValue(); |
| 1530 value.replace('\\', "\\\\"); | 1530 value.replace('\\', "\\\\"); |
| 1531 value.replace('\n', "\\n"); | 1531 value.replace('\n', "\\n"); |
| 1532 WTFLogAlways("%s%s\t%p \"%s\"\n", prefix, nodeName().utf8().data(), this
, value.utf8().data()); | 1532 WTFLogAlways("%s%s\t%p \"%s\"\n", prefix, nodeName().utf8().data(), this
, value.utf8().data()); |
| 1533 } else if (isDocumentTypeNode()) { | 1533 } else if (isDocumentTypeNode()) { |
| 1534 WTFLogAlways("%sDOCTYPE %s\t%p\n", prefix, nodeName().utf8().data(), thi
s); | 1534 WTFLogAlways("%sDOCTYPE %s\t%p\n", prefix, nodeName().utf8().data(), thi
s); |
| 1535 } else if (getNodeType() == PROCESSING_INSTRUCTION_NODE) { | 1535 } else if (getNodeType() == kProcessingInstructionNode) { |
| 1536 WTFLogAlways("%s?%s\t%p\n", prefix, nodeName().utf8().data(), this); | 1536 WTFLogAlways("%s?%s\t%p\n", prefix, nodeName().utf8().data(), this); |
| 1537 } else if (isShadowRoot()) { | 1537 } else if (isShadowRoot()) { |
| 1538 // nodeName of ShadowRoot is #document-fragment. It's confused with | 1538 // nodeName of ShadowRoot is #document-fragment. It's confused with |
| 1539 // DocumentFragment. | 1539 // DocumentFragment. |
| 1540 WTFLogAlways("%s#shadow-root\t%p\n", prefix, this); | 1540 WTFLogAlways("%s#shadow-root\t%p\n", prefix, this); |
| 1541 } else { | 1541 } else { |
| 1542 StringBuilder attrs; | 1542 StringBuilder attrs; |
| 1543 appendAttributeDesc(this, attrs, idAttr, " ID"); | 1543 appendAttributeDesc(this, attrs, idAttr, " ID"); |
| 1544 appendAttributeDesc(this, attrs, classAttr, " CLASS"); | 1544 appendAttributeDesc(this, attrs, classAttr, " CLASS"); |
| 1545 appendAttributeDesc(this, attrs, styleAttr, " STYLE"); | 1545 appendAttributeDesc(this, attrs, styleAttr, " STYLE"); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1573 const Node* node = chain[index - 1]; | 1573 const Node* node = chain[index - 1]; |
| 1574 if (node->isShadowRoot()) { | 1574 if (node->isShadowRoot()) { |
| 1575 int count = 0; | 1575 int count = 0; |
| 1576 for (const ShadowRoot* shadowRoot = toShadowRoot(node)->olderShadowR
oot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) | 1576 for (const ShadowRoot* shadowRoot = toShadowRoot(node)->olderShadowR
oot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) |
| 1577 ++count; | 1577 ++count; |
| 1578 WTFLogAlways("/#shadow-root[%d]", count); | 1578 WTFLogAlways("/#shadow-root[%d]", count); |
| 1579 continue; | 1579 continue; |
| 1580 } | 1580 } |
| 1581 | 1581 |
| 1582 switch (node->getNodeType()) { | 1582 switch (node->getNodeType()) { |
| 1583 case ELEMENT_NODE: { | 1583 case kElementNode: { |
| 1584 WTFLogAlways("/%s", node->nodeName().utf8().data()); | 1584 WTFLogAlways("/%s", node->nodeName().utf8().data()); |
| 1585 | 1585 |
| 1586 const Element* element = toElement(node); | 1586 const Element* element = toElement(node); |
| 1587 const AtomicString& idattr = element->getIdAttribute(); | 1587 const AtomicString& idattr = element->getIdAttribute(); |
| 1588 bool hasIdAttr = !idattr.isNull() && !idattr.isEmpty(); | 1588 bool hasIdAttr = !idattr.isNull() && !idattr.isEmpty(); |
| 1589 if (node->previousSibling() || node->nextSibling()) { | 1589 if (node->previousSibling() || node->nextSibling()) { |
| 1590 int count = 0; | 1590 int count = 0; |
| 1591 for (const Node* previous = node->previousSibling(); previous; p
revious = previous->previousSibling()) { | 1591 for (const Node* previous = node->previousSibling(); previous; p
revious = previous->previousSibling()) { |
| 1592 if (previous->nodeName() == node->nodeName()) { | 1592 if (previous->nodeName() == node->nodeName()) { |
| 1593 ++count; | 1593 ++count; |
| 1594 } | 1594 } |
| 1595 } | 1595 } |
| 1596 if (hasIdAttr) | 1596 if (hasIdAttr) |
| 1597 WTFLogAlways("[@id=\"%s\" and position()=%d]", idattr.utf8()
.data(), count); | 1597 WTFLogAlways("[@id=\"%s\" and position()=%d]", idattr.utf8()
.data(), count); |
| 1598 else | 1598 else |
| 1599 WTFLogAlways("[%d]", count); | 1599 WTFLogAlways("[%d]", count); |
| 1600 } else if (hasIdAttr) { | 1600 } else if (hasIdAttr) { |
| 1601 WTFLogAlways("[@id=\"%s\"]", idattr.utf8().data()); | 1601 WTFLogAlways("[@id=\"%s\"]", idattr.utf8().data()); |
| 1602 } | 1602 } |
| 1603 break; | 1603 break; |
| 1604 } | 1604 } |
| 1605 case TEXT_NODE: | 1605 case kTextNode: |
| 1606 WTFLogAlways("/text()"); | 1606 WTFLogAlways("/text()"); |
| 1607 break; | 1607 break; |
| 1608 case ATTRIBUTE_NODE: | 1608 case kAttributeNode: |
| 1609 WTFLogAlways("/@%s", node->nodeName().utf8().data()); | 1609 WTFLogAlways("/@%s", node->nodeName().utf8().data()); |
| 1610 break; | 1610 break; |
| 1611 default: | 1611 default: |
| 1612 break; | 1612 break; |
| 1613 } | 1613 } |
| 1614 } | 1614 } |
| 1615 WTFLogAlways("\n"); | 1615 WTFLogAlways("\n"); |
| 1616 } | 1616 } |
| 1617 | 1617 |
| 1618 static void traverseTreeAndMark(const String& baseIndent, const Node* rootNode,
const Node* markedNode1, const char* markedLabel1, const Node* markedNode2, cons
t char* markedLabel2) | 1618 static void traverseTreeAndMark(const String& baseIndent, const Node* rootNode,
const Node* markedNode1, const char* markedLabel1, const Node* markedNode2, cons
t char* markedLabel2) |
| (...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2339 visitor->traceWrappers(m_next); | 2339 visitor->traceWrappers(m_next); |
| 2340 if (hasRareData()) | 2340 if (hasRareData()) |
| 2341 visitor->traceWrappers(rareData()); | 2341 visitor->traceWrappers(rareData()); |
| 2342 EventTarget::traceWrappers(visitor); | 2342 EventTarget::traceWrappers(visitor); |
| 2343 } | 2343 } |
| 2344 | 2344 |
| 2345 unsigned Node::lengthOfContents() const | 2345 unsigned Node::lengthOfContents() const |
| 2346 { | 2346 { |
| 2347 // This switch statement must be consistent with that of Range::processConte
ntsBetweenOffsets. | 2347 // This switch statement must be consistent with that of Range::processConte
ntsBetweenOffsets. |
| 2348 switch (getNodeType()) { | 2348 switch (getNodeType()) { |
| 2349 case Node::TEXT_NODE: | 2349 case Node::kTextNode: |
| 2350 case Node::CDATA_SECTION_NODE: | 2350 case Node::kCdataSectionNode: |
| 2351 case Node::COMMENT_NODE: | 2351 case Node::kCommentNode: |
| 2352 case Node::PROCESSING_INSTRUCTION_NODE: | 2352 case Node::kProcessingInstructionNode: |
| 2353 return toCharacterData(this)->length(); | 2353 return toCharacterData(this)->length(); |
| 2354 case Node::ELEMENT_NODE: | 2354 case Node::kElementNode: |
| 2355 case Node::DOCUMENT_NODE: | 2355 case Node::kDocumentNode: |
| 2356 case Node::DOCUMENT_FRAGMENT_NODE: | 2356 case Node::kDocumentFragmentNode: |
| 2357 return toContainerNode(this)->countChildren(); | 2357 return toContainerNode(this)->countChildren(); |
| 2358 case Node::ATTRIBUTE_NODE: | 2358 case Node::kAttributeNode: |
| 2359 case Node::DOCUMENT_TYPE_NODE: | 2359 case Node::kDocumentTypeNode: |
| 2360 return 0; | 2360 return 0; |
| 2361 } | 2361 } |
| 2362 ASSERT_NOT_REACHED(); | 2362 ASSERT_NOT_REACHED(); |
| 2363 return 0; | 2363 return 0; |
| 2364 } | 2364 } |
| 2365 | 2365 |
| 2366 v8::Local<v8::Object> Node::wrap(v8::Isolate* isolate, v8::Local<v8::Object> cre
ationContext) | 2366 v8::Local<v8::Object> Node::wrap(v8::Isolate* isolate, v8::Local<v8::Object> cre
ationContext) |
| 2367 { | 2367 { |
| 2368 DCHECK(!DOMDataStore::containsWrapper(this, isolate)); | 2368 DCHECK(!DOMDataStore::containsWrapper(this, isolate)); |
| 2369 | 2369 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2404 | 2404 |
| 2405 void showNodePath(const blink::Node* node) | 2405 void showNodePath(const blink::Node* node) |
| 2406 { | 2406 { |
| 2407 if (node) | 2407 if (node) |
| 2408 node->showNodePathForThis(); | 2408 node->showNodePathForThis(); |
| 2409 else | 2409 else |
| 2410 fprintf(stderr, "Cannot showNodePath for (nil)\n"); | 2410 fprintf(stderr, "Cannot showNodePath for (nil)\n"); |
| 2411 } | 2411 } |
| 2412 | 2412 |
| 2413 #endif | 2413 #endif |
| OLD | NEW |