15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2005 Frerich Raabe <raabe@kde.org> 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006, 2009 Apple Inc. All rights reserved. 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 1502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/xml/XPathStep.h" 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/XMLNSNames.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Attr.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h" 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Element.h" 3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/NodeTraversal.h" 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/xml/XPathParser.h" 3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/xml/XPathUtil.h" 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 39c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace XPath { 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 42bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)Step::Step(Axis axis, const NodeTest& nodeTest) 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_axis(axis) 44d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) , m_nodeTest(adoptPtrWillBeNoop(new NodeTest(nodeTest))) 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 48d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)Step::Step(Axis axis, const NodeTest& nodeTest, WillBeHeapVector<OwnPtrWillBeMember<Predicate> >& predicates) 49bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) : m_axis(axis) 50d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) , m_nodeTest(adoptPtrWillBeNoop(new NodeTest(nodeTest))) 51bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){ 52bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) m_predicates.swap(predicates); 53bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} 54bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Step::~Step() 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 59d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void Step::trace(Visitor* visitor) 60d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 61d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) visitor->trace(m_nodeTest); 62d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) visitor->trace(m_predicates); 63d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) ParseNode::trace(visitor); 64d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 65d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Step::optimize() 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 685d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // Evaluate predicates as part of node test if possible to avoid building 695d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // unnecessary NodeSets. 705d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // E.g., there is no need to build a set of all "foo" nodes to evaluate 715d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // "foo[@bar]", we can check the predicate while enumerating. 725d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // This optimization can be applied to predicates that are not context node 735d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // list sensitive, or to first predicate that is only context position 745d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // sensitive, e.g. foo[position() mod 2 = 0]. 75d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) WillBeHeapVector<OwnPtrWillBeMember<Predicate> > remainingPredicates; 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < m_predicates.size(); ++i) { 77d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) OwnPtrWillBeRawPtr<Predicate> predicate(m_predicates[i].release()); 78d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if ((!predicate->isContextPositionSensitive() || nodeTest().mergedPredicates().isEmpty()) && !predicate->isContextSizeSensitive() && remainingPredicates.isEmpty()) { 79d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) nodeTest().mergedPredicates().append(predicate.release()); 80bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } else { 81bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) remainingPredicates.append(predicate.release()); 82bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) swap(remainingPredicates, m_predicates); 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void optimizeStepPair(Step* first, Step* second, bool& dropSecondStep) 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dropSecondStep = false; 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (first->m_axis == Step::DescendantOrSelfAxis 92d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) && first->nodeTest().kind() == Step::NodeTest::AnyNodeTest 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && !first->m_predicates.size() 94d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) && !first->nodeTest().mergedPredicates().size()) { 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 96d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) ASSERT(first->nodeTest().data().isEmpty()); 97d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) ASSERT(first->nodeTest().namespaceURI().isEmpty()); 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 995d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // Optimize the common case of "//" AKA 1005d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // /descendant-or-self::node()/child::NodeTest to /descendant::NodeTest. 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (second->m_axis == Step::ChildAxis && second->predicatesAreContextListInsensitive()) { 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) first->m_axis = Step::DescendantAxis; 103d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) first->nodeTest() = Step::NodeTest(second->nodeTest().kind(), second->nodeTest().data(), second->nodeTest().namespaceURI()); 104d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) swap(second->nodeTest().mergedPredicates(), first->nodeTest().mergedPredicates()); 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) swap(second->m_predicates, first->m_predicates); 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) first->optimize(); 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dropSecondStep = true; 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool Step::predicatesAreContextListInsensitive() const 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < m_predicates.size(); ++i) { 115bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) Predicate* predicate = m_predicates[i].get(); 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (predicate->isContextPositionSensitive() || predicate->isContextSizeSensitive()) 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 120d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) for (size_t i = 0; i < nodeTest().mergedPredicates().size(); ++i) { 121d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) Predicate* predicate = nodeTest().mergedPredicates()[i].get(); 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (predicate->isContextPositionSensitive() || predicate->isContextSizeSensitive()) 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 129197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid Step::evaluate(EvaluationContext& evaluationContext, Node* context, NodeSet& nodes) const 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) evaluationContext.position = 0; 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 133197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch nodesInAxis(evaluationContext, context, nodes); 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check predicates that couldn't be merged into node test. 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < m_predicates.size(); i++) { 137bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) Predicate* predicate = m_predicates[i].get(); 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 139d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) OwnPtrWillBeRawPtr<NodeSet> newNodes(NodeSet::create()); 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!nodes.isSorted()) 141d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) newNodes->markSorted(false); 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned j = 0; j < nodes.size(); j++) { 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Node* node = nodes[j]; 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) evaluationContext.node = node; 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) evaluationContext.size = nodes.size(); 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) evaluationContext.position = j + 1; 149197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (predicate->evaluate(evaluationContext)) 150d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) newNodes->append(node); 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 153d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) nodes.swap(*newNodes); 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 157197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT) 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline Node::NodeType primaryNodeType(Step::Axis axis) 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (axis) { 1615d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case Step::AttributeAxis: 1625d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return Node::ATTRIBUTE_NODE; 1635d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) default: 1645d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return Node::ELEMENT_NODE; 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 16751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#endif 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Evaluate NodeTest without considering merged predicates. 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline bool nodeMatchesBasicTest(Node* node, Step::Axis axis, const Step::NodeTest& nodeTest) 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (nodeTest.kind()) { 1735d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case Step::NodeTest::TextNodeTest: { 1745d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) Node::NodeType type = node->nodeType(); 1755d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return type == Node::TEXT_NODE || type == Node::CDATA_SECTION_NODE; 1765d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 1775d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case Step::NodeTest::CommentNodeTest: 1785d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return node->nodeType() == Node::COMMENT_NODE; 1795d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case Step::NodeTest::ProcessingInstructionNodeTest: { 1805d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) const AtomicString& name = nodeTest.data(); 1815d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE && (name.isEmpty() || node->nodeName() == name); 1825d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 1835d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case Step::NodeTest::AnyNodeTest: 1845d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return true; 1855d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case Step::NodeTest::NameTest: { 1865d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) const AtomicString& name = nodeTest.data(); 1875d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) const AtomicString& namespaceURI = nodeTest.namespaceURI(); 1885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 1895d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (axis == Step::AttributeAxis) { 1905d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) ASSERT(node->isAttributeNode()); 1915d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 1925d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // In XPath land, namespace nodes are not accessible on the 1935d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // attribute axis. 1945d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (node->namespaceURI() == XMLNSNames::xmlnsNamespaceURI) 1955d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return false; 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1975d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (name == starAtom) 1985d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return namespaceURI.isEmpty() || node->namespaceURI() == namespaceURI; 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2005d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return node->localName() == name && node->namespaceURI() == namespaceURI; 2015d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2035d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // Node test on the namespace axis is not implemented yet, the caller 2045d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // has a check for it. 2055d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) ASSERT(axis != Step::NamespaceAxis); 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2075d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // For other axes, the principal node type is element. 2085d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) ASSERT(primaryNodeType(axis) == Node::ELEMENT_NODE); 2095d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (!node->isElementNode()) 2105d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return false; 2115d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) Element& element = toElement(*node); 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2135d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (name == starAtom) 2145d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return namespaceURI.isEmpty() || namespaceURI == element.namespaceURI(); 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2165d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (element.document().isHTMLDocument()) { 2175d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (element.isHTMLElement()) { 2185d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // Paths without namespaces should match HTML elements in HTML 2195d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // documents despite those having an XHTML namespace. Names are 2205d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // compared case-insensitively. 2215d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return equalIgnoringCase(element.localName(), name) && (namespaceURI.isNull() || namespaceURI == element.namespaceURI()); 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2235d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // An expression without any prefix shouldn't match no-namespace 2245d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // nodes (because HTML5 says so). 2255d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return element.hasLocalName(name) && namespaceURI == element.namespaceURI() && !namespaceURI.isNull(); 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2275d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return element.hasLocalName(name) && namespaceURI == element.namespaceURI(); 2285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 234197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic inline bool nodeMatches(EvaluationContext& evaluationContext, Node* node, Step::Axis axis, const Step::NodeTest& nodeTest) 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!nodeMatchesBasicTest(node, axis, nodeTest)) 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Only the first merged predicate may depend on position. 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++evaluationContext.position; 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 242d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) const WillBeHeapVector<OwnPtrWillBeMember<Predicate> >& mergedPredicates = nodeTest.mergedPredicates(); 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < mergedPredicates.size(); i++) { 244bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) Predicate* predicate = mergedPredicates[i].get(); 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) evaluationContext.node = node; 2475d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // No need to set context size - we only get here when evaluating 2485d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // predicates that do not depend on it. 249197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!predicate->evaluate(evaluationContext)) 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2565d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)// Result nodes are ordered in axis order. Node test (including merged 2575d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)// predicates) is applied. 258197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid Step::nodesInAxis(EvaluationContext& evaluationContext, Node* context, NodeSet& nodes) const 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(nodes.isEmpty()); 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (m_axis) { 2625d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case ChildAxis: 2635d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // In XPath model, attribute nodes do not have children. 2645d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (context->isAttributeNode()) 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2675d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) for (Node* n = context->firstChild(); n; n = n->nextSibling()) { 268197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (nodeMatches(evaluationContext, n, ChildAxis, nodeTest())) 2695d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.append(n); 2705d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 2715d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return; 2725d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 2735d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case DescendantAxis: 2745d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // In XPath model, attribute nodes do not have children. 2755d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (context->isAttributeNode()) 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2775d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 2785d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) for (Node* n = context->firstChild(); n; n = NodeTraversal::next(*n, context)) { 279197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (nodeMatches(evaluationContext, n, DescendantAxis, nodeTest())) 2805d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.append(n); 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2825d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return; 28302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2845d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case ParentAxis: 2855d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (context->isAttributeNode()) { 2865d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) Element* n = toAttr(context)->ownerElement(); 287197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (nodeMatches(evaluationContext, n, ParentAxis, nodeTest())) 2885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.append(n); 2895d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } else { 2905d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) ContainerNode* n = context->parentNode(); 291197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (n && nodeMatches(evaluationContext, n, ParentAxis, nodeTest())) 2925d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.append(n); 2935d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 2945d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return; 2955d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 2965d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case AncestorAxis: { 2975d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) Node* n = context; 2985d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (context->isAttributeNode()) { 2995d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) n = toAttr(context)->ownerElement(); 300197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (nodeMatches(evaluationContext, n, AncestorAxis, nodeTest())) 3015d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.append(n); 3025d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 3035d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) for (n = n->parentNode(); n; n = n->parentNode()) { 304197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (nodeMatches(evaluationContext, n, AncestorAxis, nodeTest())) 3055d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.append(n); 3065d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 3075d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.markSorted(false); 3085d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return; 3095d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 3105d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 3115d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case FollowingSiblingAxis: 3125d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (context->nodeType() == Node::ATTRIBUTE_NODE) 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 31402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3155d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) for (Node* n = context->nextSibling(); n; n = n->nextSibling()) { 316197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (nodeMatches(evaluationContext, n, FollowingSiblingAxis, nodeTest())) 3175d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.append(n); 3185d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 3195d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return; 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3215d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case PrecedingSiblingAxis: 3225d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (context->nodeType() == Node::ATTRIBUTE_NODE) 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3245d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 3255d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) for (Node* n = context->previousSibling(); n; n = n->previousSibling()) { 326197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (nodeMatches(evaluationContext, n, PrecedingSiblingAxis, nodeTest())) 3275d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.append(n); 3285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 3295d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.markSorted(false); 3305d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return; 3315d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 3325d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case FollowingAxis: 3335d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (context->isAttributeNode()) { 334197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch for (Node* p = NodeTraversal::next(*toAttr(context)->ownerElement()); p; p = NodeTraversal::next(*p)) { 335197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (nodeMatches(evaluationContext, p, FollowingAxis, nodeTest())) 3365d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.append(p); 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3385d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } else { 3395d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) for (Node* p = context; !isRootDomNode(p); p = p->parentNode()) { 3405d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) for (Node* n = p->nextSibling(); n; n = n->nextSibling()) { 341197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (nodeMatches(evaluationContext, n, FollowingAxis, nodeTest())) 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) nodes.append(n); 3435d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) for (Node* c = n->firstChild(); c; c = NodeTraversal::next(*c, n)) { 344197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (nodeMatches(evaluationContext, c, FollowingAxis, nodeTest())) 3455d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.append(c); 3465d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3495d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 3505d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return; 35102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3525d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case PrecedingAxis: { 3535d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (context->isAttributeNode()) 3545d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) context = toAttr(context)->ownerElement(); 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3565d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) Node* n = context; 3575d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) while (ContainerNode* parent = n->parentNode()) { 3585d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) for (n = NodeTraversal::previous(*n); n != parent; n = NodeTraversal::previous(*n)) { 359197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (nodeMatches(evaluationContext, n, PrecedingAxis, nodeTest())) 3605d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.append(n); 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3625d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) n = parent; 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3645d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.markSorted(false); 3655d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return; 3665d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 3675d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 3685d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case AttributeAxis: { 3695d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (!context->isElementNode()) 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3715d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 3725d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) Element* contextElement = toElement(context); 3735d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // Avoid lazily creating attribute nodes for attributes that we do not 3745d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // need anyway. 3755d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (nodeTest().kind() == NodeTest::NameTest && nodeTest().data() != starAtom) { 3765d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) RefPtrWillBeRawPtr<Node> n = contextElement->getAttributeNodeNS(nodeTest().namespaceURI(), nodeTest().data()); 3775d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // In XPath land, namespace nodes are not accessible on the attribute axis. 3785d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (n && n->namespaceURI() != XMLNSNames::xmlnsNamespaceURI) { 3795d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // Still need to check merged predicates. 380197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (nodeMatches(evaluationContext, n.get(), AttributeAxis, nodeTest())) 3815d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.append(n.release()); 382d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3845d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 3855d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 38676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) AttributeCollection attributes = contextElement->attributes(); 387e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) AttributeCollection::iterator end = attributes.end(); 388e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) { 3895d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) RefPtrWillBeRawPtr<Attr> attr = contextElement->ensureAttr(it->name()); 390197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (nodeMatches(evaluationContext, attr.get(), AttributeAxis, nodeTest())) 3915d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.append(attr.release()); 3925d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 3935d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return; 3945d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 3955d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 3965d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case NamespaceAxis: 3975d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // XPath namespace nodes are not implemented. 3985d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return; 3995d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 4005d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case SelfAxis: 401197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (nodeMatches(evaluationContext, context, SelfAxis, nodeTest())) 4025d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.append(context); 4035d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return; 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4055d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case DescendantOrSelfAxis: 406197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (nodeMatches(evaluationContext, context, DescendantOrSelfAxis, nodeTest())) 4075d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.append(context); 4085d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // In XPath model, attribute nodes do not have children. 4095d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (context->isAttributeNode()) 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4115d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 4125d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) for (Node* n = context->firstChild(); n; n = NodeTraversal::next(*n, context)) { 413197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (nodeMatches(evaluationContext, n, DescendantOrSelfAxis, nodeTest())) 4145d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.append(n); 4155d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 4165d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return; 4175d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 4185d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case AncestorOrSelfAxis: { 419197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (nodeMatches(evaluationContext, context, AncestorOrSelfAxis, nodeTest())) 4205d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.append(context); 4215d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) Node* n = context; 4225d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (context->isAttributeNode()) { 4235d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) n = toAttr(context)->ownerElement(); 424197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (nodeMatches(evaluationContext, n, AncestorOrSelfAxis, nodeTest())) 4255d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.append(n); 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4275d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) for (n = n->parentNode(); n; n = n->parentNode()) { 428197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (nodeMatches(evaluationContext, n, AncestorOrSelfAxis, nodeTest())) 4295d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.append(n); 4305d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 4315d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) nodes.markSorted(false); 4325d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return; 4335d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4395d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 441