| 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 11 matching lines...) Expand all Loading... |
| 22 * Boston, MA 02110-1301, USA. | 22 * Boston, MA 02110-1301, USA. |
| 23 */ | 23 */ |
| 24 | 24 |
| 25 #include "config.h" | 25 #include "config.h" |
| 26 #include "core/dom/Node.h" | 26 #include "core/dom/Node.h" |
| 27 | 27 |
| 28 #include "bindings/core/v8/DOMDataStore.h" | 28 #include "bindings/core/v8/DOMDataStore.h" |
| 29 #include "bindings/core/v8/ExceptionState.h" | 29 #include "bindings/core/v8/ExceptionState.h" |
| 30 #include "bindings/core/v8/V8DOMWrapper.h" | 30 #include "bindings/core/v8/V8DOMWrapper.h" |
| 31 #include "core/HTMLNames.h" | 31 #include "core/HTMLNames.h" |
| 32 #include "core/XMLNames.h" | |
| 33 #include "core/css/resolver/StyleResolver.h" | 32 #include "core/css/resolver/StyleResolver.h" |
| 34 #include "core/dom/AXObjectCache.h" | 33 #include "core/dom/AXObjectCache.h" |
| 35 #include "core/dom/Attr.h" | 34 #include "core/dom/Attr.h" |
| 36 #include "core/dom/Attribute.h" | 35 #include "core/dom/Attribute.h" |
| 37 #include "core/dom/ChildListMutationScope.h" | 36 #include "core/dom/ChildListMutationScope.h" |
| 38 #include "core/dom/ChildNodeList.h" | 37 #include "core/dom/ChildNodeList.h" |
| 39 #include "core/dom/DOMImplementation.h" | |
| 40 #include "core/dom/DOMNodeIds.h" | 38 #include "core/dom/DOMNodeIds.h" |
| 41 #include "core/dom/Document.h" | 39 #include "core/dom/Document.h" |
| 42 #include "core/dom/DocumentFragment.h" | 40 #include "core/dom/DocumentFragment.h" |
| 43 #include "core/dom/DocumentMarkerController.h" | 41 #include "core/dom/DocumentMarkerController.h" |
| 44 #include "core/dom/DocumentType.h" | 42 #include "core/dom/DocumentType.h" |
| 45 #include "core/dom/Element.h" | 43 #include "core/dom/Element.h" |
| 46 #include "core/dom/ElementRareData.h" | 44 #include "core/dom/ElementRareData.h" |
| 47 #include "core/dom/ElementTraversal.h" | 45 #include "core/dom/ElementTraversal.h" |
| 48 #include "core/dom/ExceptionCode.h" | 46 #include "core/dom/ExceptionCode.h" |
| 49 #include "core/dom/LayoutTreeBuilderTraversal.h" | 47 #include "core/dom/LayoutTreeBuilderTraversal.h" |
| 50 #include "core/dom/LiveNodeList.h" | |
| 51 #include "core/dom/NodeRareData.h" | 48 #include "core/dom/NodeRareData.h" |
| 52 #include "core/dom/NodeTraversal.h" | 49 #include "core/dom/NodeTraversal.h" |
| 53 #include "core/dom/ProcessingInstruction.h" | 50 #include "core/dom/ProcessingInstruction.h" |
| 54 #include "core/dom/Range.h" | 51 #include "core/dom/Range.h" |
| 55 #include "core/dom/StaticNodeList.h" | 52 #include "core/dom/StaticNodeList.h" |
| 56 #include "core/dom/StyleEngine.h" | 53 #include "core/dom/StyleEngine.h" |
| 57 #include "core/dom/TemplateContentDocumentFragment.h" | 54 #include "core/dom/TemplateContentDocumentFragment.h" |
| 58 #include "core/dom/Text.h" | 55 #include "core/dom/Text.h" |
| 59 #include "core/dom/TreeScopeAdopter.h" | 56 #include "core/dom/TreeScopeAdopter.h" |
| 60 #include "core/dom/UserActionElementSet.h" | 57 #include "core/dom/UserActionElementSet.h" |
| 61 #include "core/dom/shadow/ComposedTreeTraversal.h" | 58 #include "core/dom/shadow/ComposedTreeTraversal.h" |
| 62 #include "core/dom/shadow/ElementShadow.h" | 59 #include "core/dom/shadow/ElementShadow.h" |
| 63 #include "core/dom/shadow/InsertionPoint.h" | 60 #include "core/dom/shadow/InsertionPoint.h" |
| 64 #include "core/dom/shadow/ShadowRoot.h" | 61 #include "core/dom/shadow/ShadowRoot.h" |
| 65 #include "core/editing/htmlediting.h" | 62 #include "core/editing/htmlediting.h" |
| 66 #include "core/editing/markup.h" | |
| 67 #include "core/events/Event.h" | 63 #include "core/events/Event.h" |
| 68 #include "core/events/EventDispatchMediator.h" | 64 #include "core/events/EventDispatchMediator.h" |
| 69 #include "core/events/EventDispatcher.h" | 65 #include "core/events/EventDispatcher.h" |
| 70 #include "core/events/EventListener.h" | 66 #include "core/events/EventListener.h" |
| 71 #include "core/events/GestureEvent.h" | 67 #include "core/events/GestureEvent.h" |
| 72 #include "core/events/KeyboardEvent.h" | 68 #include "core/events/KeyboardEvent.h" |
| 73 #include "core/events/MouseEvent.h" | 69 #include "core/events/MouseEvent.h" |
| 74 #include "core/events/MutationEvent.h" | 70 #include "core/events/MutationEvent.h" |
| 75 #include "core/events/TextEvent.h" | 71 #include "core/events/TextEvent.h" |
| 76 #include "core/events/TouchEvent.h" | 72 #include "core/events/TouchEvent.h" |
| 77 #include "core/events/UIEvent.h" | 73 #include "core/events/UIEvent.h" |
| 78 #include "core/events/WheelEvent.h" | 74 #include "core/events/WheelEvent.h" |
| 79 #include "core/frame/EventHandlerRegistry.h" | 75 #include "core/frame/EventHandlerRegistry.h" |
| 80 #include "core/frame/LocalDOMWindow.h" | 76 #include "core/frame/LocalDOMWindow.h" |
| 81 #include "core/frame/LocalFrame.h" | 77 #include "core/frame/LocalFrame.h" |
| 82 #include "core/frame/Settings.h" | 78 #include "core/frame/Settings.h" |
| 83 #include "core/html/HTMLAnchorElement.h" | |
| 84 #include "core/html/HTMLDialogElement.h" | 79 #include "core/html/HTMLDialogElement.h" |
| 85 #include "core/html/HTMLFrameOwnerElement.h" | 80 #include "core/html/HTMLFrameOwnerElement.h" |
| 86 #include "core/html/HTMLStyleElement.h" | |
| 87 #include "core/input/EventHandler.h" | 81 #include "core/input/EventHandler.h" |
| 88 #include "core/layout/LayoutBox.h" | 82 #include "core/layout/LayoutBox.h" |
| 89 #include "core/page/ContextMenuController.h" | 83 #include "core/page/ContextMenuController.h" |
| 90 #include "core/page/Page.h" | 84 #include "core/page/Page.h" |
| 91 #include "core/svg/graphics/SVGImage.h" | 85 #include "core/svg/graphics/SVGImage.h" |
| 92 #include "platform/EventDispatchForbiddenScope.h" | 86 #include "platform/EventDispatchForbiddenScope.h" |
| 93 #include "platform/TraceEvent.h" | 87 #include "platform/TraceEvent.h" |
| 94 #include "platform/TracedValue.h" | 88 #include "platform/TracedValue.h" |
| 95 #include "wtf/HashSet.h" | 89 #include "wtf/HashSet.h" |
| 96 #include "wtf/Partitions.h" | 90 #include "wtf/Partitions.h" |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 if (node->hasRareData()) { | 155 if (node->hasRareData()) { |
| 162 ++nodesWithRareData; | 156 ++nodesWithRareData; |
| 163 if (node->isElementNode()) { | 157 if (node->isElementNode()) { |
| 164 ++elementsWithRareData; | 158 ++elementsWithRareData; |
| 165 if (toElement(node)->hasNamedNodeMap()) | 159 if (toElement(node)->hasNamedNodeMap()) |
| 166 ++elementsWithNamedNodeMap; | 160 ++elementsWithNamedNodeMap; |
| 167 } | 161 } |
| 168 } | 162 } |
| 169 | 163 |
| 170 switch (node->nodeType()) { | 164 switch (node->nodeType()) { |
| 171 case ELEMENT_NODE: { | 165 case ELEMENT_NODE: { |
| 172 ++elementNodes; | 166 ++elementNodes; |
| 173 | 167 |
| 174 // Tag stats | 168 // Tag stats |
| 175 Element* element = toElement(node); | 169 Element* element = toElement(node); |
| 176 HashMap<String, size_t>::AddResult result = perTagCount.add(elem
ent->tagName(), 1); | 170 HashMap<String, size_t>::AddResult result = perTagCount.add(element-
>tagName(), 1); |
| 177 if (!result.isNewEntry) | 171 if (!result.isNewEntry) |
| 178 result.storedValue->value++; | 172 result.storedValue->value++; |
| 179 | 173 |
| 180 if (const ElementData* elementData = element->elementData()) { | 174 if (const ElementData* elementData = element->elementData()) { |
| 181 attributes += elementData->attributes().size(); | 175 attributes += elementData->attributes().size(); |
| 182 ++elementsWithAttributeStorage; | 176 ++elementsWithAttributeStorage; |
| 183 } | |
| 184 break; | |
| 185 } | 177 } |
| 186 case ATTRIBUTE_NODE: { | 178 break; |
| 187 ++attrNodes; | 179 } |
| 188 break; | 180 case ATTRIBUTE_NODE: { |
| 189 } | 181 ++attrNodes; |
| 190 case TEXT_NODE: { | 182 break; |
| 191 ++textNodes; | 183 } |
| 192 break; | 184 case TEXT_NODE: { |
| 193 } | 185 ++textNodes; |
| 194 case CDATA_SECTION_NODE: { | 186 break; |
| 195 ++cdataNodes; | 187 } |
| 196 break; | 188 case CDATA_SECTION_NODE: { |
| 197 } | 189 ++cdataNodes; |
| 198 case COMMENT_NODE: { | 190 break; |
| 199 ++commentNodes; | 191 } |
| 200 break; | 192 case COMMENT_NODE: { |
| 201 } | 193 ++commentNodes; |
| 202 case PROCESSING_INSTRUCTION_NODE: { | 194 break; |
| 203 ++piNodes; | 195 } |
| 204 break; | 196 case PROCESSING_INSTRUCTION_NODE: { |
| 205 } | 197 ++piNodes; |
| 206 case DOCUMENT_NODE: { | 198 break; |
| 207 ++documentNodes; | 199 } |
| 208 break; | 200 case DOCUMENT_NODE: { |
| 209 } | 201 ++documentNodes; |
| 210 case DOCUMENT_TYPE_NODE: { | 202 break; |
| 211 ++docTypeNodes; | 203 } |
| 212 break; | 204 case DOCUMENT_TYPE_NODE: { |
| 213 } | 205 ++docTypeNodes; |
| 214 case DOCUMENT_FRAGMENT_NODE: { | 206 break; |
| 215 if (node->isShadowRoot()) | 207 } |
| 216 ++shadowRootNodes; | 208 case DOCUMENT_FRAGMENT_NODE: { |
| 217 else | 209 if (node->isShadowRoot()) |
| 218 ++fragmentNodes; | 210 ++shadowRootNodes; |
| 219 break; | 211 else |
| 220 } | 212 ++fragmentNodes; |
| 213 break; |
| 214 } |
| 221 } | 215 } |
| 222 } | 216 } |
| 223 | 217 |
| 224 printf("Number of Nodes: %d\n\n", liveNodeSet().size()); | 218 printf("Number of Nodes: %d\n\n", liveNodeSet().size()); |
| 225 printf("Number of Nodes with RareData: %zu\n\n", nodesWithRareData); | 219 printf("Number of Nodes with RareData: %zu\n\n", nodesWithRareData); |
| 226 | 220 |
| 227 printf("NodeType distribution:\n"); | 221 printf("NodeType distribution:\n"); |
| 228 printf(" Number of Element nodes: %zu\n", elementNodes); | 222 printf(" Number of Element nodes: %zu\n", elementNodes); |
| 229 printf(" Number of Attribute nodes: %zu\n", attrNodes); | 223 printf(" Number of Attribute nodes: %zu\n", attrNodes); |
| 230 printf(" Number of Text nodes: %zu\n", textNodes); | 224 printf(" Number of Text nodes: %zu\n", textNodes); |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 LayoutBoxModelObject* box = layoutBoxModelObject(); | 617 LayoutBoxModelObject* box = layoutBoxModelObject(); |
| 624 if (!box) | 618 if (!box) |
| 625 return false; | 619 return false; |
| 626 if (!box->borderBoundingBox().isEmpty()) | 620 if (!box->borderBoundingBox().isEmpty()) |
| 627 return true; | 621 return true; |
| 628 | 622 |
| 629 Vector<IntRect> rects; | 623 Vector<IntRect> rects; |
| 630 FloatPoint absPos = layoutObject()->localToAbsolute(); | 624 FloatPoint absPos = layoutObject()->localToAbsolute(); |
| 631 layoutObject()->absoluteRects(rects, flooredLayoutPoint(absPos)); | 625 layoutObject()->absoluteRects(rects, flooredLayoutPoint(absPos)); |
| 632 size_t n = rects.size(); | 626 size_t n = rects.size(); |
| 633 for (size_t i = 0; i < n; ++i) | 627 for (size_t i = 0; i < n; ++i) { |
| 634 if (!rects[i].isEmpty()) | 628 if (!rects[i].isEmpty()) { |
| 635 return true; | 629 return true; |
| 630 } |
| 631 } |
| 636 | 632 |
| 637 return false; | 633 return false; |
| 638 } | 634 } |
| 639 | 635 |
| 640 #ifndef NDEBUG | 636 #ifndef NDEBUG |
| 641 inline static ShadowRoot* oldestShadowRootFor(const Node* node) | 637 inline static ShadowRoot* oldestShadowRootFor(const Node* node) |
| 642 { | 638 { |
| 643 if (!node->isElementNode()) | 639 if (!node->isElementNode()) |
| 644 return nullptr; | 640 return nullptr; |
| 645 if (ElementShadow* shadow = toElement(node)->shadow()) | 641 if (ElementShadow* shadow = toElement(node)->shadow()) |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 bool Node::isInert() const | 782 bool Node::isInert() const |
| 787 { | 783 { |
| 788 const HTMLDialogElement* dialog = document().activeModalDialog(); | 784 const HTMLDialogElement* dialog = document().activeModalDialog(); |
| 789 if (dialog && this != document() && (!canParticipateInComposedTree() || !Com
posedTreeTraversal::containsIncludingPseudoElement(*dialog, *this))) | 785 if (dialog && this != document() && (!canParticipateInComposedTree() || !Com
posedTreeTraversal::containsIncludingPseudoElement(*dialog, *this))) |
| 790 return true; | 786 return true; |
| 791 return document().ownerElement() && document().ownerElement()->isInert(); | 787 return document().ownerElement() && document().ownerElement()->isInert(); |
| 792 } | 788 } |
| 793 | 789 |
| 794 unsigned Node::nodeIndex() const | 790 unsigned Node::nodeIndex() const |
| 795 { | 791 { |
| 796 Node *_tempNode = previousSibling(); | 792 Node* tempNode = previousSibling(); |
| 797 unsigned count = 0; | 793 unsigned count = 0; |
| 798 for (count = 0; _tempNode; count++) | 794 for (count = 0; tempNode; count++) |
| 799 _tempNode = _tempNode->previousSibling(); | 795 tempNode = tempNode->previousSibling(); |
| 800 return count; | 796 return count; |
| 801 } | 797 } |
| 802 | 798 |
| 803 NodeListsNodeData* Node::nodeLists() | 799 NodeListsNodeData* Node::nodeLists() |
| 804 { | 800 { |
| 805 return hasRareData() ? rareData()->nodeLists() : nullptr; | 801 return hasRareData() ? rareData()->nodeLists() : nullptr; |
| 806 } | 802 } |
| 807 | 803 |
| 808 void Node::clearNodeLists() | 804 void Node::clearNodeLists() |
| 809 { | 805 { |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1003 | 999 |
| 1004 // FIXME: This code is used by editing. Seems like it could move over there and
not pollute Node. | 1000 // FIXME: This code is used by editing. Seems like it could move over there and
not pollute Node. |
| 1005 Node* Node::previousNodeConsideringAtomicNodes() const | 1001 Node* Node::previousNodeConsideringAtomicNodes() const |
| 1006 { | 1002 { |
| 1007 if (previousSibling()) { | 1003 if (previousSibling()) { |
| 1008 Node* n = previousSibling(); | 1004 Node* n = previousSibling(); |
| 1009 while (!isAtomicNode(n) && n->lastChild()) | 1005 while (!isAtomicNode(n) && n->lastChild()) |
| 1010 n = n->lastChild(); | 1006 n = n->lastChild(); |
| 1011 return n; | 1007 return n; |
| 1012 } | 1008 } |
| 1013 else if (parentNode()) { | 1009 if (parentNode()) { |
| 1014 return parentNode(); | 1010 return parentNode(); |
| 1015 } | 1011 } |
| 1016 else { | 1012 return nullptr; |
| 1017 return nullptr; | |
| 1018 } | |
| 1019 } | 1013 } |
| 1020 | 1014 |
| 1021 Node* Node::nextNodeConsideringAtomicNodes() const | 1015 Node* Node::nextNodeConsideringAtomicNodes() const |
| 1022 { | 1016 { |
| 1023 if (!isAtomicNode(this) && hasChildren()) | 1017 if (!isAtomicNode(this) && hasChildren()) |
| 1024 return firstChild(); | 1018 return firstChild(); |
| 1025 if (nextSibling()) | 1019 if (nextSibling()) |
| 1026 return nextSibling(); | 1020 return nextSibling(); |
| 1027 const Node* n = this; | 1021 const Node* n = this; |
| 1028 while (n && !n->nextSibling()) | 1022 while (n && !n->nextSibling()) |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1234 } | 1228 } |
| 1235 | 1229 |
| 1236 return true; | 1230 return true; |
| 1237 } | 1231 } |
| 1238 | 1232 |
| 1239 bool Node::isDefaultNamespace(const AtomicString& namespaceURIMaybeEmpty) const | 1233 bool Node::isDefaultNamespace(const AtomicString& namespaceURIMaybeEmpty) const |
| 1240 { | 1234 { |
| 1241 const AtomicString& namespaceURI = namespaceURIMaybeEmpty.isEmpty() ? nullAt
om : namespaceURIMaybeEmpty; | 1235 const AtomicString& namespaceURI = namespaceURIMaybeEmpty.isEmpty() ? nullAt
om : namespaceURIMaybeEmpty; |
| 1242 | 1236 |
| 1243 switch (nodeType()) { | 1237 switch (nodeType()) { |
| 1244 case ELEMENT_NODE: { | 1238 case ELEMENT_NODE: { |
| 1245 const Element& element = toElement(*this); | 1239 const Element& element = toElement(*this); |
| 1246 | 1240 |
| 1247 if (element.prefix().isNull()) | 1241 if (element.prefix().isNull()) |
| 1248 return element.namespaceURI() == namespaceURI; | 1242 return element.namespaceURI() == namespaceURI; |
| 1249 | 1243 |
| 1250 AttributeCollection attributes = element.attributes(); | 1244 AttributeCollection attributes = element.attributes(); |
| 1251 for (const Attribute& attr : attributes) { | 1245 for (const Attribute& attr : attributes) { |
| 1252 if (attr.localName() == xmlnsAtom) | 1246 if (attr.localName() == xmlnsAtom) |
| 1253 return attr.value() == namespaceURI; | 1247 return attr.value() == namespaceURI; |
| 1254 } | 1248 } |
| 1255 | 1249 |
| 1256 if (Element* parent = parentElement()) | 1250 if (Element* parent = parentElement()) |
| 1257 return parent->isDefaultNamespace(namespaceURI); | 1251 return parent->isDefaultNamespace(namespaceURI); |
| 1258 | 1252 |
| 1259 return false; | 1253 return false; |
| 1260 } | 1254 } |
| 1261 case DOCUMENT_NODE: | 1255 case DOCUMENT_NODE: |
| 1262 if (Element* de = toDocument(this)->documentElement()) | 1256 if (Element* de = toDocument(this)->documentElement()) |
| 1263 return de->isDefaultNamespace(namespaceURI); | 1257 return de->isDefaultNamespace(namespaceURI); |
| 1264 return false; | 1258 return false; |
| 1265 case DOCUMENT_TYPE_NODE: | 1259 case DOCUMENT_TYPE_NODE: |
| 1266 case DOCUMENT_FRAGMENT_NODE: | 1260 case DOCUMENT_FRAGMENT_NODE: |
| 1267 return false; | 1261 return false; |
| 1268 case ATTRIBUTE_NODE: { | 1262 case ATTRIBUTE_NODE: { |
| 1269 const Attr* attr = toAttr(this); | 1263 const Attr* attr = toAttr(this); |
| 1270 if (attr->ownerElement()) | 1264 if (attr->ownerElement()) |
| 1271 return attr->ownerElement()->isDefaultNamespace(namespaceURI); | 1265 return attr->ownerElement()->isDefaultNamespace(namespaceURI); |
| 1272 return false; | 1266 return false; |
| 1273 } | 1267 } |
| 1274 default: | 1268 default: |
| 1275 if (Element* parent = parentElement()) | 1269 if (Element* parent = parentElement()) |
| 1276 return parent->isDefaultNamespace(namespaceURI); | 1270 return parent->isDefaultNamespace(namespaceURI); |
| 1277 return false; | 1271 return false; |
| 1278 } | 1272 } |
| 1279 } | 1273 } |
| 1280 | 1274 |
| 1281 const AtomicString& Node::lookupPrefix(const AtomicString& namespaceURI) const | 1275 const AtomicString& Node::lookupPrefix(const AtomicString& namespaceURI) const |
| 1282 { | 1276 { |
| 1283 // Implemented according to | 1277 // Implemented according to |
| 1284 // http://dom.spec.whatwg.org/#dom-node-lookupprefix | 1278 // http://dom.spec.whatwg.org/#dom-node-lookupprefix |
| 1285 | 1279 |
| 1286 if (namespaceURI.isEmpty() || namespaceURI.isNull()) | 1280 if (namespaceURI.isEmpty() || namespaceURI.isNull()) |
| 1287 return nullAtom; | 1281 return nullAtom; |
| 1288 | 1282 |
| 1289 const Element* context; | 1283 const Element* context; |
| 1290 | 1284 |
| 1291 switch (nodeType()) { | 1285 switch (nodeType()) { |
| 1292 case ELEMENT_NODE: | 1286 case ELEMENT_NODE: |
| 1293 context = toElement(this); | 1287 context = toElement(this); |
| 1294 break; | 1288 break; |
| 1295 case DOCUMENT_NODE: | 1289 case DOCUMENT_NODE: |
| 1296 context = toDocument(this)->documentElement(); | 1290 context = toDocument(this)->documentElement(); |
| 1297 break; | 1291 break; |
| 1298 case DOCUMENT_FRAGMENT_NODE: | 1292 case DOCUMENT_FRAGMENT_NODE: |
| 1299 case DOCUMENT_TYPE_NODE: | 1293 case DOCUMENT_TYPE_NODE: |
| 1300 context = nullptr; | 1294 context = nullptr; |
| 1301 break; | 1295 break; |
| 1302 // FIXME: Remove this when Attr no longer extends Node (CR305105) | 1296 // FIXME: Remove this when Attr no longer extends Node (CR305105) |
| 1303 case ATTRIBUTE_NODE: | 1297 case ATTRIBUTE_NODE: |
| 1304 context = toAttr(this)->ownerElement(); | 1298 context = toAttr(this)->ownerElement(); |
| 1305 break; | 1299 break; |
| 1306 default: | 1300 default: |
| 1307 context = parentElement(); | 1301 context = parentElement(); |
| 1308 break; | 1302 break; |
| 1309 } | 1303 } |
| 1310 | 1304 |
| 1311 if (!context) | 1305 if (!context) |
| 1312 return nullAtom; | 1306 return nullAtom; |
| 1313 | 1307 |
| 1314 return context->locateNamespacePrefix(namespaceURI); | 1308 return context->locateNamespacePrefix(namespaceURI); |
| 1315 } | 1309 } |
| 1316 | 1310 |
| 1317 const AtomicString& Node::lookupNamespaceURI(const String& prefix) const | 1311 const AtomicString& Node::lookupNamespaceURI(const String& prefix) const |
| 1318 { | 1312 { |
| 1319 // Implemented according to | 1313 // Implemented according to |
| 1320 // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algori
thms.html#lookupNamespaceURIAlgo | 1314 // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algori
thms.html#lookupNamespaceURIAlgo |
| 1321 | 1315 |
| 1322 if (!prefix.isNull() && prefix.isEmpty()) | 1316 if (!prefix.isNull() && prefix.isEmpty()) |
| 1323 return nullAtom; | 1317 return nullAtom; |
| 1324 | 1318 |
| 1325 switch (nodeType()) { | 1319 switch (nodeType()) { |
| 1326 case ELEMENT_NODE: { | 1320 case ELEMENT_NODE: { |
| 1327 const Element& element = toElement(*this); | 1321 const Element& element = toElement(*this); |
| 1328 | 1322 |
| 1329 if (!element.namespaceURI().isNull() && element.prefix() == prefix) | 1323 if (!element.namespaceURI().isNull() && element.prefix() == prefix) |
| 1330 return element.namespaceURI(); | 1324 return element.namespaceURI(); |
| 1331 | 1325 |
| 1332 AttributeCollection attributes = element.attributes(); | 1326 AttributeCollection attributes = element.attributes(); |
| 1333 for (const Attribute& attr : attributes) { | 1327 for (const Attribute& attr : attributes) { |
| 1334 if (attr.prefix() == xmlnsAtom && attr.localName() == prefix) { | 1328 if (attr.prefix() == xmlnsAtom && attr.localName() == prefix) { |
| 1335 if (!attr.value().isEmpty()) | 1329 if (!attr.value().isEmpty()) |
| 1336 return attr.value(); | 1330 return attr.value(); |
| 1337 return nullAtom; | 1331 return nullAtom; |
| 1338 } | |
| 1339 if (attr.localName() == xmlnsAtom && prefix.isNull()) { | |
| 1340 if (!attr.value().isEmpty()) | |
| 1341 return attr.value(); | |
| 1342 return nullAtom; | |
| 1343 } | |
| 1344 } | 1332 } |
| 1333 if (attr.localName() == xmlnsAtom && prefix.isNull()) { |
| 1334 if (!attr.value().isEmpty()) |
| 1335 return attr.value(); |
| 1336 return nullAtom; |
| 1337 } |
| 1338 } |
| 1345 | 1339 |
| 1346 if (Element* parent = parentElement()) | 1340 if (Element* parent = parentElement()) |
| 1347 return parent->lookupNamespaceURI(prefix); | 1341 return parent->lookupNamespaceURI(prefix); |
| 1348 return nullAtom; | 1342 return nullAtom; |
| 1349 } | 1343 } |
| 1350 case DOCUMENT_NODE: | 1344 case DOCUMENT_NODE: |
| 1351 if (Element* de = toDocument(this)->documentElement()) | 1345 if (Element* de = toDocument(this)->documentElement()) |
| 1352 return de->lookupNamespaceURI(prefix); | 1346 return de->lookupNamespaceURI(prefix); |
| 1353 return nullAtom; | 1347 return nullAtom; |
| 1354 case DOCUMENT_TYPE_NODE: | 1348 case DOCUMENT_TYPE_NODE: |
| 1355 case DOCUMENT_FRAGMENT_NODE: | 1349 case DOCUMENT_FRAGMENT_NODE: |
| 1356 return nullAtom; | 1350 return nullAtom; |
| 1357 case ATTRIBUTE_NODE: { | 1351 case ATTRIBUTE_NODE: { |
| 1358 const Attr *attr = toAttr(this); | 1352 const Attr *attr = toAttr(this); |
| 1359 if (attr->ownerElement()) | 1353 if (attr->ownerElement()) |
| 1360 return attr->ownerElement()->lookupNamespaceURI(prefix); | 1354 return attr->ownerElement()->lookupNamespaceURI(prefix); |
| 1361 else | 1355 return nullAtom; |
| 1362 return nullAtom; | 1356 } |
| 1363 } | 1357 default: |
| 1364 default: | 1358 if (Element* parent = parentElement()) |
| 1365 if (Element* parent = parentElement()) | 1359 return parent->lookupNamespaceURI(prefix); |
| 1366 return parent->lookupNamespaceURI(prefix); | 1360 return nullAtom; |
| 1367 return nullAtom; | |
| 1368 } | 1361 } |
| 1369 } | 1362 } |
| 1370 | 1363 |
| 1371 String Node::textContent(bool convertBRsToNewlines) const | 1364 String Node::textContent(bool convertBRsToNewlines) const |
| 1372 { | 1365 { |
| 1373 // This covers ProcessingInstruction and Comment that should return their | 1366 // This covers ProcessingInstruction and Comment that should return their |
| 1374 // value when .textContent is accessed on them, but should be ignored when | 1367 // value when .textContent is accessed on them, but should be ignored when |
| 1375 // iterated over as a descendant of a ContainerNode. | 1368 // iterated over as a descendant of a ContainerNode. |
| 1376 if (isCharacterDataNode()) | 1369 if (isCharacterDataNode()) |
| 1377 return toCharacterData(this)->data(); | 1370 return toCharacterData(this)->data(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1388 } else if (node.isTextNode()) { | 1381 } else if (node.isTextNode()) { |
| 1389 content.append(toText(node).data()); | 1382 content.append(toText(node).data()); |
| 1390 } | 1383 } |
| 1391 } | 1384 } |
| 1392 return content.toString(); | 1385 return content.toString(); |
| 1393 } | 1386 } |
| 1394 | 1387 |
| 1395 void Node::setTextContent(const String& text) | 1388 void Node::setTextContent(const String& text) |
| 1396 { | 1389 { |
| 1397 switch (nodeType()) { | 1390 switch (nodeType()) { |
| 1398 case TEXT_NODE: | 1391 case TEXT_NODE: |
| 1399 case CDATA_SECTION_NODE: | 1392 case CDATA_SECTION_NODE: |
| 1400 case COMMENT_NODE: | 1393 case COMMENT_NODE: |
| 1401 case PROCESSING_INSTRUCTION_NODE: | 1394 case PROCESSING_INSTRUCTION_NODE: |
| 1402 setNodeValue(text); | 1395 setNodeValue(text); |
| 1396 return; |
| 1397 case ELEMENT_NODE: |
| 1398 case DOCUMENT_FRAGMENT_NODE: { |
| 1399 // FIXME: Merge this logic into replaceChildrenWithText. |
| 1400 RefPtrWillBeRawPtr<ContainerNode> container = toContainerNode(this); |
| 1401 |
| 1402 // Note: This is an intentional optimization. |
| 1403 // See crbug.com/352836 also. |
| 1404 // No need to do anything if the text is identical. |
| 1405 if (container->hasOneTextChild() && toText(container->firstChild())->dat
a() == text) |
| 1403 return; | 1406 return; |
| 1404 case ELEMENT_NODE: | |
| 1405 case DOCUMENT_FRAGMENT_NODE: { | |
| 1406 // FIXME: Merge this logic into replaceChildrenWithText. | |
| 1407 RefPtrWillBeRawPtr<ContainerNode> container = toContainerNode(this); | |
| 1408 | 1407 |
| 1409 // Note: This is an intentional optimization. | 1408 ChildListMutationScope mutation(*this); |
| 1410 // See crbug.com/352836 also. | 1409 // Note: This API will not insert empty text nodes: |
| 1411 // No need to do anything if the text is identical. | 1410 // http://dom.spec.whatwg.org/#dom-node-textcontent |
| 1412 if (container->hasOneTextChild() && toText(container->firstChild())-
>data() == text) | 1411 if (text.isEmpty()) { |
| 1413 return; | 1412 container->removeChildren(DispatchSubtreeModifiedEvent); |
| 1414 | 1413 } else { |
| 1415 ChildListMutationScope mutation(*this); | 1414 container->removeChildren(OmitSubtreeModifiedEvent); |
| 1416 // Note: This API will not insert empty text nodes: | 1415 container->appendChild(document().createTextNode(text), ASSERT_NO_EX
CEPTION); |
| 1417 // http://dom.spec.whatwg.org/#dom-node-textcontent | |
| 1418 if (text.isEmpty()) { | |
| 1419 container->removeChildren(DispatchSubtreeModifiedEvent); | |
| 1420 } else { | |
| 1421 container->removeChildren(OmitSubtreeModifiedEvent); | |
| 1422 container->appendChild(document().createTextNode(text), ASSERT_N
O_EXCEPTION); | |
| 1423 } | |
| 1424 return; | |
| 1425 } | 1416 } |
| 1426 case ATTRIBUTE_NODE: | 1417 return; |
| 1427 case DOCUMENT_NODE: | 1418 } |
| 1428 case DOCUMENT_TYPE_NODE: | 1419 case ATTRIBUTE_NODE: |
| 1429 // Do nothing. | 1420 case DOCUMENT_NODE: |
| 1430 return; | 1421 case DOCUMENT_TYPE_NODE: |
| 1422 // Do nothing. |
| 1423 return; |
| 1431 } | 1424 } |
| 1432 ASSERT_NOT_REACHED(); | 1425 ASSERT_NOT_REACHED(); |
| 1433 } | 1426 } |
| 1434 | 1427 |
| 1435 bool Node::offsetInCharacters() const | 1428 bool Node::offsetInCharacters() const |
| 1436 { | 1429 { |
| 1437 return isCharacterDataNode(); | 1430 return isCharacterDataNode(); |
| 1438 } | 1431 } |
| 1439 | 1432 |
| 1440 unsigned short Node::compareDocumentPosition(const Node* otherNode, ShadowTreesT
reatment treatment) const | 1433 unsigned short Node::compareDocumentPosition(const Node* otherNode, ShadowTreesT
reatment treatment) const |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1519 if (child2->nodeType() == ATTRIBUTE_NODE) | 1512 if (child2->nodeType() == ATTRIBUTE_NODE) |
| 1520 return DOCUMENT_POSITION_PRECEDING | connection; | 1513 return DOCUMENT_POSITION_PRECEDING | connection; |
| 1521 | 1514 |
| 1522 // If one of the children is a shadow root, | 1515 // If one of the children is a shadow root, |
| 1523 if (child1->isShadowRoot() || child2->isShadowRoot()) { | 1516 if (child1->isShadowRoot() || child2->isShadowRoot()) { |
| 1524 if (!child2->isShadowRoot()) | 1517 if (!child2->isShadowRoot()) |
| 1525 return Node::DOCUMENT_POSITION_FOLLOWING | connection; | 1518 return Node::DOCUMENT_POSITION_FOLLOWING | connection; |
| 1526 if (!child1->isShadowRoot()) | 1519 if (!child1->isShadowRoot()) |
| 1527 return Node::DOCUMENT_POSITION_PRECEDING | connection; | 1520 return Node::DOCUMENT_POSITION_PRECEDING | connection; |
| 1528 | 1521 |
| 1529 for (ShadowRoot* child = toShadowRoot(child2)->olderShadowRoot()
; child; child = child->olderShadowRoot()) | 1522 for (ShadowRoot* child = toShadowRoot(child2)->olderShadowRoot()
; child; child = child->olderShadowRoot()) { |
| 1530 if (child == child1) | 1523 if (child == child1) { |
| 1531 return Node::DOCUMENT_POSITION_FOLLOWING | connection; | 1524 return Node::DOCUMENT_POSITION_FOLLOWING | connection; |
| 1525 } |
| 1526 } |
| 1532 | 1527 |
| 1533 return Node::DOCUMENT_POSITION_PRECEDING | connection; | 1528 return Node::DOCUMENT_POSITION_PRECEDING | connection; |
| 1534 } | 1529 } |
| 1535 | 1530 |
| 1536 if (!child2->nextSibling()) | 1531 if (!child2->nextSibling()) |
| 1537 return DOCUMENT_POSITION_FOLLOWING | connection; | 1532 return DOCUMENT_POSITION_FOLLOWING | connection; |
| 1538 if (!child1->nextSibling()) | 1533 if (!child1->nextSibling()) |
| 1539 return DOCUMENT_POSITION_PRECEDING | connection; | 1534 return DOCUMENT_POSITION_PRECEDING | connection; |
| 1540 | 1535 |
| 1541 // Otherwise we need to see which node occurs first. Crawl backward
s from child2 looking for child1. | 1536 // Otherwise we need to see which node occurs first. Crawl backward
s from child2 looking for child1. |
| 1542 for (Node* child = child2->previousSibling(); child; child = child->
previousSibling()) { | 1537 for (Node* child = child2->previousSibling(); child; child = child->
previousSibling()) { |
| 1543 if (child == child1) | 1538 if (child == child1) |
| 1544 return DOCUMENT_POSITION_FOLLOWING | connection; | 1539 return DOCUMENT_POSITION_FOLLOWING | connection; |
| 1545 } | 1540 } |
| 1546 return DOCUMENT_POSITION_PRECEDING | connection; | 1541 return DOCUMENT_POSITION_PRECEDING | connection; |
| 1547 } | 1542 } |
| 1548 } | 1543 } |
| 1549 | 1544 |
| 1550 // There was no difference between the two parent chains, i.e., one was a su
bset of the other. The shorter | 1545 // There was no difference between the two parent chains, i.e., one was a su
bset of the other. The shorter |
| 1551 // chain is the ancestor. | 1546 // chain is the ancestor. |
| 1552 return index1 < index2 ? | 1547 return index1 < index2 ? |
| 1553 DOCUMENT_POSITION_FOLLOWING | DOCUMENT_POSITION_CONTAINED_BY | co
nnection : | 1548 DOCUMENT_POSITION_FOLLOWING | DOCUMENT_POSITION_CONTAINED_BY | connectio
n : |
| 1554 DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_CONTAINS | connec
tion; | 1549 DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_CONTAINS | connection; |
| 1555 } | 1550 } |
| 1556 | 1551 |
| 1557 String Node::debugName() const | 1552 String Node::debugName() const |
| 1558 { | 1553 { |
| 1559 StringBuilder name; | 1554 StringBuilder name; |
| 1560 name.append(nodeName()); | 1555 name.append(nodeName()); |
| 1561 | 1556 |
| 1562 if (isElementNode()) { | 1557 if (isElementNode()) { |
| 1563 const Element& thisElement = toElement(*this); | 1558 const Element& thisElement = toElement(*this); |
| 1564 if (thisElement.hasID()) { | 1559 if (thisElement.hasID()) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1646 | 1641 |
| 1647 switch (node->nodeType()) { | 1642 switch (node->nodeType()) { |
| 1648 case ELEMENT_NODE: { | 1643 case ELEMENT_NODE: { |
| 1649 WTFLogAlways("/%s", node->nodeName().utf8().data()); | 1644 WTFLogAlways("/%s", node->nodeName().utf8().data()); |
| 1650 | 1645 |
| 1651 const Element* element = toElement(node); | 1646 const Element* element = toElement(node); |
| 1652 const AtomicString& idattr = element->getIdAttribute(); | 1647 const AtomicString& idattr = element->getIdAttribute(); |
| 1653 bool hasIdAttr = !idattr.isNull() && !idattr.isEmpty(); | 1648 bool hasIdAttr = !idattr.isNull() && !idattr.isEmpty(); |
| 1654 if (node->previousSibling() || node->nextSibling()) { | 1649 if (node->previousSibling() || node->nextSibling()) { |
| 1655 int count = 0; | 1650 int count = 0; |
| 1656 for (Node* previous = node->previousSibling(); previous; previou
s = previous->previousSibling()) | 1651 for (Node* previous = node->previousSibling(); previous; previou
s = previous->previousSibling()) { |
| 1657 if (previous->nodeName() == node->nodeName()) | 1652 if (previous->nodeName() == node->nodeName()) { |
| 1658 ++count; | 1653 ++count; |
| 1654 } |
| 1655 } |
| 1659 if (hasIdAttr) | 1656 if (hasIdAttr) |
| 1660 WTFLogAlways("[@id=\"%s\" and position()=%d]", idattr.utf8()
.data(), count); | 1657 WTFLogAlways("[@id=\"%s\" and position()=%d]", idattr.utf8()
.data(), count); |
| 1661 else | 1658 else |
| 1662 WTFLogAlways("[%d]", count); | 1659 WTFLogAlways("[%d]", count); |
| 1663 } else if (hasIdAttr) { | 1660 } else if (hasIdAttr) { |
| 1664 WTFLogAlways("[@id=\"%s\"]", idattr.utf8().data()); | 1661 WTFLogAlways("[@id=\"%s\"]", idattr.utf8().data()); |
| 1665 } | 1662 } |
| 1666 break; | 1663 break; |
| 1667 } | 1664 } |
| 1668 case TEXT_NODE: | 1665 case TEXT_NODE: |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1700 traverseTreeAndMark(indent.toString(), pseudo, markedNode1, mark
edLabel1, markedNode2, markedLabel2); | 1697 traverseTreeAndMark(indent.toString(), pseudo, markedNode1, mark
edLabel1, markedNode2, markedLabel2); |
| 1701 if (Element* pseudo = element.pseudoElement(FIRST_LETTER)) | 1698 if (Element* pseudo = element.pseudoElement(FIRST_LETTER)) |
| 1702 traverseTreeAndMark(indent.toString(), pseudo, markedNode1, mark
edLabel1, markedNode2, markedLabel2); | 1699 traverseTreeAndMark(indent.toString(), pseudo, markedNode1, mark
edLabel1, markedNode2, markedLabel2); |
| 1703 if (Element* pseudo = element.pseudoElement(BACKDROP)) | 1700 if (Element* pseudo = element.pseudoElement(BACKDROP)) |
| 1704 traverseTreeAndMark(indent.toString(), pseudo, markedNode1, mark
edLabel1, markedNode2, markedLabel2); | 1701 traverseTreeAndMark(indent.toString(), pseudo, markedNode1, mark
edLabel1, markedNode2, markedLabel2); |
| 1705 } | 1702 } |
| 1706 | 1703 |
| 1707 if (node.isShadowRoot()) { | 1704 if (node.isShadowRoot()) { |
| 1708 if (ShadowRoot* youngerShadowRoot = toShadowRoot(node).youngerShadow
Root()) | 1705 if (ShadowRoot* youngerShadowRoot = toShadowRoot(node).youngerShadow
Root()) |
| 1709 traverseTreeAndMark(indent.toString(), youngerShadowRoot, marked
Node1, markedLabel1, markedNode2, markedLabel2); | 1706 traverseTreeAndMark(indent.toString(), youngerShadowRoot, marked
Node1, markedLabel1, markedNode2, markedLabel2); |
| 1710 } else if (ShadowRoot* oldestShadowRoot = oldestShadowRootFor(&node)) | 1707 } else if (ShadowRoot* oldestShadowRoot = oldestShadowRootFor(&node)) { |
| 1711 traverseTreeAndMark(indent.toString(), oldestShadowRoot, markedNode1
, markedLabel1, markedNode2, markedLabel2); | 1708 traverseTreeAndMark(indent.toString(), oldestShadowRoot, markedNode1
, markedLabel1, markedNode2, markedLabel2); |
| 1709 } |
| 1712 } | 1710 } |
| 1713 } | 1711 } |
| 1714 | 1712 |
| 1715 static void traverseTreeAndMarkInComposedTree(const String& baseIndent, const No
de* rootNode, const Node* markedNode1, const char* markedLabel1, const Node* mar
kedNode2, const char* markedLabel2) | 1713 static void traverseTreeAndMarkInComposedTree(const String& baseIndent, const No
de* rootNode, const Node* markedNode1, const char* markedLabel1, const Node* mar
kedNode2, const char* markedLabel2) |
| 1716 { | 1714 { |
| 1717 for (const Node* node = rootNode; node; node = ComposedTreeTraversal::nextSi
bling(*node)) { | 1715 for (const Node* node = rootNode; node; node = ComposedTreeTraversal::nextSi
bling(*node)) { |
| 1718 StringBuilder indent; | 1716 StringBuilder indent; |
| 1719 if (node == markedNode1) | 1717 if (node == markedNode1) |
| 1720 indent.append(markedLabel1); | 1718 indent.append(markedLabel1); |
| 1721 if (node == markedNode2) | 1719 if (node == markedNode2) |
| (...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2501 | 2499 |
| 2502 void showNodePath(const blink::Node* node) | 2500 void showNodePath(const blink::Node* node) |
| 2503 { | 2501 { |
| 2504 if (node) | 2502 if (node) |
| 2505 node->showNodePathForThis(); | 2503 node->showNodePathForThis(); |
| 2506 else | 2504 else |
| 2507 fprintf(stderr, "Cannot showNodePath for (nil)\n"); | 2505 fprintf(stderr, "Cannot showNodePath for (nil)\n"); |
| 2508 } | 2506 } |
| 2509 | 2507 |
| 2510 #endif | 2508 #endif |
| OLD | NEW |