зеркало из https://github.com/mozilla/pjs.git
Fix for bug 248025 (cannot add a DOM Node as an xsl:param using XSLTProcessor.setParameter()). r=Pike, sr=jst.
This commit is contained in:
Родитель
76f54b84d0
Коммит
7e60d907f0
|
@ -47,8 +47,7 @@
|
|||
#include "nsIDOMDocument.h"
|
||||
#include "nsDOMString.h"
|
||||
|
||||
nsXPathResult::nsXPathResult() : mNumberValue(0),
|
||||
mDocument(0),
|
||||
nsXPathResult::nsXPathResult() : mDocument(nsnull),
|
||||
mCurrentPos(0),
|
||||
mResultType(ANY_TYPE),
|
||||
mInvalidIteratorState(PR_TRUE)
|
||||
|
@ -57,7 +56,9 @@ nsXPathResult::nsXPathResult() : mNumberValue(0),
|
|||
|
||||
nsXPathResult::~nsXPathResult()
|
||||
{
|
||||
Reset();
|
||||
if (mDocument) {
|
||||
mDocument->RemoveObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsXPathResult)
|
||||
|
@ -73,125 +74,124 @@ NS_INTERFACE_MAP_END
|
|||
NS_IMETHODIMP
|
||||
nsXPathResult::GetResultType(PRUint16 *aResultType)
|
||||
{
|
||||
NS_ENSURE_ARG(aResultType);
|
||||
*aResultType = mResultType;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPathResult::GetNumberValue(double *aNumberValue)
|
||||
{
|
||||
if (mResultType != NUMBER_TYPE)
|
||||
if (mResultType != NUMBER_TYPE) {
|
||||
return NS_ERROR_DOM_TYPE_ERR;
|
||||
}
|
||||
|
||||
*aNumberValue = mResult.get()->numberValue();
|
||||
|
||||
NS_ENSURE_ARG(aNumberValue);
|
||||
*aNumberValue = mNumberValue;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPathResult::GetStringValue(nsAString &aStringValue)
|
||||
{
|
||||
if (mResultType != STRING_TYPE)
|
||||
if (mResultType != STRING_TYPE) {
|
||||
return NS_ERROR_DOM_TYPE_ERR;
|
||||
}
|
||||
|
||||
mResult.get()->stringValue(aStringValue);
|
||||
|
||||
if (mStringValue)
|
||||
aStringValue.Assign(*mStringValue);
|
||||
else
|
||||
SetDOMStringToNull(aStringValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPathResult::GetBooleanValue(PRBool *aBooleanValue)
|
||||
{
|
||||
if (mResultType != BOOLEAN_TYPE)
|
||||
if (mResultType != BOOLEAN_TYPE) {
|
||||
return NS_ERROR_DOM_TYPE_ERR;
|
||||
}
|
||||
|
||||
*aBooleanValue = mResult.get()->booleanValue();
|
||||
|
||||
NS_ENSURE_ARG(aBooleanValue);
|
||||
*aBooleanValue = mBooleanValue;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPathResult::GetSingleNodeValue(nsIDOMNode **aSingleNodeValue)
|
||||
{
|
||||
if (mResultType != FIRST_ORDERED_NODE_TYPE &&
|
||||
mResultType != ANY_UNORDERED_NODE_TYPE)
|
||||
if (!isNode()) {
|
||||
return NS_ERROR_DOM_TYPE_ERR;
|
||||
}
|
||||
|
||||
txNodeSet *nodeSet = NS_STATIC_CAST(txNodeSet*, mResult.get());
|
||||
if (nodeSet->size() > 0) {
|
||||
return txXPathNativeNode::getNode(nodeSet->get(0), aSingleNodeValue);
|
||||
}
|
||||
|
||||
*aSingleNodeValue = nsnull;
|
||||
|
||||
NS_ENSURE_ARG(aSingleNodeValue);
|
||||
*aSingleNodeValue = mNode;
|
||||
NS_IF_ADDREF(*aSingleNodeValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPathResult::GetInvalidIteratorState(PRBool *aInvalidIteratorState)
|
||||
{
|
||||
NS_ENSURE_ARG(aInvalidIteratorState);
|
||||
*aInvalidIteratorState = isIterator() && mInvalidIteratorState;
|
||||
|
||||
if (mResultType != UNORDERED_NODE_ITERATOR_TYPE &&
|
||||
mResultType != ORDERED_NODE_ITERATOR_TYPE) {
|
||||
*aInvalidIteratorState = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*aInvalidIteratorState = mInvalidIteratorState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPathResult::GetSnapshotLength(PRUint32 *aSnapshotLength)
|
||||
{
|
||||
if (mResultType != UNORDERED_NODE_SNAPSHOT_TYPE &&
|
||||
mResultType != ORDERED_NODE_SNAPSHOT_TYPE)
|
||||
if (!isSnapshot()) {
|
||||
return NS_ERROR_DOM_TYPE_ERR;
|
||||
}
|
||||
|
||||
txNodeSet *nodeSet = NS_STATIC_CAST(txNodeSet*, mResult.get());
|
||||
*aSnapshotLength = (PRUint32)nodeSet->size();
|
||||
|
||||
NS_ENSURE_ARG(aSnapshotLength);
|
||||
*aSnapshotLength = 0;
|
||||
if (mElements)
|
||||
*aSnapshotLength = mElements->Count();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPathResult::IterateNext(nsIDOMNode **aResult)
|
||||
{
|
||||
if (mResultType != UNORDERED_NODE_ITERATOR_TYPE &&
|
||||
mResultType != ORDERED_NODE_ITERATOR_TYPE)
|
||||
if (!isIterator()) {
|
||||
return NS_ERROR_DOM_TYPE_ERR;
|
||||
|
||||
if (mDocument)
|
||||
mDocument->FlushPendingNotifications(Flush_Content);
|
||||
|
||||
if (mInvalidIteratorState)
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
|
||||
NS_ENSURE_ARG(aResult);
|
||||
if (mElements && mCurrentPos < (PRUint32)mElements->Count()) {
|
||||
*aResult = mElements->ObjectAt(mCurrentPos++);
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mDocument) {
|
||||
mDocument->FlushPendingNotifications(Flush_Content);
|
||||
}
|
||||
|
||||
if (mInvalidIteratorState) {
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
txNodeSet *nodeSet = NS_STATIC_CAST(txNodeSet*, mResult.get());
|
||||
if (mCurrentPos < (PRUint32)nodeSet->size()) {
|
||||
return txXPathNativeNode::getNode(nodeSet->get(mCurrentPos), aResult);
|
||||
}
|
||||
|
||||
*aResult = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPathResult::SnapshotItem(PRUint32 aIndex, nsIDOMNode **aResult)
|
||||
{
|
||||
if (mResultType != UNORDERED_NODE_SNAPSHOT_TYPE &&
|
||||
mResultType != ORDERED_NODE_SNAPSHOT_TYPE)
|
||||
if (!isSnapshot()) {
|
||||
return NS_ERROR_DOM_TYPE_ERR;
|
||||
|
||||
NS_ENSURE_ARG(aResult);
|
||||
if (mElements && aIndex < (PRUint32)mElements->Count()) {
|
||||
*aResult = mElements->ObjectAt(aIndex);
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
txNodeSet *nodeSet = NS_STATIC_CAST(txNodeSet*, mResult.get());
|
||||
if (aIndex < (PRUint32)nodeSet->size()) {
|
||||
return txXPathNativeNode::getNode(nodeSet->get(aIndex), aResult);
|
||||
}
|
||||
|
||||
*aResult = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -245,81 +245,48 @@ nsXPathResult::ContentRemoved(nsIDocument* aDocument,
|
|||
Invalidate();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsXPathResult::SetExprResult(txAExprResult* aExprResult, PRUint16 aResultType)
|
||||
{
|
||||
Reset();
|
||||
if (mDocument) {
|
||||
mDocument->RemoveObserver(this);
|
||||
mDocument = nsnull;
|
||||
}
|
||||
|
||||
mResultType = aResultType;
|
||||
mResult.set(aExprResult);
|
||||
|
||||
if (mResultType == NUMBER_TYPE) {
|
||||
mNumberValue = aExprResult->numberValue();
|
||||
if (!isIterator()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mResultType == STRING_TYPE) {
|
||||
mStringValue = new nsString;
|
||||
NS_ENSURE_TRUE(mStringValue, NS_ERROR_OUT_OF_MEMORY);
|
||||
aExprResult->stringValue(*mStringValue);
|
||||
return NS_OK;
|
||||
}
|
||||
mInvalidIteratorState = PR_FALSE;
|
||||
|
||||
if (mResultType == BOOLEAN_TYPE) {
|
||||
mBooleanValue = aExprResult->booleanValue();
|
||||
return NS_OK;
|
||||
}
|
||||
txNodeSet* nodeSet = NS_STATIC_CAST(txNodeSet*, aExprResult);
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
if (nodeSet->size() > 0) {
|
||||
nsresult rv = txXPathNativeNode::getNode(nodeSet->get(0),
|
||||
getter_AddRefs(node));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aExprResult->getResultType() == txAExprResult::NODESET) {
|
||||
nsresult rv = NS_OK;
|
||||
txNodeSet* nodeSet = NS_STATIC_CAST(txNodeSet*, aExprResult);
|
||||
|
||||
if (mResultType == FIRST_ORDERED_NODE_TYPE ||
|
||||
mResultType == ANY_UNORDERED_NODE_TYPE) {
|
||||
if (nodeSet->size() > 0) {
|
||||
txXPathNativeNode::getNode(nodeSet->get(0), &mNode);
|
||||
}
|
||||
// If we support the document() function in DOM-XPath we need to
|
||||
// observe all documents that we have resultnodes in.
|
||||
nsCOMPtr<nsIDOMDocument> document;
|
||||
node->GetOwnerDocument(getter_AddRefs(document));
|
||||
if (document) {
|
||||
mDocument = do_QueryInterface(document);
|
||||
}
|
||||
else {
|
||||
if (mResultType == UNORDERED_NODE_ITERATOR_TYPE ||
|
||||
mResultType == ORDERED_NODE_ITERATOR_TYPE) {
|
||||
mInvalidIteratorState = PR_FALSE;
|
||||
}
|
||||
|
||||
PRInt32 count = nodeSet->size();
|
||||
if (count == 0)
|
||||
return NS_OK;
|
||||
|
||||
mElements = new nsCOMArray<nsIDOMNode>;
|
||||
NS_ENSURE_TRUE(mElements, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
PRInt32 i;
|
||||
for (i = 0; i < count; ++i) {
|
||||
txXPathNativeNode::getNode(nodeSet->get(i), getter_AddRefs(node));
|
||||
NS_ASSERTION(node, "node isn't an nsIDOMNode");
|
||||
mElements->AppendObject(node);
|
||||
}
|
||||
|
||||
// If we support the document() function in DOM-XPath we need to
|
||||
// observe all documents that we have resultnodes in.
|
||||
if (mResultType == UNORDERED_NODE_ITERATOR_TYPE ||
|
||||
mResultType == ORDERED_NODE_ITERATOR_TYPE) {
|
||||
nsCOMPtr<nsIDOMDocument> document;
|
||||
node->GetOwnerDocument(getter_AddRefs(document));
|
||||
if (document)
|
||||
mDocument = do_QueryInterface(document);
|
||||
else
|
||||
mDocument = do_QueryInterface(node);
|
||||
|
||||
NS_ASSERTION(mDocument, "We need a document!");
|
||||
if (mDocument)
|
||||
mDocument->AddObserver(this);
|
||||
}
|
||||
mDocument = do_QueryInterface(node);
|
||||
}
|
||||
|
||||
NS_ASSERTION(mDocument, "We need a document!");
|
||||
if (mDocument) {
|
||||
mDocument->AddObserver(this);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_ERROR_DOM_TYPE_ERR;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -327,32 +294,79 @@ nsXPathResult::Invalidate()
|
|||
{
|
||||
if (mDocument) {
|
||||
mDocument->RemoveObserver(this);
|
||||
mDocument = 0;
|
||||
mDocument = nsnull;
|
||||
}
|
||||
mInvalidIteratorState = PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nsXPathResult::Reset()
|
||||
nsresult
|
||||
nsXPathResult::GetExprResult(txAExprResult** aExprResult)
|
||||
{
|
||||
Invalidate();
|
||||
|
||||
if (mResultType == STRING_TYPE) {
|
||||
delete mStringValue;
|
||||
mStringValue = 0;
|
||||
}
|
||||
else if (mResultType == UNORDERED_NODE_ITERATOR_TYPE ||
|
||||
mResultType == ORDERED_NODE_ITERATOR_TYPE ||
|
||||
mResultType == UNORDERED_NODE_SNAPSHOT_TYPE ||
|
||||
mResultType == ORDERED_NODE_SNAPSHOT_TYPE) {
|
||||
delete mElements;
|
||||
mCurrentPos = 0;
|
||||
}
|
||||
else if (mResultType == FIRST_ORDERED_NODE_TYPE ||
|
||||
mResultType == ANY_UNORDERED_NODE_TYPE) {
|
||||
NS_IF_RELEASE(mNode);
|
||||
if (isIterator() && mInvalidIteratorState) {
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
mResultType = ANY_TYPE;
|
||||
return;
|
||||
*aExprResult = mResult.get();
|
||||
if (!*aExprResult) {
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
NS_ADDREF(*aExprResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXPathResult::Clone(nsIXPathResult **aResult)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
|
||||
if (isIterator() && mInvalidIteratorState) {
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXPathResult> result = new nsXPathResult();
|
||||
if (!result) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsresult rv = result->SetExprResult(mResult.get(), mResultType);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
result.swap(*aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
txResultHolder::set(txAExprResult *aResult)
|
||||
{
|
||||
releaseNodeSet();
|
||||
|
||||
// XXX This will keep the recycler alive, should we clear it?
|
||||
mResult = aResult;
|
||||
|
||||
if (mResult && mResult->getResultType() == txAExprResult::NODESET) {
|
||||
txNodeSet *nodeSet =
|
||||
NS_STATIC_CAST(txNodeSet*,
|
||||
NS_STATIC_CAST(txAExprResult*, mResult));
|
||||
PRInt32 i, count = nodeSet->size();
|
||||
for (i = 0; i < count; ++i) {
|
||||
txXPathNativeNode::addRef(nodeSet->get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
txResultHolder::releaseNodeSet()
|
||||
{
|
||||
if (mResult && mResult->getResultType() == txAExprResult::NODESET) {
|
||||
txNodeSet *nodeSet =
|
||||
NS_STATIC_CAST(txNodeSet*,
|
||||
NS_STATIC_CAST(txAExprResult*, mResult));
|
||||
PRInt32 i, count = nodeSet->size();
|
||||
for (i = 0; i < count; ++i) {
|
||||
txXPathNativeNode::release(nodeSet->get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,14 +39,13 @@
|
|||
#ifndef nsXPathResult_h__
|
||||
#define nsXPathResult_h__
|
||||
|
||||
#include "ExprResult.h"
|
||||
#include "nsIDOMXPathResult.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDocumentObserver.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCOMArray.h"
|
||||
|
||||
class txAExprResult;
|
||||
|
||||
// {15b9b301-2012-11d6-a7f2-e6d0a678995c}
|
||||
#define NS_IXPATHRESULT_IID \
|
||||
{ 0x15b9b301, 0x2012, 0x11d6, {0xa7, 0xf2, 0xe6, 0xd0, 0xa6, 0x78, 0x99, 0x5c }};
|
||||
|
@ -55,8 +54,34 @@ class nsIXPathResult : public nsISupports
|
|||
{
|
||||
public:
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IXPATHRESULT_IID)
|
||||
NS_IMETHOD SetExprResult(txAExprResult* aExprResult,
|
||||
PRUint16 aResultType) = 0;
|
||||
virtual nsresult SetExprResult(txAExprResult *aExprResult,
|
||||
PRUint16 aResultType) = 0;
|
||||
virtual nsresult GetExprResult(txAExprResult **aExprResult) = 0;
|
||||
virtual nsresult Clone(nsIXPathResult **aResult) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper class to keep Mozilla node objects alive as long as the nodeset is
|
||||
* alive.
|
||||
*/
|
||||
class txResultHolder
|
||||
{
|
||||
public:
|
||||
~txResultHolder()
|
||||
{
|
||||
releaseNodeSet();
|
||||
}
|
||||
|
||||
txAExprResult *get()
|
||||
{
|
||||
return mResult;
|
||||
}
|
||||
void set(txAExprResult *aResult);
|
||||
|
||||
private:
|
||||
void releaseNodeSet();
|
||||
|
||||
nsRefPtr<txAExprResult> mResult;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -80,19 +105,30 @@ public:
|
|||
NS_DECL_NSIDOCUMENTOBSERVER
|
||||
|
||||
// nsIXPathResult interface
|
||||
NS_IMETHOD SetExprResult(txAExprResult* aExprResult,
|
||||
PRUint16 aResultType);
|
||||
private:
|
||||
void Invalidate();
|
||||
void Reset();
|
||||
nsresult SetExprResult(txAExprResult *aExprResult, PRUint16 aResultType);
|
||||
nsresult GetExprResult(txAExprResult **aExprResult);
|
||||
nsresult Clone(nsIXPathResult **aResult);
|
||||
|
||||
union {
|
||||
double mNumberValue;
|
||||
nsString* mStringValue;
|
||||
PRBool mBooleanValue;
|
||||
nsIDOMNode* mNode;
|
||||
nsCOMArray<nsIDOMNode>* mElements;
|
||||
};
|
||||
private:
|
||||
PRBool isSnapshot() const
|
||||
{
|
||||
return mResultType == UNORDERED_NODE_SNAPSHOT_TYPE ||
|
||||
mResultType == ORDERED_NODE_SNAPSHOT_TYPE;
|
||||
}
|
||||
PRBool isIterator() const
|
||||
{
|
||||
return mResultType == UNORDERED_NODE_ITERATOR_TYPE ||
|
||||
mResultType == ORDERED_NODE_ITERATOR_TYPE;
|
||||
}
|
||||
PRBool isNode() const
|
||||
{
|
||||
return mResultType == FIRST_ORDERED_NODE_TYPE ||
|
||||
mResultType == ANY_UNORDERED_NODE_TYPE;
|
||||
}
|
||||
|
||||
void Invalidate();
|
||||
|
||||
txResultHolder mResult;
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
PRUint32 mCurrentPos;
|
||||
PRUint16 mResultType;
|
||||
|
|
|
@ -162,6 +162,17 @@ public:
|
|||
static nsresult getNode(const txXPathNode& aNode, nsIDOMNode** aResult);
|
||||
static nsIContent* getContent(const txXPathNode& aNode);
|
||||
static nsIDocument* getDocument(const txXPathNode& aNode);
|
||||
static void addRef(const txXPathNode& aNode)
|
||||
{
|
||||
// Hopefully it's ok to access mContent through mDocument.
|
||||
NS_ADDREF(aNode.mDocument);
|
||||
}
|
||||
static void release(const txXPathNode& aNode)
|
||||
{
|
||||
// Hopefully it's ok to access mContent through mDocument.
|
||||
nsISupports *node = aNode.mDocument;
|
||||
NS_RELEASE(node);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -47,12 +47,14 @@
|
|||
#include "nsIDOMClassInfo.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMDocumentFragment.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIScriptLoader.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsXPathResult.h"
|
||||
#include "txExecutionState.h"
|
||||
#include "txMozillaTextOutput.h"
|
||||
#include "txMozillaXMLOutput.h"
|
||||
|
@ -61,6 +63,7 @@
|
|||
#include "txUnknownHandler.h"
|
||||
#include "txXSLTProcessor.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "jsapi.h"
|
||||
|
||||
static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID);
|
||||
|
||||
|
@ -482,8 +485,11 @@ txMozillaXSLTProcessor::SetParameter(const nsAString & aNamespaceURI,
|
|||
nsIVariant *aValue)
|
||||
{
|
||||
NS_ENSURE_ARG(aValue);
|
||||
|
||||
nsCOMPtr<nsIVariant> value = aValue;
|
||||
|
||||
PRUint16 dataType;
|
||||
aValue->GetDataType(&dataType);
|
||||
value->GetDataType(&dataType);
|
||||
switch (dataType) {
|
||||
// Number
|
||||
case nsIDataType::VTYPE_INT8:
|
||||
|
@ -511,14 +517,145 @@ txMozillaXSLTProcessor::SetParameter(const nsAString & aNamespaceURI,
|
|||
case nsIDataType::VTYPE_UTF8STRING:
|
||||
case nsIDataType::VTYPE_CSTRING:
|
||||
case nsIDataType::VTYPE_ASTRING:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Nodeset
|
||||
case nsIDataType::VTYPE_INTERFACE:
|
||||
case nsIDataType::VTYPE_INTERFACE_IS:
|
||||
{
|
||||
nsCOMPtr<nsISupports> supports;
|
||||
nsresult rv = value->GetAsISupports(getter_AddRefs(supports));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(supports);
|
||||
if (node) {
|
||||
if (!URIUtils::CanCallerAccess(node)) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXPathResult> xpathResult = do_QueryInterface(supports);
|
||||
if (xpathResult) {
|
||||
nsRefPtr<txAExprResult> result;
|
||||
nsresult rv = xpathResult->GetExprResult(getter_AddRefs(result));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (result->getResultType() == txAExprResult::NODESET) {
|
||||
txNodeSet *nodeSet =
|
||||
NS_STATIC_CAST(txNodeSet*,
|
||||
NS_STATIC_CAST(txAExprResult*, result));
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
PRInt32 i, count = nodeSet->size();
|
||||
for (i = 0; i < count; ++i) {
|
||||
rv = txXPathNativeNode::getNode(nodeSet->get(i),
|
||||
getter_AddRefs(node));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!URIUtils::CanCallerAccess(node)) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clone the nsXPathResult so that mutations don't affect this
|
||||
// variable.
|
||||
nsCOMPtr<nsIXPathResult> clone;
|
||||
rv = xpathResult->Clone(getter_AddRefs(clone));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIWritableVariant> variant =
|
||||
do_CreateInstance("@mozilla.org/variant;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = variant->SetAsISupports(clone);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
value = variant;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNodeList> nodeList = do_QueryInterface(supports);
|
||||
if (nodeList) {
|
||||
PRUint32 length;
|
||||
nodeList->GetLength(&length);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
PRUint32 i;
|
||||
for (i = 0; i < length; ++i) {
|
||||
nodeList->Item(i, getter_AddRefs(node));
|
||||
|
||||
if (!URIUtils::CanCallerAccess(node)) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Random JS Objects will be converted to a string.
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> holder =
|
||||
do_QueryInterface(supports);
|
||||
if (holder) {
|
||||
break;
|
||||
}
|
||||
|
||||
// We don't know how to handle this type of param.
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
case nsIDataType::VTYPE_ARRAY:
|
||||
{
|
||||
// This might still be an error, but we'll only
|
||||
// find out later since we lazily evaluate.
|
||||
PRUint16 type;
|
||||
nsIID iid;
|
||||
PRUint32 count;
|
||||
void* array;
|
||||
nsresult rv = value->GetAsArray(&type, &iid, &count, &array);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (type != nsIDataType::VTYPE_INTERFACE &&
|
||||
type != nsIDataType::VTYPE_INTERFACE_IS) {
|
||||
nsMemory::Free(array);
|
||||
|
||||
// We only support arrays of DOM nodes.
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
nsISupports** values = NS_STATIC_CAST(nsISupports**, array);
|
||||
|
||||
PRUint32 i;
|
||||
for (i = 0; i < count; ++i) {
|
||||
nsISupports *supports = values[i];
|
||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(supports);
|
||||
|
||||
if (node) {
|
||||
rv = URIUtils::CanCallerAccess(node) ? NS_OK :
|
||||
NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
else {
|
||||
// We only support arrays of DOM nodes.
|
||||
rv = NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
while (i < count) {
|
||||
NS_RELEASE(values[i++]);
|
||||
}
|
||||
nsMemory::Free(array);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_RELEASE(supports);
|
||||
}
|
||||
|
||||
nsMemory::Free(array);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -536,11 +673,11 @@ txMozillaXSLTProcessor::SetParameter(const nsAString & aNamespaceURI,
|
|||
|
||||
txVariable* var = (txVariable*)mVariables.get(varName);
|
||||
if (var) {
|
||||
var->setValue(aValue);
|
||||
var->setValue(value);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
var = new txVariable(aValue);
|
||||
var = new txVariable(value);
|
||||
NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return mVariables.add(varName, var);
|
||||
|
@ -927,25 +1064,153 @@ txVariable::Convert(nsIVariant *aValue, txAExprResult** aResult)
|
|||
case nsIDataType::VTYPE_INTERFACE:
|
||||
case nsIDataType::VTYPE_INTERFACE_IS:
|
||||
{
|
||||
nsID *iid;
|
||||
nsCOMPtr<nsISupports> supports;
|
||||
nsresult rv = aValue->GetAsInterface(&iid, getter_AddRefs(supports));
|
||||
nsresult rv = aValue->GetAsISupports(getter_AddRefs(supports));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (iid) {
|
||||
// XXX Figure out what the user added and if we can do
|
||||
// anything with it.
|
||||
// nsIDOMNode, nsIDOMNodeList, nsIDOMXPathResult
|
||||
nsMemory::Free(iid);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(supports);
|
||||
if (node) {
|
||||
nsAutoPtr<txXPathNode> xpathNode(txXPathNativeNode::createXPathNode(node));
|
||||
if (!xpathNode) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aResult = new txNodeSet(*xpathNode, nsnull);
|
||||
if (!*aResult) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ADDREF(*aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXPathResult> xpathResult = do_QueryInterface(supports);
|
||||
if (xpathResult) {
|
||||
return xpathResult->GetExprResult(aResult);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNodeList> nodeList = do_QueryInterface(supports);
|
||||
if (nodeList) {
|
||||
nsRefPtr<txNodeSet> nodeSet = new txNodeSet(nsnull);
|
||||
if (!nodeSet) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
PRUint32 length;
|
||||
nodeList->GetLength(&length);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
PRUint32 i;
|
||||
for (i = 0; i < length; ++i) {
|
||||
nodeList->Item(i, getter_AddRefs(node));
|
||||
|
||||
txXPathNode *xpathNode =
|
||||
txXPathNativeNode::createXPathNode(node);
|
||||
if (!xpathNode) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nodeSet->add(*xpathNode);
|
||||
}
|
||||
|
||||
NS_ADDREF(*aResult = nodeSet);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Convert random JS Objects to a string.
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> holder =
|
||||
do_QueryInterface(supports);
|
||||
if (holder) {
|
||||
nsCOMPtr<nsIXPConnect> xpc =
|
||||
do_GetService(nsIXPConnect::GetCID(), &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIXPCNativeCallContext> cc;
|
||||
rv = xpc->GetCurrentNativeCallContext(getter_AddRefs(cc));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
JSContext* cx;
|
||||
rv = cc->GetJSContext(&cx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
JSObject *jsobj;
|
||||
rv = holder->GetJSObject(&jsobj);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
JSString *str = JS_ValueToString(cx, OBJECT_TO_JSVAL(jsobj));
|
||||
NS_ENSURE_TRUE(str, NS_ERROR_FAILURE);
|
||||
|
||||
const PRUnichar *strChars =
|
||||
NS_REINTERPRET_CAST(const PRUnichar*,
|
||||
::JS_GetStringChars(str));
|
||||
nsDependentString value(strChars, ::JS_GetStringLength(str));
|
||||
|
||||
*aResult = new StringResult(value, nsnull);
|
||||
if (!*aResult) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ADDREF(*aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case nsIDataType::VTYPE_ARRAY:
|
||||
{
|
||||
// XXX Figure out what the user added and if we can do
|
||||
// anything with it. Array of Nodes.
|
||||
break;
|
||||
PRUint16 type;
|
||||
nsIID iid;
|
||||
PRUint32 count;
|
||||
void* array;
|
||||
nsresult rv = aValue->GetAsArray(&type, &iid, &count, &array);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ASSERTION(type == nsIDataType::VTYPE_INTERFACE ||
|
||||
type == nsIDataType::VTYPE_INTERFACE_IS,
|
||||
"Huh, we checked this in SetParameter?");
|
||||
|
||||
nsISupports** values = NS_STATIC_CAST(nsISupports**, array);
|
||||
|
||||
nsRefPtr<txNodeSet> nodeSet = new txNodeSet(nsnull);
|
||||
if (!nodeSet) {
|
||||
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, values);
|
||||
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
PRUint32 i;
|
||||
for (i = 0; i < count; ++i) {
|
||||
nsISupports *supports = values[i];
|
||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(supports);
|
||||
NS_ASSERTION(node, "Huh, we checked this in SetParameter?");
|
||||
|
||||
txXPathNode *xpathNode =
|
||||
txXPathNativeNode::createXPathNode(node);
|
||||
if (!xpathNode) {
|
||||
while (i < count) {
|
||||
NS_RELEASE(values[i++]);
|
||||
}
|
||||
nsMemory::Free(array);
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nodeSet->add(*xpathNode);
|
||||
|
||||
NS_RELEASE(supports);
|
||||
}
|
||||
|
||||
nsMemory::Free(array);
|
||||
|
||||
NS_ADDREF(*aResult = nodeSet);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче