| OLD | NEW |
| 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 swap(remainingPredicates, m_predicates); | 83 swap(remainingPredicates, m_predicates); |
| 84 } | 84 } |
| 85 | 85 |
| 86 bool optimizeStepPair(Step* first, Step* second) | 86 bool optimizeStepPair(Step* first, Step* second) |
| 87 { | 87 { |
| 88 if (first->m_axis == Step::DescendantOrSelfAxis | 88 if (first->m_axis == Step::DescendantOrSelfAxis |
| 89 && first->nodeTest().getKind() == Step::NodeTest::AnyNodeTest | 89 && first->nodeTest().getKind() == Step::NodeTest::AnyNodeTest |
| 90 && !first->m_predicates.size() | 90 && !first->m_predicates.size() |
| 91 && !first->nodeTest().mergedPredicates().size()) { | 91 && !first->nodeTest().mergedPredicates().size()) { |
| 92 | 92 |
| 93 ASSERT(first->nodeTest().data().isEmpty()); | 93 DCHECK(first->nodeTest().data().isEmpty()); |
| 94 ASSERT(first->nodeTest().namespaceURI().isEmpty()); | 94 DCHECK(first->nodeTest().namespaceURI().isEmpty()); |
| 95 | 95 |
| 96 // Optimize the common case of "//" AKA | 96 // Optimize the common case of "//" AKA |
| 97 // /descendant-or-self::node()/child::NodeTest to /descendant::NodeTest. | 97 // /descendant-or-self::node()/child::NodeTest to /descendant::NodeTest. |
| 98 if (second->m_axis == Step::ChildAxis && second->predicatesAreContextLis
tInsensitive()) { | 98 if (second->m_axis == Step::ChildAxis && second->predicatesAreContextLis
tInsensitive()) { |
| 99 first->m_axis = Step::DescendantAxis; | 99 first->m_axis = Step::DescendantAxis; |
| 100 first->nodeTest() = Step::NodeTest(second->nodeTest().getKind(), sec
ond->nodeTest().data(), second->nodeTest().namespaceURI()); | 100 first->nodeTest() = Step::NodeTest(second->nodeTest().getKind(), sec
ond->nodeTest().data(), second->nodeTest().namespaceURI()); |
| 101 swap(second->nodeTest().mergedPredicates(), first->nodeTest().merged
Predicates()); | 101 swap(second->nodeTest().mergedPredicates(), first->nodeTest().merged
Predicates()); |
| 102 swap(second->m_predicates, first->m_predicates); | 102 swap(second->m_predicates, first->m_predicates); |
| 103 first->optimize(); | 103 first->optimize(); |
| 104 return true; | 104 return true; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 // compared case-insensitively. | 220 // compared case-insensitively. |
| 221 return equalIgnoringCase(element.localName(), name) && (namespac
eURI.isNull() || namespaceURI == element.namespaceURI()); | 221 return equalIgnoringCase(element.localName(), name) && (namespac
eURI.isNull() || namespaceURI == element.namespaceURI()); |
| 222 } | 222 } |
| 223 // An expression without any prefix shouldn't match no-namespace | 223 // An expression without any prefix shouldn't match no-namespace |
| 224 // nodes (because HTML5 says so). | 224 // nodes (because HTML5 says so). |
| 225 return element.hasLocalName(name) && namespaceURI == element.namespa
ceURI() && !namespaceURI.isNull(); | 225 return element.hasLocalName(name) && namespaceURI == element.namespa
ceURI() && !namespaceURI.isNull(); |
| 226 } | 226 } |
| 227 return element.hasLocalName(name) && namespaceURI == element.namespaceUR
I(); | 227 return element.hasLocalName(name) && namespaceURI == element.namespaceUR
I(); |
| 228 } | 228 } |
| 229 } | 229 } |
| 230 ASSERT_NOT_REACHED(); | 230 NOTREACHED(); |
| 231 return false; | 231 return false; |
| 232 } | 232 } |
| 233 | 233 |
| 234 static inline bool nodeMatches(EvaluationContext& evaluationContext, Node* node,
Step::Axis axis, const Step::NodeTest& nodeTest) | 234 static inline bool nodeMatches(EvaluationContext& evaluationContext, Node* node,
Step::Axis axis, const Step::NodeTest& nodeTest) |
| 235 { | 235 { |
| 236 if (!nodeMatchesBasicTest(node, axis, nodeTest)) | 236 if (!nodeMatchesBasicTest(node, axis, nodeTest)) |
| 237 return false; | 237 return false; |
| 238 | 238 |
| 239 // Only the first merged predicate may depend on position. | 239 // Only the first merged predicate may depend on position. |
| 240 ++evaluationContext.position; | 240 ++evaluationContext.position; |
| 241 | 241 |
| 242 const HeapVector<Member<Predicate>>& mergedPredicates = nodeTest.mergedPredi
cates(); | 242 const HeapVector<Member<Predicate>>& mergedPredicates = nodeTest.mergedPredi
cates(); |
| 243 for (unsigned i = 0; i < mergedPredicates.size(); i++) { | 243 for (unsigned i = 0; i < mergedPredicates.size(); i++) { |
| 244 Predicate* predicate = mergedPredicates[i].get(); | 244 Predicate* predicate = mergedPredicates[i].get(); |
| 245 | 245 |
| 246 evaluationContext.node = node; | 246 evaluationContext.node = node; |
| 247 // No need to set context size - we only get here when evaluating | 247 // No need to set context size - we only get here when evaluating |
| 248 // predicates that do not depend on it. | 248 // predicates that do not depend on it. |
| 249 if (!predicate->evaluate(evaluationContext)) | 249 if (!predicate->evaluate(evaluationContext)) |
| 250 return false; | 250 return false; |
| 251 } | 251 } |
| 252 | 252 |
| 253 return true; | 253 return true; |
| 254 } | 254 } |
| 255 | 255 |
| 256 // Result nodes are ordered in axis order. Node test (including merged | 256 // Result nodes are ordered in axis order. Node test (including merged |
| 257 // predicates) is applied. | 257 // predicates) is applied. |
| 258 void Step::nodesInAxis(EvaluationContext& evaluationContext, Node* context, Node
Set& nodes) const | 258 void Step::nodesInAxis(EvaluationContext& evaluationContext, Node* context, Node
Set& nodes) const |
| 259 { | 259 { |
| 260 ASSERT(nodes.isEmpty()); | 260 DCHECK(nodes.isEmpty()); |
| 261 switch (m_axis) { | 261 switch (m_axis) { |
| 262 case ChildAxis: | 262 case ChildAxis: |
| 263 // In XPath model, attribute nodes do not have children. | 263 // In XPath model, attribute nodes do not have children. |
| 264 if (context->isAttributeNode()) | 264 if (context->isAttributeNode()) |
| 265 return; | 265 return; |
| 266 | 266 |
| 267 for (Node* n = context->firstChild(); n; n = n->nextSibling()) { | 267 for (Node* n = context->firstChild(); n; n = n->nextSibling()) { |
| 268 if (nodeMatches(evaluationContext, n, ChildAxis, nodeTest())) | 268 if (nodeMatches(evaluationContext, n, ChildAxis, nodeTest())) |
| 269 nodes.append(n); | 269 nodes.append(n); |
| 270 } | 270 } |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 424 nodes.append(n); | 424 nodes.append(n); |
| 425 } | 425 } |
| 426 for (n = n->parentNode(); n; n = n->parentNode()) { | 426 for (n = n->parentNode(); n; n = n->parentNode()) { |
| 427 if (nodeMatches(evaluationContext, n, AncestorOrSelfAxis, nodeTest()
)) | 427 if (nodeMatches(evaluationContext, n, AncestorOrSelfAxis, nodeTest()
)) |
| 428 nodes.append(n); | 428 nodes.append(n); |
| 429 } | 429 } |
| 430 nodes.markSorted(false); | 430 nodes.markSorted(false); |
| 431 return; | 431 return; |
| 432 } | 432 } |
| 433 } | 433 } |
| 434 ASSERT_NOT_REACHED(); | 434 NOTREACHED(); |
| 435 } | 435 } |
| 436 | 436 |
| 437 } // namespace XPath | 437 } // namespace XPath |
| 438 | 438 |
| 439 } // namespace blink | 439 } // namespace blink |
| OLD | NEW |