Bug 1027095 - Convert XPathResult to WebIDL bindings - add WebIDL API and switch. r=bz.

This commit is contained in:
Peter Van der Beken 2013-07-04 17:40:06 +02:00
parent c81bd31d3c
commit 7785f47487
27 changed files with 309 additions and 302 deletions

View File

@ -122,6 +122,7 @@ class TouchList;
class TreeWalker;
class UndoManager;
class XPathEvaluator;
class XPathResult;
template<typename> class OwningNonNull;
template<typename> class Sequence;
@ -2274,10 +2275,10 @@ public:
mozilla::ErrorResult& rv);
already_AddRefed<nsIDOMXPathNSResolver>
CreateNSResolver(nsINode* aNodeResolver, mozilla::ErrorResult& rv);
already_AddRefed<nsISupports>
Evaluate(const nsAString& aExpression, nsINode* aContextNode,
already_AddRefed<mozilla::dom::XPathResult>
Evaluate(JSContext* aCx, const nsAString& aExpression, nsINode* aContextNode,
nsIDOMXPathNSResolver* aResolver, uint16_t aType,
nsISupports* aResult, mozilla::ErrorResult& rv);
JS::Handle<JSObject*> aResult, mozilla::ErrorResult& rv);
// Touch event handlers already on nsINode
already_AddRefed<mozilla::dom::Touch>
CreateTouch(nsIDOMWindow* aView, mozilla::dom::EventTarget* aTarget,

View File

@ -218,6 +218,7 @@
#include "nsISecurityConsoleMessage.h"
#include "nsCharSeparatedTokenizer.h"
#include "mozilla/dom/XPathEvaluator.h"
#include "mozilla/dom/XPathResult.h"
#include "nsIDocumentEncoder.h"
#include "nsIDocumentActivity.h"
#include "nsIStructuredCloneContainer.h"
@ -12104,13 +12105,14 @@ nsIDocument::CreateNSResolver(nsINode* aNodeResolver,
return XPathEvaluator()->CreateNSResolver(aNodeResolver, rv);
}
already_AddRefed<nsISupports>
nsIDocument::Evaluate(const nsAString& aExpression, nsINode* aContextNode,
nsIDOMXPathNSResolver* aResolver, uint16_t aType,
nsISupports* aResult, ErrorResult& rv)
already_AddRefed<XPathResult>
nsIDocument::Evaluate(JSContext* aCx, const nsAString& aExpression,
nsINode* aContextNode, nsIDOMXPathNSResolver* aResolver,
uint16_t aType, JS::Handle<JSObject*> aResult,
ErrorResult& rv)
{
return XPathEvaluator()->Evaluate(aExpression, aContextNode, aResolver, aType,
aResult, rv);
return XPathEvaluator()->Evaluate(aCx, aExpression, aContextNode, aResolver,
aType, aResult, rv);
}
NS_IMETHODIMP

View File

@ -137,7 +137,6 @@ function evalXPathInDocumentFragment(aContextNode, aPath) {
// Apply our remaining xpath to the found node.
var expr = aContextNode.ownerDocument.createExpression(realPath, null);
var result = expr.evaluate(targetNode, UNORDERED_TYPE, null);
do_check_true(result instanceof C_i.nsIDOMXPathResult);
return result.singleNodeValue;
}

View File

@ -6,6 +6,11 @@
#include "nsXULTemplateQueryProcessorXML.h"
#include "nsXULTemplateResultXML.h"
#include "nsXMLBinding.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/XPathResult.h"
using namespace mozilla;
using namespace mozilla::dom;
NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(nsXMLBindingSet)
NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE(nsXMLBindingSet)
@ -83,30 +88,32 @@ nsXMLBindingSet::LookupTargetIndex(nsIAtom* aTargetVariable,
return -1;
}
void
XPathResult*
nsXMLBindingValues::GetAssignmentFor(nsXULTemplateResultXML* aResult,
nsXMLBinding* aBinding,
int32_t aIndex,
uint16_t aType,
nsIDOMXPathResult** aValue)
uint16_t aType)
{
*aValue = mValues.SafeObjectAt(aIndex);
if (!*aValue) {
nsCOMPtr<nsIDOMNode> contextNode;
aResult->GetNode(getter_AddRefs(contextNode));
if (contextNode) {
nsCOMPtr<nsISupports> resultsupports;
aBinding->mExpr->Evaluate(contextNode, aType,
nullptr, getter_AddRefs(resultsupports));
nsCOMPtr<nsIDOMXPathResult> result = do_QueryInterface(resultsupports);
if (result && mValues.ReplaceObjectAt(result, aIndex))
*aValue = result;
}
XPathResult* value = mValues.SafeElementAt(aIndex);
if (value) {
return value;
}
NS_IF_ADDREF(*aValue);
nsCOMPtr<nsIDOMNode> contextNode;
aResult->GetNode(getter_AddRefs(contextNode));
if (!contextNode) {
return nullptr;
}
mValues.EnsureLengthAtLeast(aIndex + 1);
nsCOMPtr<nsISupports> resultsupports;
aBinding->mExpr->Evaluate(contextNode, aType,
nullptr, getter_AddRefs(resultsupports));
mValues.ReplaceElementAt(aIndex, XPathResult::FromSupports(resultsupports));
return mValues[aIndex];
}
void
@ -115,15 +122,16 @@ nsXMLBindingValues::GetNodeAssignmentFor(nsXULTemplateResultXML* aResult,
int32_t aIndex,
nsIDOMNode** aNode)
{
nsCOMPtr<nsIDOMXPathResult> result;
GetAssignmentFor(aResult, aBinding, aIndex,
nsIDOMXPathResult::FIRST_ORDERED_NODE_TYPE,
getter_AddRefs(result));
XPathResult* result = GetAssignmentFor(aResult, aBinding, aIndex,
XPathResult::FIRST_ORDERED_NODE_TYPE);
if (result)
result->GetSingleNodeValue(aNode);
else
nsINode* node;
ErrorResult rv;
if (result && (node = result->GetSingleNodeValue(rv))) {
CallQueryInterface(node, aNode);
} else {
*aNode = nullptr;
}
}
void
@ -132,12 +140,13 @@ nsXMLBindingValues::GetStringAssignmentFor(nsXULTemplateResultXML* aResult,
int32_t aIndex,
nsAString& aValue)
{
nsCOMPtr<nsIDOMXPathResult> result;
GetAssignmentFor(aResult, aBinding, aIndex,
nsIDOMXPathResult::STRING_TYPE, getter_AddRefs(result));
XPathResult* result = GetAssignmentFor(aResult, aBinding, aIndex,
XPathResult::STRING_TYPE);
if (result)
result->GetStringValue(aValue);
else
if (result) {
ErrorResult rv;
result->GetStringValue(aValue, rv);
} else {
aValue.Truncate();
}
}

View File

@ -13,6 +13,11 @@
class nsXULTemplateResultXML;
class nsXMLBindingValues;
namespace mozilla {
namespace dom {
class XPathResult;
}
}
/**
* Classes related to storing bindings for XML handling.
@ -92,7 +97,7 @@ protected:
* scan through the binding set in mBindings for the right target atom.
* Its index will correspond to the index in this array.
*/
nsCOMArray<nsIDOMXPathResult> mValues;
nsTArray<nsRefPtr<mozilla::dom::XPathResult> > mValues;
public:
@ -117,14 +122,12 @@ public:
* aBinding the binding looked up using LookupTargetIndex
* aIndex the index of the assignment to retrieve
* aType the type of result expected
* aValue the value of the assignment
*/
void
mozilla::dom::XPathResult*
GetAssignmentFor(nsXULTemplateResultXML* aResult,
nsXMLBinding* aBinding,
int32_t idx,
uint16_t type,
nsIDOMXPathResult** aValue);
uint16_t type);
void
GetNodeAssignmentFor(nsXULTemplateResultXML* aResult,

View File

@ -26,6 +26,7 @@
#include "nsXULTemplateResultXML.h"
#include "nsXULSortService.h"
using namespace mozilla;
using namespace mozilla::dom;
NS_IMPL_ISUPPORTS(nsXMLQuery, nsXMLQuery)
@ -42,21 +43,21 @@ nsXULTemplateResultSetXML::HasMoreElements(bool *aResult)
{
// if GetSnapshotLength failed, then the return type was not a set of
// nodes, so just return false in this case.
uint32_t length;
if (NS_SUCCEEDED(mResults->GetSnapshotLength(&length)))
*aResult = (mPosition < length);
else
*aResult = false;
ErrorResult rv;
uint32_t length = mResults->GetSnapshotLength(rv);
*aResult = !rv.Failed() && mPosition < length;
return NS_OK;
}
NS_IMETHODIMP
nsXULTemplateResultSetXML::GetNext(nsISupports **aResult)
{
nsCOMPtr<nsIDOMNode> node;
nsresult rv = mResults->SnapshotItem(mPosition, getter_AddRefs(node));
NS_ENSURE_SUCCESS(rv, rv);
ErrorResult rv;
nsCOMPtr<nsIDOMNode> node =
do_QueryInterface(mResults->SnapshotItem(mPosition, rv));
if (rv.Failed()) {
return rv.ErrorCode();
}
nsXULTemplateResultXML* result =
new nsXULTemplateResultXML(mQuery, node, mBindingSet);
@ -331,13 +332,11 @@ nsXULTemplateQueryProcessorXML::GenerateResults(nsISupports* aDatasource,
nsCOMPtr<nsISupports> exprsupportsresults;
nsresult rv = expr->Evaluate(context,
nsIDOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE,
XPathResult::ORDERED_NODE_SNAPSHOT_TYPE,
nullptr, getter_AddRefs(exprsupportsresults));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMXPathResult> exprresults =
do_QueryInterface(exprsupportsresults);
XPathResult* exprresults = XPathResult::FromSupports(exprsupportsresults);
nsXULTemplateResultSetXML* results =
new nsXULTemplateResultSetXML(xmlquery, exprresults,
xmlquery->GetBindingSet());

View File

@ -17,11 +17,11 @@
#include "nsIDOMEventListener.h"
#include "nsIDOMXPathExpression.h"
#include "nsIDOMXPathEvaluator.h"
#include "nsIDOMXPathResult.h"
#include "nsXMLBinding.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIXMLHttpRequest.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/XPathResult.h"
class nsXULTemplateQueryProcessorXML;
@ -91,7 +91,7 @@ private:
nsRefPtr<nsXMLBindingSet> mBindingSet;
// set of results contained in this enumerator
nsCOMPtr<nsIDOMXPathResult> mResults;
nsRefPtr<mozilla::dom::XPathResult> mResults;
// current position within the list of results
uint32_t mPosition;
@ -105,7 +105,7 @@ public:
NS_DECL_NSISIMPLEENUMERATOR
nsXULTemplateResultSetXML(nsXMLQuery* aQuery,
nsIDOMXPathResult* aResults,
mozilla::dom::XPathResult* aResults,
nsXMLBindingSet* aBindingSet)
: mQuery(aQuery),
mBindingSet(aBindingSet),

View File

@ -114,7 +114,6 @@
#include "nsIDOMXPathExpression.h"
#include "nsIDOMNSXPathExpression.h"
#include "nsIDOMXPathNSResolver.h"
#include "nsIDOMXPathResult.h"
// Storage includes
#include "nsIDOMStorage.h"
@ -350,8 +349,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(XPathNSResolver, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(XPathResult, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
// WhatWG Storage
@ -958,10 +955,6 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMXPathNSResolver)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(XPathResult, nsIDOMXPathResult)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMXPathResult)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(Storage, nsIDOMStorage)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMStorage)
DOM_CLASSINFO_MAP_END

View File

@ -48,7 +48,6 @@ DOMCI_CLASS(XSLTProcessor)
// DOM Level 3 XPath objects
DOMCI_CLASS(XPathExpression)
DOMCI_CLASS(XPathNSResolver)
DOMCI_CLASS(XPathResult)
// WhatWG WebApps Objects
DOMCI_CLASS(Storage)

View File

@ -1659,6 +1659,10 @@ DOMInterfaces = {
'wrapperCache': False
},
'XPathResult': {
'resultNotAddRefed': ['singleNodeValue', 'iterateNext', 'snapshotItem']
},
'XULDocument': {
'headerFile': 'XULDocument.h'
},
@ -1996,7 +2000,6 @@ addExternalIface('StackFrame', nativeType='nsIStackFrame',
addExternalIface('URI', nativeType='nsIURI', headerFile='nsIURI.h',
notflattened=True)
addExternalIface('UserDataHandler')
addExternalIface('XPathResult', nativeType='nsISupports')
addExternalIface('XPathExpression')
addExternalIface('XPathNSResolver')
addExternalIface('XULCommandDispatcher')

View File

@ -5,7 +5,6 @@
#include "domstubs.idl"
interface nsIDOMXPathResult;
interface XPathException;
/**

View File

@ -10,7 +10,6 @@
#include "domstubs.idl"
interface nsIDOMXPathNSResolver;
interface nsIDOMXPathResult;
interface nsIDOMXPathExpression;
interface XPathException;

View File

@ -9,7 +9,6 @@
#include "domstubs.idl"
interface nsIDOMXPathResult;
interface XPathException;
[scriptable, uuid(75506f82-b504-11d5-a7f2-ca108ab8b6fc)]

View File

@ -7,11 +7,9 @@
* Corresponds to http://www.w3.org/TR/2002/WD-DOM-Level-3-XPath-20020208
*/
#include "domstubs.idl"
#include "nsISupports.idl"
interface XPathException;
[scriptable, uuid(75506f84-b504-11d5-a7f2-ca108ab8b6fc)]
[uuid(75506f84-b504-11d5-a7f2-ca108ab8b6fc)]
interface nsIDOMXPathResult : nsISupports
{
// XPathResultType
@ -25,27 +23,4 @@ interface nsIDOMXPathResult : nsISupports
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;
// raises(XPathException) on retrieval
readonly attribute DOMString stringValue;
// raises(XPathException) on retrieval
readonly attribute boolean booleanValue;
// raises(XPathException) on retrieval
readonly attribute nsIDOMNode singleNodeValue;
// raises(XPathException) on retrieval
readonly attribute boolean invalidIteratorState;
readonly attribute unsigned long snapshotLength;
// raises(XPathException) on retrieval
nsIDOMNode iterateNext()
raises(XPathException,
DOMException);
nsIDOMNode snapshotItem(in unsigned long index)
raises(XPathException);
};

View File

@ -6,7 +6,6 @@
interface XPathExpression;
interface XPathNSResolver;
interface XPathResult;
[Constructor]
interface XPathEvaluator {
@ -19,5 +18,5 @@ interface XPathEvaluator {
[Throws]
XPathResult evaluate(DOMString expression, Node? contextNode,
XPathNSResolver? resolver, unsigned short type,
XPathResult? result);
object? result);
};

View File

@ -0,0 +1,38 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Corresponds to http://www.w3.org/TR/2002/WD-DOM-Level-3-XPath-20020208
*/
interface XPathResult {
// XPathResultType
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;
[Throws]
readonly attribute double numberValue;
[Throws]
readonly attribute DOMString stringValue;
[Throws]
readonly attribute boolean booleanValue;
[Throws]
readonly attribute Node? singleNodeValue;
readonly attribute boolean invalidIteratorState;
[Throws]
readonly attribute unsigned long snapshotLength;
[Throws]
Node? iterateNext();
[Throws]
Node? snapshotItem(unsigned long index);
};

View File

@ -479,6 +479,7 @@ WEBIDL_FILES = [
'XMLSerializer.webidl',
'XMLStylesheetProcessingInstruction.webidl',
'XPathEvaluator.webidl',
'XPathResult.webidl',
'XULCommandEvent.webidl',
'XULDocument.webidl',
'XULElement.webidl',

View File

@ -39,8 +39,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=319374
var result = xp.evaluate("*",
document.getElementById('content'),
null,
SpecialPowers.Ci.nsIDOMXPathResult.
UNORDERED_NODE_ITERATOR_TYPE,
XPathResult.UNORDERED_NODE_ITERATOR_TYPE,
null);
var res = null;
while (res = result.iterateNext()) {
@ -69,8 +68,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=319374
var xp2 = SpecialPowers.wrap(xp).evaluate(".",
anonAttr1,
null,
SpecialPowers.Ci.nsIDOMXPathResult.
UNORDERED_NODE_ITERATOR_TYPE,
XPathResult.UNORDERED_NODE_ITERATOR_TYPE,
null);
// Attribute changing in a different anonymous tree.
anonAttr2.value = "foo";
@ -87,8 +85,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=319374
var xp3 = xp.evaluate(".",
anonAttr1,
null,
SpecialPowers.Ci.nsIDOMXPathResult.
UNORDERED_NODE_ITERATOR_TYPE,
XPathResult.UNORDERED_NODE_ITERATOR_TYPE,
null);
// Attribute changing in the same anonymous tree.
anonAttr1.ownerElement.setAttribute("foo", "bar");

View File

@ -21,6 +21,7 @@
#include "nsNameSpaceManager.h"
#include "nsContentUtils.h"
#include "mozilla/dom/XPathEvaluatorBinding.h"
#include "mozilla/dom/BindingUtils.h"
extern nsresult
TX_ResolveFunctionCallXPCOM(const nsCString &aContractID, int32_t aNamespaceID,
@ -174,16 +175,18 @@ XPathEvaluator::CreateNSResolver(nsINode* aNodeResolver,
return res.forget();
}
already_AddRefed<nsISupports>
XPathEvaluator::Evaluate(const nsAString& aExpression, nsINode* aContextNode,
already_AddRefed<XPathResult>
XPathEvaluator::Evaluate(JSContext* aCx, const nsAString& aExpression,
nsINode* aContextNode,
nsIDOMXPathNSResolver* aResolver, uint16_t aType,
nsISupports* aResult, ErrorResult& rv)
JS::Handle<JSObject*> aResult, ErrorResult& rv)
{
nsCOMPtr<nsIDOMNode> contextNode = do_QueryInterface(aContextNode);
nsCOMPtr<nsISupports> res;
rv = Evaluate(aExpression, contextNode, aResolver, aType,
aResult, getter_AddRefs(res));
return res.forget();
aResult ? UnwrapDOMObjectToISupports(aResult) : nullptr,
getter_AddRefs(res));
return res.forget().downcast<nsIXPathResult>().downcast<XPathResult>();
}

View File

@ -21,6 +21,7 @@ namespace mozilla {
namespace dom {
class GlobalObject;
class XPathResult;
/**
* A class for evaluating an XPath expression string
@ -50,10 +51,11 @@ public:
ErrorResult& rv);
already_AddRefed<nsIDOMXPathNSResolver>
CreateNSResolver(nsINode* aNodeResolver, ErrorResult& rv);
already_AddRefed<nsISupports>
Evaluate(const nsAString& aExpression, nsINode* aContextNode,
nsIDOMXPathNSResolver* aResolver, uint16_t aType,
nsISupports* aResult, ErrorResult& rv);
already_AddRefed<XPathResult>
Evaluate(JSContext* aCx, const nsAString& aExpression,
nsINode* aContextNode, nsIDOMXPathNSResolver* aResolver,
uint16_t aType, JS::Handle<JSObject*> aResult,
ErrorResult& rv);
private:
nsWeakPtr mDocument;
nsRefPtr<txResultRecycler> mRecycler;

View File

@ -15,30 +15,34 @@
#include "nsDOMString.h"
#include "txXPathTreeWalker.h"
#include "nsCycleCollectionParticipant.h"
DOMCI_DATA(XPathResult, mozilla::dom::XPathResult)
#include "mozilla/dom/XPathResultBinding.h"
namespace mozilla {
namespace dom {
XPathResult::XPathResult() : mDocument(nullptr),
mCurrentPos(0),
mResultType(ANY_TYPE),
mInvalidIteratorState(true),
mBooleanResult(false),
mNumberResult(0)
XPathResult::XPathResult(nsINode* aParent)
: mParent(aParent),
mDocument(nullptr),
mCurrentPos(0),
mResultType(ANY_TYPE),
mInvalidIteratorState(true),
mBooleanResult(false),
mNumberResult(0)
{
SetIsDOMBinding();
}
XPathResult::XPathResult(const XPathResult &aResult)
: mResult(aResult.mResult),
: mParent(aResult.mParent),
mResult(aResult.mResult),
mResultNodes(aResult.mResultNodes),
mDocument(aResult.mDocument),
mContextNode(aResult.mContextNode),
mCurrentPos(0),
mResultType(aResult.mResultType),
mContextNode(aResult.mContextNode),
mInvalidIteratorState(aResult.mInvalidIteratorState)
{
SetIsDOMBinding();
if (mDocument) {
mDocument->AddMutationObserver(this);
}
@ -51,13 +55,18 @@ XPathResult::~XPathResult()
NS_IMPL_CYCLE_COLLECTION_CLASS(XPathResult)
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(XPathResult)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(XPathResult)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
{
tmp->RemoveObserver();
}
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(XPathResult)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResultNodes)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@ -66,13 +75,18 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(XPathResult)
NS_IMPL_CYCLE_COLLECTING_RELEASE(XPathResult)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XPathResult)
NS_INTERFACE_MAP_ENTRY(nsIDOMXPathResult)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
NS_INTERFACE_MAP_ENTRY(nsIXPathResult)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMXPathResult)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XPathResult)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPathResult)
NS_INTERFACE_MAP_END
JSObject*
XPathResult::WrapObject(JSContext* aCx)
{
return XPathResultBinding::Wrap(aCx, this);
}
void
XPathResult::RemoveObserver()
{
@ -81,92 +95,12 @@ XPathResult::RemoveObserver()
}
}
NS_IMETHODIMP
XPathResult::GetResultType(uint16_t *aResultType)
{
*aResultType = mResultType;
return NS_OK;
}
NS_IMETHODIMP
XPathResult::GetNumberValue(double *aNumberValue)
{
if (mResultType != NUMBER_TYPE) {
return NS_ERROR_DOM_TYPE_ERR;
}
*aNumberValue = mNumberResult;
return NS_OK;
}
NS_IMETHODIMP
XPathResult::GetStringValue(nsAString &aStringValue)
{
if (mResultType != STRING_TYPE) {
return NS_ERROR_DOM_TYPE_ERR;
}
aStringValue = mStringResult;
return NS_OK;
}
NS_IMETHODIMP
XPathResult::GetBooleanValue(bool *aBooleanValue)
{
if (mResultType != BOOLEAN_TYPE) {
return NS_ERROR_DOM_TYPE_ERR;
}
*aBooleanValue = mBooleanResult;
return NS_OK;
}
NS_IMETHODIMP
XPathResult::GetSingleNodeValue(nsIDOMNode **aSingleNodeValue)
{
if (!isNode()) {
return NS_ERROR_DOM_TYPE_ERR;
}
if (mResultNodes.Count() > 0) {
NS_ADDREF(*aSingleNodeValue = mResultNodes[0]);
}
else {
*aSingleNodeValue = nullptr;
}
return NS_OK;
}
NS_IMETHODIMP
XPathResult::GetInvalidIteratorState(bool *aInvalidIteratorState)
{
*aInvalidIteratorState = isIterator() && mInvalidIteratorState;
return NS_OK;
}
NS_IMETHODIMP
XPathResult::GetSnapshotLength(uint32_t *aSnapshotLength)
{
if (!isSnapshot()) {
return NS_ERROR_DOM_TYPE_ERR;
}
*aSnapshotLength = (uint32_t)mResultNodes.Count();
return NS_OK;
}
NS_IMETHODIMP
XPathResult::IterateNext(nsIDOMNode **aResult)
nsINode*
XPathResult::IterateNext(ErrorResult& aRv)
{
if (!isIterator()) {
return NS_ERROR_DOM_TYPE_ERR;
aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
return nullptr;
}
if (mDocument) {
@ -174,29 +108,11 @@ XPathResult::IterateNext(nsIDOMNode **aResult)
}
if (mInvalidIteratorState) {
return NS_ERROR_DOM_INVALID_STATE_ERR;
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
if (mCurrentPos < (uint32_t)mResultNodes.Count()) {
NS_ADDREF(*aResult = mResultNodes[mCurrentPos++]);
}
else {
*aResult = nullptr;
}
return NS_OK;
}
NS_IMETHODIMP
XPathResult::SnapshotItem(uint32_t aIndex, nsIDOMNode **aResult)
{
if (!isSnapshot()) {
return NS_ERROR_DOM_TYPE_ERR;
}
NS_IF_ADDREF(*aResult = mResultNodes.SafeObjectAt(aIndex));
return NS_OK;
return mResultNodes.SafeObjectAt(mCurrentPos++);
}
void
@ -306,13 +222,10 @@ XPathResult::SetExprResult(txAExprResult* aExprResult, uint16_t aResultType,
if (aExprResult->getResultType() == txAExprResult::NODESET) {
txNodeSet *nodeSet = static_cast<txNodeSet*>(aExprResult);
nsCOMPtr<nsIDOMNode> node;
int32_t i, count = nodeSet->size();
for (i = 0; i < count; ++i) {
txXPathNativeNode::getNode(nodeSet->get(i), getter_AddRefs(node));
if (node) {
mResultNodes.AppendObject(node);
}
nsINode* node = txXPathNativeNode::getNode(nodeSet->get(i));
mResultNodes.AppendObject(node);
}
if (count > 0) {
@ -329,15 +242,7 @@ XPathResult::SetExprResult(txAExprResult* aExprResult, uint16_t aResultType,
if (mResultNodes.Count() > 0) {
// If we support the document() function in DOM-XPath we need to
// observe all documents that we have resultnodes in.
nsCOMPtr<nsIDOMDocument> document;
mResultNodes[0]->GetOwnerDocument(getter_AddRefs(document));
if (document) {
mDocument = do_QueryInterface(document);
}
else {
mDocument = do_QueryInterface(mResultNodes[0]);
}
mDocument = mResultNodes[0]->OwnerDoc();
NS_ASSERTION(mDocument, "We need a document!");
if (mDocument) {
mDocument->AddMutationObserver(this);
@ -427,12 +332,7 @@ XPathResult::Clone(nsIXPathResult **aResult)
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
nsCOMPtr<nsIXPathResult> result = new XPathResult(*this);
if (!result) {
return NS_ERROR_OUT_OF_MEMORY;
}
result.swap(*aResult);
NS_ADDREF(*aResult = new XPathResult(*this));
return NS_OK;
}

View File

@ -6,16 +6,20 @@
#ifndef mozilla_dom_XPathResult_h
#define mozilla_dom_XPathResult_h
#include "txExprResult.h"
#include "nsIDOMXPathResult.h"
#include "nsStubMutationObserver.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsCOMArray.h"
#include "nsWeakPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "nsString.h"
#include "nsWrapperCache.h"
#include "nsINode.h"
class nsIDocument;
class txAExprResult;
// {662f2c9a-c7cd-4cab-9349-e733df5a838c}
#define NS_IXPATHRESULT_IID \
@ -40,21 +44,106 @@ namespace dom {
/**
* A class for evaluating an XPath expression string
*/
class XPathResult MOZ_FINAL : public nsIDOMXPathResult,
class XPathResult MOZ_FINAL : public nsIXPathResult,
public nsStubMutationObserver,
public nsIXPathResult
public nsWrapperCache
{
public:
XPathResult();
XPathResult(nsINode* aParent);
XPathResult(const XPathResult &aResult);
~XPathResult();
enum {
ANY_TYPE = 0U,
NUMBER_TYPE = 1U,
STRING_TYPE = 2U,
BOOLEAN_TYPE = 3U,
UNORDERED_NODE_ITERATOR_TYPE = 4U,
ORDERED_NODE_ITERATOR_TYPE = 5U,
UNORDERED_NODE_SNAPSHOT_TYPE = 6U,
ORDERED_NODE_SNAPSHOT_TYPE = 7U,
ANY_UNORDERED_NODE_TYPE = 8U,
FIRST_ORDERED_NODE_TYPE = 9U
};
// nsISupports interface
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(XPathResult, nsIDOMXPathResult)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(XPathResult,
nsIXPathResult)
// nsIDOMXPathResult interface
NS_DECL_NSIDOMXPATHRESULT
static XPathResult* FromSupports(nsISupports* aSupports)
{
return static_cast<XPathResult*>(static_cast<nsIXPathResult*>(aSupports));
}
virtual JSObject* WrapObject(JSContext* aCx);
nsINode* GetParentObject() const
{
return mParent;
}
uint16_t ResultType() const
{
return mResultType;
}
double GetNumberValue(ErrorResult& aRv) const
{
if (mResultType != NUMBER_TYPE) {
aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
return 0;
}
return mNumberResult;
}
void GetStringValue(nsAString &aStringValue, ErrorResult& aRv) const
{
if (mResultType != STRING_TYPE) {
aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
return;
}
aStringValue = mStringResult;
}
bool GetBooleanValue(ErrorResult& aRv) const
{
if (mResultType != BOOLEAN_TYPE) {
aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
return false;
}
return mBooleanResult;
}
nsINode* GetSingleNodeValue(ErrorResult& aRv) const
{
if (!isNode()) {
aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
return nullptr;
}
return mResultNodes.SafeObjectAt(0);
}
bool InvalidIteratorState() const
{
return isIterator() && mInvalidIteratorState;
}
uint32_t GetSnapshotLength(ErrorResult& aRv) const
{
if (!isSnapshot()) {
aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
return 0;
}
return (uint32_t)mResultNodes.Count();
}
nsINode* IterateNext(ErrorResult& aRv);
nsINode* SnapshotItem(uint32_t aIndex, ErrorResult& aRv) const
{
if (!isSnapshot()) {
aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
return nullptr;
}
return mResultNodes.SafeObjectAt(aIndex);
}
// nsIMutationObserver interface
NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
@ -64,7 +153,6 @@ public:
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
// nsIXPathResult interface
nsresult SetExprResult(txAExprResult *aExprResult, uint16_t aResultType,
nsINode* aContextNode) MOZ_OVERRIDE;
nsresult GetExprResult(txAExprResult **aExprResult) MOZ_OVERRIDE;
@ -101,12 +189,13 @@ private:
void Invalidate(const nsIContent* aChangeRoot);
nsCOMPtr<nsINode> mParent;
nsRefPtr<txAExprResult> mResult;
nsCOMArray<nsIDOMNode> mResultNodes;
nsCOMArray<nsINode> mResultNodes;
nsCOMPtr<nsIDocument> mDocument;
nsWeakPtr mContextNode;
uint32_t mCurrentPos;
uint16_t mResultType;
nsWeakPtr mContextNode;
bool mInvalidIteratorState;
bool mBooleanResult;
double mNumberResult;

View File

@ -116,20 +116,20 @@ nsXPathExpression::EvaluateWithContext(nsIDOMNode *aContextNode,
NS_ENSURE_SUCCESS(rv, rv);
uint16_t resultType = aType;
if (aType == nsIDOMXPathResult::ANY_TYPE) {
if (aType == XPathResult::ANY_TYPE) {
short exprResultType = exprResult->getResultType();
switch (exprResultType) {
case txAExprResult::NUMBER:
resultType = nsIDOMXPathResult::NUMBER_TYPE;
resultType = XPathResult::NUMBER_TYPE;
break;
case txAExprResult::STRING:
resultType = nsIDOMXPathResult::STRING_TYPE;
resultType = XPathResult::STRING_TYPE;
break;
case txAExprResult::BOOLEAN:
resultType = nsIDOMXPathResult::BOOLEAN_TYPE;
resultType = XPathResult::BOOLEAN_TYPE;
break;
case txAExprResult::NODESET:
resultType = nsIDOMXPathResult::UNORDERED_NODE_ITERATOR_TYPE;
resultType = XPathResult::UNORDERED_NODE_ITERATOR_TYPE;
break;
case txAExprResult::RESULT_TREE_FRAGMENT:
NS_ERROR("Can't return a tree fragment!");
@ -141,8 +141,7 @@ nsXPathExpression::EvaluateWithContext(nsIDOMNode *aContextNode,
nsCOMPtr<nsIXPathResult> xpathResult = do_QueryInterface(aInResult);
if (!xpathResult) {
// Either no aInResult or not one of ours.
xpathResult = new XPathResult();
NS_ENSURE_TRUE(xpathResult, NS_ERROR_OUT_OF_MEMORY);
xpathResult = new XPathResult(context);
}
rv = xpathResult->SetExprResult(exprResult, resultType, context);
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -25,7 +25,7 @@
#include <stdint.h>
#include <algorithm>
using mozilla::dom::Attr;
using namespace mozilla::dom;
const uint32_t kUnknownIndex = uint32_t(-1);
@ -683,11 +683,9 @@ txXPathNativeNode::createXPathNode(nsIContent* aContent, bool aKeepRootAlive)
/* static */
txXPathNode*
txXPathNativeNode::createXPathNode(nsIDOMNode* aNode, bool aKeepRootAlive)
txXPathNativeNode::createXPathNode(nsINode* aNode, bool aKeepRootAlive)
{
uint16_t nodeType;
aNode->GetNodeType(&nodeType);
uint16_t nodeType = aNode->NodeType();
if (nodeType == nsIDOMNode::ATTRIBUTE_NODE) {
nsCOMPtr<nsIAttribute> attr = do_QueryInterface(aNode);
NS_ASSERTION(attr, "doesn't implement nsIAttribute");
@ -714,9 +712,8 @@ txXPathNativeNode::createXPathNode(nsIDOMNode* aNode, bool aKeepRootAlive)
return nullptr;
}
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
uint32_t index;
nsINode* root = aKeepRootAlive ? node.get() : nullptr;
nsINode* root = aKeepRootAlive ? aNode : nullptr;
if (nodeType == nsIDOMNode::DOCUMENT_NODE) {
index = txXPathNode::eDocument;
@ -728,7 +725,7 @@ txXPathNativeNode::createXPathNode(nsIDOMNode* aNode, bool aKeepRootAlive)
}
}
return new txXPathNode(node, index, root);
return new txXPathNode(aNode, index, root);
}
/* static */
@ -740,11 +737,11 @@ txXPathNativeNode::createXPathNode(nsIDOMDocument* aDocument)
}
/* static */
nsresult
txXPathNativeNode::getNode(const txXPathNode& aNode, nsIDOMNode** aResult)
nsINode*
txXPathNativeNode::getNode(const txXPathNode& aNode)
{
if (!aNode.isAttribute()) {
return CallQueryInterface(aNode.mNode, aResult);
return aNode.mNode;
}
const nsAttrName* name = aNode.Content()->GetAttrNameAt(aNode.mIndex);
@ -752,13 +749,10 @@ txXPathNativeNode::getNode(const txXPathNode& aNode, nsIDOMNode** aResult)
nsAutoString namespaceURI;
nsContentUtils::NameSpaceManager()->GetNameSpaceURI(name->NamespaceID(), namespaceURI);
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(aNode.mNode);
nsCOMPtr<nsIDOMAttr> attr;
element->GetAttributeNodeNS(namespaceURI,
nsDependentAtomString(name->LocalName()),
getter_AddRefs(attr));
return CallQueryInterface(attr, aResult);
nsCOMPtr<Element> element = do_QueryInterface(aNode.mNode);
nsDOMAttributeMap* map = element->Attributes();
return map->GetNamedItemNS(namespaceURI,
nsDependentAtomString(name->LocalName()));
}
/* static */

View File

@ -117,12 +117,22 @@ public:
class txXPathNativeNode
{
public:
static txXPathNode* createXPathNode(nsIDOMNode* aNode,
static txXPathNode* createXPathNode(nsINode* aNode,
bool aKeepRootAlive = false);
static txXPathNode* createXPathNode(nsIDOMNode* aNode,
bool aKeepRootAlive = false)
{
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
return createXPathNode(node, aKeepRootAlive);
}
static txXPathNode* createXPathNode(nsIContent* aContent,
bool aKeepRootAlive = false);
static txXPathNode* createXPathNode(nsIDOMDocument* aDocument);
static nsresult getNode(const txXPathNode& aNode, nsIDOMNode** aResult);
static nsINode* getNode(const txXPathNode& aNode);
static nsresult getNode(const txXPathNode& aNode, nsIDOMNode** aResult)
{
return CallQueryInterface(getNode(aNode), aResult);
}
static nsIContent* getContent(const txXPathNode& aNode);
static nsIDocument* getDocument(const txXPathNode& aNode);
static void addRef(const txXPathNode& aNode)

View File

@ -43,14 +43,6 @@ members = [
# dom/interfaces/xpath
'nsIDOMXPathExpression.evaluate',
'nsIDOMXPathNSResolver.lookupNamespaceURI',
'nsIDOMXPathResult.snapshotItem',
'nsIDOMXPathResult.iterateNext',
'nsIDOMXPathResult.snapshotLength',
'nsIDOMXPathResult.resultType',
'nsIDOMXPathResult.numberValue',
'nsIDOMXPathResult.stringValue',
'nsIDOMXPathResult.booleanValue',
'nsIDOMXPathResult.singleNodeValue',
'nsIDOMNSXPathExpression.evaluateWithContext',
# layout/xul/base/public

View File

@ -159,6 +159,7 @@
#include "nsIDOMWheelEvent.h"
#include "nsIDOMXMLDocument.h"
#include "nsIDOMXPathEvaluator.h"
#include "nsIDOMXPathResult.h"
#include "nsIDOMXULCommandEvent.h"
#include "nsIDOMXULDocument.h"
#include "nsIDOMXULElement.h"
@ -321,6 +322,7 @@
#include "mozilla/dom/XMLHttpRequestUploadBinding.h"
#include "mozilla/dom/XMLSerializerBinding.h"
#include "mozilla/dom/XPathEvaluatorBinding.h"
#include "mozilla/dom/XPathResultBinding.h"
#include "mozilla/dom/XULCommandEventBinding.h"
#include "mozilla/dom/XULDocumentBinding.h"
#include "mozilla/dom/XULElementBinding.h"
@ -529,6 +531,7 @@ const ComponentsInterfaceShimEntry kComponentsInterfaceShimMap[] =
DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIXMLHttpRequestEventTarget, XMLHttpRequestEventTarget),
DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIXMLHttpRequestUpload, XMLHttpRequestUpload),
DEFINE_SHIM(XPathEvaluator),
DEFINE_SHIM(XPathResult),
DEFINE_SHIM(XULCommandEvent),
DEFINE_SHIM(XULDocument),
DEFINE_SHIM(XULElement),