1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* ***** BEGIN LICENSE BLOCK *****
3
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
5
* The contents of this file are subject to the Netscape Public License
6
* Version 1.1 (the "License"); you may not use this file except in
7
* compliance with the License. You may obtain a copy of the License at
8
* http://www.mozilla.org/NPL/
10
* Software distributed under the License is distributed on an "AS IS" basis,
11
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
* for the specific language governing rights and limitations under the
15
* The Original Code is mozilla.org code.
17
* The Initial Developer of the Original Code is
18
* Netscape Communications Corporation.
19
* Portions created by the Initial Developer are Copyright (C) 2001
20
* the Initial Developer. All Rights Reserved.
23
* Peter Van der Beken <peterv@netscape.com>
26
* Alternatively, the contents of this file may be used under the terms of
27
* either the GNU General Public License Version 2 or later (the "GPL"), or
28
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29
* in which case the provisions of the GPL or the LGPL are applicable instead
30
* of those above. If you wish to allow use of your version of this file only
31
* under the terms of either the GPL or the LGPL, and not to allow others to
32
* use your version of this file under the terms of the NPL, indicate your
33
* decision by deleting the provisions above and replace them with the notice
34
* and other provisions required by the GPL or the LGPL. If you do not delete
35
* the provisions above, a recipient may use your version of this file under
36
* the terms of any one of the NPL, the GPL or the LGPL.
38
* ***** END LICENSE BLOCK ***** */
40
#include "nsXPathResult.h"
41
#include "ExprResult.h"
42
#include "txNodeSet.h"
43
#include "nsDOMError.h"
44
#include "nsIContent.h"
45
#include "nsIDOMClassInfo.h"
46
#include "nsIDOMNode.h"
47
#include "nsXPathException.h"
48
#include "nsIDOMDocument.h"
49
#include "nsDOMString.h"
51
nsXPathResult::nsXPathResult() : mNumberValue(0),
54
mResultType(ANY_TYPE),
55
mInvalidIteratorState(PR_TRUE)
59
nsXPathResult::~nsXPathResult()
64
NS_IMPL_ADDREF(nsXPathResult)
65
NS_IMPL_RELEASE(nsXPathResult)
66
NS_INTERFACE_MAP_BEGIN(nsXPathResult)
67
NS_INTERFACE_MAP_ENTRY(nsIDOMXPathResult)
68
NS_INTERFACE_MAP_ENTRY(nsIDocumentObserver)
69
NS_INTERFACE_MAP_ENTRY(nsIXPathResult)
70
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMXPathResult)
71
NS_INTERFACE_MAP_ENTRY_EXTERNAL_DOM_CLASSINFO(XPathResult)
75
nsXPathResult::GetResultType(PRUint16 *aResultType)
77
NS_ENSURE_ARG(aResultType);
78
*aResultType = mResultType;
83
nsXPathResult::GetNumberValue(double *aNumberValue)
85
if (mResultType != NUMBER_TYPE)
86
return NS_ERROR_DOM_TYPE_ERR;
88
NS_ENSURE_ARG(aNumberValue);
89
*aNumberValue = mNumberValue;
94
nsXPathResult::GetStringValue(nsAString &aStringValue)
96
if (mResultType != STRING_TYPE)
97
return NS_ERROR_DOM_TYPE_ERR;
100
aStringValue.Assign(*mStringValue);
102
SetDOMStringToNull(aStringValue);
107
nsXPathResult::GetBooleanValue(PRBool *aBooleanValue)
109
if (mResultType != BOOLEAN_TYPE)
110
return NS_ERROR_DOM_TYPE_ERR;
112
NS_ENSURE_ARG(aBooleanValue);
113
*aBooleanValue = mBooleanValue;
118
nsXPathResult::GetSingleNodeValue(nsIDOMNode **aSingleNodeValue)
120
if (mResultType != FIRST_ORDERED_NODE_TYPE &&
121
mResultType != ANY_UNORDERED_NODE_TYPE)
122
return NS_ERROR_DOM_TYPE_ERR;
124
NS_ENSURE_ARG(aSingleNodeValue);
125
*aSingleNodeValue = mNode;
126
NS_IF_ADDREF(*aSingleNodeValue);
131
nsXPathResult::GetInvalidIteratorState(PRBool *aInvalidIteratorState)
133
NS_ENSURE_ARG(aInvalidIteratorState);
135
if (mResultType != UNORDERED_NODE_ITERATOR_TYPE &&
136
mResultType != ORDERED_NODE_ITERATOR_TYPE) {
137
*aInvalidIteratorState = PR_FALSE;
141
*aInvalidIteratorState = mInvalidIteratorState;
146
nsXPathResult::GetSnapshotLength(PRUint32 *aSnapshotLength)
148
if (mResultType != UNORDERED_NODE_SNAPSHOT_TYPE &&
149
mResultType != ORDERED_NODE_SNAPSHOT_TYPE)
150
return NS_ERROR_DOM_TYPE_ERR;
152
NS_ENSURE_ARG(aSnapshotLength);
153
*aSnapshotLength = 0;
155
*aSnapshotLength = mElements->Count();
160
nsXPathResult::IterateNext(nsIDOMNode **aResult)
162
if (mResultType != UNORDERED_NODE_ITERATOR_TYPE &&
163
mResultType != ORDERED_NODE_ITERATOR_TYPE)
164
return NS_ERROR_DOM_TYPE_ERR;
167
mDocument->FlushPendingNotifications(PR_FALSE);
169
if (mInvalidIteratorState)
170
return NS_ERROR_DOM_INVALID_STATE_ERR;
172
NS_ENSURE_ARG(aResult);
173
if (mElements && mCurrentPos < (PRUint32)mElements->Count()) {
174
*aResult = mElements->ObjectAt(mCurrentPos++);
183
nsXPathResult::SnapshotItem(PRUint32 aIndex, nsIDOMNode **aResult)
185
if (mResultType != UNORDERED_NODE_SNAPSHOT_TYPE &&
186
mResultType != ORDERED_NODE_SNAPSHOT_TYPE)
187
return NS_ERROR_DOM_TYPE_ERR;
189
NS_ENSURE_ARG(aResult);
190
if (mElements && aIndex < (PRUint32)mElements->Count()) {
191
*aResult = mElements->ObjectAt(aIndex);
199
NS_IMPL_NSIDOCUMENTOBSERVER_CORE_STUB(nsXPathResult)
200
NS_IMPL_NSIDOCUMENTOBSERVER_LOAD_STUB(nsXPathResult)
201
NS_IMPL_NSIDOCUMENTOBSERVER_REFLOW_STUB(nsXPathResult)
202
NS_IMPL_NSIDOCUMENTOBSERVER_STYLE_STUB(nsXPathResult)
203
NS_IMPL_NSIDOCUMENTOBSERVER_STATE_STUB(nsXPathResult)
206
nsXPathResult::CharacterDataChanged(nsIDocument* aDocument,
207
nsIContent *aContent,
214
nsXPathResult::AttributeChanged(nsIDocument* aDocument,
215
nsIContent* aContent,
216
PRInt32 aNameSpaceID,
224
nsXPathResult::ContentAppended(nsIDocument* aDocument,
225
nsIContent* aContainer,
226
PRInt32 aNewIndexInContainer)
232
nsXPathResult::ContentInserted(nsIDocument* aDocument,
233
nsIContent* aContainer,
235
PRInt32 aIndexInContainer)
241
nsXPathResult::ContentReplaced(nsIDocument* aDocument,
242
nsIContent* aContainer,
243
nsIContent* aOldChild,
244
nsIContent* aNewChild,
245
PRInt32 aIndexInContainer)
251
nsXPathResult::ContentRemoved(nsIDocument* aDocument,
252
nsIContent* aContainer,
254
PRInt32 aIndexInContainer)
260
nsXPathResult::SetExprResult(txAExprResult* aExprResult, PRUint16 aResultType)
264
mResultType = aResultType;
266
if (mResultType == NUMBER_TYPE) {
267
mNumberValue = aExprResult->numberValue();
271
if (mResultType == STRING_TYPE) {
272
mStringValue = new nsString;
273
NS_ENSURE_TRUE(mStringValue, NS_ERROR_OUT_OF_MEMORY);
274
aExprResult->stringValue(*mStringValue);
278
if (mResultType == BOOLEAN_TYPE) {
279
mBooleanValue = aExprResult->booleanValue();
283
if (aExprResult->getResultType() == txAExprResult::NODESET) {
285
txNodeSet* nodeSet = NS_STATIC_CAST(txNodeSet*, aExprResult);
287
if (mResultType == FIRST_ORDERED_NODE_TYPE ||
288
mResultType == ANY_UNORDERED_NODE_TYPE) {
289
if (nodeSet->size() > 0) {
290
txXPathNativeNode::getNode(nodeSet->get(0), &mNode);
294
if (mResultType == UNORDERED_NODE_ITERATOR_TYPE ||
295
mResultType == ORDERED_NODE_ITERATOR_TYPE) {
296
mInvalidIteratorState = PR_FALSE;
299
PRInt32 count = nodeSet->size();
303
mElements = new nsCOMArray<nsIDOMNode>;
304
NS_ENSURE_TRUE(mElements, NS_ERROR_OUT_OF_MEMORY);
306
nsCOMPtr<nsIDOMNode> node;
308
for (i = 0; i < count; ++i) {
309
txXPathNativeNode::getNode(nodeSet->get(i), getter_AddRefs(node));
310
NS_ASSERTION(node, "node isn't an nsIDOMNode");
311
mElements->AppendObject(node);
314
// If we support the document() function in DOM-XPath we need to
315
// observe all documents that we have resultnodes in.
316
if (mResultType == UNORDERED_NODE_ITERATOR_TYPE ||
317
mResultType == ORDERED_NODE_ITERATOR_TYPE) {
318
nsCOMPtr<nsIDOMDocument> document;
319
node->GetOwnerDocument(getter_AddRefs(document));
321
mDocument = do_QueryInterface(document);
323
mDocument = do_QueryInterface(node);
325
NS_ASSERTION(mDocument, "We need a document!");
327
mDocument->AddObserver(this);
333
return NS_ERROR_DOM_TYPE_ERR;
337
nsXPathResult::Invalidate()
340
mDocument->RemoveObserver(this);
343
mInvalidIteratorState = PR_TRUE;
347
nsXPathResult::Reset()
351
if (mResultType == STRING_TYPE) {
355
else if (mResultType == UNORDERED_NODE_ITERATOR_TYPE ||
356
mResultType == ORDERED_NODE_ITERATOR_TYPE ||
357
mResultType == UNORDERED_NODE_SNAPSHOT_TYPE ||
358
mResultType == ORDERED_NODE_SNAPSHOT_TYPE) {
362
else if (mResultType == FIRST_ORDERED_NODE_TYPE ||
363
mResultType == ANY_UNORDERED_NODE_TYPE) {
364
NS_IF_RELEASE(mNode);
367
mResultType = ANY_TYPE;