1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "mozilla/dom/XPathEvaluator.h"
7 #include "mozilla/Move.h"
10 #include "mozilla/dom/XPathExpression.h"
11 #include "nsXPathNSResolver.h"
12 #include "XPathResult.h"
13 #include "nsContentCID.h"
15 #include "txExprParser.h"
17 #include "txURIUtils.h"
18 #include "nsIDocument.h"
19 #include "nsIDOMDocument.h"
20 #include "nsDOMString.h"
21 #include "nsNameSpaceManager.h"
22 #include "nsContentUtils.h"
23 #include "txIXPathContext.h"
24 #include "mozilla/dom/XPathEvaluatorBinding.h"
25 #include "mozilla/dom/BindingUtils.h"
28 TX_ResolveFunctionCallXPCOM(const nsCString
&aContractID
, int32_t aNamespaceID
,
29 nsIAtom
*aName
, nsISupports
*aState
,
30 FunctionCall
**aFunction
);
35 // txIParseContext implementation
36 class XPathEvaluatorParseContext
: public txIParseContext
39 XPathEvaluatorParseContext(nsIDOMXPathNSResolver
* aResolver
,
40 bool aIsCaseSensitive
)
41 : mResolver(aResolver
),
43 mIsCaseSensitive(aIsCaseSensitive
)
52 nsresult
resolveNamespacePrefix(nsIAtom
* aPrefix
, int32_t& aID
);
53 nsresult
resolveFunctionCall(nsIAtom
* aName
, int32_t aID
,
54 FunctionCall
** aFunction
);
55 bool caseInsensitiveNameTests();
56 void SetErrorOffset(uint32_t aOffset
);
59 nsIDOMXPathNSResolver
* mResolver
;
61 bool mIsCaseSensitive
;
64 NS_IMPL_ISUPPORTS(XPathEvaluator
, nsIDOMXPathEvaluator
)
66 XPathEvaluator::XPathEvaluator(nsIDocument
* aDocument
)
67 : mDocument(do_GetWeakReference(aDocument
))
71 XPathEvaluator::~XPathEvaluator()
76 XPathEvaluator::CreateNSResolver(nsIDOMNode
*aNodeResolver
,
77 nsIDOMXPathNSResolver
**aResult
)
79 NS_ENSURE_ARG(aNodeResolver
);
80 if (!nsContentUtils::CanCallerAccess(aNodeResolver
))
81 return NS_ERROR_DOM_SECURITY_ERR
;
83 *aResult
= new nsXPathNSResolver(aNodeResolver
);
84 NS_ENSURE_TRUE(*aResult
, NS_ERROR_OUT_OF_MEMORY
);
91 XPathEvaluator::Evaluate(const nsAString
& aExpression
,
92 nsIDOMNode
*aContextNode
,
93 nsIDOMXPathNSResolver
*aResolver
,
95 nsISupports
*aInResult
,
96 nsISupports
**aResult
)
99 nsAutoPtr
<XPathExpression
> expression(CreateExpression(aExpression
,
102 return rv
.ErrorCode();
105 nsCOMPtr
<nsINode
> node
= do_QueryInterface(aContextNode
);
107 return NS_ERROR_FAILURE
;
110 nsCOMPtr
<nsIXPathResult
> inResult
= do_QueryInterface(aInResult
);
111 nsRefPtr
<XPathResult
> result
=
112 expression
->Evaluate(*node
, aType
,
113 static_cast<XPathResult
*>(inResult
.get()), rv
);
115 return rv
.ErrorCode();
118 *aResult
= ToSupports(result
.forget().take());
125 XPathEvaluator::CreateExpression(const nsAString
& aExpression
,
126 nsIDOMXPathNSResolver
*aResolver
,
130 mRecycler
= new txResultRecycler
;
133 nsCOMPtr
<nsIDocument
> doc
= do_QueryReferent(mDocument
);
134 XPathEvaluatorParseContext
pContext(aResolver
, !(doc
&& doc
->IsHTML()));
136 nsAutoPtr
<Expr
> expression
;
137 aRv
= txExprParser::createExpr(PromiseFlatString(aExpression
), &pContext
,
138 getter_Transfers(expression
));
140 if (aRv
.ErrorCode() != NS_ERROR_DOM_NAMESPACE_ERR
) {
141 aRv
.Throw(NS_ERROR_DOM_INVALID_EXPRESSION_ERR
);
147 return new XPathExpression(Move(expression
), mRecycler
, doc
);
151 XPathEvaluator::WrapObject(JSContext
* aCx
)
153 return dom::XPathEvaluatorBinding::Wrap(aCx
, this);
157 already_AddRefed
<XPathEvaluator
>
158 XPathEvaluator::Constructor(const GlobalObject
& aGlobal
,
161 nsRefPtr
<XPathEvaluator
> newObj
= new XPathEvaluator(nullptr);
162 return newObj
.forget();
165 already_AddRefed
<nsIDOMXPathNSResolver
>
166 XPathEvaluator::CreateNSResolver(nsINode
* aNodeResolver
,
169 nsCOMPtr
<nsIDOMNode
> nodeResolver
= do_QueryInterface(aNodeResolver
);
170 nsCOMPtr
<nsIDOMXPathNSResolver
> res
;
171 rv
= CreateNSResolver(nodeResolver
, getter_AddRefs(res
));
175 already_AddRefed
<XPathResult
>
176 XPathEvaluator::Evaluate(JSContext
* aCx
, const nsAString
& aExpression
,
177 nsINode
* aContextNode
,
178 nsIDOMXPathNSResolver
* aResolver
, uint16_t aType
,
179 JS::Handle
<JSObject
*> aResult
, ErrorResult
& rv
)
181 nsCOMPtr
<nsIDOMNode
> contextNode
= do_QueryInterface(aContextNode
);
182 nsCOMPtr
<nsISupports
> res
;
183 rv
= Evaluate(aExpression
, contextNode
, aResolver
, aType
,
184 aResult
? UnwrapDOMObjectToISupports(aResult
) : nullptr,
185 getter_AddRefs(res
));
186 return res
.forget().downcast
<nsIXPathResult
>().downcast
<XPathResult
>();
191 * Implementation of txIParseContext private to XPathEvaluator, based on a
192 * nsIDOMXPathNSResolver
195 nsresult
XPathEvaluatorParseContext::resolveNamespacePrefix
196 (nsIAtom
* aPrefix
, int32_t& aID
)
198 aID
= kNameSpaceID_Unknown
;
201 return NS_ERROR_DOM_NAMESPACE_ERR
;
206 aPrefix
->ToString(prefix
);
210 nsresult rv
= mResolver
->LookupNamespaceURI(prefix
, ns
);
211 NS_ENSURE_SUCCESS(rv
, rv
);
213 if (DOMStringIsNull(ns
)) {
214 return NS_ERROR_DOM_NAMESPACE_ERR
;
218 aID
= kNameSpaceID_None
;
223 // get the namespaceID for the URI
224 return nsContentUtils::NameSpaceManager()->RegisterNameSpace(ns
, aID
);
228 XPathEvaluatorParseContext::resolveFunctionCall(nsIAtom
* aName
,
232 return NS_ERROR_XPATH_UNKNOWN_FUNCTION
;
235 bool XPathEvaluatorParseContext::caseInsensitiveNameTests()
237 return !mIsCaseSensitive
;
241 XPathEvaluatorParseContext::SetErrorOffset(uint32_t aOffset
)
246 } // namespace mozilla