dom/xslt/xpath/nsXPathExpression.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "nsXPathExpression.h"
michael@0 7 #include "txExpr.h"
michael@0 8 #include "txExprResult.h"
michael@0 9 #include "nsError.h"
michael@0 10 #include "nsIDOMCharacterData.h"
michael@0 11 #include "nsDOMClassInfoID.h"
michael@0 12 #include "nsIDOMDocument.h"
michael@0 13 #include "nsXPathResult.h"
michael@0 14 #include "txURIUtils.h"
michael@0 15 #include "txXPathTreeWalker.h"
michael@0 16
michael@0 17 NS_IMPL_CYCLE_COLLECTION(nsXPathExpression, mDocument)
michael@0 18
michael@0 19 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXPathExpression)
michael@0 20 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXPathExpression)
michael@0 21
michael@0 22 DOMCI_DATA(XPathExpression, nsXPathExpression)
michael@0 23
michael@0 24 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXPathExpression)
michael@0 25 NS_INTERFACE_MAP_ENTRY(nsIDOMXPathExpression)
michael@0 26 NS_INTERFACE_MAP_ENTRY(nsIDOMNSXPathExpression)
michael@0 27 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMXPathExpression)
michael@0 28 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XPathExpression)
michael@0 29 NS_INTERFACE_MAP_END
michael@0 30
michael@0 31 nsXPathExpression::nsXPathExpression(nsAutoPtr<Expr>& aExpression,
michael@0 32 txResultRecycler* aRecycler,
michael@0 33 nsIDOMDocument *aDocument)
michael@0 34 : mExpression(aExpression),
michael@0 35 mRecycler(aRecycler),
michael@0 36 mDocument(aDocument)
michael@0 37 {
michael@0 38 }
michael@0 39
michael@0 40 NS_IMETHODIMP
michael@0 41 nsXPathExpression::Evaluate(nsIDOMNode *aContextNode,
michael@0 42 uint16_t aType,
michael@0 43 nsISupports *aInResult,
michael@0 44 nsISupports **aResult)
michael@0 45 {
michael@0 46 return EvaluateWithContext(aContextNode, 1, 1, aType, aInResult, aResult);
michael@0 47 }
michael@0 48
michael@0 49 NS_IMETHODIMP
michael@0 50 nsXPathExpression::EvaluateWithContext(nsIDOMNode *aContextNode,
michael@0 51 uint32_t aContextPosition,
michael@0 52 uint32_t aContextSize,
michael@0 53 uint16_t aType,
michael@0 54 nsISupports *aInResult,
michael@0 55 nsISupports **aResult)
michael@0 56 {
michael@0 57 nsCOMPtr<nsINode> context = do_QueryInterface(aContextNode);
michael@0 58 NS_ENSURE_ARG(context);
michael@0 59
michael@0 60 if (aContextPosition > aContextSize)
michael@0 61 return NS_ERROR_FAILURE;
michael@0 62
michael@0 63 if (!nsContentUtils::CanCallerAccess(aContextNode))
michael@0 64 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 65
michael@0 66 if (mDocument && mDocument != aContextNode) {
michael@0 67 nsCOMPtr<nsIDOMDocument> contextDocument;
michael@0 68 aContextNode->GetOwnerDocument(getter_AddRefs(contextDocument));
michael@0 69
michael@0 70 if (mDocument != contextDocument) {
michael@0 71 return NS_ERROR_DOM_WRONG_DOCUMENT_ERR;
michael@0 72 }
michael@0 73 }
michael@0 74
michael@0 75 uint16_t nodeType = context->NodeType();
michael@0 76
michael@0 77 if (nodeType == nsIDOMNode::TEXT_NODE ||
michael@0 78 nodeType == nsIDOMNode::CDATA_SECTION_NODE) {
michael@0 79 nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(aContextNode);
michael@0 80 NS_ENSURE_TRUE(textNode, NS_ERROR_FAILURE);
michael@0 81
michael@0 82 if (textNode) {
michael@0 83 uint32_t textLength;
michael@0 84 textNode->GetLength(&textLength);
michael@0 85 if (textLength == 0)
michael@0 86 return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
michael@0 87 }
michael@0 88
michael@0 89 // XXX Need to get logical XPath text node for CDATASection
michael@0 90 // and Text nodes.
michael@0 91 }
michael@0 92 else if (nodeType != nsIDOMNode::DOCUMENT_NODE &&
michael@0 93 nodeType != nsIDOMNode::ELEMENT_NODE &&
michael@0 94 nodeType != nsIDOMNode::ATTRIBUTE_NODE &&
michael@0 95 nodeType != nsIDOMNode::COMMENT_NODE &&
michael@0 96 nodeType != nsIDOMNode::PROCESSING_INSTRUCTION_NODE) {
michael@0 97 return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
michael@0 98 }
michael@0 99
michael@0 100 NS_ENSURE_ARG(aResult);
michael@0 101 *aResult = nullptr;
michael@0 102
michael@0 103 nsAutoPtr<txXPathNode> contextNode(txXPathNativeNode::createXPathNode(aContextNode));
michael@0 104 if (!contextNode) {
michael@0 105 return NS_ERROR_OUT_OF_MEMORY;
michael@0 106 }
michael@0 107
michael@0 108 EvalContextImpl eContext(*contextNode, aContextPosition, aContextSize,
michael@0 109 mRecycler);
michael@0 110 nsRefPtr<txAExprResult> exprResult;
michael@0 111 nsresult rv = mExpression->evaluate(&eContext, getter_AddRefs(exprResult));
michael@0 112 NS_ENSURE_SUCCESS(rv, rv);
michael@0 113
michael@0 114 uint16_t resultType = aType;
michael@0 115 if (aType == nsIDOMXPathResult::ANY_TYPE) {
michael@0 116 short exprResultType = exprResult->getResultType();
michael@0 117 switch (exprResultType) {
michael@0 118 case txAExprResult::NUMBER:
michael@0 119 resultType = nsIDOMXPathResult::NUMBER_TYPE;
michael@0 120 break;
michael@0 121 case txAExprResult::STRING:
michael@0 122 resultType = nsIDOMXPathResult::STRING_TYPE;
michael@0 123 break;
michael@0 124 case txAExprResult::BOOLEAN:
michael@0 125 resultType = nsIDOMXPathResult::BOOLEAN_TYPE;
michael@0 126 break;
michael@0 127 case txAExprResult::NODESET:
michael@0 128 resultType = nsIDOMXPathResult::UNORDERED_NODE_ITERATOR_TYPE;
michael@0 129 break;
michael@0 130 case txAExprResult::RESULT_TREE_FRAGMENT:
michael@0 131 NS_ERROR("Can't return a tree fragment!");
michael@0 132 return NS_ERROR_FAILURE;
michael@0 133 }
michael@0 134 }
michael@0 135
michael@0 136 // We need a result object and it must be our implementation.
michael@0 137 nsCOMPtr<nsIXPathResult> xpathResult = do_QueryInterface(aInResult);
michael@0 138 if (!xpathResult) {
michael@0 139 // Either no aInResult or not one of ours.
michael@0 140 xpathResult = new nsXPathResult();
michael@0 141 NS_ENSURE_TRUE(xpathResult, NS_ERROR_OUT_OF_MEMORY);
michael@0 142 }
michael@0 143 rv = xpathResult->SetExprResult(exprResult, resultType, context);
michael@0 144 NS_ENSURE_SUCCESS(rv, rv);
michael@0 145
michael@0 146 return CallQueryInterface(xpathResult, aResult);
michael@0 147 }
michael@0 148
michael@0 149 /*
michael@0 150 * Implementation of the txIEvalContext private to nsXPathExpression
michael@0 151 * EvalContextImpl bases on only one context node and no variables
michael@0 152 */
michael@0 153
michael@0 154 nsresult
michael@0 155 nsXPathExpression::EvalContextImpl::getVariable(int32_t aNamespace,
michael@0 156 nsIAtom* aLName,
michael@0 157 txAExprResult*& aResult)
michael@0 158 {
michael@0 159 aResult = 0;
michael@0 160 return NS_ERROR_INVALID_ARG;
michael@0 161 }
michael@0 162
michael@0 163 bool nsXPathExpression::EvalContextImpl::isStripSpaceAllowed(const txXPathNode& aNode)
michael@0 164 {
michael@0 165 return false;
michael@0 166 }
michael@0 167
michael@0 168 void* nsXPathExpression::EvalContextImpl::getPrivateContext()
michael@0 169 {
michael@0 170 // we don't have a private context here.
michael@0 171 return nullptr;
michael@0 172 }
michael@0 173
michael@0 174 txResultRecycler* nsXPathExpression::EvalContextImpl::recycler()
michael@0 175 {
michael@0 176 return mRecycler;
michael@0 177 }
michael@0 178
michael@0 179 void nsXPathExpression::EvalContextImpl::receiveError(const nsAString& aMsg,
michael@0 180 nsresult aRes)
michael@0 181 {
michael@0 182 mLastError = aRes;
michael@0 183 // forward aMsg to console service?
michael@0 184 }
michael@0 185
michael@0 186 const txXPathNode& nsXPathExpression::EvalContextImpl::getContextNode()
michael@0 187 {
michael@0 188 return mContextNode;
michael@0 189 }
michael@0 190
michael@0 191 uint32_t nsXPathExpression::EvalContextImpl::size()
michael@0 192 {
michael@0 193 return mContextSize;
michael@0 194 }
michael@0 195
michael@0 196 uint32_t nsXPathExpression::EvalContextImpl::position()
michael@0 197 {
michael@0 198 return mContextPosition;
michael@0 199 }

mercurial