2006-05-08 Anders Carlsson <acarlsson@apple.com>
authorandersca <andersca@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 8 May 2006 21:27:25 +0000 (21:27 +0000)
committerandersca <andersca@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 8 May 2006 21:27:25 +0000 (21:27 +0000)
        Reviewed by Darin, Eric and Maciej.

        http://bugzilla.opendarwin.org/show_bug.cgi?id=6638
        Support Mozilla's XPathEvaluator object.

        * DerivedSources.make:
        Generate XPath grammar, and JavaScript wrappers.

        * WebCore.xcodeproj/project.pbxproj:
        Add new files to project

        * bindings/js/kjs_binding.cpp:
        (KJS::):
        (KJS::setDOMException):
        Handle setting XPath exceptions.

        * bindings/objc/DOM.mm:
        Just return nil for now when trying to create a wrapper for
        XPath namespace nodes.

        * bindings/scripts/CodeGeneratorJS.pm:
        Add XPath types. Also add a "CanBeConstructed" extended attribute
        for interfaces that can be constructed directly.

        * bridge/mac/WebCorePageBridge.mm:
        (initializeLoggingChannelsIfNecessary):
        Initialize LogXPath channel.

        * dom/DOMImplementation.cpp:
        (WebCore::DOMImplementation::hasFeature):
        Support "xpath" version "3.0".

        * dom/Document.cpp:
        (WebCore::Document::Document):

        (WebCore::Document::importNode):
        Ignore XPath namespace nodes.

        (WebCore::Document::createExpression):
        (WebCore::Document::createNSResolver):
        (WebCore::Document::evaluate):
        New functions which call down to a lazily created XPathEvaluator.

        * dom/Document.h:
        Add function declarations.

        * dom/Document.idl:
        Add XPath methods.

        * dom/Node.h:
        (WebCore::Node::):
        Add XPATH_NAMESPACE_NODE type.

        * editing/markup.cpp:
        (WebCore::startMarkup):
        Ignore XPath namespace nodes.

        * page/DOMWindow.idl:
        Add constructors for XPathEvaluator and XPathResult.

        * platform/Logging.cpp:
        * platform/Logging.h:
        Add XPath log channel

        * xpath: Added.
        * xpath/XPathEvaluator.cpp: Added.
        (WebCore::XPathEvaluator::createExpression):
        (WebCore::XPathEvaluator::createNSResolver):
        (WebCore::XPathEvaluator::evaluate):
        * xpath/XPathEvaluator.h: Added.
        (WebCore::):
        * xpath/XPathEvaluator.idl: Added.
        * xpath/XPathExpression.cpp: Added.
        (WebCore::XPathExpression::createExpression):
        (WebCore::XPathExpression::~XPathExpression):
        (WebCore::XPathExpression::evaluate):
        * xpath/XPathExpression.h: Added.
        * xpath/XPathExpression.idl: Added.
        * xpath/XPathNSResolver.cpp: Added.
        (WebCore::XPathNSResolver::XPathNSResolver):
        (WebCore::XPathNSResolver::lookupNamespaceURI):
        * xpath/XPathNSResolver.h: Added.
        * xpath/XPathNSResolver.idl: Added.
        * xpath/XPathNamespace.cpp: Added.
        (WebCore::XPathNamespace::XPathNamespace):
        (WebCore::XPathNamespace::~XPathNamespace):
        (WebCore::XPathNamespace::ownerDocument):
        (WebCore::XPathNamespace::ownerElement):
        (WebCore::XPathNamespace::prefix):
        (WebCore::XPathNamespace::nodeName):
        (WebCore::XPathNamespace::nodeValue):
        (WebCore::XPathNamespace::namespaceURI):
        (WebCore::XPathNamespace::nodeType):
        * xpath/XPathNamespace.h: Added.
        * xpath/XPathResult.cpp: Added.
        (WebCore::InvalidatingEventListener::InvalidatingEventListener):
        (WebCore::InvalidatingEventListener::handleEvent):
        (WebCore::XPathResult::XPathResult):
        (WebCore::XPathResult::~XPathResult):
        (WebCore::XPathResult::convertTo):
        (WebCore::XPathResult::resultType):
        (WebCore::XPathResult::numberValue):
        (WebCore::XPathResult::stringValue):
        (WebCore::XPathResult::booleanValue):
        (WebCore::XPathResult::singleNodeValue):
        (WebCore::XPathResult::invalidateIteratorState):
        (WebCore::XPathResult::invalidIteratorState):
        (WebCore::XPathResult::snapshotLength):
        (WebCore::XPathResult::iterateNext):
        (WebCore::XPathResult::snapshotItem):
        * xpath/XPathResult.h: Added.
        (WebCore::XPathResult::):
        * xpath/XPathResult.idl: Added.
        * xpath/impl: Added.
        * xpath/impl/XPathExpressionNode.cpp: Added.
        (WebCore::XPath::Expression::evaluationContext):
        (WebCore::XPath::Expression::Expression):
        (WebCore::XPath::Expression::~Expression):
        (WebCore::XPath::Expression::evaluate):
        (WebCore::XPath::Expression::addSubExpression):
        (WebCore::XPath::Expression::optimize):
        (WebCore::XPath::Expression::subExprCount):
        (WebCore::XPath::Expression::subExpr):
        (WebCore::XPath::Expression::isConstant):
        * xpath/impl/XPathExpressionNode.h: Added.
        (WebCore::XPath::EvaluationContext::EvaluationContext):
        * xpath/impl/XPathFunctions.cpp: Added.
        (WebCore::XPath::Interval::Interval):
        (WebCore::XPath::Interval::contains):
        (WebCore::XPath::Interval::asString):
        (WebCore::XPath::Function::setArguments):
        (WebCore::XPath::Function::setName):
        (WebCore::XPath::Function::arg):
        (WebCore::XPath::Function::argCount):
        (WebCore::XPath::Function::name):
        (WebCore::XPath::FunLast::doEvaluate):
        (WebCore::XPath::FunLast::isConstant):
        (WebCore::XPath::FunPosition::doEvaluate):
        (WebCore::XPath::FunPosition::isConstant):
        (WebCore::XPath::FunLocalName::isConstant):
        (WebCore::XPath::FunLocalName::doEvaluate):
        (WebCore::XPath::FunNamespaceURI::isConstant):
        (WebCore::XPath::FunNamespaceURI::doEvaluate):
        (WebCore::XPath::FunName::isConstant):
        (WebCore::XPath::FunName::doEvaluate):
        (WebCore::XPath::FunCount::doEvaluate):
        (WebCore::XPath::FunCount::isConstant):
        (WebCore::XPath::FunString::doEvaluate):
        (WebCore::XPath::FunConcat::doEvaluate):
        (WebCore::XPath::FunStartsWith::doEvaluate):
        (WebCore::XPath::FunContains::doEvaluate):
        (WebCore::XPath::FunSubstringBefore::doEvaluate):
        (WebCore::XPath::FunSubstringAfter::doEvaluate):
        (WebCore::XPath::FunSubstring::doEvaluate):
        (WebCore::XPath::FunStringLength::doEvaluate):
        (WebCore::XPath::FunNormalizeSpace::doEvaluate):
        (WebCore::XPath::FunTranslate::doEvaluate):
        (WebCore::XPath::FunBoolean::doEvaluate):
        (WebCore::XPath::FunNot::doEvaluate):
        (WebCore::XPath::FunTrue::doEvaluate):
        (WebCore::XPath::FunTrue::isConstant):
        (WebCore::XPath::FunLang::doEvaluate):
        (WebCore::XPath::FunLang::isConstant):
        (WebCore::XPath::FunFalse::doEvaluate):
        (WebCore::XPath::FunFalse::isConstant):
        (WebCore::XPath::FunNumber::doEvaluate):
        (WebCore::XPath::FunSum::doEvaluate):
        (WebCore::XPath::FunFloor::doEvaluate):
        (WebCore::XPath::FunCeiling::doEvaluate):
        (WebCore::XPath::FunRound::doEvaluate):
        (WebCore::XPath::FunctionLibrary::self):
        (WebCore::XPath::FunctionLibrary::FunctionLibrary):
        (WebCore::XPath::FunctionLibrary::createFunction):
        * xpath/impl/XPathFunctions.h: Added.
        * xpath/impl/XPathGrammar.y: Added.
        * xpath/impl/XPathParser.cpp: Added.
        (WebCore::XPath::):
        (WebCore::XPath::Parser::charCat):
        (WebCore::XPath::Parser::isAxisName):
        (WebCore::XPath::Parser::isNodeTypeName):
        (WebCore::XPath::Parser::isOperatorContext):
        (WebCore::XPath::Parser::skipWS):
        (WebCore::XPath::Parser::makeTokenAndAdvance):
        (WebCore::XPath::Parser::makeIntTokenAndAdvance):
        (WebCore::XPath::Parser::peekAheadHelper):
        (WebCore::XPath::Parser::peekCurHelper):
        (WebCore::XPath::Parser::lexString):
        (WebCore::XPath::Parser::lexNumber):
        (WebCore::XPath::Parser::lexNCName):
        (WebCore::XPath::Parser::lexQName):
        (WebCore::XPath::Parser::nextTokenInternal):
        (WebCore::XPath::Parser::nextToken):
        (WebCore::XPath::Parser::Parser):
        (WebCore::XPath::Parser::reset):
        (WebCore::XPath::Parser::lex):
        (WebCore::XPath::Parser::parseStatement):
        (WebCore::XPath::Parser::registerParseNode):
        (WebCore::XPath::Parser::unregisterParseNode):
        (WebCore::XPath::Parser::registerPredicateVector):
        (WebCore::XPath::Parser::unregisterPredicateVector):
        (WebCore::XPath::Parser::registerExpressionVector):
        (WebCore::XPath::Parser::unregisterExpressionVector):
        (WebCore::XPath::Parser::registerString):
        (WebCore::XPath::Parser::unregisterString):
        * xpath/impl/XPathParser.h: Added.
        (WebCore::XPath::Token::Token):
        (WebCore::XPath::Parser::):
        (WebCore::XPath::Parser::current):
        * xpath/impl/XPathPath.cpp: Added.
        (WebCore::XPath::Filter::Filter):
        (WebCore::XPath::Filter::~Filter):
        (WebCore::XPath::Filter::doEvaluate):
        (WebCore::XPath::LocationPath::LocationPath):
        (WebCore::XPath::LocationPath::~LocationPath):
        (WebCore::XPath::LocationPath::optimize):
        (WebCore::XPath::LocationPath::doEvaluate):
        (WebCore::XPath::Path::Path):
        (WebCore::XPath::Path::~Path):
        (WebCore::XPath::Path::doEvaluate):
        * xpath/impl/XPathPath.h: Added.
        * xpath/impl/XPathPredicate.cpp: Added.
        (WebCore::XPath::Number::Number):
        (WebCore::XPath::Number::isConstant):
        (WebCore::XPath::Number::doEvaluate):
        (WebCore::XPath::StringExpression::StringExpression):
        (WebCore::XPath::StringExpression::isConstant):
        (WebCore::XPath::StringExpression::doEvaluate):
        (WebCore::XPath::Negative::doEvaluate):
        (WebCore::XPath::NumericOp::NumericOp):
        (WebCore::XPath::NumericOp::doEvaluate):
        (WebCore::XPath::EqTestOp::EqTestOp):
        (WebCore::XPath::EqTestOp::doEvaluate):
        (WebCore::XPath::LogicalOp::LogicalOp):
        (WebCore::XPath::LogicalOp::shortCircuitOn):
        (WebCore::XPath::LogicalOp::isConstant):
        (WebCore::XPath::LogicalOp::doEvaluate):
        (WebCore::XPath::Union::doEvaluate):
        (WebCore::XPath::Predicate::Predicate):
        (WebCore::XPath::Predicate::~Predicate):
        (WebCore::XPath::Predicate::evaluate):
        (WebCore::XPath::Predicate::optimize):
        * xpath/impl/XPathPredicate.h: Added.
        (WebCore::XPath::NumericOp::):
        (WebCore::XPath::EqTestOp::):
        (WebCore::XPath::LogicalOp::):
        * xpath/impl/XPathStep.cpp: Added.
        (WebCore::XPath::Step::axisAsString):
        (WebCore::XPath::Step::Step):
        (WebCore::XPath::Step::~Step):
        (WebCore::XPath::Step::evaluate):
        (WebCore::XPath::Step::nodesInAxis):
        (WebCore::XPath::Step::nodeTestMatches):
        (WebCore::XPath::Step::optimize):
        (WebCore::XPath::Step::namespaceFromNodetest):
        (WebCore::XPath::Step::primaryNodeType):
        * xpath/impl/XPathStep.h: Added.
        (WebCore::XPath::Step::):
        * xpath/impl/XPathUtil.cpp: Added.
        (WebCore::XPath::isRootDomNode):
        (WebCore::XPath::stringValue):
        (WebCore::XPath::isValidContextNode):
        * xpath/impl/XPathUtil.h: Added.
        * xpath/impl/XPathValue.cpp: Added.
        (WebCore::XPath::Value::Value):
        (WebCore::XPath::Value::type):
        (WebCore::XPath::Value::isNodeVector):
        (WebCore::XPath::Value::isBoolean):
        (WebCore::XPath::Value::isNumber):
        (WebCore::XPath::Value::isString):
        (WebCore::XPath::Value::toNodeVector):
        (WebCore::XPath::Value::toBoolean):
        (WebCore::XPath::Value::toNumber):
        (WebCore::XPath::Value::toString):
        * xpath/impl/XPathValue.h: Added.
        (WebCore::XPath::Value::):
        * xpath/impl/XPathVariableReference.cpp: Added.
        (WebCore::XPath::VariableReference::VariableReference):
        (WebCore::XPath::VariableReference::isConstant):
        (WebCore::XPath::VariableReference::doEvaluate):
        * xpath/impl/XPathVariableReference.h: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@14234 268f45cc-cd09-0410-ab3c-d52691b4dbfc

49 files changed:
WebCore/ChangeLog
WebCore/DerivedSources.make
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/bindings/js/kjs_binding.cpp
WebCore/bindings/objc/DOM.mm
WebCore/bindings/scripts/CodeGeneratorJS.pm
WebCore/bridge/mac/WebCorePageBridge.mm
WebCore/dom/DOMImplementation.cpp
WebCore/dom/Document.cpp
WebCore/dom/Document.h
WebCore/dom/Document.idl
WebCore/dom/Node.h
WebCore/editing/markup.cpp
WebCore/page/DOMWindow.idl
WebCore/platform/Logging.cpp
WebCore/platform/Logging.h
WebCore/xpath/XPathEvaluator.cpp [new file with mode: 0644]
WebCore/xpath/XPathEvaluator.h [new file with mode: 0644]
WebCore/xpath/XPathEvaluator.idl [new file with mode: 0644]
WebCore/xpath/XPathExpression.cpp [new file with mode: 0644]
WebCore/xpath/XPathExpression.h [new file with mode: 0644]
WebCore/xpath/XPathExpression.idl [new file with mode: 0644]
WebCore/xpath/XPathNSResolver.cpp [new file with mode: 0644]
WebCore/xpath/XPathNSResolver.h [new file with mode: 0644]
WebCore/xpath/XPathNSResolver.idl [new file with mode: 0644]
WebCore/xpath/XPathNamespace.cpp [new file with mode: 0644]
WebCore/xpath/XPathNamespace.h [new file with mode: 0644]
WebCore/xpath/XPathResult.cpp [new file with mode: 0644]
WebCore/xpath/XPathResult.h [new file with mode: 0644]
WebCore/xpath/XPathResult.idl [new file with mode: 0644]
WebCore/xpath/impl/XPathExpressionNode.cpp [new file with mode: 0644]
WebCore/xpath/impl/XPathExpressionNode.h [new file with mode: 0644]
WebCore/xpath/impl/XPathFunctions.cpp [new file with mode: 0644]
WebCore/xpath/impl/XPathFunctions.h [new file with mode: 0644]
WebCore/xpath/impl/XPathGrammar.y [new file with mode: 0644]
WebCore/xpath/impl/XPathParser.cpp [new file with mode: 0644]
WebCore/xpath/impl/XPathParser.h [new file with mode: 0644]
WebCore/xpath/impl/XPathPath.cpp [new file with mode: 0644]
WebCore/xpath/impl/XPathPath.h [new file with mode: 0644]
WebCore/xpath/impl/XPathPredicate.cpp [new file with mode: 0644]
WebCore/xpath/impl/XPathPredicate.h [new file with mode: 0644]
WebCore/xpath/impl/XPathStep.cpp [new file with mode: 0644]
WebCore/xpath/impl/XPathStep.h [new file with mode: 0644]
WebCore/xpath/impl/XPathUtil.cpp [new file with mode: 0644]
WebCore/xpath/impl/XPathUtil.h [new file with mode: 0644]
WebCore/xpath/impl/XPathValue.cpp [new file with mode: 0644]
WebCore/xpath/impl/XPathValue.h [new file with mode: 0644]
WebCore/xpath/impl/XPathVariableReference.cpp [new file with mode: 0644]
WebCore/xpath/impl/XPathVariableReference.h [new file with mode: 0644]

