EncodedJSValue JSC_HOST_CALL jsXPathEvaluatorPrototypeFunctionEvaluate(ExecState* exec) { JSValue thisValue = exec->hostThisValue(); JSXPathEvaluator* castedThis = jsDynamicCast<JSXPathEvaluator*>(thisValue); if (!castedThis) return throwVMTypeError(exec); ASSERT_GC_OBJECT_INHERITS(castedThis, JSXPathEvaluator::info()); XPathEvaluator& impl = castedThis->impl(); ExceptionCode ec = 0; const String& expression(exec->argument(0).isEmpty() ? String() : exec->argument(0).toString(exec)->value(exec)); if (exec->hadException()) return JSValue::encode(jsUndefined()); Node* contextNode(toNode(exec->argument(1))); if (exec->hadException()) return JSValue::encode(jsUndefined()); RefPtr<XPathNSResolver> customResolver; XPathNSResolver* resolver = toXPathNSResolver(exec->argument(2)); if (!resolver) { customResolver = JSCustomXPathNSResolver::create(exec, exec->argument(2)); if (exec->hadException()) return JSValue::encode(jsUndefined()); resolver = customResolver.get(); } uint16_t type(toUInt16(exec, exec->argument(3), NormalConversion)); if (exec->hadException()) return JSValue::encode(jsUndefined()); XPathResult* inResult(toXPathResult(exec->argument(4))); if (exec->hadException()) return JSValue::encode(jsUndefined()); JSC::JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(impl.evaluate(expression, contextNode, resolver, type, inResult, ec))); setDOMException(exec, ec); return JSValue::encode(result); }
EncodedJSValue JSC_HOST_CALL jsXPathEvaluatorPrototypeFunctionEvaluate(ExecState* exec) { JSValue thisValue = exec->hostThisValue(); if (!thisValue.inherits(&JSXPathEvaluator::s_info)) return throwVMTypeError(exec); JSXPathEvaluator* castedThis = static_cast<JSXPathEvaluator*>(asObject(thisValue)); XPathEvaluator* imp = static_cast<XPathEvaluator*>(castedThis->impl()); ExceptionCode ec = 0; const String& expression(ustringToString(exec->argument(0).toString(exec))); if (exec->hadException()) return JSValue::encode(jsUndefined()); Node* contextNode(toNode(exec->argument(1))); if (exec->hadException()) return JSValue::encode(jsUndefined()); RefPtr<XPathNSResolver> customResolver; XPathNSResolver* resolver = toXPathNSResolver(exec->argument(2)); if (!resolver) { customResolver = JSCustomXPathNSResolver::create(exec, exec->argument(2)); if (exec->hadException()) return JSValue::encode(jsUndefined()); resolver = customResolver.get(); } unsigned short type(exec->argument(3).toUInt32(exec)); if (exec->hadException()) return JSValue::encode(jsUndefined()); XPathResult* inResult(toXPathResult(exec->argument(4))); if (exec->hadException()) return JSValue::encode(jsUndefined()); JSC::JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->evaluate(expression, contextNode, resolver, type, inResult, ec))); setDOMException(exec, ec); return JSValue::encode(result); }
EncodedJSValue JSC_HOST_CALL jsXPathExpressionPrototypeFunctionEvaluate(ExecState* exec) { JSValue thisValue = exec->hostThisValue(); if (!thisValue.inherits(&JSXPathExpression::s_info)) return throwVMTypeError(exec); JSXPathExpression* castedThis = static_cast<JSXPathExpression*>(asObject(thisValue)); ASSERT_GC_OBJECT_INHERITS(castedThis, &JSXPathExpression::s_info); XPathExpression* imp = static_cast<XPathExpression*>(castedThis->impl()); ExceptionCode ec = 0; Node* contextNode(toNode(exec->argument(0))); if (exec->hadException()) return JSValue::encode(jsUndefined()); unsigned short type(exec->argument(1).toUInt32(exec)); if (exec->hadException()) return JSValue::encode(jsUndefined()); XPathResult* inResult(toXPathResult(exec->argument(2))); if (exec->hadException()) return JSValue::encode(jsUndefined()); JSC::JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->evaluate(contextNode, type, inResult, ec))); setDOMException(exec, ec); return JSValue::encode(result); }
already_AddRefed<XPathResult> XPathExpression::EvaluateWithContext(nsINode& aContextNode, uint32_t aContextPosition, uint32_t aContextSize, uint16_t aType, XPathResult* aInResult, ErrorResult& aRv) { if (aContextPosition > aContextSize) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } if (!nsContentUtils::LegacyIsCallerNativeCode() && !nsContentUtils::CanCallerAccess(&aContextNode)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return nullptr; } if (mCheckDocument) { nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument); if (doc != aContextNode.OwnerDoc()) { aRv.Throw(NS_ERROR_DOM_WRONG_DOCUMENT_ERR); return nullptr; } } uint16_t nodeType = aContextNode.NodeType(); if (nodeType == nsIDOMNode::TEXT_NODE || nodeType == nsIDOMNode::CDATA_SECTION_NODE) { nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(&aContextNode); if (!textNode) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } uint32_t textLength; textNode->GetLength(&textLength); if (textLength == 0) { aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); return nullptr; } // XXX Need to get logical XPath text node for CDATASection // and Text nodes. } else if (nodeType != nsIDOMNode::DOCUMENT_NODE && nodeType != nsIDOMNode::ELEMENT_NODE && nodeType != nsIDOMNode::ATTRIBUTE_NODE && nodeType != nsIDOMNode::COMMENT_NODE && nodeType != nsIDOMNode::PROCESSING_INSTRUCTION_NODE) { aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); return nullptr; } nsAutoPtr<txXPathNode> contextNode(txXPathNativeNode::createXPathNode(&aContextNode)); if (!contextNode) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } EvalContextImpl eContext(*contextNode, aContextPosition, aContextSize, mRecycler); RefPtr<txAExprResult> exprResult; aRv = mExpression->evaluate(&eContext, getter_AddRefs(exprResult)); if (aRv.Failed()) { return nullptr; } uint16_t resultType = aType; if (aType == XPathResult::ANY_TYPE) { short exprResultType = exprResult->getResultType(); switch (exprResultType) { case txAExprResult::NUMBER: resultType = XPathResult::NUMBER_TYPE; break; case txAExprResult::STRING: resultType = XPathResult::STRING_TYPE; break; case txAExprResult::BOOLEAN: resultType = XPathResult::BOOLEAN_TYPE; break; case txAExprResult::NODESET: resultType = XPathResult::UNORDERED_NODE_ITERATOR_TYPE; break; case txAExprResult::RESULT_TREE_FRAGMENT: aRv.Throw(NS_ERROR_FAILURE); return nullptr; } } RefPtr<XPathResult> xpathResult = aInResult; if (!xpathResult) { xpathResult = new XPathResult(&aContextNode); } aRv = xpathResult->SetExprResult(exprResult, resultType, &aContextNode); return xpathResult.forget(); }
NS_IMETHODIMP nsXPathExpression::EvaluateWithContext(nsIDOMNode *aContextNode, PRUint32 aContextPosition, PRUint32 aContextSize, PRUint16 aType, nsISupports *aInResult, nsISupports **aResult) { NS_ENSURE_ARG(aContextNode); if (aContextPosition > aContextSize) return NS_ERROR_FAILURE; if (!URIUtils::CanCallerAccess(aContextNode)) return NS_ERROR_DOM_SECURITY_ERR; nsresult rv; PRUint16 nodeType; rv = aContextNode->GetNodeType(&nodeType); NS_ENSURE_SUCCESS(rv, rv); if (nodeType == nsIDOMNode::TEXT_NODE || nodeType == nsIDOMNode::CDATA_SECTION_NODE) { nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(aContextNode); NS_ENSURE_TRUE(textNode, NS_ERROR_FAILURE); if (textNode) { PRUint32 textLength; textNode->GetLength(&textLength); if (textLength == 0) return NS_ERROR_DOM_NOT_SUPPORTED_ERR; } // XXX Need to get logical XPath text node for CDATASection // and Text nodes. } else if (nodeType != nsIDOMNode::DOCUMENT_NODE && nodeType != nsIDOMNode::ELEMENT_NODE && nodeType != nsIDOMNode::ATTRIBUTE_NODE && nodeType != nsIDOMNode::COMMENT_NODE && nodeType != nsIDOMNode::PROCESSING_INSTRUCTION_NODE && nodeType != nsIDOMXPathNamespace::XPATH_NAMESPACE_NODE) { return NS_ERROR_DOM_NOT_SUPPORTED_ERR; } NS_ENSURE_ARG(aResult); *aResult = nsnull; nsAutoPtr<txXPathNode> contextNode(txXPathNativeNode::createXPathNode(aContextNode)); if (!contextNode) { return NS_ERROR_OUT_OF_MEMORY; } EvalContextImpl eContext(*contextNode, aContextPosition, aContextSize, mRecycler); nsRefPtr<txAExprResult> exprResult; rv = mExpression->evaluate(&eContext, getter_AddRefs(exprResult)); NS_ENSURE_SUCCESS(rv, rv); PRUint16 resultType = aType; if (aType == nsIDOMXPathResult::ANY_TYPE) { short exprResultType = exprResult->getResultType(); switch (exprResultType) { case txAExprResult::NUMBER: resultType = nsIDOMXPathResult::NUMBER_TYPE; break; case txAExprResult::STRING: resultType = nsIDOMXPathResult::STRING_TYPE; break; case txAExprResult::BOOLEAN: resultType = nsIDOMXPathResult::BOOLEAN_TYPE; break; case txAExprResult::NODESET: resultType = nsIDOMXPathResult::UNORDERED_NODE_ITERATOR_TYPE; break; case txAExprResult::RESULT_TREE_FRAGMENT: NS_ERROR("Can't return a tree fragment!"); return NS_ERROR_FAILURE; } } // We need a result object and it must be our implementation. nsCOMPtr<nsIXPathResult> xpathResult = do_QueryInterface(aInResult); if (!xpathResult) { // Either no aInResult or not one of ours. xpathResult = new nsXPathResult(); NS_ENSURE_TRUE(xpathResult, NS_ERROR_OUT_OF_MEMORY); } rv = xpathResult->SetExprResult(exprResult, resultType); NS_ENSURE_SUCCESS(rv, rv); return CallQueryInterface(xpathResult, aResult); }