From a36acd266d68128ede505e4b1ff24399b2fdf41b Mon Sep 17 00:00:00 2001 From: "doronr%us.ibm.com" Date: Wed, 23 Feb 2005 17:17:47 +0000 Subject: [PATCH] Bug 282777 - Implement index() xpath function. Patch by aaronr@us.ibm.com, r=sicking, beaufour --- .../source/xpath/XFormsFunctionCall.cpp | 30 +++++++++++++++++-- .../source/xpath/nsIXFormsUtilityService.h | 9 +++++- .../source/xpath/nsXFormsXPathEvaluator.cpp | 4 ++- extensions/xforms/nsXFormsUtilityService.cpp | 13 ++++++++ 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/extensions/transformiix/source/xpath/XFormsFunctionCall.cpp b/extensions/transformiix/source/xpath/XFormsFunctionCall.cpp index 5eb01446b49..4072fb801c6 100644 --- a/extensions/transformiix/source/xpath/XFormsFunctionCall.cpp +++ b/extensions/transformiix/source/xpath/XFormsFunctionCall.cpp @@ -180,8 +180,34 @@ XFormsFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult) // its index. if (!requireParams(1, 1, aContext)) return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT; - - return NS_ERROR_NOT_IMPLEMENTED; + + nsAutoString indexId; + evaluateToString((Expr*)iter.next(), aContext, indexId); + + // here document is the XForms document + nsCOMPtr document; + rv = mResolverNode->GetOwnerDocument(getter_AddRefs(document)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(document, NS_ERROR_NULL_POINTER); + + // indexId should be the id of a nsIXFormsRepeatElement + nsCOMPtr repeatEle; + rv = document->GetElementById(indexId, getter_AddRefs(repeatEle)); + NS_ENSURE_SUCCESS(rv, rv); + + // now get the index value from the xforms:repeat. Need to use the + // service to do this work so that we don't have dependencies in + // transformiix on XForms. + nsCOMPtrxformsService = + do_GetService("@mozilla.org/xforms-utility-service;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + + PRUint32 index; + rv = xformsService->GetRepeatIndex(repeatEle, &index); + NS_ENSURE_SUCCESS(rv, rv); + + return aContext->recycler()->getNumberResult(index, aResult); + } case INSTANCE: { diff --git a/extensions/transformiix/source/xpath/nsIXFormsUtilityService.h b/extensions/transformiix/source/xpath/nsIXFormsUtilityService.h index cc9f8a9c41b..3f19241ab85 100644 --- a/extensions/transformiix/source/xpath/nsIXFormsUtilityService.h +++ b/extensions/transformiix/source/xpath/nsIXFormsUtilityService.h @@ -65,7 +65,8 @@ class nsIXFormsModelElement; /* forward declaration */ NS_IMETHOD GetModelFromNode(nsIDOMNode *node, nsIDOMNode **_retval); \ NS_IMETHOD IsNodeAssocWithModel(nsIDOMNode *aNode, nsIDOMNode *aModel, PRBool *_retval); \ NS_IMETHOD GetInstanceDocumentRoot(const nsAString & aID, nsIDOMNode *aModelNode, nsIDOMNode **_retval); \ - NS_IMETHOD ValidateString(const nsAString & aValue, const nsAString & aType, const nsAString & aNamespace, PRBool *_retval); + NS_IMETHOD ValidateString(const nsAString & aValue, const nsAString & aType, const nsAString & aNamespace, PRBool *_retval); \ + NS_IMETHOD GetRepeatIndex(nsIDOMNode *aRepeat, PRUint32 *aIndex); /** * Private interface implemented by the nsXFormsUtilityService in XForms extension. @@ -116,6 +117,12 @@ class NS_NO_VTABLE nsIXFormsUtilityService : public nsISupports { /* boolean validateString (in AString aValue, in AString aType, in AString aNamespace); */ NS_IMETHOD ValidateString(const nsAString & aValue, const nsAString & aType, const nsAString & aNamespace, PRBool *_retval) = 0; + /** + * Function to retrieve the index from the given repeat element. + */ + /* unsigned long getRepeatIndex (in nsIDOMNode aRepeat); */ + NS_IMETHOD GetRepeatIndex(nsIDOMNode *aRepeat, PRUint32 *aIndex) = 0; + }; #define NS_ERROR_XFORMS_CALCUATION_EXCEPTION \ diff --git a/extensions/transformiix/source/xpath/nsXFormsXPathEvaluator.cpp b/extensions/transformiix/source/xpath/nsXFormsXPathEvaluator.cpp index 390f0c379b8..c8c0d243426 100644 --- a/extensions/transformiix/source/xpath/nsXFormsXPathEvaluator.cpp +++ b/extensions/transformiix/source/xpath/nsXFormsXPathEvaluator.cpp @@ -211,7 +211,9 @@ nsXFormsXPathEvaluator::XFormsParseContextImpl::resolveFunctionCall( aFnCall = new XFormsFunctionCall(XFormsFunctionCall::IF); } else if (aName == txXPathAtoms::index) { - aFnCall = new XFormsFunctionCall(XFormsFunctionCall::INDEX); + NS_ENSURE_TRUE(mResolverNode, NS_ERROR_FAILURE); + aFnCall = new XFormsFunctionCall(XFormsFunctionCall::INDEX, + mResolverNode); } else if (aName == txXPathAtoms::instance) { NS_ENSURE_TRUE(mResolverNode, NS_ERROR_FAILURE); diff --git a/extensions/xforms/nsXFormsUtilityService.cpp b/extensions/xforms/nsXFormsUtilityService.cpp index 642a2c319c7..ac4763b8771 100644 --- a/extensions/xforms/nsXFormsUtilityService.cpp +++ b/extensions/xforms/nsXFormsUtilityService.cpp @@ -46,6 +46,7 @@ #include "nsIXFormsModelElement.h" #include "nsIDOMNodeList.h" #include "nsIInstanceElementPrivate.h" +#include "nsIXFormsRepeatElement.h" NS_IMPL_ISUPPORTS1(nsXFormsUtilityService, nsIXFormsUtilityService) @@ -223,3 +224,15 @@ nsXFormsUtilityService::ValidateString(const nsAString & aValue, return NS_ERROR_NOT_IMPLEMENTED; } + +NS_IMETHODIMP +nsXFormsUtilityService::GetRepeatIndex(nsIDOMNode *aRepeat, PRUint32 *aIndex) +{ + NS_ASSERTION(aIndex, "no return buffer for index, we'll crash soon"); + *aIndex = 0; + + nsCOMPtr repeatEle = do_QueryInterface(aRepeat); + NS_ENSURE_TRUE(repeatEle, NS_ERROR_NULL_POINTER); + + return repeatEle->GetIndex(aIndex); +}