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