index 5d1fbe5..3e8557f 100644 (file)
@@ -1,3 +1,286 @@
+2006-05-08  Anders Carlsson  <acarlsson@apple.com>
+
+        Reviewed by Darin, Eric and Maciej.
+
+        http://bugzilla.opendarwin.org/show_bug.cgi?id=6638
+        Support Mozilla's XPathEvaluator object.
+        
+        * DerivedSources.make:
+        Generate XPath grammar, and JavaScript wrappers.
+        
+        * WebCore.xcodeproj/project.pbxproj:
+        Add new files to project
+        
+        * bindings/js/kjs_binding.cpp:
+        (KJS::):
+        (KJS::setDOMException):
+        Handle setting XPath exceptions.
+        
+        * bindings/objc/DOM.mm:
+        Just return nil for now when trying to create a wrapper for 
+        XPath namespace nodes.
+
+        * bindings/scripts/CodeGeneratorJS.pm:
+        Add XPath types. Also add a "CanBeConstructed" extended attribute
+        for interfaces that can be constructed directly.
+        
+        * bridge/mac/WebCorePageBridge.mm:
+        (initializeLoggingChannelsIfNecessary):
+        Initialize LogXPath channel.
+        
+        * dom/DOMImplementation.cpp:
+        (WebCore::DOMImplementation::hasFeature):
+        Support "xpath" version "3.0".
+        
+        * dom/Document.cpp:
+        (WebCore::Document::Document):
+        
+        (WebCore::Document::importNode):
+        Ignore XPath namespace nodes.
+        
+        (WebCore::Document::createExpression):
+        (WebCore::Document::createNSResolver):
+        (WebCore::Document::evaluate):
+        New functions which call down to a lazily created XPathEvaluator.
+
+        * dom/Document.h:
+        Add function declarations.
+        
+        * dom/Document.idl:
+        Add XPath methods.
+        
+        * dom/Node.h:
+        (WebCore::Node::):
+        Add XPATH_NAMESPACE_NODE type.
+        
+        * editing/markup.cpp:
+        (WebCore::startMarkup):
+        Ignore XPath namespace nodes.
+        
+        * page/DOMWindow.idl:
+        Add constructors for XPathEvaluator and XPathResult.
+        
+        * platform/Logging.cpp:
+        * platform/Logging.h:
+        Add XPath log channel
+
+        * xpath: Added.
+        * xpath/XPathEvaluator.cpp: Added.
+        (WebCore::XPathEvaluator::createExpression):
+        (WebCore::XPathEvaluator::createNSResolver):
+        (WebCore::XPathEvaluator::evaluate):
+        * xpath/XPathEvaluator.h: Added.
+        (WebCore::):
+        * xpath/XPathEvaluator.idl: Added.
+        * xpath/XPathExpression.cpp: Added.
+        (WebCore::XPathExpression::createExpression):
+        (WebCore::XPathExpression::~XPathExpression):
+        (WebCore::XPathExpression::evaluate):
+        * xpath/XPathExpression.h: Added.
+        * xpath/XPathExpression.idl: Added.
+        * xpath/XPathNSResolver.cpp: Added.
+        (WebCore::XPathNSResolver::XPathNSResolver):
+        (WebCore::XPathNSResolver::lookupNamespaceURI):
+        * xpath/XPathNSResolver.h: Added.
+        * xpath/XPathNSResolver.idl: Added.
+        * xpath/XPathNamespace.cpp: Added.
+        (WebCore::XPathNamespace::XPathNamespace):
+        (WebCore::XPathNamespace::~XPathNamespace):
+        (WebCore::XPathNamespace::ownerDocument):
+        (WebCore::XPathNamespace::ownerElement):
+        (WebCore::XPathNamespace::prefix):
+        (WebCore::XPathNamespace::nodeName):
+        (WebCore::XPathNamespace::nodeValue):
+        (WebCore::XPathNamespace::namespaceURI):
+        (WebCore::XPathNamespace::nodeType):
+        * xpath/XPathNamespace.h: Added.
+        * xpath/XPathResult.cpp: Added.
+        (WebCore::InvalidatingEventListener::InvalidatingEventListener):
+        (WebCore::InvalidatingEventListener::handleEvent):
+        (WebCore::XPathResult::XPathResult):
+        (WebCore::XPathResult::~XPathResult):
+        (WebCore::XPathResult::convertTo):
+        (WebCore::XPathResult::resultType):
+        (WebCore::XPathResult::numberValue):
+        (WebCore::XPathResult::stringValue):
+        (WebCore::XPathResult::booleanValue):
+        (WebCore::XPathResult::singleNodeValue):
+        (WebCore::XPathResult::invalidateIteratorState):
+        (WebCore::XPathResult::invalidIteratorState):
+        (WebCore::XPathResult::snapshotLength):
+        (WebCore::XPathResult::iterateNext):
+        (WebCore::XPathResult::snapshotItem):
+        * xpath/XPathResult.h: Added.
+        (WebCore::XPathResult::):
+        * xpath/XPathResult.idl: Added.
+        * xpath/impl: Added.
+        * xpath/impl/XPathExpressionNode.cpp: Added.
+        (WebCore::XPath::Expression::evaluationContext):
+        (WebCore::XPath::Expression::Expression):
+        (WebCore::XPath::Expression::~Expression):
+        (WebCore::XPath::Expression::evaluate):
+        (WebCore::XPath::Expression::addSubExpression):
+        (WebCore::XPath::Expression::optimize):
+        (WebCore::XPath::Expression::subExprCount):
+        (WebCore::XPath::Expression::subExpr):
+        (WebCore::XPath::Expression::isConstant):
+        * xpath/impl/XPathExpressionNode.h: Added.
+        (WebCore::XPath::EvaluationContext::EvaluationContext):
+        * xpath/impl/XPathFunctions.cpp: Added.
+        (WebCore::XPath::Interval::Interval):
+        (WebCore::XPath::Interval::contains):
+        (WebCore::XPath::Interval::asString):
+        (WebCore::XPath::Function::setArguments):
+        (WebCore::XPath::Function::setName):
+        (WebCore::XPath::Function::arg):
+        (WebCore::XPath::Function::argCount):
+        (WebCore::XPath::Function::name):
+        (WebCore::XPath::FunLast::doEvaluate):
+        (WebCore::XPath::FunLast::isConstant):
+        (WebCore::XPath::FunPosition::doEvaluate):
+        (WebCore::XPath::FunPosition::isConstant):
+        (WebCore::XPath::FunLocalName::isConstant):
+        (WebCore::XPath::FunLocalName::doEvaluate):
+        (WebCore::XPath::FunNamespaceURI::isConstant):
+        (WebCore::XPath::FunNamespaceURI::doEvaluate):
+        (WebCore::XPath::FunName::isConstant):
+        (WebCore::XPath::FunName::doEvaluate):
+        (WebCore::XPath::FunCount::doEvaluate):
+        (WebCore::XPath::FunCount::isConstant):
+        (WebCore::XPath::FunString::doEvaluate):
+        (WebCore::XPath::FunConcat::doEvaluate):
+        (WebCore::XPath::FunStartsWith::doEvaluate):
+        (WebCore::XPath::FunContains::doEvaluate):
+        (WebCore::XPath::FunSubstringBefore::doEvaluate):
+        (WebCore::XPath::FunSubstringAfter::doEvaluate):
+        (WebCore::XPath::FunSubstring::doEvaluate):
+        (WebCore::XPath::FunStringLength::doEvaluate):
+        (WebCore::XPath::FunNormalizeSpace::doEvaluate):
+        (WebCore::XPath::FunTranslate::doEvaluate):
+        (WebCore::XPath::FunBoolean::doEvaluate):
+        (WebCore::XPath::FunNot::doEvaluate):
+        (WebCore::XPath::FunTrue::doEvaluate):
+        (WebCore::XPath::FunTrue::isConstant):
+        (WebCore::XPath::FunLang::doEvaluate):
+        (WebCore::XPath::FunLang::isConstant):
+        (WebCore::XPath::FunFalse::doEvaluate):
+        (WebCore::XPath::FunFalse::isConstant):
+        (WebCore::XPath::FunNumber::doEvaluate):
+        (WebCore::XPath::FunSum::doEvaluate):
+        (WebCore::XPath::FunFloor::doEvaluate):
+        (WebCore::XPath::FunCeiling::doEvaluate):
+        (WebCore::XPath::FunRound::doEvaluate):
+        (WebCore::XPath::FunctionLibrary::self):
+        (WebCore::XPath::FunctionLibrary::FunctionLibrary):
+        (WebCore::XPath::FunctionLibrary::createFunction):
+        * xpath/impl/XPathFunctions.h: Added.
+        * xpath/impl/XPathGrammar.y: Added.
+        * xpath/impl/XPathParser.cpp: Added.
+        (WebCore::XPath::):
+        (WebCore::XPath::Parser::charCat):
+        (WebCore::XPath::Parser::isAxisName):
+        (WebCore::XPath::Parser::isNodeTypeName):
+        (WebCore::XPath::Parser::isOperatorContext):
+        (WebCore::XPath::Parser::skipWS):
+        (WebCore::XPath::Parser::makeTokenAndAdvance):
+        (WebCore::XPath::Parser::makeIntTokenAndAdvance):
+        (WebCore::XPath::Parser::peekAheadHelper):
+        (WebCore::XPath::Parser::peekCurHelper):
+        (WebCore::XPath::Parser::lexString):
+        (WebCore::XPath::Parser::lexNumber):
+        (WebCore::XPath::Parser::lexNCName):
+        (WebCore::XPath::Parser::lexQName):
+        (WebCore::XPath::Parser::nextTokenInternal):
+        (WebCore::XPath::Parser::nextToken):
+        (WebCore::XPath::Parser::Parser):
+        (WebCore::XPath::Parser::reset):
+        (WebCore::XPath::Parser::lex):
+        (WebCore::XPath::Parser::parseStatement):
+        (WebCore::XPath::Parser::registerParseNode):
+        (WebCore::XPath::Parser::unregisterParseNode):
+        (WebCore::XPath::Parser::registerPredicateVector):
+        (WebCore::XPath::Parser::unregisterPredicateVector):
+        (WebCore::XPath::Parser::registerExpressionVector):
+        (WebCore::XPath::Parser::unregisterExpressionVector):
+        (WebCore::XPath::Parser::registerString):
+        (WebCore::XPath::Parser::unregisterString):
+        * xpath/impl/XPathParser.h: Added.
+        (WebCore::XPath::Token::Token):
+        (WebCore::XPath::Parser::):
+        (WebCore::XPath::Parser::current):
+        * xpath/impl/XPathPath.cpp: Added.
+        (WebCore::XPath::Filter::Filter):
+        (WebCore::XPath::Filter::~Filter):
+        (WebCore::XPath::Filter::doEvaluate):
+        (WebCore::XPath::LocationPath::LocationPath):
+        (WebCore::XPath::LocationPath::~LocationPath):
+        (WebCore::XPath::LocationPath::optimize):
+        (WebCore::XPath::LocationPath::doEvaluate):
+        (WebCore::XPath::Path::Path):
+        (WebCore::XPath::Path::~Path):
+        (WebCore::XPath::Path::doEvaluate):
+        * xpath/impl/XPathPath.h: Added.
+        * xpath/impl/XPathPredicate.cpp: Added.
+        (WebCore::XPath::Number::Number):
+        (WebCore::XPath::Number::isConstant):
+        (WebCore::XPath::Number::doEvaluate):
+        (WebCore::XPath::StringExpression::StringExpression):
+        (WebCore::XPath::StringExpression::isConstant):
+        (WebCore::XPath::StringExpression::doEvaluate):
+        (WebCore::XPath::Negative::doEvaluate):
+        (WebCore::XPath::NumericOp::NumericOp):
+        (WebCore::XPath::NumericOp::doEvaluate):
+        (WebCore::XPath::EqTestOp::EqTestOp):
+        (WebCore::XPath::EqTestOp::doEvaluate):
+        (WebCore::XPath::LogicalOp::LogicalOp):
+        (WebCore::XPath::LogicalOp::shortCircuitOn):
+        (WebCore::XPath::LogicalOp::isConstant):
+        (WebCore::XPath::LogicalOp::doEvaluate):
+        (WebCore::XPath::Union::doEvaluate):
+        (WebCore::XPath::Predicate::Predicate):
+        (WebCore::XPath::Predicate::~Predicate):
+        (WebCore::XPath::Predicate::evaluate):
+        (WebCore::XPath::Predicate::optimize):
+        * xpath/impl/XPathPredicate.h: Added.
+        (WebCore::XPath::NumericOp::):
+        (WebCore::XPath::EqTestOp::):
+        (WebCore::XPath::LogicalOp::):
+        * xpath/impl/XPathStep.cpp: Added.
+        (WebCore::XPath::Step::axisAsString):
+        (WebCore::XPath::Step::Step):
+        (WebCore::XPath::Step::~Step):
+        (WebCore::XPath::Step::evaluate):
+        (WebCore::XPath::Step::nodesInAxis):
+        (WebCore::XPath::Step::nodeTestMatches):
+        (WebCore::XPath::Step::optimize):
+        (WebCore::XPath::Step::namespaceFromNodetest):
+        (WebCore::XPath::Step::primaryNodeType):
+        * xpath/impl/XPathStep.h: Added.
+        (WebCore::XPath::Step::):
+        * xpath/impl/XPathUtil.cpp: Added.
+        (WebCore::XPath::isRootDomNode):
+        (WebCore::XPath::stringValue):
+        (WebCore::XPath::isValidContextNode):
+        * xpath/impl/XPathUtil.h: Added.
+        * xpath/impl/XPathValue.cpp: Added.
+        (WebCore::XPath::Value::Value):
+        (WebCore::XPath::Value::type):
+        (WebCore::XPath::Value::isNodeVector):
+        (WebCore::XPath::Value::isBoolean):
+        (WebCore::XPath::Value::isNumber):
+        (WebCore::XPath::Value::isString):
+        (WebCore::XPath::Value::toNodeVector):
+        (WebCore::XPath::Value::toBoolean):
+        (WebCore::XPath::Value::toNumber):
+        (WebCore::XPath::Value::toString):
+        * xpath/impl/XPathValue.h: Added.
+        (WebCore::XPath::Value::):
+        * xpath/impl/XPathVariableReference.cpp: Added.
+        (WebCore::XPath::VariableReference::VariableReference):
+        (WebCore::XPath::VariableReference::isConstant):
+        (WebCore::XPath::VariableReference::doEvaluate):
+        * xpath/impl/XPathVariableReference.h: Added.
+
 2006-05-08  David Hyatt  <hyatt@apple.com>
 
         Comprehensive box-sizing fix.  This patch changes all form controls to
index 15a6720..3e4b36f 100644 (file)
@@ -31,6 +31,7 @@ VPATH = \
     $(WebCore)/dom \
     $(WebCore)/html \
     $(WebCore)/page \
+    $(WebCore)/xpath \
 #
 
 .PHONY : all
@@ -72,6 +73,10 @@ all : \
     JSRange.h \
     JSText.h \
     JSUIEvent.h \
+    JSXPathEvaluator.h \
+    JSXPathExpression.h \
+    JSXPathNSResolver.h \
+    JSXPathResult.h \
     JSWheelEvent.h \
     JSXMLHttpRequest.lut.h \
     JSXMLSerializer.lut.h \
@@ -79,6 +84,7 @@ all : \
     SVGNames.cpp \
     UserAgentStyleSheets.h \
     XLinkNames.cpp \
+    XPathGrammar.cpp \
     kjs_css.lut.h \
     kjs_dom.lut.h \
     kjs_events.lut.h \
@@ -130,6 +136,15 @@ CSSGrammar.cpp : css/CSSGrammar.y
        cat CSSGrammar.cpp.h CSSGrammar.hpp > CSSGrammar.h
        rm -f CSSGrammar.cpp.h CSSGrammar.hpp
 
+# XPath grammar
+
+XPathGrammar.cpp : xpath/impl/XPathGrammar.y
+       bison -d -p xpathyy $< -o $@
+       touch XPathGrammar.cpp.h
+       touch XPathGrammar.hpp
+       cat XPathGrammar.cpp.h XPathGrammar.hpp > XPathGrammar.h
+       rm -f XPathGrammar.cpp.h XPathGrammar.hpp
+
 # user agent style sheets
 
 USER_AGENT_STYLE_SHEETS = $(WebCore)/css/html4.css $(WebCore)/css/quirks.css $(WebCore)/css/svg.css 
@@ -183,4 +198,4 @@ JS_BINDINGS_SCRIPTS = \
 #
 
 JS%.h : %.idl $(JS_BINDINGS_SCRIPTS)
-       perl -I$(WebCore)/bindings/scripts $(WebCore)/bindings/scripts/generate-bindings.pl --generator JS --include dom --include html --outputdir . $<
+       perl -I$(WebCore)/bindings/scripts $(WebCore)/bindings/scripts/generate-bindings.pl --generator JS --include dom --include html --include xpath --outputdir  . $<
index 05abfad..adcc429 100644 (file)
                14E8378E09F85D4F00B85AE4 /* JSEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 14E8378D09F85D4F00B85AE4 /* JSEvent.h */; };
                14EC267F09CA07E000E1EEEC /* EventTargetNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 14EC267D09CA07E000E1EEEC /* EventTargetNode.h */; };
                14EC268009CA07E000E1EEEC /* EventTargetNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14EC267E09CA07E000E1EEEC /* EventTargetNode.cpp */; };
+               1A5D938E0A0B9ACC00B1121F /* XPathParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5D938C0A0B9ACC00B1121F /* XPathParser.cpp */; };
+               1A5D938F0A0B9ACC00B1121F /* XPathParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5D938D0A0B9ACC00B1121F /* XPathParser.h */; };
+               1A6931760A0CD4FA00C127FE /* XPathValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A6931740A0CD4FA00C127FE /* XPathValue.h */; };
+               1A6931770A0CD4FA00C127FE /* XPathValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A6931750A0CD4FA00C127FE /* XPathValue.cpp */; };
+               1A7629830A0740A000989F5B /* XPathExpressionNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7629590A0740A000989F5B /* XPathExpressionNode.cpp */; };
+               1A7629840A0740A000989F5B /* XPathExpressionNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A76295A0A0740A000989F5B /* XPathExpressionNode.h */; };
+               1A76298A0A0740A000989F5B /* XPathFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7629610A0740A000989F5B /* XPathFunctions.cpp */; };
+               1A76298B0A0740A000989F5B /* XPathFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A7629620A0740A000989F5B /* XPathFunctions.h */; };
+               1A76298E0A0740A000989F5B /* XPathPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7629650A0740A000989F5B /* XPathPath.cpp */; };
+               1A76298F0A0740A000989F5B /* XPathPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A7629660A0740A000989F5B /* XPathPath.h */; };
+               1A7629900A0740A000989F5B /* XPathPredicate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7629670A0740A000989F5B /* XPathPredicate.cpp */; };
+               1A7629910A0740A000989F5B /* XPathPredicate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A7629680A0740A000989F5B /* XPathPredicate.h */; };
+               1A7629920A0740A000989F5B /* XPathStep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7629690A0740A000989F5B /* XPathStep.cpp */; };
+               1A7629930A0740A000989F5B /* XPathStep.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A76296A0A0740A000989F5B /* XPathStep.h */; };
+               1A7629970A0740A000989F5B /* XPathUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A76296E0A0740A000989F5B /* XPathUtil.cpp */; };
+               1A7629980A0740A000989F5B /* XPathUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A76296F0A0740A000989F5B /* XPathUtil.h */; };
+               1A7629990A0740A000989F5B /* XPathVariableReference.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7629700A0740A000989F5B /* XPathVariableReference.cpp */; };
+               1A76299A0A0740A000989F5B /* XPathVariableReference.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A7629710A0740A000989F5B /* XPathVariableReference.h */; };
+               1A76299D0A0740A000989F5B /* XPathEvaluator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7629750A0740A000989F5B /* XPathEvaluator.cpp */; };
+               1A76299E0A0740A000989F5B /* XPathEvaluator.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A7629760A0740A000989F5B /* XPathEvaluator.h */; };
+               1A7629A00A0740A000989F5B /* XPathExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7629780A0740A000989F5B /* XPathExpression.cpp */; };
+               1A7629A10A0740A000989F5B /* XPathExpression.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A7629790A0740A000989F5B /* XPathExpression.h */; };
+               1A7629A30A0740A000989F5B /* XPathNamespace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A76297B0A0740A000989F5B /* XPathNamespace.cpp */; };
+               1A7629A40A0740A000989F5B /* XPathNamespace.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A76297C0A0740A000989F5B /* XPathNamespace.h */; };
+               1A7629A50A0740A000989F5B /* XPathNSResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A76297D0A0740A000989F5B /* XPathNSResolver.cpp */; };
+               1A7629A60A0740A000989F5B /* XPathNSResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A76297E0A0740A000989F5B /* XPathNSResolver.h */; };
+               1A7629A80A0740A000989F5B /* XPathResult.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7629800A0740A000989F5B /* XPathResult.cpp */; };
+               1A7629A90A0740A000989F5B /* XPathResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A7629810A0740A000989F5B /* XPathResult.h */; };
+               1A7629D50A07425100989F5B /* XPathGrammar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7629D30A07425100989F5B /* XPathGrammar.cpp */; };
+               1A7629D60A07425100989F5B /* XPathGrammar.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A7629D40A07425100989F5B /* XPathGrammar.h */; };
+               1A762C730A074F2600989F5B /* JSXPathEvaluator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A762C6B0A074F2600989F5B /* JSXPathEvaluator.cpp */; };
+               1A762C740A074F2600989F5B /* JSXPathEvaluator.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A762C6C0A074F2600989F5B /* JSXPathEvaluator.h */; };
+               1A762C750A074F2600989F5B /* JSXPathExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A762C6D0A074F2600989F5B /* JSXPathExpression.cpp */; };
+               1A762C760A074F2600989F5B /* JSXPathExpression.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A762C6E0A074F2600989F5B /* JSXPathExpression.h */; };
+               1A762C770A074F2600989F5B /* JSXPathNSResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A762C6F0A074F2600989F5B /* JSXPathNSResolver.cpp */; };
+               1A762C780A074F2600989F5B /* JSXPathNSResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A762C700A074F2600989F5B /* JSXPathNSResolver.h */; };
+               1A762C790A074F2600989F5B /* JSXPathResult.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A762C710A074F2600989F5B /* JSXPathResult.cpp */; };
+               1A762C7A0A074F2600989F5B /* JSXPathResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A762C720A074F2600989F5B /* JSXPathResult.h */; };
                550A0BC9085F6039007353D6 /* QualifiedName.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 550A0BC7085F6039007353D6 /* QualifiedName.cpp */; };
                550A0BCA085F6039007353D6 /* QualifiedName.h in Headers */ = {isa = PBXBuildFile; fileRef = 550A0BC8085F6039007353D6 /* QualifiedName.h */; };
                550A0BCD085F604D007353D6 /* HTMLNames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 550A0BCB085F604D007353D6 /* HTMLNames.cpp */; };
                14E8378D09F85D4F00B85AE4 /* JSEvent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSEvent.h; sourceTree = "<group>"; };
                14EC267D09CA07E000E1EEEC /* EventTargetNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventTargetNode.h; sourceTree = "<group>"; };
                14EC267E09CA07E000E1EEEC /* EventTargetNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventTargetNode.cpp; sourceTree = "<group>"; };
+               1A5D938C0A0B9ACC00B1121F /* XPathParser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = XPathParser.cpp; sourceTree = "<group>"; };
+               1A5D938D0A0B9ACC00B1121F /* XPathParser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = XPathParser.h; sourceTree = "<group>"; };
+               1A6931740A0CD4FA00C127FE /* XPathValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XPathValue.h; sourceTree = "<group>"; };
+               1A6931750A0CD4FA00C127FE /* XPathValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XPathValue.cpp; sourceTree = "<group>"; };
+               1A7629590A0740A000989F5B /* XPathExpressionNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = XPathExpressionNode.cpp; sourceTree = "<group>"; };
+               1A76295A0A0740A000989F5B /* XPathExpressionNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = XPathExpressionNode.h; sourceTree = "<group>"; };
+               1A7629610A0740A000989F5B /* XPathFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = XPathFunctions.cpp; sourceTree = "<group>"; };
+               1A7629620A0740A000989F5B /* XPathFunctions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = XPathFunctions.h; sourceTree = "<group>"; };
+               1A7629650A0740A000989F5B /* XPathPath.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = XPathPath.cpp; sourceTree = "<group>"; };
+               1A7629660A0740A000989F5B /* XPathPath.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = XPathPath.h; sourceTree = "<group>"; };
+               1A7629670A0740A000989F5B /* XPathPredicate.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = XPathPredicate.cpp; sourceTree = "<group>"; };
+               1A7629680A0740A000989F5B /* XPathPredicate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = XPathPredicate.h; sourceTree = "<group>"; };
+               1A7629690A0740A000989F5B /* XPathStep.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = XPathStep.cpp; sourceTree = "<group>"; };
+               1A76296A0A0740A000989F5B /* XPathStep.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = XPathStep.h; sourceTree = "<group>"; };
+               1A76296E0A0740A000989F5B /* XPathUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = XPathUtil.cpp; sourceTree = "<group>"; };
+               1A76296F0A0740A000989F5B /* XPathUtil.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = XPathUtil.h; sourceTree = "<group>"; };
+               1A7629700A0740A000989F5B /* XPathVariableReference.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = XPathVariableReference.cpp; sourceTree = "<group>"; };
+               1A7629710A0740A000989F5B /* XPathVariableReference.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = XPathVariableReference.h; sourceTree = "<group>"; };
+               1A7629720A0740A000989F5B /* XPathGrammar.y */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.yacc; path = XPathGrammar.y; sourceTree = "<group>"; };
+               1A7629750A0740A000989F5B /* XPathEvaluator.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = XPathEvaluator.cpp; sourceTree = "<group>"; };
+               1A7629760A0740A000989F5B /* XPathEvaluator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = XPathEvaluator.h; sourceTree = "<group>"; };
+               1A7629770A0740A000989F5B /* XPathEvaluator.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = XPathEvaluator.idl; sourceTree = "<group>"; };
+               1A7629780A0740A000989F5B /* XPathExpression.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = XPathExpression.cpp; sourceTree = "<group>"; };
+               1A7629790A0740A000989F5B /* XPathExpression.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = XPathExpression.h; sourceTree = "<group>"; };
+               1A76297A0A0740A000989F5B /* XPathExpression.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = XPathExpression.idl; sourceTree = "<group>"; };
+               1A76297B0A0740A000989F5B /* XPathNamespace.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = XPathNamespace.cpp; sourceTree = "<group>"; };
+               1A76297C0A0740A000989F5B /* XPathNamespace.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = XPathNamespace.h; sourceTree = "<group>"; };
+               1A76297D0A0740A000989F5B /* XPathNSResolver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = XPathNSResolver.cpp; sourceTree = "<group>"; };
+               1A76297E0A0740A000989F5B /* XPathNSResolver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = XPathNSResolver.h; sourceTree = "<group>"; };
+               1A76297F0A0740A000989F5B /* XPathNSResolver.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = XPathNSResolver.idl; sourceTree = "<group>"; };
+               1A7629800A0740A000989F5B /* XPathResult.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = XPathResult.cpp; sourceTree = "<group>"; };
+               1A7629810A0740A000989F5B /* XPathResult.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = XPathResult.h; sourceTree = "<group>"; };
+               1A7629820A0740A000989F5B /* XPathResult.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = XPathResult.idl; sourceTree = "<group>"; };
+               1A7629D30A07425100989F5B /* XPathGrammar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = XPathGrammar.cpp; sourceTree = "<group>"; };
+               1A7629D40A07425100989F5B /* XPathGrammar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = XPathGrammar.h; sourceTree = "<group>"; };
+               1A762C6B0A074F2600989F5B /* JSXPathEvaluator.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSXPathEvaluator.cpp; sourceTree = "<group>"; };
+               1A762C6C0A074F2600989F5B /* JSXPathEvaluator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSXPathEvaluator.h; sourceTree = "<group>"; };
+               1A762C6D0A074F2600989F5B /* JSXPathExpression.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSXPathExpression.cpp; sourceTree = "<group>"; };
+               1A762C6E0A074F2600989F5B /* JSXPathExpression.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSXPathExpression.h; sourceTree = "<group>"; };
+               1A762C6F0A074F2600989F5B /* JSXPathNSResolver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSXPathNSResolver.cpp; sourceTree = "<group>"; };
+               1A762C700A074F2600989F5B /* JSXPathNSResolver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSXPathNSResolver.h; sourceTree = "<group>"; };
+               1A762C710A074F2600989F5B /* JSXPathResult.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSXPathResult.cpp; sourceTree = "<group>"; };
+               1A762C720A074F2600989F5B /* JSXPathResult.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSXPathResult.h; sourceTree = "<group>"; };
                2D90660B0665D937006B6F1A /* ClipboardMac.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = ClipboardMac.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                2D90660C0665D937006B6F1A /* ClipboardMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ClipboardMac.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                4758C44308C5F217009BAF05 /* KCanvasPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KCanvasPath.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                                F523D2F302DE443B018635CA /* rendering */,
                                A8C0F6DC089701F100BA5114 /* WebCore+SVG */,
                                E1F0424309839389006694EA /* xml */,
