Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Side by Side Diff: Source/core/xml/XPathStep.cpp

Issue 344553002: Fix style erros in XPath-related files. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/xml/XPathResult.cpp ('k') | Source/core/xml/XPathUtil.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2005 Frerich Raabe <raabe@kde.org> 2 * Copyright (C) 2005 Frerich Raabe <raabe@kde.org>
3 * Copyright (C) 2006, 2009 Apple Inc. All rights reserved. 3 * Copyright (C) 2006, 2009 Apple Inc. All rights reserved.
4 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> 4 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 9 *
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 58
59 void Step::trace(Visitor* visitor) 59 void Step::trace(Visitor* visitor)
60 { 60 {
61 visitor->trace(m_nodeTest); 61 visitor->trace(m_nodeTest);
62 visitor->trace(m_predicates); 62 visitor->trace(m_predicates);
63 ParseNode::trace(visitor); 63 ParseNode::trace(visitor);
64 } 64 }
65 65
66 void Step::optimize() 66 void Step::optimize()
67 { 67 {
68 // Evaluate predicates as part of node test if possible to avoid building un necessary NodeSets. 68 // Evaluate predicates as part of node test if possible to avoid building
69 // E.g., there is no need to build a set of all "foo" nodes to evaluate "foo [@bar]", we can check the predicate while enumerating. 69 // unnecessary NodeSets.
70 // This optimization can be applied to predicates that are not context node list sensitive, or to first predicate that is only context position sensitive, e .g. foo[position() mod 2 = 0]. 70 // E.g., there is no need to build a set of all "foo" nodes to evaluate
71 // "foo[@bar]", we can check the predicate while enumerating.
72 // This optimization can be applied to predicates that are not context node
73 // list sensitive, or to first predicate that is only context position
74 // sensitive, e.g. foo[position() mod 2 = 0].
71 WillBeHeapVector<OwnPtrWillBeMember<Predicate> > remainingPredicates; 75 WillBeHeapVector<OwnPtrWillBeMember<Predicate> > remainingPredicates;
72 for (size_t i = 0; i < m_predicates.size(); ++i) { 76 for (size_t i = 0; i < m_predicates.size(); ++i) {
73 OwnPtrWillBeRawPtr<Predicate> predicate(m_predicates[i].release()); 77 OwnPtrWillBeRawPtr<Predicate> predicate(m_predicates[i].release());
74 if ((!predicate->isContextPositionSensitive() || nodeTest().mergedPredic ates().isEmpty()) && !predicate->isContextSizeSensitive() && remainingPredicates .isEmpty()) { 78 if ((!predicate->isContextPositionSensitive() || nodeTest().mergedPredic ates().isEmpty()) && !predicate->isContextSizeSensitive() && remainingPredicates .isEmpty()) {
75 nodeTest().mergedPredicates().append(predicate.release()); 79 nodeTest().mergedPredicates().append(predicate.release());
76 } else { 80 } else {
77 remainingPredicates.append(predicate.release()); 81 remainingPredicates.append(predicate.release());
78 } 82 }
79 } 83 }
80 swap(remainingPredicates, m_predicates); 84 swap(remainingPredicates, m_predicates);
81 } 85 }
82 86
83 void optimizeStepPair(Step* first, Step* second, bool& dropSecondStep) 87 void optimizeStepPair(Step* first, Step* second, bool& dropSecondStep)
84 { 88 {
85 dropSecondStep = false; 89 dropSecondStep = false;
86 90
87 if (first->m_axis == Step::DescendantOrSelfAxis 91 if (first->m_axis == Step::DescendantOrSelfAxis
88 && first->nodeTest().kind() == Step::NodeTest::AnyNodeTest 92 && first->nodeTest().kind() == Step::NodeTest::AnyNodeTest
89 && !first->m_predicates.size() 93 && !first->m_predicates.size()
90 && !first->nodeTest().mergedPredicates().size()) { 94 && !first->nodeTest().mergedPredicates().size()) {
91 95
92 ASSERT(first->nodeTest().data().isEmpty()); 96 ASSERT(first->nodeTest().data().isEmpty());
93 ASSERT(first->nodeTest().namespaceURI().isEmpty()); 97 ASSERT(first->nodeTest().namespaceURI().isEmpty());
94 98
95 // Optimize the common case of "//" AKA /descendant-or-self::node()/chil d::NodeTest to /descendant::NodeTest. 99 // Optimize the common case of "//" AKA
100 // /descendant-or-self::node()/child::NodeTest to /descendant::NodeTest.
96 if (second->m_axis == Step::ChildAxis && second->predicatesAreContextLis tInsensitive()) { 101 if (second->m_axis == Step::ChildAxis && second->predicatesAreContextLis tInsensitive()) {
97 first->m_axis = Step::DescendantAxis; 102 first->m_axis = Step::DescendantAxis;
98 first->nodeTest() = Step::NodeTest(second->nodeTest().kind(), second ->nodeTest().data(), second->nodeTest().namespaceURI()); 103 first->nodeTest() = Step::NodeTest(second->nodeTest().kind(), second ->nodeTest().data(), second->nodeTest().namespaceURI());
99 swap(second->nodeTest().mergedPredicates(), first->nodeTest().merged Predicates()); 104 swap(second->nodeTest().mergedPredicates(), first->nodeTest().merged Predicates());
100 swap(second->m_predicates, first->m_predicates); 105 swap(second->m_predicates, first->m_predicates);
101 first->optimize(); 106 first->optimize();
102 dropSecondStep = true; 107 dropSecondStep = true;
103 } 108 }
104 } 109 }
105 } 110 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 } 152 }
148 153
149 nodes.swap(*newNodes); 154 nodes.swap(*newNodes);
150 } 155 }
151 } 156 }
152 157
153 #if ASSERT_ENABLED 158 #if ASSERT_ENABLED
154 static inline Node::NodeType primaryNodeType(Step::Axis axis) 159 static inline Node::NodeType primaryNodeType(Step::Axis axis)
155 { 160 {
156 switch (axis) { 161 switch (axis) {
157 case Step::AttributeAxis: 162 case Step::AttributeAxis:
158 return Node::ATTRIBUTE_NODE; 163 return Node::ATTRIBUTE_NODE;
159 default: 164 default:
160 return Node::ELEMENT_NODE; 165 return Node::ELEMENT_NODE;
161 } 166 }
162 } 167 }
163 #endif 168 #endif
164 169
165 // Evaluate NodeTest without considering merged predicates. 170 // Evaluate NodeTest without considering merged predicates.
166 static inline bool nodeMatchesBasicTest(Node* node, Step::Axis axis, const Step: :NodeTest& nodeTest) 171 static inline bool nodeMatchesBasicTest(Node* node, Step::Axis axis, const Step: :NodeTest& nodeTest)
167 { 172 {
168 switch (nodeTest.kind()) { 173 switch (nodeTest.kind()) {
169 case Step::NodeTest::TextNodeTest: { 174 case Step::NodeTest::TextNodeTest: {
170 Node::NodeType type = node->nodeType(); 175 Node::NodeType type = node->nodeType();
171 return type == Node::TEXT_NODE || type == Node::CDATA_SECTION_NODE; 176 return type == Node::TEXT_NODE || type == Node::CDATA_SECTION_NODE;
172 } 177 }
173 case Step::NodeTest::CommentNodeTest: 178 case Step::NodeTest::CommentNodeTest:
174 return node->nodeType() == Node::COMMENT_NODE; 179 return node->nodeType() == Node::COMMENT_NODE;
175 case Step::NodeTest::ProcessingInstructionNodeTest: { 180 case Step::NodeTest::ProcessingInstructionNodeTest: {
176 const AtomicString& name = nodeTest.data(); 181 const AtomicString& name = nodeTest.data();
177 return node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE && (nam e.isEmpty() || node->nodeName() == name); 182 return node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE && (name.is Empty() || node->nodeName() == name);
178 } 183 }
179 case Step::NodeTest::AnyNodeTest: 184 case Step::NodeTest::AnyNodeTest:
180 return true; 185 return true;
181 case Step::NodeTest::NameTest: { 186 case Step::NodeTest::NameTest: {
182 const AtomicString& name = nodeTest.data(); 187 const AtomicString& name = nodeTest.data();
183 const AtomicString& namespaceURI = nodeTest.namespaceURI(); 188 const AtomicString& namespaceURI = nodeTest.namespaceURI();
184 189
185 if (axis == Step::AttributeAxis) { 190 if (axis == Step::AttributeAxis) {
186 ASSERT(node->isAttributeNode()); 191 ASSERT(node->isAttributeNode());
187 192
188 // In XPath land, namespace nodes are not accessible on the attr ibute axis. 193 // In XPath land, namespace nodes are not accessible on the
189 if (node->namespaceURI() == XMLNSNames::xmlnsNamespaceURI) 194 // attribute axis.
190 return false; 195 if (node->namespaceURI() == XMLNSNames::xmlnsNamespaceURI)
191
192 if (name == starAtom)
193 return namespaceURI.isEmpty() || node->namespaceURI() == nam espaceURI;
194
195 return node->localName() == name && node->namespaceURI() == name spaceURI;
196 }
197
198 // Node test on the namespace axis is not implemented yet, the calle r has a check for it.
199 ASSERT(axis != Step::NamespaceAxis);
200
201 // For other axes, the principal node type is element.
202 ASSERT(primaryNodeType(axis) == Node::ELEMENT_NODE);
203 if (!node->isElementNode())
204 return false; 196 return false;
205 Element& element = toElement(*node);
206 197
207 if (name == starAtom) 198 if (name == starAtom)
208 return namespaceURI.isEmpty() || namespaceURI == element.namespa ceURI(); 199 return namespaceURI.isEmpty() || node->namespaceURI() == namespa ceURI;
209 200
210 if (element.document().isHTMLDocument()) { 201 return node->localName() == name && node->namespaceURI() == namespac eURI;
211 if (element.isHTMLElement()) { 202 }
212 // Paths without namespaces should match HTML elements in HT ML documents despite those having an XHTML namespace. Names are compared case-in sensitively. 203
213 return equalIgnoringCase(element.localName(), name) && (name spaceURI.isNull() || namespaceURI == element.namespaceURI()); 204 // Node test on the namespace axis is not implemented yet, the caller
214 } 205 // has a check for it.
215 // An expression without any prefix shouldn't match no-namespace nodes (because HTML5 says so). 206 ASSERT(axis != Step::NamespaceAxis);
216 return element.hasLocalName(name) && namespaceURI == element.nam espaceURI() && !namespaceURI.isNull(); 207
208 // For other axes, the principal node type is element.
209 ASSERT(primaryNodeType(axis) == Node::ELEMENT_NODE);
210 if (!node->isElementNode())
211 return false;
212 Element& element = toElement(*node);
213
214 if (name == starAtom)
215 return namespaceURI.isEmpty() || namespaceURI == element.namespaceUR I();
216
217 if (element.document().isHTMLDocument()) {
218 if (element.isHTMLElement()) {
219 // Paths without namespaces should match HTML elements in HTML
220 // documents despite those having an XHTML namespace. Names are
221 // compared case-insensitively.
222 return equalIgnoringCase(element.localName(), name) && (namespac eURI.isNull() || namespaceURI == element.namespaceURI());
217 } 223 }
218 return element.hasLocalName(name) && namespaceURI == element.namespa ceURI(); 224 // An expression without any prefix shouldn't match no-namespace
225 // nodes (because HTML5 says so).
226 return element.hasLocalName(name) && namespaceURI == element.namespa ceURI() && !namespaceURI.isNull();
219 } 227 }
228 return element.hasLocalName(name) && namespaceURI == element.namespaceUR I();
229 }
220 } 230 }
221 ASSERT_NOT_REACHED(); 231 ASSERT_NOT_REACHED();
222 return false; 232 return false;
223 } 233 }
224 234
225 static inline bool nodeMatches(Node* node, Step::Axis axis, const Step::NodeTest & nodeTest) 235 static inline bool nodeMatches(Node* node, Step::Axis axis, const Step::NodeTest & nodeTest)
226 { 236 {
227 if (!nodeMatchesBasicTest(node, axis, nodeTest)) 237 if (!nodeMatchesBasicTest(node, axis, nodeTest))
228 return false; 238 return false;
229 239
230 EvaluationContext& evaluationContext = Expression::evaluationContext(); 240 EvaluationContext& evaluationContext = Expression::evaluationContext();
231 241
232 // Only the first merged predicate may depend on position. 242 // Only the first merged predicate may depend on position.
233 ++evaluationContext.position; 243 ++evaluationContext.position;
234 244
235 const WillBeHeapVector<OwnPtrWillBeMember<Predicate> >& mergedPredicates = n odeTest.mergedPredicates(); 245 const WillBeHeapVector<OwnPtrWillBeMember<Predicate> >& mergedPredicates = n odeTest.mergedPredicates();
236 for (unsigned i = 0; i < mergedPredicates.size(); i++) { 246 for (unsigned i = 0; i < mergedPredicates.size(); i++) {
237 Predicate* predicate = mergedPredicates[i].get(); 247 Predicate* predicate = mergedPredicates[i].get();
238 248
239 evaluationContext.node = node; 249 evaluationContext.node = node;
240 // No need to set context size - we only get here when evaluating predic ates that do not depend on it. 250 // No need to set context size - we only get here when evaluating
251 // predicates that do not depend on it.
241 if (!predicate->evaluate()) 252 if (!predicate->evaluate())
242 return false; 253 return false;
243 } 254 }
244 255
245 return true; 256 return true;
246 } 257 }
247 258
248 // Result nodes are ordered in axis order. Node test (including merged predicate s) is applied. 259 // Result nodes are ordered in axis order. Node test (including merged
260 // predicates) is applied.
249 void Step::nodesInAxis(Node* context, NodeSet& nodes) const 261 void Step::nodesInAxis(Node* context, NodeSet& nodes) const
250 { 262 {
251 ASSERT(nodes.isEmpty()); 263 ASSERT(nodes.isEmpty());
252 switch (m_axis) { 264 switch (m_axis) {
253 case ChildAxis: 265 case ChildAxis:
254 if (context->isAttributeNode()) // In XPath model, attribute nodes d o not have children. 266 // In XPath model, attribute nodes do not have children.
255 return; 267 if (context->isAttributeNode())
268 return;
256 269
257 for (Node* n = context->firstChild(); n; n = n->nextSibling()) 270 for (Node* n = context->firstChild(); n; n = n->nextSibling()) {
258 if (nodeMatches(n, ChildAxis, nodeTest())) 271 if (nodeMatches(n, ChildAxis, nodeTest()))
259 nodes.append(n); 272 nodes.append(n);
273 }
274 return;
275
276 case DescendantAxis:
277 // In XPath model, attribute nodes do not have children.
278 if (context->isAttributeNode())
260 return; 279 return;
261 case DescendantAxis:
262 if (context->isAttributeNode()) // In XPath model, attribute nodes d o not have children.
263 return;
264 280
265 for (Node* n = context->firstChild(); n; n = NodeTraversal::next(*n, context)) 281 for (Node* n = context->firstChild(); n; n = NodeTraversal::next(*n, con text)) {
266 if (nodeMatches(n, DescendantAxis, nodeTest())) 282 if (nodeMatches(n, DescendantAxis, nodeTest()))
267 nodes.append(n); 283 nodes.append(n);
284 }
285 return;
286
287 case ParentAxis:
288 if (context->isAttributeNode()) {
289 Element* n = toAttr(context)->ownerElement();
290 if (nodeMatches(n, ParentAxis, nodeTest()))
291 nodes.append(n);
292 } else {
293 ContainerNode* n = context->parentNode();
294 if (n && nodeMatches(n, ParentAxis, nodeTest()))
295 nodes.append(n);
296 }
297 return;
298
299 case AncestorAxis: {
300 Node* n = context;
301 if (context->isAttributeNode()) {
302 n = toAttr(context)->ownerElement();
303 if (nodeMatches(n, AncestorAxis, nodeTest()))
304 nodes.append(n);
305 }
306 for (n = n->parentNode(); n; n = n->parentNode()) {
307 if (nodeMatches(n, AncestorAxis, nodeTest()))
308 nodes.append(n);
309 }
310 nodes.markSorted(false);
311 return;
312 }
313
314 case FollowingSiblingAxis:
315 if (context->nodeType() == Node::ATTRIBUTE_NODE)
268 return; 316 return;
269 case ParentAxis: 317
270 if (context->isAttributeNode()) { 318 for (Node* n = context->nextSibling(); n; n = n->nextSibling()) {
271 Element* n = toAttr(context)->ownerElement(); 319 if (nodeMatches(n, FollowingSiblingAxis, nodeTest()))
272 if (nodeMatches(n, ParentAxis, nodeTest())) 320 nodes.append(n);
273 nodes.append(n); 321 }
274 } else { 322 return;
275 ContainerNode* n = context->parentNode(); 323
276 if (n && nodeMatches(n, ParentAxis, nodeTest())) 324 case PrecedingSiblingAxis:
277 nodes.append(n); 325 if (context->nodeType() == Node::ATTRIBUTE_NODE)
326 return;
327
328 for (Node* n = context->previousSibling(); n; n = n->previousSibling()) {
329 if (nodeMatches(n, PrecedingSiblingAxis, nodeTest()))
330 nodes.append(n);
331 }
332 nodes.markSorted(false);
333 return;
334
335 case FollowingAxis:
336 if (context->isAttributeNode()) {
337 Node* p = toAttr(context)->ownerElement();
338 while ((p = NodeTraversal::next(*p))) {
339 if (nodeMatches(p, FollowingAxis, nodeTest()))
340 nodes.append(p);
278 } 341 }
279 return; 342 } else {
280 case AncestorAxis: { 343 for (Node* p = context; !isRootDomNode(p); p = p->parentNode()) {
281 Node* n = context; 344 for (Node* n = p->nextSibling(); n; n = n->nextSibling()) {
282 if (context->isAttributeNode()) { 345 if (nodeMatches(n, FollowingAxis, nodeTest()))
283 n = toAttr(context)->ownerElement(); 346 nodes.append(n);
284 if (nodeMatches(n, AncestorAxis, nodeTest())) 347 for (Node* c = n->firstChild(); c; c = NodeTraversal::next(* c, n)) {
285 nodes.append(n); 348 if (nodeMatches(c, FollowingAxis, nodeTest()))
286 } 349 nodes.append(c);
287 for (n = n->parentNode(); n; n = n->parentNode())
288 if (nodeMatches(n, AncestorAxis, nodeTest()))
289 nodes.append(n);
290 nodes.markSorted(false);
291 return;
292 }
293 case FollowingSiblingAxis:
294 if (context->nodeType() == Node::ATTRIBUTE_NODE)
295 return;
296
297 for (Node* n = context->nextSibling(); n; n = n->nextSibling())
298 if (nodeMatches(n, FollowingSiblingAxis, nodeTest()))
299 nodes.append(n);
300 return;
301 case PrecedingSiblingAxis:
302 if (context->nodeType() == Node::ATTRIBUTE_NODE)
303 return;
304
305 for (Node* n = context->previousSibling(); n; n = n->previousSibling ())
306 if (nodeMatches(n, PrecedingSiblingAxis, nodeTest()))
307 nodes.append(n);
308
309 nodes.markSorted(false);
310 return;
311 case FollowingAxis:
312 if (context->isAttributeNode()) {
313 Node* p = toAttr(context)->ownerElement();
314 while ((p = NodeTraversal::next(*p))) {
315 if (nodeMatches(p, FollowingAxis, nodeTest()))
316 nodes.append(p);
317 }
318 } else {
319 for (Node* p = context; !isRootDomNode(p); p = p->parentNode()) {
320 for (Node* n = p->nextSibling(); n; n = n->nextSibling()) {
321 if (nodeMatches(n, FollowingAxis, nodeTest()))
322 nodes.append(n);
323 for (Node* c = n->firstChild(); c; c = NodeTraversal::ne xt(*c, n))
324 if (nodeMatches(c, FollowingAxis, nodeTest()))
325 nodes.append(c);
326 } 350 }
327 } 351 }
328 } 352 }
353 }
354 return;
355
356 case PrecedingAxis: {
357 if (context->isAttributeNode())
358 context = toAttr(context)->ownerElement();
359
360 Node* n = context;
361 while (ContainerNode* parent = n->parentNode()) {
362 for (n = NodeTraversal::previous(*n); n != parent; n = NodeTraversal ::previous(*n)) {
363 if (nodeMatches(n, PrecedingAxis, nodeTest()))
364 nodes.append(n);
365 }
366 n = parent;
367 }
368 nodes.markSorted(false);
369 return;
370 }
371
372 case AttributeAxis: {
373 if (!context->isElementNode())
329 return; 374 return;
330 case PrecedingAxis: {
331 if (context->isAttributeNode())
332 context = toAttr(context)->ownerElement();
333 375
334 Node* n = context; 376 Element* contextElement = toElement(context);
335 while (ContainerNode* parent = n->parentNode()) { 377 // Avoid lazily creating attribute nodes for attributes that we do not
336 for (n = NodeTraversal::previous(*n); n != parent; n = NodeTrave rsal::previous(*n)) 378 // need anyway.
337 if (nodeMatches(n, PrecedingAxis, nodeTest())) 379 if (nodeTest().kind() == NodeTest::NameTest && nodeTest().data() != star Atom) {
338 nodes.append(n); 380 RefPtrWillBeRawPtr<Node> n = contextElement->getAttributeNodeNS(node Test().namespaceURI(), nodeTest().data());
339 n = parent; 381 // In XPath land, namespace nodes are not accessible on the attribut e axis.
340 } 382 if (n && n->namespaceURI() != XMLNSNames::xmlnsNamespaceURI) {
341 nodes.markSorted(false); 383 // Still need to check merged predicates.
342 return; 384 if (nodeMatches(n.get(), AttributeAxis, nodeTest()))
343 } 385 nodes.append(n.release());
344 case AttributeAxis: {
345 if (!context->isElementNode())
346 return;
347
348 Element* contextElement = toElement(context);
349
350 // Avoid lazily creating attribute nodes for attributes that we do n ot need anyway.
351 if (nodeTest().kind() == NodeTest::NameTest && nodeTest().data() != starAtom) {
352 RefPtrWillBeRawPtr<Node> n = contextElement->getAttributeNodeNS( nodeTest().namespaceURI(), nodeTest().data());
353 if (n && n->namespaceURI() != XMLNSNames::xmlnsNamespaceURI) { / / In XPath land, namespace nodes are not accessible on the attribute axis.
354 if (nodeMatches(n.get(), AttributeAxis, nodeTest())) // Stil l need to check merged predicates.
355 nodes.append(n.release());
356 }
357 return;
358 }
359
360 if (!contextElement->hasAttributes())
361 return;
362
363 AttributeIteratorAccessor attributes = contextElement->attributesIte rator();
364 AttributeConstIterator end = attributes.end();
365 for (AttributeConstIterator it = attributes.begin(); it != end; ++it ) {
366 RefPtrWillBeRawPtr<Attr> attr = contextElement->ensureAttr(it->n ame());
367 if (nodeMatches(attr.get(), AttributeAxis, nodeTest()))
368 nodes.append(attr.release());
369 } 386 }
370 return; 387 return;
371 } 388 }
372 case NamespaceAxis: 389
373 // XPath namespace nodes are not implemented. 390 if (!contextElement->hasAttributes())
374 return; 391 return;
375 case SelfAxis: 392
376 if (nodeMatches(context, SelfAxis, nodeTest())) 393 AttributeIteratorAccessor attributes = contextElement->attributesIterato r();
377 nodes.append(context); 394 AttributeConstIterator end = attributes.end();
395 for (AttributeConstIterator it = attributes.begin(); it != end; ++it) {
396 RefPtrWillBeRawPtr<Attr> attr = contextElement->ensureAttr(it->name( ));
397 if (nodeMatches(attr.get(), AttributeAxis, nodeTest()))
398 nodes.append(attr.release());
399 }
400 return;
401 }
402
403 case NamespaceAxis:
404 // XPath namespace nodes are not implemented.
405 return;
406
407 case SelfAxis:
408 if (nodeMatches(context, SelfAxis, nodeTest()))
409 nodes.append(context);
410 return;
411
412 case DescendantOrSelfAxis:
413 if (nodeMatches(context, DescendantOrSelfAxis, nodeTest()))
414 nodes.append(context);
415 // In XPath model, attribute nodes do not have children.
416 if (context->isAttributeNode())
378 return; 417 return;
379 case DescendantOrSelfAxis:
380 if (nodeMatches(context, DescendantOrSelfAxis, nodeTest()))
381 nodes.append(context);
382 if (context->isAttributeNode()) // In XPath model, attribute nodes d o not have children.
383 return;
384 418
385 for (Node* n = context->firstChild(); n; n = NodeTraversal::next(*n, context)) { 419 for (Node* n = context->firstChild(); n; n = NodeTraversal::next(*n, con text)) {
386 if (nodeMatches(n, DescendantOrSelfAxis, nodeTest())) 420 if (nodeMatches(n, DescendantOrSelfAxis, nodeTest()))
387 nodes.append(n); 421 nodes.append(n);
388 } 422 }
389 return; 423 return;
390 case AncestorOrSelfAxis: {
391 if (nodeMatches(context, AncestorOrSelfAxis, nodeTest()))
392 nodes.append(context);
393 Node* n = context;
394 if (context->isAttributeNode()) {
395 n = toAttr(context)->ownerElement();
396 if (nodeMatches(n, AncestorOrSelfAxis, nodeTest()))
397 nodes.append(n);
398 }
399 for (n = n->parentNode(); n; n = n->parentNode())
400 if (nodeMatches(n, AncestorOrSelfAxis, nodeTest()))
401 nodes.append(n);
402 424
403 nodes.markSorted(false); 425 case AncestorOrSelfAxis: {
404 return; 426 if (nodeMatches(context, AncestorOrSelfAxis, nodeTest()))
427 nodes.append(context);
428 Node* n = context;
429 if (context->isAttributeNode()) {
430 n = toAttr(context)->ownerElement();
431 if (nodeMatches(n, AncestorOrSelfAxis, nodeTest()))
432 nodes.append(n);
405 } 433 }
434 for (n = n->parentNode(); n; n = n->parentNode()) {
435 if (nodeMatches(n, AncestorOrSelfAxis, nodeTest()))
436 nodes.append(n);
437 }
438 nodes.markSorted(false);
439 return;
440 }
406 } 441 }
407 ASSERT_NOT_REACHED(); 442 ASSERT_NOT_REACHED();
408 } 443 }
409 444
445 }
410 446
411 } 447 }
412 }
OLDNEW
« no previous file with comments | « Source/core/xml/XPathResult.cpp ('k') | Source/core/xml/XPathUtil.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698