+                               1A7629570A0740A000989F5B /* xpath */,
                                656580EC09D12B20000E61D7 /* Derived Sources */,
                                089C1665FE841158C02AAC07 /* Resources */,
                                0867D69AFE84028FC02AAC07 /* Frameworks */,
                        path = Resources;
                        sourceTree = "<group>";
                };
+               1A7629570A0740A000989F5B /* xpath */ = {
+                       isa = PBXGroup;
+                       children = (
+                               1A7629580A0740A000989F5B /* impl */,
+                               1A7629750A0740A000989F5B /* XPathEvaluator.cpp */,
+                               1A7629760A0740A000989F5B /* XPathEvaluator.h */,
+                               1A7629770A0740A000989F5B /* XPathEvaluator.idl */,
+                               1A7629780A0740A000989F5B /* XPathExpression.cpp */,
+                               1A7629790A0740A000989F5B /* XPathExpression.h */,
+                               1A76297A0A0740A000989F5B /* XPathExpression.idl */,
+                               1A76297B0A0740A000989F5B /* XPathNamespace.cpp */,
+                               1A76297C0A0740A000989F5B /* XPathNamespace.h */,
+                               1A76297D0A0740A000989F5B /* XPathNSResolver.cpp */,
+                               1A76297E0A0740A000989F5B /* XPathNSResolver.h */,
+                               1A76297F0A0740A000989F5B /* XPathNSResolver.idl */,
+                               1A7629800A0740A000989F5B /* XPathResult.cpp */,
+                               1A7629810A0740A000989F5B /* XPathResult.h */,
+                               1A7629820A0740A000989F5B /* XPathResult.idl */,
+                       );
+                       path = xpath;
+                       sourceTree = "<group>";
+               };
+               1A7629580A0740A000989F5B /* impl */ = {
+                       isa = PBXGroup;
+                       children = (
+                               1A7629590A0740A000989F5B /* XPathExpressionNode.cpp */,
+                               1A76295A0A0740A000989F5B /* XPathExpressionNode.h */,
+                               1A7629610A0740A000989F5B /* XPathFunctions.cpp */,
+                               1A7629620A0740A000989F5B /* XPathFunctions.h */,
+                               1A7629720A0740A000989F5B /* XPathGrammar.y */,
+                               1A5D938C0A0B9ACC00B1121F /* XPathParser.cpp */,
+                               1A5D938D0A0B9ACC00B1121F /* XPathParser.h */,
+                               1A7629650A0740A000989F5B /* XPathPath.cpp */,
+                               1A7629660A0740A000989F5B /* XPathPath.h */,
+                               1A7629670A0740A000989F5B /* XPathPredicate.cpp */,
+                               1A7629680A0740A000989F5B /* XPathPredicate.h */,
+                               1A7629690A0740A000989F5B /* XPathStep.cpp */,
+                               1A76296A0A0740A000989F5B /* XPathStep.h */,
+                               1A76296E0A0740A000989F5B /* XPathUtil.cpp */,
+                               1A76296F0A0740A000989F5B /* XPathUtil.h */,
+                               1A6931750A0CD4FA00C127FE /* XPathValue.cpp */,
+                               1A6931740A0CD4FA00C127FE /* XPathValue.h */,
+                               1A7629700A0740A000989F5B /* XPathVariableReference.cpp */,
+                               1A7629710A0740A000989F5B /* XPathVariableReference.h */,
+                       );
+                       path = impl;
+                       sourceTree = "<group>";
+               };
                55998A57052B598F0017A6C1 /* Accessibility */ = {
                        isa = PBXGroup;
                        children = (
                                65DF31F009D1CC60000BE325 /* JSText.h */,
                                A86629CA09DA2B47009633A5 /* JSUIEvent.cpp */,
                                A86629C909DA2B47009633A5 /* JSUIEvent.h */,
+                               1A762C6B0A074F2600989F5B /* JSXPathEvaluator.cpp */,
+                               1A762C6C0A074F2600989F5B /* JSXPathEvaluator.h */,
+                               1A762C6D0A074F2600989F5B /* JSXPathExpression.cpp */,
+                               1A762C6E0A074F2600989F5B /* JSXPathExpression.h */,
+                               1A762C6F0A074F2600989F5B /* JSXPathNSResolver.cpp */,
+                               1A762C700A074F2600989F5B /* JSXPathNSResolver.h */,
+                               1A762C710A074F2600989F5B /* JSXPathResult.cpp */,
+                               1A762C720A074F2600989F5B /* JSXPathResult.h */,
                                65DF31F109D1CC60000BE325 /* JSWheelEvent.cpp */,
                                65DF31F209D1CC60000BE325 /* JSWheelEvent.h */,
                                656581D709D1508D000E61D7 /* JSXMLHttpRequest.lut.h */,
                                656581AF09D14EE6000E61D7 /* UserAgentStyleSheetsData.cpp */,
                                656581EA09D1508D000E61D7 /* XLinkNames.cpp */,
                                656581EB09D1508D000E61D7 /* XLinkNames.h */,
+                               1A7629D30A07425100989F5B /* XPathGrammar.cpp */,
+                               1A7629D40A07425100989F5B /* XPathGrammar.h */,
                                142011B50A003133008303F9 /* JSCSSStyleDeclaration.h */,
                        );
                        name = "Derived Sources";
                                14DC0D3809FED073007B0235 /* JSNode.h in Headers */,
                                14D0C82509FF0EF5006B36D9 /* kjs_domnode.h in Headers */,
                                142011B70A003133008303F9 /* JSCSSStyleDeclaration.h in Headers */,
+                               1A7629840A0740A000989F5B /* XPathExpressionNode.h in Headers */,
+                               1A76298B0A0740A000989F5B /* XPathFunctions.h in Headers */,
+                               1A76298F0A0740A000989F5B /* XPathPath.h in Headers */,
+                               1A7629910A0740A000989F5B /* XPathPredicate.h in Headers */,
+                               1A7629930A0740A000989F5B /* XPathStep.h in Headers */,
+                               1A7629980A0740A000989F5B /* XPathUtil.h in Headers */,
+                               1A76299A0A0740A000989F5B /* XPathVariableReference.h in Headers */,
+                               1A76299E0A0740A000989F5B /* XPathEvaluator.h in Headers */,
+                               1A7629A10A0740A000989F5B /* XPathExpression.h in Headers */,
+                               1A7629A40A0740A000989F5B /* XPathNamespace.h in Headers */,
+                               1A7629A60A0740A000989F5B /* XPathNSResolver.h in Headers */,
+                               1A7629A90A0740A000989F5B /* XPathResult.h in Headers */,
+                               1A7629D60A07425100989F5B /* XPathGrammar.h in Headers */,
+                               1A762C740A074F2600989F5B /* JSXPathEvaluator.h in Headers */,
+                               1A762C760A074F2600989F5B /* JSXPathExpression.h in Headers */,
+                               1A762C780A074F2600989F5B /* JSXPathNSResolver.h in Headers */,
+                               1A762C7A0A074F2600989F5B /* JSXPathResult.h in Headers */,
+                               1A5D938F0A0B9ACC00B1121F /* XPathParser.h in Headers */,
+                               1A6931760A0CD4FA00C127FE /* XPathValue.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                BCFE8E320A02A1D30009E61D /* WebCoreTextRenderer.mm in Sources */,
                                14DC0D3709FED073007B0235 /* JSNode.cpp in Sources */,
                                142011B60A003133008303F9 /* JSCSSStyleDeclaration.cpp in Sources */,
+                               1A7629830A0740A000989F5B /* XPathExpressionNode.cpp in Sources */,
+                               1A76298A0A0740A000989F5B /* XPathFunctions.cpp in Sources */,
+                               1A5D938E0A0B9ACC00B1121F /* XPathParser.cpp in Sources */,
+                               1A76298E0A0740A000989F5B /* XPathPath.cpp in Sources */,
+                               1A7629900A0740A000989F5B /* XPathPredicate.cpp in Sources */,
+                               1A7629920A0740A000989F5B /* XPathStep.cpp in Sources */,
+                               1A7629970A0740A000989F5B /* XPathUtil.cpp in Sources */,
+                               1A7629990A0740A000989F5B /* XPathVariableReference.cpp in Sources */,
+                               1A76299D0A0740A000989F5B /* XPathEvaluator.cpp in Sources */,
+                               1A7629A00A0740A000989F5B /* XPathExpression.cpp in Sources */,
+                               1A7629A30A0740A000989F5B /* XPathNamespace.cpp in Sources */,
+                               1A7629A50A0740A000989F5B /* XPathNSResolver.cpp in Sources */,
+                               1A7629A80A0740A000989F5B /* XPathResult.cpp in Sources */,
+                               1A7629D50A07425100989F5B /* XPathGrammar.cpp in Sources */,
+                               1A762C730A074F2600989F5B /* JSXPathEvaluator.cpp in Sources */,
+                               1A762C750A074F2600989F5B /* JSXPathExpression.cpp in Sources */,
+                               1A762C770A074F2600989F5B /* JSXPathNSResolver.cpp in Sources */,
+                               1A762C790A074F2600989F5B /* JSXPathResult.cpp in Sources */,
                                936BDD1D0A031AEB004DF4AB /* GraphicsContextCG.cpp in Sources */,
                                BCCD13200A0C0030001AFA8B /* FontData.mm in Sources */,
+                               1A6931770A0CD4FA00C127FE /* XPathValue.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "$(DEBUG_DEFINES)",
                                        SVG_SUPPORT,
+                                       XPATH_SUPPORT,
                                );
                                HEADER_SEARCH_PATHS = (
                                        ForwardingHeaders,
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "$(DEBUG_DEFINES)",
                                        SVG_SUPPORT,
+                                       XPATH_SUPPORT,
                                );
                                HEADER_SEARCH_PATHS = (
                                        ForwardingHeaders,
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "$(DEBUG_DEFINES)",
                                        SVG_SUPPORT,
+                                       XPATH_SUPPORT,
                                );
                                HEADER_SEARCH_PATHS = (
                                        ForwardingHeaders,
index 3e9f425..d641d4d 100644 (file)
@@ -31,6 +31,7 @@
 #include "PlatformString.h"
 #include "Range.h"
 #include "dom2_eventsimpl.h"
+#include "XPathEvaluator.h"
 #include "kjs_dom.h"
 #include "kjs_window.h"
 #include <kjs/collector.h>
@@ -298,6 +299,11 @@ static const char * const eventExceptionNames[] = {
     "UNSPECIFIED_EVENT_TYPE_ERR"
 };
 
+static const char * const xpathExceptionNames[] = {
+    "INVALID_EXPRESSION_ERR",
+    "TYPE_ERR"
+};
+
 void setDOMException(ExecState* exec, ExceptionCode ec)
 {
   if (ec == 0 || exec->hadException())
@@ -307,23 +313,35 @@ void setDOMException(ExecState* exec, ExceptionCode ec)
   int code = ec;
 
   const char * const * nameTable;
+  
   int nameTableSize;
+  int nameIndex;
   if (code >= RangeExceptionOffset && code <= RangeExceptionMax) {
     type = "DOM Range";
     code -= RangeExceptionOffset;
+    nameIndex = code;
     nameTable = rangeExceptionNames;
     nameTableSize = sizeof(rangeExceptionNames) / sizeof(rangeExceptionNames[0]);
   } else if (code >= EventExceptionOffset && code <= EventExceptionMax) {
     type = "DOM Events";
     code -= EventExceptionOffset;
+    nameIndex = code;
     nameTable = eventExceptionNames;
     nameTableSize = sizeof(eventExceptionNames) / sizeof(eventExceptionNames[0]);
+  } else if (code >= XPathExceptionOffset && code <= XPathExceptionMax) {
+    type = "DOM XPath";
+    // XPath exception codes start with 51 and we don't want 51 empty elements in the name array
+    nameIndex = code - INVALID_EXPRESSION_ERR;
+    code -= XPathExceptionOffset;
+    nameTable = xpathExceptionNames;
+    nameTableSize = sizeof(xpathExceptionNames) / sizeof(xpathExceptionNames[0]);
   } else {
+    nameIndex = code;
     nameTable = exceptionNames;
     nameTableSize = sizeof(exceptionNames) / sizeof(exceptionNames[0]);
   }
 
-  const char* name = code < nameTableSize ? nameTable[code] : 0;
+  const char* name = nameIndex < nameTableSize ? nameTable[nameIndex] : 0;
 
   // 100 characters is a big enough buffer, because there are:
   //   13 characters in the message
index 0434abd..7e64d3b 100644 (file)
@@ -639,6 +639,10 @@ static ListenerMap *listenerMap;
         case Node::NOTATION_NODE:
             wrapperClass = [DOMNotation class];
             break;
+        case Node::XPATH_NAMESPACE_NODE:
+            // FIXME: Create an XPath objective C wrapper
+            // See http://bugzilla.opendarwin.org/show_bug.cgi?id=8755
+            return nil;
     }
     return [[[wrapperClass alloc] _initWithNode:impl] autorelease];
 }
index 534ecd3..3b02ceb 100644 (file)
@@ -162,7 +162,11 @@ sub AddIncludesForType
       $type eq "Node" or
       $type eq "NodeList" or 
       $type eq "Range" or 
-      $type eq "Text") {
+      $type eq "Text" or
+      $type eq "XPathEvaluator" or
+      $type eq "XPathExpression" or
+      $type eq "XPathNSResolver" or
+      $type eq "XPathResult") {
     $implIncludes{"${type}.h"} = 1;
   } elsif ($type eq "CSSStyleSheet" or $type eq "StyleSheet") {
     $implIncludes{"css_stylesheetimpl.h"} = 1;
@@ -501,7 +505,7 @@ sub GenerateImplementation
       $protoClassName = "${parentClassName}Proto";
     }
 
-    push(@implContent, constructorFor($className, $protoClassName, $interfaceName));
+    push(@implContent, constructorFor($className, $protoClassName, $interfaceName, $dataNode->extendedAttributes->{"CanBeConstructed"}));
   }
   
   # - Add functions and constants to a hashtable definition
@@ -824,7 +828,9 @@ sub GetNativeType
            $type eq "Element" or
            $type eq "Attr" or
            $type eq "DocumentType" or
-           $type eq "Range") {
+           $type eq "Range" or
+           $type eq "XPathNSResolver" or
+           $type eq "XPathResult") {
     return "${type}*";
   } elsif ($type eq "NodeFilter") {
       return "PassRefPtr<${type}>";
@@ -855,26 +861,21 @@ sub TypeCanFailConversion
     return 0; # or can it?
   } elsif ($type eq "float") {
     return 0;
-  } elsif ($type eq "AtomicString") {
-      return 0;
-  } elsif ($type eq "DOMString") {
-      return 0;
-  } elsif ($type eq "Node") {
-      return 0;
-  } elsif ($type eq "Element") {
-      return 0;
   } elsif ($type eq "Attr") {
       $implIncludes{"ExceptionCode.h"} = 1;
       return 1;
-  } elsif ($type eq "DocumentType") {
-      return 0;
-  } elsif ($type eq "EventTarget") {
-      return 0;
-  }  elsif ($type eq "Range") {
-      return 0;
-  }  elsif ($type eq "NodeFilter") {
-      return 0;
-  } elsif ($type eq "DOMWindow") {
+  } elsif ($type eq "AtomicString" or
+           $type eq "DOMString" or
+           $type eq "Node" or
+           $type eq "Element" or
+           $type eq "DocumentType" or
+           $type eq "EventTarget" or
+           $type eq "Range" or
+           $type eq "NodeFilter" or
+           $type eq "DOMWindow" or
+           $type eq "XPathEvaluator" or
+           $type eq "XPathNSResolver" or
+           $type eq "XPathResult") {
       return 0;
   } else {
     die "Don't know whether a JS value can fail conversion to type $type."
@@ -925,9 +926,6 @@ sub JSValueToNative
   } elsif ($type eq "DocumentType") {
       $implIncludes{"kjs_dom.h"} = 1;
       return "toDocumentType($value)";
-  } elsif ($type eq "Range") {
-      $implIncludes{"JSRange.h"} = 1;
-      return "toRange($value)";
   } elsif ($type eq "Element") {
     $implIncludes{"kjs_dom.h"} = 1;
     return "toElement($value)";
@@ -936,7 +934,12 @@ sub JSValueToNative
     return "toNodeFilter($value)";
   } elsif ($type eq "DOMWindow") {
     $implIncludes{"kjs_window.h"} = 1;
-    return "toDOMWindow($value)";
+    return "toDOMWindow($value)"; 
+  } elsif ($type eq "Range" or
+           $type eq "XPathNSResolver" or
+           $type eq "XPathResult") {
+    $implIncludes{"JS$type.h"} = 1;
+    return "to$type($value)";
   } else {
     die "Don't know how to convert a JS value of type $type."
   }
@@ -955,7 +958,8 @@ sub NativeToJSValue
            $type eq "unsigned long" or 
            $type eq "short" or 
            $type eq "unsigned short" or
-           $type eq "float") {
+           $type eq "float" or 
+           $type eq "double") {
     return "jsNumber($value)";
   } elsif ($type eq "DOMString") {
     my $conv = $signature->extendedAttributes->{"ConvertNullStringTo"};
@@ -1029,7 +1033,12 @@ sub NativeToJSValue
     $implIncludes{"kjs_dom.h"} = 1;
     $implIncludes{"HTMLCanvasElement.h"} = 1;
     return "toJS(exec, $value)";
-  } elsif ($type eq "CanvasGradient" or $type eq "Counter" or $type eq "Range") {
+  } elsif ($type eq "CanvasGradient" or 
+           $type eq "Counter" or 
+           $type eq "Range" or
+           $type eq "XPathExpression" or
+           $type eq "XPathNSResolver" or
+           $type eq "XPathResult") {
     $implIncludes{"JS$type.h"} = 1;
     return "toJS(exec, $value)";
   } elsif ($type eq "NodeIterator" or
@@ -1042,6 +1051,8 @@ sub NativeToJSValue
   } elsif ($type eq "DOMObject") {
     $implIncludes{"JSCanvasRenderingContext2DBase.h"} = 1;
     return "toJS(exec, $value)";
+    $implIncludes{"JS$type.h"} = 1;
+    return "toJS(exec, $value)";
   } else {
     die "Don't know how to convert a value of type $type to a JS Value";
   }
@@ -1249,6 +1260,7 @@ sub constructorFor
     my $className = shift;
     my $protoClassName = shift;
     my $interfaceName = shift;
+    my $canConstruct = shift;
     
 my $implContent = << "EOF";
 class ${className}Constructor : public DOMObject {
@@ -1261,7 +1273,17 @@ public:
     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
     JSValue* getValueProperty(ExecState*, int token) const;
     virtual const ClassInfo* classInfo() const { return &info; }
-    static const ClassInfo info;    
+    static const ClassInfo info;
+EOF
+
+    if ($canConstruct) {
+$implContent .= << "EOF";
+    virtual bool implementsConstruct() const { return true; }
+    virtual JSObject* construct(ExecState* exec, const List &args) { return static_cast<JSObject *>(toJS(exec, new $interfaceName)); }
+EOF
+    }
+
+$implContent .= << "EOF";
 };
 
 const ClassInfo ${className}Constructor::info = { "${interfaceName}Constructor", 0, &${className}ConstructorTable, 0 };
index 2b26a35..0c2c75f 100644 (file)
@@ -62,6 +62,7 @@ static void initializeLoggingChannelsIfNecessary()
     initializeLogChannel(LogEvents);
     initializeLogChannel(LogEditing);
     initializeLogChannel(LogTextConversion);
+    initializeLogChannel(LogXPath);
 }
 
 - (id)init
index 6597db5..0aebf0d 100644 (file)
@@ -61,6 +61,9 @@ bool DOMImplementation::hasFeature (const String& feature, const String& version
             || lower == "uievents"
             || lower == "views")
         return version.isEmpty() || version == "2.0";
+    if (lower == "xpath")
+        return version.isEmpty() || version == "3.0";
+    
     return false;
 }
 
index 1e90c16..80b955a 100644 (file)
 #include "render_frames.h"
 #include "xml_tokenizer.h"
 #include "xmlhttprequest.h"
+#include "XPathEvaluator.h"
+#include "XPathExpression.h"
+#include "XPathNSResolver.h"
+#include "XPathResult.h"
 
 #ifdef KHTML_XSLT
 #include "XSLTProcessor.h"
@@ -496,6 +500,7 @@ PassRefPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionCo
         case DOCUMENT_TYPE_NODE:
         case DOCUMENT_FRAGMENT_NODE:
         case NOTATION_NODE:
+        case XPATH_NAMESPACE_NODE:
             break;
     }
 
@@ -516,6 +521,7 @@ PassRefPtr<Node> Document::adoptNode(PassRefPtr<Node> source, ExceptionCode& ec)
         case NOTATION_NODE:
         case DOCUMENT_NODE:
         case DOCUMENT_TYPE_NODE:
+        case XPATH_NAMESPACE_NODE:
             ec = NOT_SUPPORTED_ERR;
             return 0;            
         case ATTRIBUTE_NODE: {                   
@@ -3091,6 +3097,40 @@ Vector<String> Document::formElementsState() const
     return stateVector;
 }
 
+#if XPATH_SUPPORT
+PassRefPtr<XPathExpression> Document::createExpression(const String& expression,
+                                                       XPathNSResolver* resolver,
+                                                       ExceptionCode& ec)
+{
+    if (!m_xpathEvaluator)
+        m_xpathEvaluator = new XPathEvaluator;
+    
+    return m_xpathEvaluator->createExpression(expression, resolver, ec);
+}
+
+PassRefPtr<XPathNSResolver> Document::createNSResolver(Node *nodeResolver)
+{
+    if (!m_xpathEvaluator)
+        m_xpathEvaluator = new XPathEvaluator;
+    
+    return m_xpathEvaluator->createNSResolver(nodeResolver);
+}
+
+PassRefPtr<XPathResult> Document::evaluate(const String& expression,
+                                           Node* contextNode,
+                                           XPathNSResolver* resolver,
+                                           unsigned short type,
+                                           XPathResult* result,
+                                           ExceptionCode& ec)
+{
+    if (!m_xpathEvaluator)
+        m_xpathEvaluator = new XPathEvaluator;
+    
+    return m_xpathEvaluator->evaluate(expression, contextNode, resolver, type, result, ec);
+}
+
+#endif // XPATH_SUPPORT
+
 void Document::setStateForNewFormElements(const Vector<String>& stateVector)
 {
     // Walk the state vector backwards so that the value to use for each
index 18578f6..9faa16a 100644 (file)
@@ -90,7 +90,13 @@ namespace WebCore {
     class Text;
     class Tokenizer;
     class TreeWalker;
-
+#if XPATH_SUPPORT
+    class XPathEvaluator;
+    class XPathExpression;
+    class XPathNSResolver;
+    class XPathResult;
+#endif
+    
 #if __APPLE__
     struct DashboardRegionValue;
 #endif
@@ -557,6 +563,20 @@ public:
 
     void finishedParsing();
 
+#if XPATH_SUPPORT
+    // XPathEvaluator methods
+    PassRefPtr<XPathExpression> createExpression(const String& expression,
+                                                 XPathNSResolver* resolver,
+                                                 ExceptionCode& ec);
+    PassRefPtr<XPathNSResolver> createNSResolver(Node *nodeResolver);
+    PassRefPtr<XPathResult> evaluate(const String& expression,
+                                     Node* contextNode,
+                                     XPathNSResolver* resolver,
+                                     unsigned short type,
+                                     XPathResult* result,
+                                     ExceptionCode& ec);
+#endif // XPATH_SUPPORT
+    
 protected:
     CSSStyleSelector* m_styleSelector;
     FrameView* m_view;
@@ -742,6 +762,10 @@ private:
     typedef HashMap<HTMLFormElement*, NameToInputMap*> FormToGroupMap;
     FormToGroupMap m_selectedRadioButtons;
     
+#if XPATH_SUPPORT
+    RefPtr<XPathEvaluator> m_xpathEvaluator;
+#endif
+    
 #if SVG_SUPPORT
     SVGDocumentExtensions* m_svgExtensions;
 #endif
index fe5075e..a58fb10 100644 (file)
@@ -114,6 +114,22 @@ module core {
         Node adoptNode(in Node source)
             raises (DOMException);
 
+#if XPATH_SUPPORT
+        // DOM Level 3 XPath (XPathEvaluator interface)
+        XPathExpression createExpression(in DOMString expression,
+                                         in XPathNSResolver resolver)
+            raises(DOMException);
+
+        XPathNSResolver createNSResolver(in Node nodeResolver);
+        
+        XPathResult evaluate(in DOMString expression,
+                             in Node contextNode, 
+                             in XPathNSResolver resolver,
+                             in unsigned short type,
+                             in XPathResult inResult)
+            raises(DOMException);
+
+#endif
         // Common extensions
 
         boolean execCommand(in DOMString command, 
index 81b33ab..e01b4a9 100644 (file)
@@ -73,7 +73,8 @@ public:
         DOCUMENT_NODE = 9,
         DOCUMENT_TYPE_NODE = 10,
         DOCUMENT_FRAGMENT_NODE = 11,
-        NOTATION_NODE = 12
+        NOTATION_NODE = 12,
+        XPATH_NAMESPACE_NODE = 13
     };
 
     Node(Document*);
index ab01852..9542e03 100644 (file)
@@ -240,6 +240,7 @@ static DeprecatedString startMarkup(const Node *node, const Range *range, EAnnot
         case Node::ENTITY_NODE:
         case Node::ENTITY_REFERENCE_NODE:
         case Node::NOTATION_NODE:
+        case Node::XPATH_NAMESPACE_NODE:
             break;
     }
     return "";
index ead6b53..61bcfd9 100644 (file)
@@ -52,6 +52,8 @@ module window {
         attribute NodeConstructor Node;
         attribute NodeFilterConstructor NodeFilter;
         attribute RangeConstructor Range;
+        attribute XPathEvaluatorConstructor XPathEvaluator;
+        attribute XPathResultConstructor XPathResult;
     };
 
 }
index bac78ff..9ec09a2 100644 (file)
@@ -36,3 +36,4 @@ KXCLogChannel LogPopupBlocking =     { 0x00000040, "WebCoreLogLevel", KXCLogChan
 KXCLogChannel LogEvents =            { 0x00000080, "WebCoreLogLevel", KXCLogChannelOff };
 KXCLogChannel LogEditing =           { 0x00000100, "WebCoreLogLevel", KXCLogChannelOff };
 KXCLogChannel LogTextConversion =    { 0x00000200, "WebCoreLogLevel", KXCLogChannelOff };
+KXCLogChannel LogXPath =             { 0x00000400, "WebCoreLogLevel", KXCLogChannelOff };
index dc00c02..50b9d8a 100644 (file)
@@ -40,5 +40,6 @@ extern KXCLogChannel LogPopupBlocking;
 extern KXCLogChannel LogEvents;
 extern KXCLogChannel LogEditing;
 extern KXCLogChannel LogTextConversion;
+extern KXCLogChannel LogXPath;
 
 #endif
diff --git a/WebCore/xpath/XPathEvaluator.cpp b/WebCore/xpath/XPathEvaluator.cpp
new file mode 100644 (file)
index 0000000..2f5e516
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+
+#if XPATH_SUPPORT
+
+#include "XPathEvaluator.h"
+#include "XPathExpression.h"
+#include "XPathNSResolver.h"
+#include "XPathResult.h"
+
+#include "ExceptionCode.h"
+
+#include "XPathUtil.h"
+
+namespace WebCore {
+
+using namespace XPath;
+    
+PassRefPtr<XPathExpression> XPathEvaluator::createExpression(const String& expression,
+                                                             XPathNSResolver* resolver,
+                                                             ExceptionCode& ec)
+{
+    return XPathExpression::createExpression(expression, resolver, ec);
+}
+
+PassRefPtr<XPathNSResolver> XPathEvaluator::createNSResolver(Node* nodeResolver)
+{
+    return new XPathNSResolver(nodeResolver);
+}
+
+PassRefPtr<XPathResult> XPathEvaluator::evaluate(const String& expression,
+                                                 Node* contextNode,
+                                                 XPathNSResolver* resolver,
+                                                 unsigned short type,
+                                                 XPathResult* result,
+                                                 ExceptionCode& ec)
+{
+    if (!isValidContextNode(contextNode)) {
+        ec = NOT_SUPPORTED_ERR;
+        return 0;
+    }
+
+    RefPtr<XPathExpression> expr = createExpression(expression, resolver, ec);
+    if (ec)
+        return 0;
+    
+    return expr->evaluate(contextNode, type, result, ec);
+}
+
+}
+
+#endif // XPATH_SUPPORT
diff --git a/WebCore/xpath/XPathEvaluator.h b/WebCore/xpath/XPathEvaluator.h
new file mode 100644 (file)
index 0000000..43129ac
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef XPathEvaluator_H
+#define XPathEvaluator_H
+
+#if XPATH_SUPPORT
+
+#include "Shared.h"
+
+#include "PlatformString.h"
+#include "ExceptionCode.h"
+
+namespace WebCore
+{
+class Node;
+
+class XPathExpression;
+class XPathNSResolver;
+class XPathResult;
+
+const int XPathExceptionOffset = 400;
+const int XPathExceptionMax = 499;   
+
+enum XPathExceptionCode { INVALID_EXPRESSION_ERR = XPathExceptionOffset + 51, TYPE_ERR };
+
+class XPathEvaluator : public Shared<XPathEvaluator>
+{
+public:
+    PassRefPtr<XPathExpression> createExpression(const String& expression,
+                                                  XPathNSResolver*,
+                                                  ExceptionCode&);
+    PassRefPtr<XPathNSResolver> createNSResolver(Node* nodeResolver);
+    PassRefPtr<XPathResult> evaluate(const String& expression,
+                                     Node* contextNode,
+                                     XPathNSResolver*,
+                                     unsigned short type,
+                                     XPathResult*,
+                                     ExceptionCode&);
+};
+
+}
+
+#endif // XPATH_SUPPORT
+
+#endif // XPathEvaluator_H
+
diff --git a/WebCore/xpath/XPathEvaluator.idl b/WebCore/xpath/XPathEvaluator.idl
new file mode 100644 (file)
index 0000000..56ccae6
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+module xpath {
+
+    interface [GenerateConstructor, CanBeConstructed] XPathEvaluator {
+        XPathExpression createExpression(in DOMString expression,
+                                         in XPathNSResolver resolver)
+            raises(core::DOMException);
+
+        XPathNSResolver createNSResolver(in Node nodeResolver);
+
+        XPathResult evaluate(in DOMString expression,
+                             in Node contextNode, 
+                             in XPathNSResolver resolver,
+                             in unsigned short type,
+                             in XPathResult inResult)
+            raises(DOMException);
+    };
+}
diff --git a/WebCore/xpath/XPathExpression.cpp b/WebCore/xpath/XPathExpression.cpp
new file mode 100644 (file)
index 0000000..93d21e5
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+
+#if XPATH_SUPPORT
+
+#include "XPathExpression.h"
+#include "PlatformString.h"
+#include "Document.h"
+#include "Node.h"
+#include "XPathNSResolver.h"
+#include "XPathParser.h"
+#include "XPathResult.h"
+#include "ExceptionCode.h"
+
+#include "XPathExpressionNode.h"
+
+namespace WebCore {
+
+using namespace XPath;
+    
+PassRefPtr<XPathExpression> XPathExpression::createExpression(const String& expression, XPathNSResolver* resolver, ExceptionCode& ec)
+{
+    RefPtr<XPathExpression> expr = new XPathExpression;
+    Parser parser;
+    
+    Expression::evaluationContext().resolver = resolver;
+    expr->m_topExpression = parser.parseStatement(expression, ec);
+    if (!expr->m_topExpression)
+        return 0;
+
+    return expr;
+}
+
+XPathExpression::~XPathExpression()
+{
+    delete m_topExpression;
+}
+
+PassRefPtr<XPathResult> XPathExpression::evaluate(Node* contextNode,
+                                                  unsigned short type,
+                                                  XPathResult*,
+                                                  ExceptionCode& ec)
+{
+    if (!isValidContextNode(contextNode)) {
+        ec = NOT_SUPPORTED_ERR;
+        return 0;
+    }
+    
+    Node* eventTarget = contextNode->ownerDocument() ? 
+        contextNode->ownerDocument() : contextNode;
+    
+    Expression::evaluationContext().node = contextNode;    
+    m_topExpression->optimize();
+    
+    RefPtr<XPathResult> result = new XPathResult(static_cast<EventTargetNode*>(eventTarget),
+                                                 m_topExpression->evaluate());
+    
+    if (type != XPathResult::ANY_TYPE) {
+        result->convertTo(type, ec);
+
+        if (ec)
+            return 0;
+    }
+
+    return result;
+}
+
+}
+
+#endif // XPATH_SUPPORT
diff --git a/WebCore/xpath/XPathExpression.h b/WebCore/xpath/XPathExpression.h
new file mode 100644 (file)
index 0000000..d7b223c
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef XPathExpression_H
+#define XPathExpression_H
+
+#if XPATH_SUPPORT
+
+#include "Shared.h"
+#include "PlatformString.h"
+
+#include "ExceptionCode.h"
+
+#include "XPathExpressionNode.h"
+
+namespace WebCore
+{
+class Node;
+
+class XPathNSResolver;
+class XPathResult;
+
+class XPathExpression : public Shared<XPathExpression>
+{
+public:
+    ~XPathExpression();
+
+    static PassRefPtr<XPathExpression> createExpression(const String& expression,
+                                                        XPathNSResolver*,
+                                                        ExceptionCode&);
+
+    PassRefPtr<XPathResult> evaluate(Node* contextNode,
+                                     unsigned short type,
+                                     XPathResult*,
+                                     ExceptionCode&);
+        
+private:
+    XPath::Expression* m_topExpression;
+};
+
+}
+
+#endif // XPATH_SUPPORT
+
+#endif // XPathExpression_H
+
diff --git a/WebCore/xpath/XPathExpression.idl b/WebCore/xpath/XPathExpression.idl
new file mode 100644 (file)
index 0000000..80052c4
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+module xpath {
+
+    interface XPathExpression {
+        XPathResult evaluate(in Node contextNode, 
+                             in unsigned short type, 
+                             in XPathResult inResult)
+            raises(DOMException);
+    };
+}
diff --git a/WebCore/xpath/XPathNSResolver.cpp b/WebCore/xpath/XPathNSResolver.cpp
new file mode 100644 (file)
index 0000000..3d1631b
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+
+#if XPATH_SUPPORT
+
+#include "XPathNSResolver.h"
+#include "Node.h"
+
+namespace WebCore {
+
+XPathNSResolver::XPathNSResolver(PassRefPtr<Node> node)
+    : m_node(node)
+{
+}
+
+String XPathNSResolver::lookupNamespaceURI(const String& prefix)
+{
+    // This is not done by Node::lookupNamespaceURI as per the DOM3 Core spec,
+    // but the XPath spec says that we should do it for XPathNSResolver.
+    if (prefix == "xml")
+        return "http://www.w3.org/XML/1998/namespace";
+    
+    return m_node ? m_node->lookupNamespaceURI(prefix) : String();
+}
+
+#endif // XPATH_SUPPORT
+
+}
+
diff --git a/WebCore/xpath/XPathNSResolver.h b/WebCore/xpath/XPathNSResolver.h
new file mode 100644 (file)
index 0000000..0c873ea
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef XPathNSResolver_H
+#define XPathNSResolver_H
+
+#if XPATH_SUPPORT
+
+#include "Shared.h"
+#include "PlatformString.h"
+#include "Node.h"
+
+namespace WebCore
+{
+
+class Node;
+
+class XPathNSResolver : public Shared<XPathNSResolver>
+{
+    public:
+        XPathNSResolver(PassRefPtr<Node>);
+
+        String lookupNamespaceURI(const String& prefix);
+
+    private:
+        RefPtr<Node> m_node;
+};
+
+}
+
+#endif // XPATH_SUPPORT
+
+#endif // XPathNSResolver_H
+
diff --git a/WebCore/xpath/XPathNSResolver.idl b/WebCore/xpath/XPathNSResolver.idl
new file mode 100644 (file)
index 0000000..084719d
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+module xpath {
+
+    interface XPathNSResolver {
+        DOMString lookupNamespaceURI(in DOMString prefix);
+    };
+}
diff --git a/WebCore/xpath/XPathNamespace.cpp b/WebCore/xpath/XPathNamespace.cpp
new file mode 100644 (file)
index 0000000..071c1fa
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+
+#if XPATH_SUPPORT
+
+#include "XPathNamespace.h"
+#include "Document.h"
+
+namespace WebCore {
+
+XPathNamespace::XPathNamespace(PassRefPtr<Element> ownerElement, const String& prefix, const String& uri)
+    : Node(ownerElement->document()),
+    m_ownerElement(ownerElement),
+    m_prefix(prefix),
+    m_uri(uri)
+{
+}
+
+XPathNamespace::~XPathNamespace()
+{
+}
+
+Document* XPathNamespace::ownerDocument() const
+{
+    return m_ownerElement->ownerDocument();
+}
+
+Element* XPathNamespace::ownerElement() const
+{
+    return m_ownerElement.get();
+}
+
+const AtomicString& XPathNamespace::prefix() const
+{
+    return m_prefix;
+}
+
+String XPathNamespace::nodeName() const
+{
+    return "#namespace";
+}
+
+String XPathNamespace::nodeValue() const
+{
+    return m_uri;
+}
+
+const AtomicString& XPathNamespace::namespaceURI() const
+{
+    return m_uri;
+}
+
+Node::NodeType XPathNamespace::nodeType() const
+{
+    return Node::XPATH_NAMESPACE_NODE;
+}
+
+#endif // XPATH_SUPPORT
+
+}
+
diff --git a/WebCore/xpath/XPathNamespace.h b/WebCore/xpath/XPathNamespace.h
new file mode 100644 (file)
index 0000000..1435763
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef XPathNamespace_H
+#define XPathNamespace_H
+
+#if XPATH_SUPPORT
+
+#include "Element.h"
+#include "AtomicString.h"
+
+namespace WebCore
+{
+
+class Document;
+
+class XPathNamespace : public Node
+{
+public:
+    XPathNamespace(PassRefPtr<Element> ownerElement,
+                   const String& prefix, const String& uri);
+    virtual ~XPathNamespace();
+
+    virtual Document* ownerDocument() const;
+    virtual Element* ownerElement() const;
+
+    virtual const AtomicString& prefix() const;
+    virtual String nodeName() const;
+    virtual String nodeValue() const;
+    virtual const AtomicString& namespaceURI() const;
+
+    virtual Node::NodeType nodeType() const;
+
+private:
+    RefPtr<Element> m_ownerElement;
+    AtomicString m_prefix;
+    AtomicString m_uri;
+};
+
+}
+
+#endif // XPATH_SUPPORT
+
+#endif // XPathNamespace_H
+
diff --git a/WebCore/xpath/XPathResult.cpp b/WebCore/xpath/XPathResult.cpp
new file mode 100644 (file)
index 0000000..3417874
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+
+#if XPATH_SUPPORT
+
+#include "XPathResult.h"
+#include "XPathEvaluator.h"
+
+#include "Document.h"
+#include "EventNames.h"
+#include "Node.h"
+#include "EventListener.h"
+#include "Logging.h"
+#include "ExceptionCode.h"
+
+namespace WebCore {
+
+using namespace XPath;
+
+class InvalidatingEventListener : public EventListener {
+public:
+    InvalidatingEventListener(EventTargetNode* node, XPathResult* result) 
+        : m_node(node), m_result(result) { }
+    
+    virtual void handleEvent(Event*, bool) { m_result->invalidateIteratorState(); }
+private:
+    EventTargetNode* m_node;
+    XPathResult* m_result;
+};
+
+XPathResult::XPathResult(EventTargetNode* eventTarget, const Value &value)
+    : m_value(value)
+    , m_eventTarget(eventTarget)
+{
+    m_eventListener = new InvalidatingEventListener(m_eventTarget.get(), this);
+    m_eventTarget->addEventListener(EventNames::DOMSubtreeModifiedEvent, m_eventListener, false);
+        
+    switch (m_value.type()) {
+        case Value::Boolean:
+            m_resultType = BOOLEAN_TYPE;
+            break;
+        case Value::Number:
+            m_resultType = NUMBER_TYPE;
+            break;
+        case Value::String_:
+            m_resultType = STRING_TYPE;
+            break;
+        case Value::NodeVector_:
+            m_resultType = UNORDERED_NODE_ITERATOR_TYPE;
+            m_nodeSetPosition = 0;
+            m_nodeSet = m_value.toNodeVector();
+            m_invalidIteratorState = false;
+    }
+}
+
+XPathResult::~XPathResult()
+{
+    if (m_eventTarget)
+        m_eventTarget->removeEventListener(EventNames::DOMSubtreeModifiedEvent, m_eventListener.get(), false);
+}
+
+void XPathResult::convertTo(unsigned short type, ExceptionCode& ec)
+{
+    switch (type) {
+        case ANY_TYPE:
+            break;
+        case NUMBER_TYPE:
+            m_resultType = type;
+            m_value = m_value.toNumber();
+            break;
+        case STRING_TYPE:
+            m_resultType = type;
+            m_value = m_value.toString();
+            break;
+        case BOOLEAN_TYPE:
+            m_resultType = type;
+            m_value = m_value.toBoolean();
+            break;
+        case UNORDERED_NODE_ITERATOR_TYPE:
+        case ORDERED_NODE_ITERATOR_TYPE:
+        case UNORDERED_NODE_SNAPSHOT_TYPE:
+        case ORDERED_NODE_SNAPSHOT_TYPE:
+        case ANY_UNORDERED_NODE_TYPE:
+        case FIRST_ORDERED_NODE_TYPE:
+            if (!m_value.isNodeVector()) {
+                ec = TYPE_ERR;
+                return;
+            }
+            m_resultType = type;
+        default:
+            LOG(XPath, "Cannot convert XPathResult to unknown type '%u'!", type);
+    }
+}
+
+unsigned short XPathResult::resultType() const
+{
+    return m_resultType;
+}
+
+double XPathResult::numberValue(ExceptionCode& ec) const
+{
+    if (resultType() != NUMBER_TYPE) {
+        ec = TYPE_ERR;
+        return 0.0;
+    }
+    return m_value.toNumber();
+}
+
+String XPathResult::stringValue(ExceptionCode& ec) const
+{
+    if (resultType() != STRING_TYPE) {
+        ec = TYPE_ERR;
+        return String();
+    }
+    return m_value.toString();
+}
+
+bool XPathResult::booleanValue(ExceptionCode& ec) const
+{
+    if (resultType() != BOOLEAN_TYPE) {
+        ec = TYPE_ERR;
+        return false;
+    }
+    return m_value.toBoolean();
+}
+
+Node* XPathResult::singleNodeValue(ExceptionCode& ec) const
+{
+    if (resultType() != ANY_UNORDERED_NODE_TYPE &&
+         resultType() != FIRST_ORDERED_NODE_TYPE) {
+        ec = TYPE_ERR;
+        return 0;
+    }
+  
+    NodeVector nodes = m_value.toNodeVector();
+    if (nodes.size () == 0)
+        return 0;
+
+    return nodes[0].get();
+}
+
+void XPathResult::invalidateIteratorState()
+{ 
+    m_invalidIteratorState = true;
+    
+    ASSERT(m_eventTarget);
+    ASSERT(m_eventListener);
+    
+    m_eventTarget->removeEventListener(EventNames::DOMSubtreeModifiedEvent, m_eventListener.get(), false);
+    
+    m_eventTarget = 0;
+}
+
+bool XPathResult::invalidIteratorState() const
+{
+    if (resultType() != UNORDERED_NODE_ITERATOR_TYPE &&
+        resultType() != ORDERED_NODE_ITERATOR_TYPE)
+        return false;
+    
+    return m_invalidIteratorState;
+}
+
+unsigned long XPathResult::snapshotLength(ExceptionCode& ec) const
+{
+    if (resultType() != UNORDERED_NODE_SNAPSHOT_TYPE &&
+        resultType() != ORDERED_NODE_SNAPSHOT_TYPE) {
+        ec = TYPE_ERR;
+        return 0;
+    }
+
+    return m_value.toNodeVector().size();
+}
+
+Node* XPathResult::iterateNext(ExceptionCode& ec)
+{
+    if (resultType() != UNORDERED_NODE_ITERATOR_TYPE &&
+        resultType() != ORDERED_NODE_ITERATOR_TYPE) {
+        ec = TYPE_ERR;
+        return 0;
+    }
+    
+    if (m_invalidIteratorState) {
+        ec = INVALID_STATE_ERR;
+        return 0;
+    }
+    
+    if (m_nodeSetPosition + 1 >= m_nodeSet.size())
+        return 0;
+
+    Node* node = m_nodeSet[m_nodeSetPosition].get();
+    
+    m_nodeSetPosition++;
+
+    return node;
+}
+
+Node* XPathResult::snapshotItem(unsigned long index, ExceptionCode& ec)
+{
+    if (resultType() != UNORDERED_NODE_SNAPSHOT_TYPE &&
+         resultType() != ORDERED_NODE_SNAPSHOT_TYPE) {
+        ec = TYPE_ERR;
+        return 0;
+    }
+    
+    NodeVector nodes = m_value.toNodeVector();
+    if (index >= nodes.size())
+        return 0;
+    
+    return nodes[index].get();
+}
+
+}
+
+#endif // XPATH_SUPPORT
diff --git a/WebCore/xpath/XPathResult.h b/WebCore/xpath/XPathResult.h
new file mode 100644 (file)
index 0000000..88013f2
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef XPathResult_H
+#define XPathResult_H
+
+#if XPATH_SUPPORT
+
+#include "Shared.h"
+
+#include "XPathValue.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class Node;
+class EventTargetNode;
+class EventListener;
+
+class XPathResult : public Shared<XPathResult>
+{
+public:
+    enum XPathResultType {
+        ANY_TYPE = 0,
+        NUMBER_TYPE = 1,
+        STRING_TYPE = 2,
+        BOOLEAN_TYPE = 3,
+        UNORDERED_NODE_ITERATOR_TYPE = 4,
+        ORDERED_NODE_ITERATOR_TYPE = 5,
+        UNORDERED_NODE_SNAPSHOT_TYPE = 6,
+        ORDERED_NODE_SNAPSHOT_TYPE = 7,
+        ANY_UNORDERED_NODE_TYPE = 8,
+        FIRST_ORDERED_NODE_TYPE = 9
+    };
+    
+    XPathResult(EventTargetNode*, const XPath::Value&);
+    ~XPathResult();
+    
+    void convertTo(unsigned short type, ExceptionCode&);
+
+    unsigned short resultType() const;
+
+    double numberValue(ExceptionCode&) const;
+    String stringValue(ExceptionCode&) const;
+    bool booleanValue(ExceptionCode&) const;
+    Node* singleNodeValue(ExceptionCode&) const;
+
+    bool invalidIteratorState() const;
+    unsigned long snapshotLength(ExceptionCode&) const;
+    Node* iterateNext(ExceptionCode&);
+    Node* snapshotItem(unsigned long index, ExceptionCode&);
+
+    void invalidateIteratorState();
+private:
+    XPath::Value m_value;
+    unsigned m_nodeSetPosition;
+    XPath::NodeVector m_nodeSet;
+    unsigned short m_resultType;
+    bool m_invalidIteratorState;
+    RefPtr<EventTargetNode> m_eventTarget;
+    RefPtr<EventListener> m_eventListener;
+};
+
+}
+
+#endif // XPATH_SUPPORT
+
+#endif // XPathResult_H
+
diff --git a/WebCore/xpath/XPathResult.idl b/WebCore/xpath/XPathResult.idl
new file mode 100644 (file)
index 0000000..b79b0d5
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+module xpath {
+
+    interface [GenerateConstructor] XPathResult {
+        const unsigned short ANY_TYPE                       = 0;
+        const unsigned short NUMBER_TYPE                    = 1;
+        const unsigned short STRING_TYPE                    = 2;
+        const unsigned short BOOLEAN_TYPE                   = 3;
+        const unsigned short UNORDERED_NODE_ITERATOR_TYPE   = 4;
+        const unsigned short ORDERED_NODE_ITERATOR_TYPE     = 5;
+        const unsigned short UNORDERED_NODE_SNAPSHOT_TYPE   = 6;
+        const unsigned short ORDERED_NODE_SNAPSHOT_TYPE     = 7;
+        const unsigned short ANY_UNORDERED_NODE_TYPE        = 8;
+        const unsigned short FIRST_ORDERED_NODE_TYPE        = 9;
+
+        readonly attribute unsigned short  resultType;
+        readonly attribute double          numberValue
+            getter raises (DOMException);
+            
+        readonly attribute DOMString       stringValue
+            getter raises (DOMException);
+
+        readonly attribute boolean         booleanValue
+            getter raises (DOMException);
+
+        readonly attribute Node            singleNodeValue
+            getter raises (DOMException);
+
+        readonly attribute boolean         invalidIteratorState;
+        readonly attribute unsigned long   snapshotLength
+            getter raises (DOMException);
+            
+        Node iterateNext()
+            raises (DOMException);
+        Node snapshotItem(in unsigned long index)
+            raises (DOMException);
+    };
+}
diff --git a/WebCore/xpath/impl/XPathExpressionNode.cpp b/WebCore/xpath/impl/XPathExpressionNode.cpp
new file mode 100644 (file)
index 0000000..15212d7
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+
+#if XPATH_SUPPORT
+
+#include "Logging.h"
+#include "XPathExpressionNode.h"
+#include "Node.h"
+
+#include <cmath>
+
+using namespace std;
+
+namespace WebCore {
+namespace XPath {
+    
+EvaluationContext &Expression::evaluationContext()
+{
+    static EvaluationContext evaluationContext;
+    return evaluationContext;
+}
+
+Expression::Expression()
+    : m_constantValue(0)
+{
+}
+
+Expression::~Expression()
+{
+    deleteAllValues(m_subExpressions);
+    
+    delete m_constantValue;
+}
+
+Value Expression::evaluate() const
+{
+    if (m_constantValue)
+        return *m_constantValue;
+
+    return doEvaluate();
+}
+
+void Expression::addSubExpression(Expression* expr)
+{
+    m_subExpressions.append(expr);
+}
+
+void Expression::optimize()
+{
+    bool allSubExpressionsConstant = true;
+    
+    for (unsigned i = 0; i < m_subExpressions.size(); i++) {
+        if (m_subExpressions[i]->isConstant())
+            m_subExpressions[i]->optimize();
+        else
+            allSubExpressionsConstant = false;
+    }
+
+    if (allSubExpressionsConstant) {
+        ASSERT (!m_constantValue);
+        m_constantValue = new Value(doEvaluate());
+        deleteAllValues(m_subExpressions);
+        m_subExpressions.clear();
+    }
+}
+
+unsigned int Expression::subExprCount() const
+{
+    return m_subExpressions.size();
+}
+
+Expression* Expression::subExpr(unsigned i)
+{
+    ASSERT(i < subExprCount());
+
+    return m_subExpressions[i];
+}
+
+const Expression* Expression::subExpr(unsigned i) const
+{
+    ASSERT(i < subExprCount());
+    
+    return m_subExpressions[i];
+}
+
+bool Expression::isConstant() const
+{
+    for (unsigned i = 0; i < m_subExpressions.size(); i++) {
+        if (!m_subExpressions[i]->isConstant())
+            return false;
+    }
+
+    return true;
+}
+
+}
+}
+
+#endif // XPATH_SUPPORT
+
diff --git a/WebCore/xpath/impl/XPathExpressionNode.h b/WebCore/xpath/impl/XPathExpressionNode.h
new file mode 100644 (file)
index 0000000..9e3d96d
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * expression.h - Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef XPathExpressionNode_H
+#define XPathExpressionNode_H
+
+#if XPATH_SUPPORT
+
+#include "XPathValue.h"
+
+#include "StringHash.h"
+#include <kxmlcore/HashMap.h>
+#include <kxmlcore/Vector.h>
+
+namespace WebCore {
+class XPathNSResolver;
+
+namespace XPath {
+        
+struct EvaluationContext
+{
+    EvaluationContext() : node(0), size(0), position(0), resolver(0) { }
+
+    RefPtr<Node> node;
+    unsigned long size;
+    unsigned long position;
+    HashMap<String, String> variableBindings;
+
+    /* The function library is globally accessible through
+     * FunctionLibrary::self()
+     */
+    XPathNSResolver* resolver;
+};
+
+class ParseNode
+{
+};
+
+class Expression : public ParseNode
+{
+public:
+    static EvaluationContext& evaluationContext();
+
+    Expression();
+    virtual ~Expression();
+    virtual Value evaluate() const;
+
+    void addSubExpression(Expression* expr);
+    void optimize();
+    virtual bool isConstant() const;
+
+protected:
+    unsigned int subExprCount() const;
+    Expression* subExpr(unsigned i);
+    const Expression* subExpr(unsigned i) const;
+
+private:
+    virtual Value doEvaluate() const = 0;
+
+    Vector<Expression*> m_subExpressions;
+    Value* m_constantValue;
+};
+
+}
+}
+
+#endif // XPATH_SUPPORT
+
+#endif // EXPRESSION_H
+
diff --git a/WebCore/xpath/impl/XPathFunctions.cpp b/WebCore/xpath/impl/XPathFunctions.cpp
new file mode 100644 (file)
index 0000000..4009a35
--- /dev/null
@@ -0,0 +1,797 @@
+/*
+ * Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+
+#if XPATH_SUPPORT
+
+#include "XPathFunctions.h"
+
+#include "Logging.h"
+#include "NamedAttrMap.h"
+#include "Node.h"
+
+#include <math.h>
+
+namespace WebCore {
+namespace XPath {
+        
+#define DEFINE_FUNCTION_CREATOR(Class) \
+static Function *create##Class() { return new Class; }
+
+class Interval
+{
+public:
+    static const int Inf =-1;
+
+    Interval();
+    Interval(int value);
+    Interval(int min, int max);
+
+    bool contains(int value) const;
+
+    String asString() const;
+
+private:
+    int m_min;
+    int m_max;
+};
+
+class FunLast : public Function
+{
+public:
+    virtual bool isConstant() const;
+
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunPosition : public Function
+{
+public:
+    virtual bool isConstant() const;
+
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunCount : public Function
+{
+public:
+    virtual bool isConstant() const;
+
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunLocalName : public Function
+{
+public:
+    virtual bool isConstant() const;
+
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunNamespaceURI : public Function
+{
+public:
+    virtual bool isConstant() const;
+
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunName : public Function
+{
+public:
+    virtual bool isConstant() const;
+
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunString : public Function
+{
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunConcat : public Function
+{
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunStartsWith : public Function
+{
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunContains : public Function
+{
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunSubstringBefore : public Function
+{
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunSubstringAfter : public Function
+{
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunSubstring : public Function
+{
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunStringLength : public Function
+{
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunNormalizeSpace : public Function
+{
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunTranslate : public Function
+{
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunBoolean : public Function
+{
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunNot : public Function
+{
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunTrue : public Function
+{
+public:
+    virtual bool isConstant() const;
+
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunFalse : public Function
+{
+public:
+    virtual bool isConstant() const;
+
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunLang : public Function
+{
+public:
+    virtual bool isConstant() const;
+
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunNumber : public Function
+{
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunSum : public Function
+{
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunFloor : public Function
+{
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunCeiling : public Function
+{
+private:
+    virtual Value doEvaluate() const;
+};
+
+class FunRound : public Function
+{
+private:
+    virtual Value doEvaluate() const;
+};
+
+DEFINE_FUNCTION_CREATOR(FunLast)
+DEFINE_FUNCTION_CREATOR(FunPosition)
+DEFINE_FUNCTION_CREATOR(FunCount)
+DEFINE_FUNCTION_CREATOR(FunLocalName)
+DEFINE_FUNCTION_CREATOR(FunNamespaceURI)
+DEFINE_FUNCTION_CREATOR(FunName)
+
+DEFINE_FUNCTION_CREATOR(FunString)
+DEFINE_FUNCTION_CREATOR(FunConcat)
+DEFINE_FUNCTION_CREATOR(FunStartsWith)
+DEFINE_FUNCTION_CREATOR(FunContains)
+DEFINE_FUNCTION_CREATOR(FunSubstringBefore)
+DEFINE_FUNCTION_CREATOR(FunSubstringAfter)
+DEFINE_FUNCTION_CREATOR(FunSubstring)
+DEFINE_FUNCTION_CREATOR(FunStringLength)
+DEFINE_FUNCTION_CREATOR(FunNormalizeSpace)
+DEFINE_FUNCTION_CREATOR(FunTranslate)
+
+DEFINE_FUNCTION_CREATOR(FunBoolean)
+DEFINE_FUNCTION_CREATOR(FunNot)
+DEFINE_FUNCTION_CREATOR(FunTrue)
+DEFINE_FUNCTION_CREATOR(FunFalse)
+DEFINE_FUNCTION_CREATOR(FunLang)
+
+DEFINE_FUNCTION_CREATOR(FunNumber)
+DEFINE_FUNCTION_CREATOR(FunSum)
+DEFINE_FUNCTION_CREATOR(FunFloor)
+DEFINE_FUNCTION_CREATOR(FunCeiling)
+DEFINE_FUNCTION_CREATOR(FunRound)
+
+#undef DEFINE_FUNCTION_CREATOR
+
+Interval::Interval()
+    : m_min(Inf),
+    m_max(Inf)
+{
+}
+
+Interval::Interval(int value)
+    : m_min(value),
+    m_max(value)
+{
+}
+
+Interval::Interval(int min, int max)
+    : m_min(min),
+    m_max(max)
+{
+}
+
+bool Interval::contains(int value) const
+{
+    if (m_min == Inf && m_max == Inf)
+        return true;
+
+    if (m_min == Inf)
+        return value <= m_max;
+
+    if (m_max == Inf)
+        return value >= m_min;
+
+    return value >= m_min && value <= m_max;
+}
+
+String Interval::asString() const
+{
+    String s = "[";
+
+    if (m_min == Inf)
+        s += "-Infinity";
+    else
+        s += DeprecatedString::number(m_min);
+
+    s += "..";
+
+    if (m_max == Inf)
+        s += "Infinity";
+    else
+        s += DeprecatedString::number(m_max);
+
+    s += "]";
+
+    return s;
+}
+
+void Function::setArguments(const Vector<Expression*>& args)
+{
+    Vector<Expression*>::const_iterator end = args.end();
+
+    for (Vector<Expression*>::const_iterator it = args.begin(); it != end; it++)
+        addSubExpression(*it);
+}
+
+void Function::setName(const String& name)
+{
+    m_name = name;
+}
+
+Expression* Function::arg(int i)
+{
+    return subExpr(i);
+}
+
+const Expression* Function::arg(int i) const
+{
+    return subExpr(i);
+}
+
+unsigned int Function::argCount() const
+{
+    return subExprCount();
+}
+
+String Function::name() const
+{
+    return m_name;
+}
+
+Value FunLast::doEvaluate() const
+{
+    return double(Expression::evaluationContext().size);
+}
+
+bool FunLast::isConstant() const
+{
+    return false;
+}
+
+Value FunPosition::doEvaluate() const
+{
+    return double(Expression::evaluationContext().position);
+}
+
+bool FunPosition::isConstant() const
+{
+    return false;
+}
+
+bool FunLocalName::isConstant() const
+{
+    return false;
+}
+
+Value FunLocalName::doEvaluate() const
+{
+    Node* node = 0;
+    if (argCount() > 0) {
+        Value a = arg(0)->evaluate();
+        if (!a.isNodeVector() || a.toNodeVector().size() == 0)
+            return "";
+        
+        node = a.toNodeVector()[0].get();
+    }
+
+    if (!node)
+        node = evaluationContext().node.get();
+
+    return Value(node->localName());
+}
+
+bool FunNamespaceURI::isConstant() const
+{
+    return false;
+}
+
+Value FunNamespaceURI::doEvaluate() const
+{
+    Node* node = 0;
+    if (argCount() > 0) {
+        Value a = arg(0)->evaluate();
+        if (!a.isNodeVector() || a.toNodeVector().size() == 0)
+            return "";
+
+        node = a.toNodeVector()[0].get();
+    }
+
+    if (!node)
+        node = evaluationContext().node.get();
+
+    return Value(node->namespaceURI());
+}
+
+bool FunName::isConstant() const
+{
+    return false;
+}
+
+Value FunName::doEvaluate() const
+{
+    Node* node = 0;
+    if (argCount() > 0) {
+        Value a = arg(0)->evaluate();
+        if (!a.isNodeVector() || a.toNodeVector().size() == 0)
+            return "";
+
+        node = a.toNodeVector()[0].get();
+    }
+
+    if (!node)
+        node = evaluationContext().node.get();
+
+    return node->prefix() + ":" + node->localName();
+}
+
+Value FunCount::doEvaluate() const
+{
+    Value a = arg(0)->evaluate();
+    
+    if (!a.isNodeVector()) {
+        LOG(XPath, "count() expects <nodevector>");
+
+        return 0.0;
+    }
+    
+    return double(a.toNodeVector().size());
+}
+
+bool FunCount::isConstant() const
+{
+    return false;
+}
+
+Value FunString::doEvaluate() const
+{
+    if (argCount() == 0) {
+        String s = Value(Expression::evaluationContext().node).toString();
+        return s;
+    }
+    return arg(0)->evaluate().toString();
+}
+
+Value FunConcat::doEvaluate() const
+{
+    String str;
+
+    for (unsigned int i = 0; i < argCount(); ++i)
+        str += arg(i)->evaluate().toString();
+
+    return str;
+}
+
+Value FunStartsWith::doEvaluate() const
+{
+    String s1 = arg(0)->evaluate().toString();
+    String s2 = arg(1)->evaluate().toString();
+
+    if (s2.isEmpty())
+        return true;
+
+    return s1.startsWith(s2);
+}
+
+Value FunContains::doEvaluate() const
+{
+    String s1 = arg(0)->evaluate().toString();
+    String s2 = arg(1)->evaluate().toString();
+
+    if (s2.isEmpty()) 
+        return true;
+
+    return s1.contains(s2) != 0;
+}
+
+Value FunSubstringBefore::doEvaluate() const
+{
+    String s1 = arg(0)->evaluate().toString();
+    String s2 = arg(1)->evaluate().toString();
+
+    if (s2.isEmpty())
+        return "";
+
+    int i = s1.find(s2);
+
+    if (i == -1)
+        return "";
+
+    return s1.left(i);
+}
+
+Value FunSubstringAfter::doEvaluate() const
+{
+    String s1 = arg(0)->evaluate().toString();
+    String s2 = arg(1)->evaluate().toString();
+
+    if (s2.isEmpty())
+        return s2;
+
+    int i = s1.find(s2);
+    if (i == -1)
+        return "";
+
+    return Value(s1.deprecatedString().mid(i + 1));
+}
+
+Value FunSubstring::doEvaluate() const
+{
+    String s = arg(0)->evaluate().toString();
+    long pos = long(round(arg(1)->evaluate().toNumber()));
+    bool haveLength = argCount() == 3;
+    long len = -1;
+    if (haveLength)
+        len = long(round(arg(2)->evaluate().toNumber()));
+
+    if (pos > long(s.length())) 
+        return "";
+
+    if (haveLength && pos < 1) {
+        len -= 1 - pos;
+        pos = 1;
+        if (len < 1)
+            return "";
+    }
+
+    return Value(s.deprecatedString().mid(pos - 1, len));
+}
+
+Value FunStringLength::doEvaluate() const
+{
+    if (argCount() == 0) {
+        String s = Value(Expression::evaluationContext().node).toString();
+        return double(s.length());
+    }
+
+    return double(arg(0)->evaluate().toString().length());
+}
+
+Value FunNormalizeSpace::doEvaluate() const
+{
+    if (argCount() == 0) {
+        String s = Value(Expression::evaluationContext().node).toString();
+        return Value(s.deprecatedString().simplifyWhiteSpace());
+    }
+
+    String s = arg(0)->evaluate().toString();
+    return Value(s.deprecatedString().simplifyWhiteSpace());
+}
+
+Value FunTranslate::doEvaluate() const
+{
+    String s1 = arg(0)->evaluate().toString();
+    String s2 = arg(1)->evaluate().toString();
+    String s3 = arg(2)->evaluate().toString();
+    String newString;
+
+    for (unsigned i1 = 0; i1 < s1.length(); ++i1) {
+        QChar ch = s1[i1];
+        int i2 = s2.find(ch);
+        
+        if (i2 == -1) 
+            newString += ch;
+        else if ((unsigned)i2 < s3.length())
+            newString += s3[ i2 ];
+    }
+
+    return newString;
+}
+
+Value FunBoolean::doEvaluate() const
+{
+    return arg(0)->evaluate().toBoolean();
+}
+
+Value FunNot::doEvaluate() const
+{
+    return !arg(0)->evaluate().toBoolean();
+}
+
+Value FunTrue::doEvaluate() const
+{
+    return true;
+}
+
+bool FunTrue::isConstant() const
+{
+    return true;
+}
+
+Value FunLang::doEvaluate() const
+{
+    String lang = arg(0)->evaluate().toString();
+
+    RefPtr<Node> langNode = 0;
+    Node* node = evaluationContext().node.get();
+
+    String xms("xms");
+    String xmsnsURI = node->lookupNamespaceURI(xms);
+
+    while (node) {
+        NamedAttrMap *attrs = node->attributes();
+        String l("lang");
+        langNode = attrs->getNamedItemNS(xmsnsURI, l);
+        if (langNode)
+            break;
+
+        node = node->parentNode();
+    }
+
+    if (!langNode)
+        return false;
+
+    String langNodeValue = langNode->nodeValue();
+
+    // extract 'en' out of 'en-us'
+    int index = langNodeValue.find('-');
+    if (index != -1)
+        langNodeValue = langNodeValue.left(index);
+    
+    return langNodeValue.lower() == lang.lower();
+}
+
+bool FunLang::isConstant() const
+{
+    return false;
+}
+
+Value FunFalse::doEvaluate() const
+{
+    return false;
+}
+
+bool FunFalse::isConstant() const
+{
+    return true;
+}
+
+Value FunNumber::doEvaluate() const
+{
+    return arg(0)->evaluate().toNumber();
+}
+
+Value FunSum::doEvaluate() const
+{
+    Value a = arg(0)->evaluate();
+    if (!a.isNodeVector()) {
+        LOG(XPath, "sum() expects <nodevector>");
+        return 0.0;
+    }
+
+    double sum = 0.0;
+    NodeVector nodes = a.toNodeVector();
+    
+    for (unsigned i = 0; i < nodes.size(); i++)
+        sum += Value(stringValue(nodes[i].get()).deprecatedString()).toNumber();
+    
+    return sum;
+}
+
+Value FunFloor::doEvaluate() const
+{
+    double num = arg(0)->evaluate().toNumber();
+
+    return floor(num);
+}
+
+Value FunCeiling::doEvaluate() const
+{
+    double num = arg(0)->evaluate().toNumber();
+
+    return ceil(num);
+}
+
+Value FunRound::doEvaluate() const
+{
+    return round(arg(0)->evaluate().toNumber());
+}
+
+struct FunctionLibrary::FunctionRec
+{
+    typedef Function *(*FactoryFn)();
+
+    FactoryFn factoryFn;
+    Interval args;
+};
+
+struct FunctionMapping
+{
+    const char *name;
+    FunctionLibrary::FunctionRec function;
+};
+
+FunctionLibrary& FunctionLibrary::self()
+{
+    static FunctionLibrary instance;
+    return instance;
+}
+
+FunctionLibrary::FunctionLibrary()
+{
+    static const FunctionMapping functions[] = {
+    { "last", { &createFunLast, 0 } },
+    { "last", { &createFunLast, 0 } },
+    { "position", { &createFunPosition, 0 } },
+    { "count", { &createFunCount, 1 } },
+    { "sum", { &createFunSum, 1 } },
+    { "local-name", { &createFunLocalName, Interval(0, 1) } },
+    { "namespace-uri", { &createFunNamespaceURI, Interval(0, 1) } },
+    { "name", { &createFunName, Interval(0, 1) } },
+    { "string", { &createFunString, Interval(0, 1) } },
+    { "concat", { &createFunConcat, Interval(2, Interval::Inf) } },
+    { "starts-with", { &createFunStartsWith, 2 } },
+    { "contains", { &createFunContains, 2 } },
+    { "substring-before", { &createFunSubstringBefore, 2 } },
+    { "substring-after", { &createFunSubstringAfter, 2 } },
+    { "substring", { &createFunSubstring, Interval(2, 3) } },
+    { "string-length", { &createFunStringLength, 1 } },
+    { "normalize-space", { &createFunNormalizeSpace, 1 } },
+    { "translate", { &createFunTranslate, 3 } },
+        
+    { "boolean", { &createFunBoolean, 1 } },
+    { "not", { &createFunNot, 1 } },
+    { "true", { &createFunTrue, 0 } },
+    { "false", { &createFunFalse, 0 } },
+    { "lang", { &createFunLang, 1 } },
+        
+    { "number", { &createFunNumber, 1 } },
+    { "floor", { &createFunFloor, 1 } },
+    { "ceiling", { &createFunCeiling, 1 } },
+    { "round", { &createFunRound, 1 } }
+    };
+    const unsigned int numFunctions = sizeof(functions) / sizeof(functions[ 0 ]);
+        
+    for (unsigned i = 0; i < numFunctions; ++i)
+        m_functionDict.set(functions[i].name, functions[i].function);
+}
+
+Function *FunctionLibrary::createFunction(const char *name, const Vector<Expression*> &args) const
+{
+    if (!m_functionDict.contains(name)) {
+        LOG(XPath, "Function '%s' not supported by this implementation.", name);
+        
+        // Return a dummy function instead of 0.
+        Function *funcTrue = m_functionDict.get("true").factoryFn();
+        funcTrue->setName("true");
+        return funcTrue;
+    }
+
+    FunctionRec functionRec = m_functionDict.get(name);
+    if (!functionRec.args.contains(args.size())) {
+        LOG(XPath, "Function '%s' requires %d arguments, but %d given.", name, functionRec.args.asString().ascii(), args.size());
+        return 0;
+    }
+
+    Function *function = functionRec.factoryFn();
+    function->setArguments(args);
+    function->setName(name);
+    
+    return function;
+}
+
+}
+}
+
+#endif // XPATH_SUPPORT
diff --git a/WebCore/xpath/impl/XPathFunctions.h b/WebCore/xpath/impl/XPathFunctions.h
new file mode 100644 (file)
index 0000000..52e4352
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * functions.h - Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef XPathFunctions_H
+#define XPathFunctions_H
+
+#if XPATH_SUPPORT
+
+#include "XPathExpressionNode.h"
+
+#include "StringHash.h"
+
+#include "PlatformString.h"
+
+namespace WebCore {
+namespace XPath {
+    
+class Function : public Expression
+{
+public:
+    void setArguments(const Vector<Expression*>&);
+    void setName(const String&);
+
+protected:
+    Expression* arg(int pos);
+    const Expression* arg(int pos) const;
+    unsigned int argCount() const;
+    String name() const;
+
+private:
+    String m_name;
+};
+
+class FunctionLibrary
+{
+    friend struct FunctionMapping;
+public:
+    static FunctionLibrary &self();
+
+    Function* createFunction(const char* name, const Vector<Expression*> &args = Vector<Expression*>()) const;
+
+private:
+    struct FunctionRec;
+
+    FunctionLibrary();
+    FunctionLibrary(const FunctionLibrary &rhs);
+    FunctionLibrary &operator=(const FunctionLibrary &rhs);
+
+    HashMap<String, FunctionRec> m_functionDict;
+};
+
+}
+}
+
+#endif // XPATH_SUPPORT
+
+#endif // XPath_Functions_H
+
diff --git a/WebCore/xpath/impl/XPathGrammar.y b/WebCore/xpath/impl/XPathGrammar.y
new file mode 100644 (file)
index 0000000..420b740
--- /dev/null
@@ -0,0 +1,502 @@
+%{
+#include "config.h"
+
+#include "XPathParser.h"
+#include "XPathFunctions.h"
+#include "XPathPath.h"
+#include "XPathStep.h"
+#include "XPathPredicate.h"
+#include "XPathUtil.h"
+#include "XPathVariableReference.h"
+    
+#include "XPathNSResolver.h"
+#include "XPathEvaluator.h"
+#include "ExceptionCode.h"
+
+#define YYDEBUG 0
+#define YYPARSE_PARAM parser
+
+using namespace WebCore;
+using namespace XPath;
+
+%}
+
+%pure_parser
+
+%union
+{
+    Step::AxisType axisType;
+    int        num;
+    String *str;
+    Expression* expr;
+    Vector<Predicate*>* predList;
+    Vector<Expression*>* argList;
+    Step* step;
+    LocationPath *locationPath;
+}
+
+%{
+
+int xpathyylex(YYSTYPE *yylval) { return Parser::current()->lex(yylval); }
+void xpathyyerror(const char *str) { }
+    
+%}
+
+%left <num> MULOP RELOP EQOP
+%left <str> PLUS MINUS
+%left <str> OR AND
+%token <axisType> AXISNAME
+%token <str> NODETYPE PI FUNCTIONNAME LITERAL
+%token <str> VARIABLEREFERENCE NUMBER
+%token <str> DOTDOT SLASHSLASH NAMETEST
+%token ERROR
+
+%type <locationPath> LocationPath
+%type <locationPath> AbsoluteLocationPath
+%type <locationPath> RelativeLocationPath
+%type <step> Step
+%type <axisType> AxisSpecifier
+%type <step> DescendantOrSelf
+%type <str> NodeTest
+%type <expr> Predicate
+%type <predList> PredicateList
+%type <step> AbbreviatedStep
+%type <expr> Expr
+%type <expr> PrimaryExpr
+%type <expr> FunctionCall
+%type <argList> ArgumentList
+%type <expr> Argument
+%type <expr> UnionExpr
+%type <expr> PathExpr
+%type <expr> FilterExpr
+%type <expr> OrExpr
+%type <expr> AndExpr
+%type <expr> EqualityExpr
+%type <expr> RelationalExpr
+%type <expr> AdditiveExpr
+%type <expr> MultiplicativeExpr
+%type <expr> UnaryExpr
+
+%%
+
+Expr:
+    OrExpr
+    {
+        static_cast<Parser*>(parser)->m_topExpr = $1;
+    }
+    ;
+
+LocationPath:
+    RelativeLocationPath
+    {
+        $$->m_absolute = false;
+    }
+    |
+    AbsoluteLocationPath
+    {
+        $$->m_absolute = true;
+    }
+    ;
+
+AbsoluteLocationPath:
+    '/'
+    {
+        $$ = new LocationPath;
+        static_cast<Parser*>(parser)->registerParseNode($$);
+    }
+    |
+    '/' RelativeLocationPath
+    {
+        $$ = $2;
+    }
+    |
+    DescendantOrSelf RelativeLocationPath
+    {
+        $$ = $2;
+        $$->m_steps.insert(0, $1);
+        static_cast<Parser*>(parser)->unregisterParseNode($1);
+    }
+    ;
+
+RelativeLocationPath:
+    Step
+    {
+        $$ = new LocationPath;
+        $$->m_steps.append($1);
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterParseNode($1);
+    }
+    |
+    RelativeLocationPath '/' Step
+    {
+        $$->m_steps.append($3);
+        static_cast<Parser*>(parser)->unregisterParseNode($3);
+    }
+    |
+    RelativeLocationPath DescendantOrSelf Step
+    {
+        $$->m_steps.append($2);
+        $$->m_steps.append($3);
+        static_cast<Parser*>(parser)->unregisterParseNode($2);
+        static_cast<Parser*>(parser)->unregisterParseNode($3);
+    }
+    ;
+
+Step:
+    NodeTest
+    {
+        $$ = new Step(Step::ChildAxis, *$1);
+        delete $1;
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterString($1);
+    }
+    |
+    NodeTest PredicateList
+    {
+        $$ = new Step(Step::ChildAxis, *$1, *$2);
+        delete $1;
+        delete $2;
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterString($1);
+        static_cast<Parser*>(parser)->unregisterPredicateVector($2);
+    }
+    |
+    AxisSpecifier NodeTest
+    {
+        $$ = new Step($1, *$2);
+        delete $2;
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterString($2);
+    }
+    |
+    AxisSpecifier NodeTest PredicateList
+    {
+        $$ = new Step($1, *$2,  *$3);
+        delete $2;
+        delete $3;
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterString($2);
+        static_cast<Parser*>(parser)->unregisterPredicateVector($3);
+    }
+    |
+    AbbreviatedStep
+    ;
+
+AxisSpecifier:
+    AXISNAME
+    |
+    '@'
+    {
+        $$ = Step::AttributeAxis;
+    }
+    ;
+
+NodeTest:
+    NAMETEST
+    {
+        const int colon = $1->find(':');
+        if (colon > -1) {
+            String prefix($1->left(colon));
+            XPathNSResolver *resolver = Expression::evaluationContext().resolver;
+            if (!resolver || resolver->lookupNamespaceURI(prefix).isNull()) {
+                static_cast<Parser*>(parser)->m_gotNamespaceError = true;
+                YYABORT;
+            }
+        }
+    }
+    |
+    NODETYPE '(' ')'
+    {
+        $$ = new String(*$1 + "()");
+        delete $1;
+        static_cast<Parser*>(parser)->registerString($$);
+        static_cast<Parser*>(parser)->unregisterString($1);
+    }
+    |
+    PI '(' ')'
+    |
+    PI '(' LITERAL ')'
+    {
+        String s = *$1 + " " + *$3;
+        $$ = new String(s.deprecatedString().stripWhiteSpace());
+        delete $1;
+        delete $3;
+        static_cast<Parser*>(parser)->registerString($$);
+        static_cast<Parser*>(parser)->unregisterString($1);        
+        static_cast<Parser*>(parser)->unregisterString($3);
+    }
+    ;
+
+PredicateList:
+    Predicate
+    {
+        $$ = new Vector<Predicate*>;
+        $$->append(new Predicate($1));
+        static_cast<Parser*>(parser)->registerPredicateVector($$);
+        static_cast<Parser*>(parser)->unregisterParseNode($1);
+    }
+    |
+    PredicateList Predicate
+    {
+        $$->append(new Predicate($2));
+        static_cast<Parser*>(parser)->unregisterParseNode($2);
+    }
+    ;
+
+Predicate:
+    '[' Expr ']'
+    {
+        $$ = $2;
+    }
+    ;
+
+DescendantOrSelf:
+    SLASHSLASH
+    {
+        $$ = new Step(Step::DescendantOrSelfAxis, "node()");
+        static_cast<Parser*>(parser)->registerParseNode($$);
+    }
+    ;
+
+AbbreviatedStep:
+    '.'
+    {
+        $$ = new Step(Step::SelfAxis, "node()");
+        static_cast<Parser*>(parser)->registerParseNode($$);
+    }
+    |
+    DOTDOT
+    {
+        $$ = new Step(Step::ParentAxis, "node()");
+        static_cast<Parser*>(parser)->registerParseNode($$);
+    }
+    ;
+
+PrimaryExpr:
+    VARIABLEREFERENCE
+    {
+        $$ = new VariableReference(*$1);
+        delete $1;
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterString($1);
+    }
+    |
+    '(' Expr ')'
+    {
+        $$ = $2;
+    }
+    |
+    LITERAL
+    {
+        $$ = new StringExpression(*$1);
+        delete $1;
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterString($1);        
+    }
+    |
+    NUMBER
+    {
+        $$ = new Number($1->deprecatedString().toDouble());
+        delete $1;
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterString($1);
+    }
+    |
+    FunctionCall
+    ;
+
+FunctionCall:
+    FUNCTIONNAME '(' ')'
+    {
+        $$ = FunctionLibrary::self().createFunction($1->deprecatedString().latin1());
+        delete $1;
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterString($1);
+    }
+    |
+    FUNCTIONNAME '(' ArgumentList ')'
+    {
+        $$ = FunctionLibrary::self().createFunction($1->deprecatedString().latin1(), *$3);
+        delete $1;
+        delete $3;
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterString($1);
+        static_cast<Parser*>(parser)->unregisterExpressionVector($3);
+    }
+    ;
+
+ArgumentList:
+    Argument
+    {
+        $$ = new Vector<Expression*>;
+        $$->append($1);
+        static_cast<Parser*>(parser)->registerExpressionVector($$);
+        static_cast<Parser*>(parser)->unregisterParseNode($1);
+    }
+    |
+    ArgumentList ',' Argument
+    {
+        $$->append($3);
+        static_cast<Parser*>(parser)->unregisterParseNode($3);
+    }
+    ;
+
+Argument:
+    Expr
+    ;
+
+
+UnionExpr:
+    PathExpr
+    |
+    UnionExpr '|' PathExpr
+    {
+        $$ = new Union;
+        $$->addSubExpression($1);
+        $$->addSubExpression($3);
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterParseNode($1);
+        static_cast<Parser*>(parser)->unregisterParseNode($3);
+    }
+    ;
+
+PathExpr:
+    LocationPath
+    {
+        $$ = $1;
+    }
+    |
+    FilterExpr
+    {
+        $$ = $1;
+    }
+    |
+    FilterExpr '/' RelativeLocationPath
+    {
+        $3->m_absolute = true;
+        $$ = new Path(static_cast<Filter*>($1), $3);
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterParseNode($1);
+        static_cast<Parser*>(parser)->unregisterParseNode($3);
+    }
+    |
+    FilterExpr DescendantOrSelf RelativeLocationPath
+    {
+        $3->m_steps.insert(0, $2);
+        $3->m_absolute = true;
+        $$ = new Path(static_cast<Filter*>($1), $3);
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterParseNode($1);
+        static_cast<Parser*>(parser)->unregisterParseNode($3);
+    }
+    ;
+
+FilterExpr:
+    PrimaryExpr
+    {
+        $$ = $1;
+    }
+    |
+    PrimaryExpr PredicateList
+    {
+        $$ = new Filter($1, *$2);
+        delete $2;
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterParseNode($1);
+        static_cast<Parser*>(parser)->unregisterPredicateVector($2);
+    }
+    ;
+
+OrExpr:
+    AndExpr
+    |
+    OrExpr OR AndExpr
+    {
+        $$ = new LogicalOp(LogicalOp::OP_Or, $1, $3);
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterParseNode($1);
+        static_cast<Parser*>(parser)->unregisterParseNode($3);
+    }
+    ;
+
+AndExpr:
+    EqualityExpr
+    |
+    AndExpr AND EqualityExpr
+    {
+        $$ = new LogicalOp(LogicalOp::OP_And, $1, $3);
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterParseNode($1);
+        static_cast<Parser*>(parser)->unregisterParseNode($3);
+    }
+    ;
+
+EqualityExpr:
+    RelationalExpr
+    |
+    EqualityExpr EQOP RelationalExpr
+    {
+        $$ = new EqTestOp($2, $1, $3);
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterParseNode($1);
+        static_cast<Parser*>(parser)->unregisterParseNode($3);
+    }
+    ;
+
+RelationalExpr:
+    AdditiveExpr
+    |
+    RelationalExpr RELOP AdditiveExpr
+    {
+        $$ = new NumericOp($2, $1, $3);
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterParseNode($1);
+        static_cast<Parser*>(parser)->unregisterParseNode($3);
+    }
+    ;
+
+AdditiveExpr:
+    MultiplicativeExpr
+    |
+    AdditiveExpr PLUS MultiplicativeExpr
+    {
+        $$ = new NumericOp(NumericOp::OP_Add, $1, $3);
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterParseNode($1);
+        static_cast<Parser*>(parser)->unregisterParseNode($3);
+    }
+    |
+    AdditiveExpr MINUS MultiplicativeExpr
+    {
+        $$ = new NumericOp(NumericOp::OP_Sub, $1, $3);
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterParseNode($1);
+        static_cast<Parser*>(parser)->unregisterParseNode($3);
+    }
+    ;
+
+MultiplicativeExpr:
+    UnaryExpr
+    |
+    MultiplicativeExpr MULOP UnaryExpr
+    {
+        $$ = new NumericOp($2, $1, $3);
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterParseNode($1);
+        static_cast<Parser*>(parser)->unregisterParseNode($3);
+    }
+    ;
+
+UnaryExpr:
+    UnionExpr
+    |
+    MINUS UnaryExpr
+    {
+        $$ = new Negative;
+        $$->addSubExpression($2);
+        static_cast<Parser*>(parser)->registerParseNode($$);
+        static_cast<Parser*>(parser)->unregisterParseNode($2);
+    }
+    ;
+
+
diff --git a/WebCore/xpath/impl/XPathParser.cpp b/WebCore/xpath/impl/XPathParser.cpp
new file mode 100644 (file)
index 0000000..9903b94
--- /dev/null
@@ -0,0 +1,549 @@
+/*
+ * Copyright 2005 Maksim Orlovich <maksim@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+
+#if XPATH_SUPPORT
+
+#include "XPathParser.h"
+#include "XPathEvaluator.h"
+
+namespace WebCore {
+namespace XPath {
+
+#include "XPathGrammar.h"    
+
+struct AxisNameMapping
+{
+    const char* name;
+    Step::AxisType type;
+};
+
+static AxisNameMapping axisNames[] = {
+    { "ancestor", Step::AncestorAxis },
+    { "ancestor-or-self", Step::AncestorOrSelfAxis },
+    { "attribute", Step::AttributeAxis },
+    { "child", Step::ChildAxis },
+    { "descendant", Step::DescendantAxis },
+    { "descendant-or-self", Step::DescendantOrSelfAxis },
+    { "following", Step::FollowingAxis },
+    { "following-sibling", Step::FollowingSiblingAxis },
+    { "namespace", Step::NamespaceAxis },
+    { "parent", Step::ParentAxis },
+    { "preceding", Step::PrecedingAxis },
+    { "preceding-sibling", Step::PrecedingSiblingAxis },
+    { "self", Step::SelfAxis }
+};
+
+static unsigned int axisNamesCount = sizeof(axisNames) / sizeof(axisNames[0]);
+static const char* const nodeTypeNames[] = {
+    "comment",
+    "text",
+    "processing-instruction",
+    "node",
+    0
+};
+
+HashMap<String, Step::AxisType>* Parser::s_axisNamesDict = 0;
+HashSet<String>* Parser::s_nodeTypeNamesDict = 0;
+
+Parser* Parser::currentParser = 0;
+
+Parser::XMLCat Parser::charCat(QChar aChar)
+{
+    //### might need to add some special cases from the XML spec.
+
+    if (aChar.unicode() == '_')
+        return NameStart;
+
+    if (aChar.unicode() == '.' || aChar.unicode() == '-')
+        return NameCont;
+    switch (u_charType(aChar.unicode())) {
+        case U_LOWERCASE_LETTER: //Ll
+        case U_UPPERCASE_LETTER: //Lu
+        case U_OTHER_LETTER:     //Lo
+        case U_TITLECASE_LETTER: //Lt
+        case U_LETTER_NUMBER:    //Nl
+            return NameStart;
+        case U_COMBINING_SPACING_MARK: //Mc
+        case U_ENCLOSING_MARK:         //Me
+        case U_NON_SPACING_MARK:       //Mn
+        case U_MODIFIER_LETTER:        //Lm
+        case U_DECIMAL_DIGIT_NUMBER:   //Nd
+            return NameCont;
+        default:
+            return NotPartOfName;
+    }
+}
+
+bool Parser::isAxisName(String name, Step::AxisType& type)
+{
+    if (!s_axisNamesDict) {
+        s_axisNamesDict = new HashMap<String, Step::AxisType>;
+        for (unsigned int p = 0; p < axisNamesCount; ++p)
+            s_axisNamesDict->set(axisNames[p].name,
+                                 axisNames[p].type);
+    }
+
+    HashMap<String, Step::AxisType>::iterator it = s_axisNamesDict->find(name);
+    
+    if (it != s_axisNamesDict->end()) {
+        type = it->second;
+        return true;
+    } else    
+        return false;
+}
+
+bool Parser::isNodeTypeName(String name)
+{
+    if (!s_nodeTypeNamesDict) {
+        s_nodeTypeNamesDict = new HashSet<String>;
+        for (int p = 0; nodeTypeNames[p]; ++p)
+            s_nodeTypeNamesDict->add(nodeTypeNames[p]);
+    }
+    return s_nodeTypeNamesDict->contains(String(name));
+}
+
+/* Returns whether the last parsed token matches the [32] Operator rule
+ * (check http://www.w3.org/TR/xpath#exprlex). Necessary to disambiguate
+ * the tokens.
+ */
+bool Parser::isOperatorContext()
+{
+    if (m_nextPos == 0)
+        return false;
+
+    switch (m_lastTokenType) {
+        case AND: case OR: case MULOP:
+        case '/': case SLASHSLASH: case '|': case PLUS: case MINUS:
+        case EQOP: case RELOP:
+        case '@': case AXISNAME:   case '(': case '[':
+            return false;
+        default:
+            return true;
+    }
+}
+
+void Parser::skipWS()
+{
+    while (m_nextPos < m_data.length() && m_data[m_nextPos].isSpace())
+        ++m_nextPos;
+}
+
+Token Parser::makeTokenAndAdvance(int code, int advance)
+{
+    m_nextPos += advance;
+    return Token(code);
+}
+
+Token Parser::makeIntTokenAndAdvance(int code, int val, int advance)
+{
+    m_nextPos += advance;
+    return Token(code, val);
+}
+
+//Returns next char if it's there and interesting, 0 otherwise
+char Parser::peekAheadHelper()
+{
+    if (m_nextPos + 1 >= m_data.length())
+        return 0;
+    QChar next = m_data[m_nextPos + 1];
+    if (next.unicode() >= 0xff)
+        return 0;
+
+    return next.unicode();
+}
+
+char Parser::peekCurHelper()
+{
+    if (m_nextPos >= m_data.length())
+        return 0;
+    QChar next = m_data[m_nextPos];
+    if (next.unicode() >= 0xff)
+        return 0;
+
+    return next.unicode();
+}
+
+Token Parser::lexString()
+{
+    QChar delimiter = m_data[m_nextPos];
+    int   startPos  = m_nextPos + 1;
+
+    for (m_nextPos = startPos; m_nextPos < m_data.length(); ++m_nextPos) {
+        if (m_data[m_nextPos] == delimiter) {
+            String value = m_data.deprecatedString().mid(startPos, m_nextPos - startPos);
+            ++m_nextPos; //Consume the char;
+            return Token(LITERAL, value);
+        }
+    }
+
+    //Ouch, went off the end -- report error
+    return Token(ERROR);
+}
+
+Token Parser::lexNumber()
+{
+    int startPos = m_nextPos;
+    bool seenDot = false;
+
+    //Go until end or a non-digits character
+    for (; m_nextPos < m_data.length(); ++m_nextPos) {
+        QChar aChar = m_data[m_nextPos];
+        if (aChar.unicode() >= 0xff) break;
+
+        if (aChar.unicode() < '0' || aChar.unicode() > '9') {
+            if (aChar.unicode() == '.' && !seenDot)
+                seenDot = true;
+            else
+                break;
+        }
+    }
+
+    String value = m_data.deprecatedString().mid(startPos, m_nextPos - startPos);
+    return Token(NUMBER, value);
+}
+
+Token Parser::lexNCName()
+{
+    int startPos = m_nextPos;
+    if (m_nextPos < m_data.length() && charCat(m_data[m_nextPos]) == NameStart) {
+        //Keep going until we get a character that's not good for names.
+        for (; m_nextPos < m_data.length(); ++m_nextPos) {
+            if (charCat(m_data[m_nextPos]) == NotPartOfName)
+                break;
+        }
+        
+        String value = m_data.deprecatedString().mid(startPos, m_nextPos - startPos);
+        return Token(ERROR + 1, value);
+    }
+
+    return makeTokenAndAdvance(ERROR);
+}
+
+Token Parser::lexQName()
+{
+    Token t1 = lexNCName();
+    if (t1.type == ERROR) return t1;
+    skipWS();
+    //If the next character is :, what we just got it the prefix, if not,
+    //it's the whole thing
+    if (peekAheadHelper() != ':')
+        return t1;
+
+    Token t2 = lexNCName();
+    if (t2.type == ERROR) return t2;
+
+    return Token(ERROR + 1, t1.value + ":" + t2.value);
+}
+
+Token Parser::nextTokenInternal()
+{
+    skipWS();
+
+    if (m_nextPos >= m_data.length())
+        return Token(0);
+
+    char code = peekCurHelper();
+    switch (code) {
+        case '(': case ')': case '[': case ']':
+        case '@': case ',': case '|':
+            return makeTokenAndAdvance(code);
+        case '\'':
+        case '\"':
+            return lexString();
+        case '0': case '1': case '2': case '3': case '4':
+        case '5': case '6': case '7': case '8': case '9':
+            return lexNumber();
+        case '.': {
+            char next = peekAheadHelper();
+            if (next == '.')
+                return makeTokenAndAdvance(DOTDOT, 2);
+            else if (next >= '0' && next <= '9')
+                return lexNumber();
+            else
+                return makeTokenAndAdvance('.');
+        }
+        case '/':
+            if (peekAheadHelper() == '/')
+                return makeTokenAndAdvance(SLASHSLASH, 2);
+            else
+                return makeTokenAndAdvance('/');
+        case '+':
+            return makeTokenAndAdvance(PLUS);
+        case '-':
+            return makeTokenAndAdvance(MINUS);
+        case '=':
+            return makeIntTokenAndAdvance(EQOP, EqTestOp::OP_EQ);
+        case '!':
+            if (peekAheadHelper() == '=')
+                return makeIntTokenAndAdvance(EQOP, EqTestOp::OP_NE, 2);
+
+            return Token(ERROR);
+        case '<':
+            if (peekAheadHelper() == '=')
+                return makeIntTokenAndAdvance(RELOP, NumericOp::OP_LE, 2);
+
+            return makeIntTokenAndAdvance(RELOP, NumericOp::OP_LT);
+        case '>':
+            if (peekAheadHelper() == '=')
+                return makeIntTokenAndAdvance(RELOP, NumericOp::OP_GE, 2);
+
+            return makeIntTokenAndAdvance(RELOP, NumericOp::OP_GT);
+        case '*':
+            if (isOperatorContext())
+                return makeIntTokenAndAdvance(MULOP, NumericOp::OP_Mul);
+            else {
+                ++m_nextPos;
+                return Token(NAMETEST, "*");
+            }
+        case '$': {//$ QName
+            m_nextPos++;
+            Token par = lexQName();
+            if (par.type == ERROR)
+                return par;
+
+            return Token(VARIABLEREFERENCE, par.value);
+        }
+    }
+
+    Token t1 = lexNCName();
+    if (t1.type == ERROR) return t1;
+
+    skipWS();
+    //If we're in an operator context, check for any operator names
+    if (isOperatorContext()) {
+        if (t1.value == "and") //### hash?
+            return Token(AND);
+        if (t1.value == "or")
+            return Token(OR);
+        if (t1.value == "mod")
+            return Token(MULOP, NumericOp::OP_Mod);
+        if (t1.value == "div")
+            return Token(MULOP, NumericOp::OP_Div);
+    }
+
+    //See whether we are at a :
+    if (peekCurHelper() == ':') {
+        m_nextPos++;
+        //Any chance it's an axis name?
+        if (peekCurHelper() == ':') {
+            m_nextPos++;
+            
+            //It might be an axis name.
+            Step::AxisType axisType;
+            if (isAxisName(t1.value, axisType))
+                return Token(AXISNAME, axisType);
+            //Ugh, :: is only valid in axis names -> error
+            return Token(ERROR);
+        }
+
+        //Seems like this is a fully qualified qname, or perhaps the * modified one from NameTest
+        skipWS();
+        if (peekCurHelper() == '*') {
+            m_nextPos++;
+            return Token(NAMETEST, t1.value + ":*");
+        }
+        
+        //Make a full qname..
+        Token t2 = lexNCName();
+        if (t2.type == ERROR) return t2;
+        
+        t1.value = t1.value + ':' + t2.value;
+    }
+
+    skipWS();
+    if (peekCurHelper() == '(') {
+        //note: we don't swallow the (here!
+        
+        //either node type of function name
+        if (isNodeTypeName(t1.value)) {
+            if (t1.value == "processing-instruction")
+                return Token(PI, t1.value);
+
+            return Token(NODETYPE, t1.value);
+        }
+        //must be a function name.
+        return Token(FUNCTIONNAME, t1.value);
+    }
+
+    //At this point, it must be NAMETEST
+    return Token(NAMETEST, t1.value);
+}
+
+Token Parser::nextToken()
+{
+    Token toRet = nextTokenInternal();
+    m_lastTokenType = toRet.type;
+    return toRet;
+}
+
+Parser::Parser()
+{
+    reset(String());
+}
+
+void Parser::reset(const String& data)
+{
+    m_nextPos = 0;
+    m_data = data;
+    m_lastTokenType = 0;
+    
+    m_topExpr = 0;
+    m_gotNamespaceError = false;
+}
+
+int Parser::lex(void* data)
+{
+    YYSTYPE* yylval = static_cast<YYSTYPE*>(data);
+    Token tok = nextToken();
+    if (!tok.value.isEmpty()) {
+        yylval->str = new String(tok.value);
+        registerString(yylval->str);
+    } else if (tok.intValue)
+        yylval->num = tok.intValue;
+    
+    return tok.type;
+}
+
+Expression* Parser::parseStatement(const String& statement, ExceptionCode& code)
+{
+    reset(statement);
+    
+    Parser* oldParser = currentParser;
+    currentParser = this;
+    int parseError = xpathyyparse(this);
+    currentParser = oldParser;
+        
+    if (parseError) {
+        deleteAllValues(m_parseNodes);
+        deleteAllValues(m_expressionVectors);
+        deleteAllValues(m_predicateVectors);
+        deleteAllValues(m_strings);
+        
+        if (m_gotNamespaceError)
+            code = NAMESPACE_ERR;
+        else
+            code = INVALID_EXPRESSION_ERR;
+        return 0;
+    } else {
+        ASSERT(m_parseNodes.size() == 1); // Top expression
+        ASSERT(m_expressionVectors.size() == 0);
+        ASSERT(m_predicateVectors.size() == 0);
+        ASSERT(m_strings.size() == 0);
+        
+        m_parseNodes.clear();
+    }
+    
+    return m_topExpr;
+}
+
+void Parser::registerParseNode(ParseNode* node)
+{
+    if (node == 0)
+        return;
+    
+    ASSERT(!m_parseNodes.contains(node));
+    
+    m_parseNodes.add(node);
+}
+
+void Parser::unregisterParseNode(ParseNode* node)
+{
+    if (node == 0)
+        return;
+    
+    ASSERT(m_parseNodes.contains(node));
+
+    m_parseNodes.remove(node);
+}
+
+void Parser::registerPredicateVector(Vector<Predicate*>* vector)
+{
+    if (vector == 0)
+        return;
+
+    ASSERT(!m_predicateVectors.contains(vector));
+    
+    m_predicateVectors.add(vector);
+}
+
+void Parser::unregisterPredicateVector(Vector<Predicate*>* vector)
+{
+    if (vector == 0)
+        return;
+
+    ASSERT(m_predicateVectors.contains(vector));
+    
+    m_predicateVectors.remove(vector);
+}
+
+
+void Parser::registerExpressionVector(Vector<Expression*>* vector)
+{
+    if (vector == 0)
+        return;
+
+    ASSERT(!m_expressionVectors.contains(vector));
+    
+    m_expressionVectors.add(vector);    
+}
+
+void Parser::unregisterExpressionVector(Vector<Expression*>* vector)
+{
+    if (vector == 0)
+        return;
+
+    ASSERT(m_expressionVectors.contains(vector));
+    
+    m_expressionVectors.remove(vector);        
+}
+
+void Parser::registerString(String* s)
+{
+    if (s == 0)
+        return;
+    
+    ASSERT(!m_strings.contains(s));
+    
+    m_strings.add(s);        
+}
+
+void Parser::unregisterString(String* s)
+{
+    if (s == 0)
+        return;
+    
+    ASSERT(m_strings.contains(s));
+    
+    m_strings.remove(s);
+}
+
+}
+}
+
+#endif // XPATH_SUPPORT
+
diff --git a/WebCore/xpath/impl/XPathParser.h b/WebCore/xpath/impl/XPathParser.h
new file mode 100644 (file)
index 0000000..a503516
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2005 Maksim Orlovich <maksim@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef XPathParser_H
+#define XPathParser_H
+
+#if XPATH_SUPPORT
+
+#include <kxmlcore/Noncopyable.h>
+
+#include "StringHash.h"
+#include "PlatformString.h"
+
+#include "XPathStep.h"
+#include "XPathPath.h"
+#include "XPathPredicate.h"
+#include "XPathExpressionNode.h"
+#include "XPathUtil.h"
+
+namespace WebCore {
+namespace XPath {
+
+struct Token
+{
+    int     type;
+    String value;
+    int     intValue; //0 if not set
+    
+    Token(int t): type(t), intValue(0) {}
+    Token(int t, String v): type(t), value(v) {}
+    Token(int t, int v): type(t), intValue(v) {}
+};
+
+class Parser : Noncopyable
+{
+private:
+    static Parser* currentParser;
+    
+    unsigned m_nextPos;
+    String m_data;
+    int m_lastTokenType;
+    
+    static HashMap<String, Step::AxisType>* s_axisNamesDict;
+    static HashSet<String>* s_nodeTypeNamesDict;
+    
+    enum XMLCat {
+        NameStart,
+        NameCont,
+        NotPartOfName
+    };
+    
+    XMLCat charCat(QChar aChar);
+    
+    bool isAxisName(String name, Step::AxisType &type);
+    bool isNodeTypeName(String name);
+    bool isOperatorContext();
+    
+    void  skipWS();
+    Token makeTokenAndAdvance(int code, int advance = 1);
+    Token makeIntTokenAndAdvance(int code, int val, int advance = 1);
+    char  peekAheadHelper();
+    char  peekCurHelper();
+    
+    Token lexString();
+    Token lexNumber();
+    Token lexNCName();
+    Token lexQName();
+    
+    Token nextToken();
+    Token nextTokenInternal();
+    
+    void reset(const String& data);
+    
+    HashSet<ParseNode*> m_parseNodes;
+    HashSet<Vector<Predicate*>*> m_predicateVectors;
+    HashSet<Vector<Expression*>*> m_expressionVectors;
+    HashSet<String*> m_strings;
+public:
+    Parser();
+    
+    Expression* parseStatement(const String& statement, ExceptionCode&);
+
+    static Parser* current() { return currentParser; }
+          
+    int lex(void* yylval);
+
+    Expression* m_topExpr;
+    bool m_gotNamespaceError;
+    
+    void registerParseNode(ParseNode*);
+    void unregisterParseNode(ParseNode*);
+    
+    void registerPredicateVector(Vector<Predicate*>*);
+    void unregisterPredicateVector(Vector<Predicate*>*);
+
+    void registerExpressionVector(Vector<Expression*>*);
+    void unregisterExpressionVector(Vector<Expression*>*);
+    
+    void registerString(String*);
+    void unregisterString(String*);
+};
+
+}
+}
+
+#endif // XPATH_SUPPORT
+
+#endif
diff --git a/WebCore/xpath/impl/XPathPath.cpp b/WebCore/xpath/impl/XPathPath.cpp
new file mode 100644 (file)
index 0000000..e5749ec
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+
+#if XPATH_SUPPORT
+
+#include "Logging.h"
+
+#include "XPathPath.h"
+
+#include "Document.h"
+#include "Node.h"
+
+namespace WebCore {
+namespace XPath {
+        
+Filter::Filter(Expression* expr, const Vector<Predicate*>& predicates)
+    : m_expr(expr),
+    m_predicates(predicates)
+{
+}
+
+Filter::~Filter()
+{
+    delete m_expr;
+    deleteAllValues(m_predicates);
+}
+
+Value Filter::doEvaluate() const
+{
+    Value v = m_expr->evaluate();
+    
+    if (!v.isNodeVector()) {
+        if (!m_predicates.isEmpty())
+            LOG(XPath, "Ignoring predicates for filter since expression does not evaluate to a nodevector!");
+
+        return v;
+    }
+
+    NodeVector inNodes = v.toNodeVector(), outNodes;
+    for (unsigned i = 0; i < m_predicates.size(); i++) {
+        outNodes.clear();
+        Expression::evaluationContext().size = inNodes.size();
+        Expression::evaluationContext().position = 0;
+        
+        for (unsigned j = 0; j < inNodes.size(); j++) {
+            Node* node = inNodes[j].get();
+            
+            Expression::evaluationContext().node = node;
+            ++Expression::evaluationContext().position;
+            
+            if (m_predicates[i]->evaluate())
+                outNodes.append(node);
+        }
+        inNodes = outNodes;
+    }
+
+    return outNodes;
+}
+
+LocationPath::LocationPath()
+    : m_absolute(false)
+{
+}
+
+LocationPath::~LocationPath()
+{
+    deleteAllValues(m_steps);
+}
+
+void LocationPath::optimize()
+{
+    for (unsigned i = 0; i < m_steps.size(); i++)
+        m_steps[i]->optimize();
+}
+
+Value LocationPath::doEvaluate() const
+{
+    if (m_absolute) {
+        LOG(XPath, "Evaluating absolute path expression with %i location steps.", m_steps.size());
+    } else {
+        LOG(XPath, "Evaluating relative path expression with %i location steps.", m_steps.size());
+    }
+
+    NodeVector inDomNodes, outDomNodes;
+
+    /* For absolute location paths, the context node is ignored - the
+     * document's root node is used instead.
+     */
+    Node* context = Expression::evaluationContext().node.get();
+    if (m_absolute && context->nodeType() != Node::DOCUMENT_NODE) 
+        context = context->ownerDocument();
+
+    inDomNodes.append(context);
+    
+    for (unsigned i = 0; i < m_steps.size(); i++) {
+        Step* step = m_steps[i];
+
+        for (unsigned j = 0; j < inDomNodes.size(); j++) {
+            NodeVector matches = step->evaluate(inDomNodes[j].get());
+            
+            outDomNodes.append(matches);
+        }
+        
+        inDomNodes = outDomNodes;
+        outDomNodes.clear();
+    }
+
+    return inDomNodes;
+}
+
+Path::Path(Filter* filter, LocationPath* path)
+    : m_filter(filter),
+    m_path(path)
+{
+}
+
+Path::~Path()
+{
+    delete m_filter;
+    delete m_path;
+}
+
+Value Path::doEvaluate() const
+{
+    return Value();
+}
+
+}
+}
+
+#endif // XPATH_SUPPORT
diff --git a/WebCore/xpath/impl/XPathPath.h b/WebCore/xpath/impl/XPathPath.h
new file mode 100644 (file)
index 0000000..da1aa1d
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * path.h - Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef XPathPath_H
+#define XPathPath_H
+
+#if XPATH_SUPPORT
+
+#include "XPathExpressionNode.h"
+#include "XPathStep.h"
+
+#include <kxmlcore/Vector.h>
+
+extern int xpathyyparse(void*);
+
+namespace WebCore {
+namespace XPath {
+        
+class Filter : public Expression
+{
+public:
+    Filter(Expression*, const Vector<Predicate*>& = Vector<Predicate*>());
+    virtual ~Filter();
+
+private:
+    virtual Value doEvaluate() const;
+
+    Expression* m_expr;
+    Vector<Predicate*> m_predicates;
+};
+
+class LocationPath : public Expression
+{
+friend int ::xpathyyparse(void*);
+public:
+    LocationPath();
+    virtual ~LocationPath();
+
+    void optimize();
+
+private:
+    virtual Value doEvaluate() const;
+
+    Vector<Step*> m_steps;
+    bool m_absolute;
+};
+
+class Path : public Expression
+{
+public:
+    Path(Filter*, LocationPath*);
+    virtual ~Path();
+
+private:
+    virtual Value doEvaluate() const;
+
+    Filter* m_filter;
+    LocationPath* m_path;
+};
+
+}
+}
+
+#endif // XPATH_SUPPORT
+
+#endif // XPath_Path_H
+
diff --git a/WebCore/xpath/impl/XPathPredicate.cpp b/WebCore/xpath/impl/XPathPredicate.cpp
new file mode 100644 (file)
index 0000000..09fb27b
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+
+#if XPATH_SUPPORT
+
+#include "XPathPredicate.h"
+#include "XPathFunctions.h"
+#include "Logging.h"
+
+#include "Node.h"
+
+#include <math.h>
+
+namespace WebCore {
+namespace XPath {
+        
+Number::Number(double value)
+    : m_value(value)
+{
+}
+
+bool Number::isConstant() const
+{
+    return true;
+}
+
+Value Number::doEvaluate() const
+{
+    return m_value;
+}
+
+StringExpression::StringExpression(const String& value)
+    : m_value(value)
+{
+}
+
+bool StringExpression::isConstant() const
+{
+    return true;
+}
+
+Value StringExpression::doEvaluate() const
+{
+    return m_value;
+}
+
+Value Negative::doEvaluate() const
+{
+    Value p(subExpr(0)->evaluate());
+    if (!p.isNumber()) {
+        LOG(XPath, "Unary minus is undefined for non-numeric types.");
+        return Value();
+    }
+    return -p.toNumber();
+}
+
+NumericOp::NumericOp(int opCode, Expression* lhs, Expression* rhs) :
+    m_opCode(opCode)
+{
+    addSubExpression(lhs);
+    addSubExpression(rhs);
+}
+
+Value NumericOp::doEvaluate() const
+{
+    Value lhs(subExpr(0)->evaluate());
+    Value rhs(subExpr(1)->evaluate());
+    
+    if (!lhs.isNumber() || !rhs.isNumber()) {
+        LOG(XPath, "Cannot perform operation on non-numeric types.");
+        return Value();
+    }
+
+    double leftVal = lhs.toNumber(), rightVal = rhs.toNumber();
+
+    switch (m_opCode) {
+        case OP_Add:
+            return leftVal + rightVal;
+        case OP_Sub:
+            return leftVal - rightVal;
+        case OP_Mul:
+            return leftVal * rightVal;
+        case OP_Div:
+            return leftVal / rightVal;
+        case OP_Mod:
+            return remainder(leftVal, rightVal);
+        case OP_GT:
+            return leftVal > rightVal;
+        case OP_GE:
+            return leftVal >= rightVal;
+        case OP_LT:
+            return leftVal < rightVal;
+        case OP_LE:
+            return leftVal <= rightVal;
+    }
+    
+    return Value();
+}
+
+EqTestOp::EqTestOp(int opCode, Expression* lhs, Expression* rhs) :
+    m_opCode(opCode)
+{
+    addSubExpression(lhs);
+    addSubExpression(rhs);
+}
+
+Value EqTestOp::doEvaluate() const
+{
+    Value lhs(subExpr(0)->evaluate());
+    Value rhs(subExpr(1)->evaluate());
+
+    bool equal;
+    if (lhs.isBoolean() || rhs.isBoolean()) {
+        equal = (lhs.toBoolean() == rhs.toBoolean());
+    } else if (lhs.isNumber() || rhs.isNumber()) {
+        equal = (lhs.toNumber() == rhs.toNumber());
+    } else {
+        equal = (lhs.toString() == rhs.toString());
+    }
+
+    if (m_opCode == OP_EQ)
+        return equal;
+
+    return !equal;
+}
+
+LogicalOp::LogicalOp(int opCode, Expression* lhs, Expression* rhs) :
+    m_opCode(opCode)
+{
+    addSubExpression(lhs);
+    addSubExpression(rhs);
+}
+
+bool LogicalOp::shortCircuitOn() const
+{
+    if (m_opCode == OP_And)
+        return false; //false and foo
+
+    return true;  //true or bar
+}
+
+bool LogicalOp::isConstant() const
+{
+    return subExpr(0)->isConstant() &&
+           subExpr(0)->evaluate().toBoolean() == shortCircuitOn();
+}
+
+Value LogicalOp::doEvaluate() const
+{
+    Value lhs(subExpr(0)->evaluate());
+
+    // This is not only an optimization, http://www.w3.org/TR/xpath
+    // dictates that we must do short-circuit evaluation
+    bool lhsBool = lhs.toBoolean();
+    if (lhsBool == shortCircuitOn())
+        return lhsBool;
+
+    return subExpr(1)->evaluate().toBoolean();
+}
+
+Value Union::doEvaluate() const
+{
+    Value lhs = subExpr(0)->evaluate();
+    Value rhs = subExpr(1)->evaluate();
+    if (!lhs.isNodeVector() || !rhs.isNodeVector()) {
+        LOG(XPath, "Union operator '|' works only with nodevectors.");
+        return NodeVector();
+    }
+    
+    NodeVector lhsNodes = lhs.toNodeVector();
+    NodeVector rhsNodes = rhs.toNodeVector();
+    NodeVector result = lhsNodes;
+    
+    HashSet<Node*> nodes;
+    
+    for (unsigned i = 0; i < rhsNodes.size(); i++) {
+        Node* node = rhsNodes[i].get();
+        
+        if (!nodes.contains(node)) {
+            result.append(node);
+            nodes.add(node);
+        }
+    }
+    
+    return result;
+}
+
+Predicate::Predicate(Expression* expr)
+    : m_expr(expr)
+{
+}
+
+Predicate::~Predicate()
+{
+    delete m_expr;
+}
+
+bool Predicate::evaluate() const
+{
+    ASSERT(m_expr != 0);
+
+    Value result(m_expr->evaluate());
+
+    // foo[3] really means foo[position()=3]
+    if (result.isNumber()) {
+        Expression* realExpr = new EqTestOp(EqTestOp::OP_EQ,
+                        FunctionLibrary::self().createFunction("position"),
+                        new Number(result.toNumber()));
+        result = realExpr->evaluate();
+        delete realExpr;
+    }
+
+    return result.toBoolean();
+}
+
+void Predicate::optimize()
+{
+    m_expr->optimize();
+}
+
+}
+}
+
+#endif // XPATH_SUPPORT
diff --git a/WebCore/xpath/impl/XPathPredicate.h b/WebCore/xpath/impl/XPathPredicate.h
new file mode 100644 (file)
index 0000000..a241d3f
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * predicate.h - Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef XPathPredicate_H
+#define XPathPredicate_H
+
+#if XPATH_SUPPORT
+
+#include "XPathExpressionNode.h"
+
+namespace WebCore {
+namespace XPath {
+        
+class Number : public Expression
+{
+public:
+    Number(double value);
+
+    bool isConstant() const;
+
+private:
+    virtual Value doEvaluate() const;
+
+    double m_value;
+};
+
+class StringExpression : public Expression
+{
+public:
+    StringExpression(const String& value);
+
+    bool isConstant() const;
+
+private:
+    virtual Value doEvaluate() const;
+
+    String m_value;
+};
+
+class Negative : public Expression
+{
+private:
+    virtual Value doEvaluate() const;
+};
+
+class BinaryExprBase : public Expression
+{
+};
+
+class NumericOp : public BinaryExprBase
+{
+public:
+    enum {
+        OP_Add = 1,
+        OP_Sub,
+        OP_Mul,
+        OP_Div,
+        OP_Mod,
+        OP_GT,
+        OP_LT,
+        OP_GE,
+        OP_LE
+    };
+
+    NumericOp(int opCode, Expression* lhs, Expression* rhs);
+
+private:
+    virtual Value doEvaluate() const;
+    int m_opCode;
+};
+
+class EqTestOp : public BinaryExprBase
+{
+public:
+    enum {
+        OP_EQ = 1,
+        OP_NE
+    };
+
+    EqTestOp(int opCode, Expression* lhs, Expression* rhs);
+
+private:
+    virtual Value doEvaluate() const;
+    int m_opCode;
+};
+
+class LogicalOp : public BinaryExprBase
+{
+public:
+    enum {
+        OP_And = 1,
+        OP_Or
+    };
+
+    LogicalOp(int opCode, Expression* lhs, Expression* rhs);
+
+    virtual bool isConstant() const;
+
+private:
+    bool shortCircuitOn() const;
+    virtual Value doEvaluate() const;
+    int m_opCode;
+};
+
+class Union : public BinaryExprBase
+{
+private:
+    virtual Value doEvaluate() const;
+};
+
+class Predicate
+{
+public:
+    Predicate(Expression*);
+    ~Predicate();
+
+    bool evaluate() const;
+
+    void optimize();
+
+private:
+    Predicate(const Predicate &rhs);
+    Predicate &operator=(const Predicate &rhs);
+
+    Expression* m_expr;
+};
+
+}
+}
+
+#endif // XPATH_SUPPORT
+
+#endif // PREDICATE_H
+
diff --git a/WebCore/xpath/impl/XPathStep.cpp b/WebCore/xpath/impl/XPathStep.cpp
new file mode 100644 (file)
index 0000000..05c8d15
--- /dev/null
@@ -0,0 +1,373 @@
+/*
+ * Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+
+#if XPATH_SUPPORT
+
+#include "XPathStep.h"
+
+#include "Logging.h"
+#include "Document.h"
+#include "NamedAttrMap.h"
+#include "Node.h"
+#include "Text.h"
+#include "XPathNSResolver.h"
+
+namespace WebCore {
+namespace XPath {
+
+String Step::axisAsString(AxisType axis)
+{
+    switch (axis) {
+        case AncestorAxis: return "ancestor";
+        case AncestorOrSelfAxis: return "ancestor-or-self";
+        case AttributeAxis: return "attribute";
+        case ChildAxis: return "child";
+        case DescendantAxis: return "descendant";
+        case DescendantOrSelfAxis: return "descendant-or-self";
+        case FollowingAxis: return "following";
+        case FollowingSiblingAxis: return "following-sibling";
+        case NamespaceAxis: return "namespace";
+        case ParentAxis: return "parent";
+        case PrecedingAxis: return "preceding";
+        case PrecedingSiblingAxis: return "preceding-sibling";
+        case SelfAxis: return "self";
+    }
+    return String();
+}
+
+Step::Step()
+{
+}
+
+Step::Step(AxisType axis, const String& nodeTest, const Vector<Predicate*>& predicates)
+    : m_axis(axis),
+    m_nodeTest(nodeTest),
+    m_predicates(predicates)
+{
+}
+
+Step::~Step()
+{
+    deleteAllValues(m_predicates);
+}
+
+NodeVector Step::evaluate(Node* context) const
+{
+    LOG(XPath, "Evaluating step, axis='%s', nodetest='%s', %u predicates",
+            axisAsString(m_axis).ascii(), m_nodeTest.ascii(), m_predicates.size());
+    if (context->nodeType() == Node::ELEMENT_NODE)
+        LOG(XPath, "Context node is an element called %s", context->nodeName().ascii());
+    else if (context->nodeType() == Node::ATTRIBUTE_NODE)
+        LOG(XPath, "Context node is an attribute called %s with value %s", 
+               context->nodeName().ascii(), 
+               context->nodeValue().ascii());
+    else
+        LOG(XPath, "Context node is of unknown type %d", context->nodeType());
+
+    NodeVector inNodes = nodesInAxis(context), outNodes;
+    LOG(XPath, "Axis %s matches %d nodes.", axisAsString(m_axis).ascii(), inNodes.size());
+
+    inNodes = nodeTestMatches(inNodes);
+    LOG(XPath, "Nodetest %s trims this number to %d", m_nodeTest.ascii(), inNodes.size());
+    
+    outNodes = inNodes;
+    for (unsigned i = 0; i < m_predicates.size(); i++) {
+        Predicate* predicate = m_predicates[i];
+
+        outNodes.clear();
+        Expression::evaluationContext().size = inNodes.size();
+        Expression::evaluationContext().position = 1;
+        for (unsigned j = 0; j < inNodes.size(); j++) {
+            Node* node = inNodes[j].get();
+
+            Expression::evaluationContext().node = node;
+            EvaluationContext backupCtx = Expression::evaluationContext();
+            if (predicate->evaluate())
+                outNodes.append(node);
+
+            Expression::evaluationContext() = backupCtx;
+            ++Expression::evaluationContext().position;
+        }
+
+        LOG(XPath, "\tPredicate trims this number to %d", outNodes.size());
+
+        inNodes = outNodes;
+    }
+    return outNodes;
+}
+
+NodeVector Step::nodesInAxis(Node* context) const
+{
+    NodeVector nodes;
+    switch (m_axis) {
+        case ChildAxis:
+            for (Node* n = context->firstChild(); n; n = n->nextSibling())
+                nodes.append(n);
+            return nodes;
+        case DescendantAxis: 
+            for (Node* n = context->firstChild(); n; n = n->traverseNextNode(context))
+                nodes.append(n);
+            return nodes;
+        case ParentAxis:
+            nodes.append(context->parentNode());
+            return nodes;
+        case AncestorAxis:
+            for (Node* n = context->parentNode(); n; n = n->parentNode())
+                nodes.append(n);
+            return nodes;
+        case FollowingSiblingAxis:
+            if (context->nodeType() == Node::ATTRIBUTE_NODE ||
+                 context->nodeType() == Node::XPATH_NAMESPACE_NODE) 
+                return NodeVector();
+            
+            for (Node* n = context->nextSibling(); n; n = n->nextSibling())
+                nodes.append(n);
+            return nodes;
+        case PrecedingSiblingAxis:
+            if (context->nodeType() == Node::ATTRIBUTE_NODE ||
+                 context->nodeType() == Node::XPATH_NAMESPACE_NODE)
+                return NodeVector();
+            
+            for (Node* n = context->previousSibling(); n; n = n->previousSibling())
+                nodes.append(n);
+            return nodes;
+        case FollowingAxis: 
+            for (Node *p = context; !isRootDomNode(p); p = p->parentNode()) {
+                for (Node* n = p->nextSibling(); n; n = n->nextSibling()) {
+                    nodes.append(n);
+                    for (Node* c = n->firstChild(); c; c = c->traverseNextNode(n))
+                        nodes.append(c);
+                }
+            }
+            return nodes;
+        case PrecedingAxis:
+            for (Node* p = context; !isRootDomNode(p); p = p->parentNode()) {
+                for (Node* n = p->previousSibling(); n ; n = n->previousSibling()) {
+                    nodes.append(n);
+                    for (Node* c = n->firstChild(); c; c = c->traverseNextNode(n))
+                        nodes.append(c);
+                }
+            }
+            return nodes;
+        case AttributeAxis: {
+            if (context->nodeType() != Node::ELEMENT_NODE)
+                return NodeVector();
+
+            NamedAttrMap* attrs = context->attributes();
+            if (!attrs) {
+                LOG(XPath, "Node::attributes() returned NULL!");
+                return nodes;
+            }
+
+            for (unsigned long i = 0; i < attrs->length(); ++i) 
+                nodes.append (attrs->item(i));
+            return nodes;
+        }
+        case NamespaceAxis: {
+            if (context->nodeType() != Node::ELEMENT_NODE)
+                return NodeVector();
+
+            bool foundXmlNsNode = false;
+            for (Node* node = context; node; node = node->parentNode()) {
+                NamedAttrMap* attrs = node->attributes();
+                if (!attrs) {
+                    LOG(XPath, "Node::attributes() returned NULL!");
+
+                    continue;
+                }
+
+                for (unsigned long i = 0; i < attrs->length(); ++i) {
+                    Node* n = attrs->item(i).get();
+                    if (n->nodeName().startsWith("xmlns:")) {
+                        nodes.append(n);
+                    } else if (n->nodeName() == "xmlns" &&
+                               !foundXmlNsNode) {
+                        foundXmlNsNode = true;
+                        if (!n->nodeValue().isEmpty())
+                            nodes.append(n);
+                    }
+                }
+            }
+            return nodes;
+        }
+        case SelfAxis:
+            nodes.append(context);
+            return nodes;
+        case DescendantOrSelfAxis:
+            nodes.append(context);
+            for (Node* n = context->firstChild(); n; n = n->traverseNextNode(context))
+                nodes.append(n);
+            return nodes;
+        case AncestorOrSelfAxis:
+            nodes.append(context);
+            for (Node* n = context->parentNode(); n; n = n->parentNode())
+                nodes.append(n);
+            return nodes;
+    }
+
+    return NodeVector();
+}
+
+
+NodeVector Step::nodeTestMatches(const NodeVector& nodes) const
+{
+    String ns = namespaceFromNodetest(m_nodeTest);
+    NodeVector matches;
+    if (m_nodeTest == "*") {
+        for (unsigned i = 0; i < nodes.size(); i++) {
+            Node* node = nodes[i].get();
+            if (node->nodeType() == primaryNodeType(m_axis)) {
+                if (ns.isEmpty() ||
+                     node->namespaceURI() == ns) {
+                    matches.append(node);
+                }
+            }
+        }
+        return nodes;
+    } else if (m_nodeTest == "text()") {
+        for (unsigned i = 0; i < nodes.size(); i++) {
+            Node* node = nodes[i].get();
+            if (node->nodeType() == Node::TEXT_NODE ||
+                node->nodeType() == Node::CDATA_SECTION_NODE) 
+                matches.append(node);
+        }
+        return matches;
+    } else if (m_nodeTest == "comment()") {
+        for (unsigned i = 0; i < nodes.size(); i++) {
+            Node* node = nodes[i].get();
+            if (node->nodeType() == Node::COMMENT_NODE)
+                matches.append(node);
+        }
+        return matches;
+    } else if (m_nodeTest.startsWith("processing-instruction")) {
+        String param;
+
+        const int space = m_nodeTest.find(' ');
+        if (space > -1)
+            param = m_nodeTest.deprecatedString().mid(space + 1);
+
+        for (unsigned i = 0; i < nodes.size(); i++) {
+            Node* node = nodes[i].get();
+
+            if (node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE &&
+                (param.isEmpty() || node->nodeName() == param))
+                    matches.append(node);
+        }    
+        return matches;
+    } else if (m_nodeTest == "node()")
+        return nodes;
+    else {
+        String prefix, localName;
+
+        const int colon = m_nodeTest.find(':');
+        if (colon > -1) {
+            prefix = m_nodeTest.left(colon);
+            localName = m_nodeTest.deprecatedString().mid(colon + 1);
+        } else {
+            localName = m_nodeTest;
+        }
+
+        if (!prefix.isEmpty() &&
+            Expression::evaluationContext().resolver->lookupNamespaceURI(prefix).isEmpty()) {
+                /* FIXME: Throw NAMESPACE_ERR exception */
+        }
+
+        if (m_axis == AttributeAxis) {
+            // In XPath land, namespace nodes are not accessible
+            // on the attribute axis.
+            if (localName == "xmlns")
+                return matches;
+
+            for (unsigned i = 0; i < nodes.size(); i++) {
+                Node* node = nodes[i].get();
+                
+                if (node->nodeName() == localName) {
+                    matches.append(node);
+                    break; // There can only be one.
+                }
+            }
+
+            return matches;
+        } else if (m_axis == NamespaceAxis) {
+            LOG(XPath, "Node test %s on axis %s is not implemented yet.",
+                m_nodeTest.ascii(), axisAsString(m_axis).ascii());
+        } else {
+            for (unsigned i = 0; i < nodes.size(); i++) {
+                Node* node = nodes[i].get();
+                // We use tagQName here because we don't want the element name in uppercase 
+                // like we get with HTML elements.
+                if (node->nodeType() == Node::ELEMENT_NODE &&
+                    static_cast<Element*>(node)->tagQName().toString() == localName) {
+                    matches.append(node);
+                }
+            }
+
+            return matches;
+        }
+    }
+    
+    LOG(XPath, "Node test %s on axis %s is not implemented yet.",
+        m_nodeTest.ascii(), axisAsString(m_axis).ascii());
+
+    return matches;
+}
+
+void Step::optimize()
+{
+    for (unsigned i = 0; i < m_predicates.size(); i++)
+        m_predicates[i]->optimize();
+}
+
+String Step::namespaceFromNodetest(const String& nodeTest) const
+{
+    int i = nodeTest.find(':');
+    if (i == -1)
+        return String();
+
+    String prefix(nodeTest.left(i));
+    
+    Node* ctxNode = Expression::evaluationContext().node.get();
+    return ctxNode->lookupNamespaceURI(prefix);
+}
+
+Node::NodeType Step::primaryNodeType(AxisType axis) const
+{
+    switch (axis) {
+        case AttributeAxis:
+            return Node::ATTRIBUTE_NODE;
+        case NamespaceAxis:
+            return Node::XPATH_NAMESPACE_NODE;
+        default:
+            return Node::ELEMENT_NODE;
+    }
+}
+
+}
+}
+
+#endif // XPATH_SUPPORT
diff --git a/WebCore/xpath/impl/XPathStep.h b/WebCore/xpath/impl/XPathStep.h
new file mode 100644 (file)
index 0000000..cd4ef60
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * step.h - Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef XPathStep_H
+#define XPathStep_H
+
+#if XPATH_SUPPORT
+
+#include "XPathPredicate.h"
+#include "XPathUtil.h"
+
+#include "Node.h"
+
+namespace WebCore {
+namespace XPath {
+        
+class Step : public ParseNode
+{
+public:
+    enum AxisType {
+        AncestorAxis=1, AncestorOrSelfAxis, AttributeAxis,
+        ChildAxis, DescendantAxis, DescendantOrSelfAxis,
+        FollowingAxis, FollowingSiblingAxis, NamespaceAxis,
+        ParentAxis, PrecedingAxis, PrecedingSiblingAxis,
+        SelfAxis
+    };
+
+    static String axisAsString(AxisType axis);
+
+    Step();
+    Step(AxisType axis, const String& nodeTest, const Vector<Predicate*> &predicates = Vector<Predicate*>());
+    ~Step();
+
+    NodeVector evaluate(Node* context) const;
+
+    void optimize();
+
+private:
+    NodeVector nodesInAxis(Node* context) const;
+    NodeVector nodeTestMatches(const NodeVector& nodes) const;
+    String namespaceFromNodetest(const String& nodeTest) const;
+    Node::NodeType primaryNodeType(AxisType axis) const;
+
+    AxisType m_axis;
+    String m_nodeTest;
+    Vector<Predicate*> m_predicates;
+};
+
+}
+}
+
+#endif // XPATH_SUPPORT
+
+#endif // XPath_Step_H
+
diff --git a/WebCore/xpath/impl/XPathUtil.cpp b/WebCore/xpath/impl/XPathUtil.cpp
new file mode 100644 (file)
index 0000000..98c1219
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+
+#if XPATH_SUPPORT
+
+#include "XPathUtil.h"
+#include "Node.h"
+
+namespace WebCore {
+namespace XPath {
+        
+bool isRootDomNode(Node* node)
+{
+    return node && !node->parentNode();
+}
+
+String stringValue(Node* node)
+{
+    switch (node->nodeType()) {
+        case Node::ATTRIBUTE_NODE:
+        case Node::PROCESSING_INSTRUCTION_NODE:
+        case Node::COMMENT_NODE:
+        case Node::TEXT_NODE:
+            return node->nodeValue();
+        default:
+            if (isRootDomNode(node)
+                 || node->nodeType() == Node::ELEMENT_NODE) {
+                String str;
+                
+                for (Node* n = node->firstChild(); n; n = n->traverseNextNode(node))
+                    str += stringValue(n);
+
+                return str;
+            }
+    }
+    
+    return String();
+}
+
+bool isValidContextNode(Node* node)
+{
+    return node && (
+           node->nodeType() == Node::ELEMENT_NODE ||
+           node->nodeType() == Node::ATTRIBUTE_NODE ||
+           node->nodeType() == Node::TEXT_NODE ||
+           node->nodeType() == Node::CDATA_SECTION_NODE ||
+           node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE ||
+           node->nodeType() == Node::COMMENT_NODE ||
+           node->nodeType() == Node::DOCUMENT_NODE ||
+           node->nodeType() == Node::XPATH_NAMESPACE_NODE);
+}
+
+}
+}
+
+#endif // XPATH_SUPPORT
+
diff --git a/WebCore/xpath/impl/XPathUtil.h b/WebCore/xpath/impl/XPathUtil.h
new file mode 100644 (file)
index 0000000..20308ba
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * util.h - Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef XPathUtil_H
+#define XPathUtil_H
+
+#if XPATH_SUPPORT
+
+#include "PlatformString.h"
+#include "Node.h"
+
+#include <kxmlcore/Vector.h>
+
+namespace WebCore {
+
+namespace XPath {
+
+typedef Vector<RefPtr<Node> > NodeVector;
+    
+/* @return whether the given node is the root node.
+ */
+bool isRootDomNode(Node* node);
+
+/* @return the 'string-value' of the given node as specified by
+   http://www.w3.org/TR/xpath
+ */
+String stringValue(Node* node);
+
+/* @return whether the given node is a valid context node
+ */
+bool isValidContextNode(Node* node);
+
+}
+}
+
+#endif // XPATH_SUPPORT
+
+#endif // XPath_Util_H
+
diff --git a/WebCore/xpath/impl/XPathValue.cpp b/WebCore/xpath/impl/XPathValue.cpp
new file mode 100644 (file)
index 0000000..a0b3aaf
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+
+#if XPATH_SUPPORT
+
+#include "XPathValue.h"
+#include "Logging.h"
+
+namespace WebCore {
+namespace XPath {
+
+Value::Value()
+{
+}
+
+Value::Value(Node* value)
+    : m_type(NodeVector_)
+{
+    m_nodevector.append(value);
+}
+
+Value::Value(const NodeVector& value)
+    : m_type(NodeVector_)
+    , m_nodevector(value)
+{
+}
+
+Value::Value(bool value)
+    : m_type(Boolean),
+    m_bool(value)
+{
+}
+
+Value::Value(double value)
+    : m_type(Number),
+    m_number(value)
+{
+}
+
+Value::Value(const String& value)
+    : m_type(String_),
+    m_string(value)
+{
+}
+
+Value::Type Value::type() const
+{
+    return m_type;
+}
+
+bool Value::isNodeVector() const
+{
+    return m_type == NodeVector_;
+}
+
+bool Value::isBoolean() const
+{
+    return m_type == Boolean;
+}
+
+bool Value::isNumber() const
+{
+    return m_type == Number;
+}
+
+bool Value::isString() const
+{
+    return m_type == String_;
+}
+
+NodeVector& Value::toNodeVector()
+{
+    if (m_type != NodeVector_) {
+        LOG(XPath, "Cannot convert anything to a nodevector.");
+    }
+    return m_nodevector;
+}
+
+const NodeVector &Value::toNodeVector() const
+{
+    if (m_type != NodeVector_) {
+        LOG(XPath, "Cannot convert anything to a nodevector.");
+    }
+    
+    return m_nodevector;    
+}    
+
+bool Value::toBoolean() const
+{
+    switch (m_type) {
+        case NodeVector_:
+            return !m_nodevector.isEmpty();
+        case Boolean:
+            return m_bool;
+        case Number:
+            return m_number != 0;
+        case String_:
+            return !m_string.isEmpty();
+    }
+    return false;
+}
+
+double Value::toNumber() const
+{
+    switch (m_type) {
+        case NodeVector_:
+            return Value(toString()).toNumber();
+        case Number:
+            return m_number;
+        case String_: {
+            bool canConvert;
+            DeprecatedString s = m_string.deprecatedString().simplifyWhiteSpace();
+            
+            double value = s.toDouble(&canConvert);
+            if (canConvert)
+                return value;
+
+            return NAN;
+        }
+        case Boolean:
+            return m_bool;
+    }
+    return 0.0;
+}
+
+String Value::toString() const
+{
+    switch (m_type) {
+        case NodeVector_:
+            if (m_nodevector.isEmpty()) 
+                return "";
+
+            return stringValue(m_nodevector[0].get());
+        case String_:
+            return m_string;
+        case Number:
+            if (isnan(m_number))
+                return "NaN";
+            else if (m_number == 0)
+                return "0";
+            else if (isinf(m_number)) {
+                if (signbit(m_number) == 0)
+                    return "Infinity";
+                else
+                    return "-Infinity";
+            }
+            return DeprecatedString::number(m_number);
+        case Boolean:
+            return m_bool ? "true" : "false";
+    }
+    
+    return String();
+}
+
+
+}
+}
+
+#endif // XPATH_SUPPORT
\ No newline at end of file
diff --git a/WebCore/xpath/impl/XPathValue.h b/WebCore/xpath/impl/XPathValue.h
new file mode 100644 (file)
index 0000000..7f1b1c6
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * util.h - Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef XPathValue_H
+#define XPathValue_H
+
+#if XPATH_SUPPORT
+
+#include "XPathUtil.h"
+
+namespace WebCore {
+namespace XPath {
+    
+class Value
+{
+public:
+    enum Type {
+        NodeVector_, Boolean, Number, String_
+    };
+    
+    Value();
+    Value(Node* value);
+    Value(const NodeVector& value);
+    Value(bool value);
+    Value(double value);
+    Value(const String& value);
+    
+    Type type() const;
+    bool isNodeVector() const;
+    bool isBoolean() const;
+    bool isNumber() const;
+    bool isString() const;
+    
+    NodeVector& toNodeVector();
+    const NodeVector& toNodeVector() const;
+    
+    bool toBoolean() const;
+    double toNumber() const;
+    String toString() const;
+    
+private:
+    Type m_type;
+    NodeVector m_nodevector;
+    bool m_bool;
+    double m_number;
+    String m_string;
+};
+
+}
+}
+
+#endif // XPATH_SUPPORT
+
+#endif // XPath_Value_H
+
diff --git a/WebCore/xpath/impl/XPathVariableReference.cpp b/WebCore/xpath/impl/XPathVariableReference.cpp
new file mode 100644 (file)
index 0000000..b063b8f
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+
+#if XPATH_SUPPORT
+
+#include "XPathVariableReference.h"
+
+#include "PlatformString.h"
+
+namespace WebCore {
+namespace XPath {
+    
+VariableReference::VariableReference(const String& name)
+    : m_name(name)
+{
+}
+
+bool VariableReference::isConstant() const
+{
+    return false;
+}
+
+Value VariableReference::doEvaluate() const
+{
+    HashMap<String, String>* bindings = &evaluationContext().variableBindings;
+    if (!bindings->contains(m_name))
+        // FIXME What to do if an unknown variable is referenced?
+        return "";
+
+    return bindings->get(m_name);
+}
+
+}
+}
+
+#endif // XPATH_SUPPORT
diff --git a/WebCore/xpath/impl/XPathVariableReference.h b/WebCore/xpath/impl/XPathVariableReference.h
new file mode 100644 (file)
index 0000000..621fc37
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * variablereference.h - Copyright 2005 Frerich Raabe <raabe@kde.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef XPathVariableReference_H
+#define XPathVariableReference_H
+
+#if XPATH_SUPPORT
+
+#include "XPathExpressionNode.h"
+
+namespace WebCore {
+namespace XPath {
+    
+class VariableReference : public Expression
+{
+public:
+    VariableReference(const String& name);
+
+    virtual bool isConstant() const;
+
+private:
+    virtual Value doEvaluate() const;
+
+    String m_name;
+};
+
+}
+}
+
+#endif // XPATH_SUPPORT
+
+#endif // XPath_VariableReference_H
+