mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-03 12:35:58 +00:00
xforms bug 258472 - Add the XPath functions needed for XForms, r=sicking,sr=peterv
This commit is contained in:
parent
c4d30bcb1a
commit
38e86f26fd
506
extensions/transformiix/source/xpath/XFormsFunctionCall.cpp
Normal file
506
extensions/transformiix/source/xpath/XFormsFunctionCall.cpp
Normal file
@ -0,0 +1,506 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla XForms support.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Aaron Reed <aaronr@us.ibm.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
* XFormsFunctionCall
|
||||
* A representation of the XPath NodeSet funtions
|
||||
*/
|
||||
|
||||
#include "FunctionLib.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "txNodeSet.h"
|
||||
#include "txAtoms.h"
|
||||
#include "txIXPathContext.h"
|
||||
#include "txTokenizer.h"
|
||||
#include "XFormsFunctions.h"
|
||||
#include <math.h>
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMDocumentEvent.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIXFormsUtilityService.h"
|
||||
#include "nsServiceManagerUtils.h" // needed for do_GetService?
|
||||
#include "prprf.h"
|
||||
|
||||
/*
|
||||
* Creates a XFormsFunctionCall of the given type
|
||||
*/
|
||||
XFormsFunctionCall::XFormsFunctionCall(XFormsFunctions aType, nsIDOMNode *aResolverNode)
|
||||
: mType(aType)
|
||||
, mResolverNode(aResolverNode)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
*/
|
||||
nsresult
|
||||
XFormsFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
nsresult rv = NS_OK;
|
||||
txListIterator iter(¶ms);
|
||||
|
||||
switch (mType) {
|
||||
case AVG:
|
||||
{
|
||||
if (!requireParams(1, 1, aContext))
|
||||
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
|
||||
|
||||
nsRefPtr<txNodeSet> nodes;
|
||||
nsresult rv = evaluateToNodeSet((Expr*)iter.next(), aContext,
|
||||
getter_AddRefs(nodes));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
double res = 0;
|
||||
PRInt32 i;
|
||||
for (i = 0; i < nodes->size(); ++i) {
|
||||
nsAutoString resultStr;
|
||||
txXPathNodeUtils::appendNodeValue(nodes->get(i), resultStr);
|
||||
res += Double::toDouble(resultStr);
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
res = (res/i);
|
||||
}
|
||||
else {
|
||||
res = Double::NaN;
|
||||
}
|
||||
return aContext->recycler()->getNumberResult(res, aResult);
|
||||
}
|
||||
case BOOLEANFROMSTRING:
|
||||
{
|
||||
if (!requireParams(1, 1, aContext))
|
||||
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
|
||||
|
||||
PRInt32 retvalue = -1;
|
||||
nsAutoString booleanValue;
|
||||
evaluateToString((Expr*)iter.next(), aContext, booleanValue);
|
||||
|
||||
aContext->recycler()->getBoolResult(
|
||||
booleanValue.EqualsLiteral("1") ||
|
||||
booleanValue.LowerCaseEqualsLiteral("true"),
|
||||
aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
case COUNTNONEMPTY:
|
||||
{
|
||||
if (!requireParams(1, 1, aContext))
|
||||
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
|
||||
|
||||
nsRefPtr<txNodeSet> nodes;
|
||||
nsresult rv = evaluateToNodeSet((Expr*)iter.next(), aContext,
|
||||
getter_AddRefs(nodes));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
double res = 0, test = 0;
|
||||
PRInt32 i, count=0;
|
||||
for (i = 0; i < nodes->size(); ++i) {
|
||||
nsAutoString resultStr;
|
||||
txXPathNodeUtils::appendNodeValue(nodes->get(i), resultStr);
|
||||
if (!resultStr.IsEmpty()) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return aContext->recycler()->getNumberResult(count, aResult);
|
||||
}
|
||||
case DAYSFROMDATE:
|
||||
{
|
||||
if (!requireParams(1, 1, aContext))
|
||||
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
case IF:
|
||||
{
|
||||
if (!requireParams(3, 3, aContext))
|
||||
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
|
||||
|
||||
PRBool test;
|
||||
nsAutoString valueToReturn;
|
||||
test = evaluateToBoolean((Expr*)iter.next(), aContext);
|
||||
|
||||
// grab 'true' value to return
|
||||
Expr *getvalue = (Expr*)iter.next();
|
||||
|
||||
if (!test) {
|
||||
// grab 'false' value to return
|
||||
getvalue = (Expr*)iter.next();
|
||||
}
|
||||
evaluateToString(getvalue, aContext, valueToReturn);
|
||||
|
||||
return aContext->recycler()->getStringResult(valueToReturn, aResult);
|
||||
}
|
||||
case INDEX:
|
||||
{
|
||||
// Given an element's id as the parameter, need to query the element and
|
||||
// make sure that it is a xforms:repeat node. Given that, must query
|
||||
// its index.
|
||||
if (!requireParams(1, 1, aContext))
|
||||
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
case INSTANCE:
|
||||
{
|
||||
nsresult rv;
|
||||
if (!requireParams(1, 1, aContext))
|
||||
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
|
||||
|
||||
nsRefPtr<txNodeSet> resultSet;
|
||||
rv = aContext->recycler()->getNodeSet(getter_AddRefs(resultSet));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoString instanceId;
|
||||
evaluateToString((Expr*)iter.next(), aContext, instanceId);
|
||||
|
||||
// here document is the XForms document
|
||||
nsCOMPtr<nsIDOMDocument> document;
|
||||
rv = mResolverNode->GetOwnerDocument(getter_AddRefs(document));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(document, NS_ERROR_NULL_POINTER);
|
||||
|
||||
nsCOMPtr<nsIDOMElement> instEle;
|
||||
rv = document->GetElementById(instanceId, getter_AddRefs(instEle));
|
||||
|
||||
PRBool foundInstance = PR_FALSE;
|
||||
nsAutoString localname, namespaceURI;
|
||||
if (instEle) {
|
||||
instEle->GetLocalName(localname);
|
||||
instEle->GetNamespaceURI(namespaceURI);
|
||||
if (localname.EqualsLiteral("instance") &&
|
||||
namespaceURI.EqualsLiteral(NS_NAMESPACE_XFORMS)) {
|
||||
foundInstance = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundInstance) {
|
||||
// We didn't find an instance element with the given id. Return the
|
||||
// empty result set.
|
||||
*aResult = resultSet;
|
||||
NS_ADDREF(*aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Make sure that this element is contained in the same
|
||||
// model as the context node of the expression as per
|
||||
// the XForms 1.0 spec.
|
||||
|
||||
// first step is to get the contextNode passed in to
|
||||
// the evaluation
|
||||
|
||||
nsCOMPtr<nsIDOMNode> xfContextNode;
|
||||
rv = txXPathNativeNode::getNode(aContext->getContextNode(),
|
||||
getter_AddRefs(xfContextNode));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// now see if the node we found (instEle) and the
|
||||
// context node for the evaluation (xfContextNode) link
|
||||
// back to the same model.
|
||||
nsCOMPtr<nsIXFormsUtilityService>xformsService =
|
||||
do_GetService("@mozilla.org/xforms-utility-service;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> instNode, modelInstance;
|
||||
instNode = do_QueryInterface(instEle);
|
||||
rv = xformsService->GetModelFromNode(instNode,
|
||||
getter_AddRefs(modelInstance));
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool modelContainsNode = PR_FALSE;
|
||||
rv = xformsService->IsNodeAssocWithModel(xfContextNode,
|
||||
modelInstance,
|
||||
&modelContainsNode);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (modelContainsNode) {
|
||||
// ok, we've found an instance node with the proper id
|
||||
// that fulfills the requirement of being from the
|
||||
// same model as the context node. Now we need to
|
||||
// return a 'node-set containing just the root
|
||||
// element node of the referenced instance data'.
|
||||
// Wonderful.
|
||||
|
||||
nsCOMPtr<nsIDOMNode> instanceRoot;
|
||||
rv = xformsService->GetInstanceDocumentRoot(
|
||||
instanceId,
|
||||
modelInstance,
|
||||
getter_AddRefs(instanceRoot));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(instanceRoot, NS_ERROR_NULL_POINTER);
|
||||
|
||||
nsAutoPtr<txXPathNode> txNode(txXPathNativeNode::createXPathNode(instanceRoot));
|
||||
if (txNode) {
|
||||
resultSet->add(*txNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// XXX where we need to do the work
|
||||
// if (walker.moveToElementById(instanceId)) {
|
||||
// resultSet->add(walker.getCurrentPosition());
|
||||
// }
|
||||
|
||||
*aResult = resultSet;
|
||||
NS_ADDREF(*aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
case MAX:
|
||||
{
|
||||
if (!requireParams(1, 1, aContext))
|
||||
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
|
||||
|
||||
nsRefPtr<txNodeSet> nodes;
|
||||
nsresult rv = evaluateToNodeSet((Expr*)iter.next(), aContext,
|
||||
getter_AddRefs(nodes));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
double res = Double::NaN;
|
||||
PRInt32 i;
|
||||
for (i = 0; i < nodes->size(); ++i) {
|
||||
double test;
|
||||
nsAutoString resultStr;
|
||||
txXPathNodeUtils::appendNodeValue(nodes->get(i), resultStr);
|
||||
test = Double::toDouble(resultStr);
|
||||
if (Double::isNaN(test)) {
|
||||
res = Double::NaN;
|
||||
break;
|
||||
}
|
||||
if (test > res || i == 0) {
|
||||
res = test;
|
||||
}
|
||||
}
|
||||
|
||||
return aContext->recycler()->getNumberResult(res, aResult);
|
||||
}
|
||||
case MIN:
|
||||
{
|
||||
if (!requireParams(1, 1, aContext))
|
||||
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
|
||||
|
||||
nsRefPtr<txNodeSet> nodes;
|
||||
nsresult rv = evaluateToNodeSet((Expr*)iter.next(), aContext,
|
||||
getter_AddRefs(nodes));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
double res = Double::NaN;
|
||||
PRInt32 i;
|
||||
for (i = 0; i < nodes->size(); ++i) {
|
||||
double test;
|
||||
nsAutoString resultStr;
|
||||
txXPathNodeUtils::appendNodeValue(nodes->get(i), resultStr);
|
||||
test = Double::toDouble(resultStr);
|
||||
if (Double::isNaN(test)) {
|
||||
res = Double::NaN;
|
||||
break;
|
||||
}
|
||||
if ((test < res) || (i==0)) {
|
||||
res = test;
|
||||
}
|
||||
}
|
||||
|
||||
return aContext->recycler()->getNumberResult(res, aResult);
|
||||
}
|
||||
case MONTHS:
|
||||
{
|
||||
if (!requireParams(1, 1, aContext))
|
||||
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
case NOW:
|
||||
{
|
||||
if (!requireParams(0, 0, aContext))
|
||||
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
|
||||
|
||||
PRExplodedTime time;
|
||||
char ctime[60];
|
||||
|
||||
PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &time);
|
||||
int gmtoffsethour = time.tm_params.tp_gmt_offset < 0 ?
|
||||
-1*time.tm_params.tp_gmt_offset / 3600 :
|
||||
time.tm_params.tp_gmt_offset / 3600;
|
||||
int remainder = time.tm_params.tp_gmt_offset%3600;
|
||||
int gmtoffsetminute = remainder ? remainder/60 : 00;
|
||||
|
||||
char zone_location[40];
|
||||
const int zoneBufSize = sizeof(zone_location);
|
||||
PR_snprintf(zone_location, zoneBufSize, "%c%02d:%02d\0",
|
||||
time.tm_params.tp_gmt_offset < 0 ? '-' : '+',
|
||||
gmtoffsethour, gmtoffsetminute);
|
||||
|
||||
PR_FormatTime(ctime, sizeof(ctime), "%Y-%m-%dT%H:%M:%S\0", &time);
|
||||
nsString sTime = NS_ConvertASCIItoUTF16(ctime) + NS_ConvertASCIItoUTF16(zone_location);
|
||||
|
||||
return aContext->recycler()->getStringResult(sTime, aResult);
|
||||
}
|
||||
case PROPERTY:
|
||||
{
|
||||
if (!requireParams(1, 1, aContext))
|
||||
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
|
||||
|
||||
nsAutoString property;
|
||||
evaluateToString((Expr*)iter.next(), aContext, property);
|
||||
|
||||
// This function can handle "version" and "conformance-level"
|
||||
// which is all that the XForms 1.0 spec is worried about
|
||||
if (property.Equals(NS_LITERAL_STRING("version")))
|
||||
property.Assign(NS_LITERAL_STRING("1.0"));
|
||||
else if (property.Equals(NS_LITERAL_STRING("conformance-level")))
|
||||
property.Assign(NS_LITERAL_STRING("basic"));
|
||||
|
||||
return aContext->recycler()->getStringResult(property, aResult);
|
||||
}
|
||||
case SECONDS:
|
||||
{
|
||||
double dbl=0;
|
||||
if (!requireParams(1, 1, aContext))
|
||||
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
}
|
||||
case SECONDSFROMDATETIME:
|
||||
{
|
||||
if (!requireParams(1, 1, aContext))
|
||||
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
} /* switch() */
|
||||
|
||||
aContext->receiveError(NS_LITERAL_STRING("Internal error"),
|
||||
NS_ERROR_UNEXPECTED);
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
nsresult
|
||||
XFormsFunctionCall::getNameAtom(nsIAtom** aAtom)
|
||||
{
|
||||
switch (mType) {
|
||||
case AVG:
|
||||
{
|
||||
*aAtom = txXPathAtoms::avg;
|
||||
break;
|
||||
}
|
||||
case BOOLEANFROMSTRING:
|
||||
{
|
||||
*aAtom = txXPathAtoms::booleanFromString;
|
||||
break;
|
||||
}
|
||||
case COUNTNONEMPTY:
|
||||
{
|
||||
*aAtom = txXPathAtoms::countNonEmpty;
|
||||
break;
|
||||
}
|
||||
case DAYSFROMDATE:
|
||||
{
|
||||
*aAtom = txXPathAtoms::daysFromDate;
|
||||
break;
|
||||
}
|
||||
case IF:
|
||||
{
|
||||
*aAtom = txXPathAtoms::ifFunc;
|
||||
break;
|
||||
}
|
||||
case INDEX:
|
||||
{
|
||||
*aAtom = txXPathAtoms::index;
|
||||
break;
|
||||
}
|
||||
case INSTANCE:
|
||||
{
|
||||
*aAtom = txXPathAtoms::instance;
|
||||
break;
|
||||
}
|
||||
case MAX:
|
||||
{
|
||||
*aAtom = txXPathAtoms::max;
|
||||
break;
|
||||
}
|
||||
case MIN:
|
||||
{
|
||||
*aAtom = txXPathAtoms::min;
|
||||
break;
|
||||
}
|
||||
case MONTHS:
|
||||
{
|
||||
*aAtom = txXPathAtoms::months;
|
||||
break;
|
||||
}
|
||||
case NOW:
|
||||
{
|
||||
*aAtom = txXPathAtoms::now;
|
||||
break;
|
||||
}
|
||||
case PROPERTY:
|
||||
{
|
||||
*aAtom = txXPathAtoms::property;
|
||||
break;
|
||||
}
|
||||
case SECONDS:
|
||||
{
|
||||
*aAtom = txXPathAtoms::seconds;
|
||||
break;
|
||||
}
|
||||
case SECONDSFROMDATETIME:
|
||||
{
|
||||
*aAtom = txXPathAtoms::secondsFromDateTime;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
*aAtom = 0;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
NS_ADDREF(*aAtom);
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
84
extensions/transformiix/source/xpath/XFormsFunctions.h
Normal file
84
extensions/transformiix/source/xpath/XFormsFunctions.h
Normal file
@ -0,0 +1,84 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla XForms support.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Aaron Reed <aaronr@us.ibm.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef TRANSFRMX_XFORMS_FUNCTIONS_H
|
||||
#define TRANSFRMX_XFORMS_FUNCTIONS_H
|
||||
|
||||
#include "Expr.h"
|
||||
#include "nsIDOMNode.h"
|
||||
|
||||
#define NS_NAMESPACE_XFORMS "http://www.w3.org/2002/xforms"
|
||||
#define NS_NAMESPACE_SCHEMA "http://www.w3.org/1999/XMLSchema"
|
||||
|
||||
/*
|
||||
* Represents the XPath XForms Function Calls
|
||||
*/
|
||||
class XFormsFunctionCall : public FunctionCall {
|
||||
|
||||
public:
|
||||
|
||||
enum XFormsFunctions {
|
||||
AVG, // avg()
|
||||
BOOLEANFROMSTRING, // boolean-from-string()
|
||||
COUNTNONEMPTY, // count-non-empty()
|
||||
DAYSFROMDATE, // days-from-date()
|
||||
IF, // if()
|
||||
INDEX, // index()
|
||||
INSTANCE, // instance()
|
||||
MAX, // max()
|
||||
MIN, // min()
|
||||
MONTHS, // months()
|
||||
NOW, // now()
|
||||
PROPERTY, // property()
|
||||
SECONDS, // seconds()
|
||||
SECONDSFROMDATETIME // seconds-from-dateTime()
|
||||
};
|
||||
|
||||
/*
|
||||
* Creates a Number function of the given type
|
||||
*/
|
||||
XFormsFunctionCall(XFormsFunctions aType, nsIDOMNode *resolverNode=nsnull);
|
||||
|
||||
TX_DECL_FUNCTION;
|
||||
|
||||
private:
|
||||
XFormsFunctions mType;
|
||||
nsCOMPtr<nsIDOMNode> mResolverNode;
|
||||
};
|
||||
|
||||
#endif
|
124
extensions/transformiix/source/xpath/nsIXFormsUtilityService.h
Normal file
124
extensions/transformiix/source/xpath/nsIXFormsUtilityService.h
Normal file
@ -0,0 +1,124 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla XForms support.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Aaron Reed <aaronr@us.ibm.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsIXFormsUtilityService_h
|
||||
#define nsIXFormsUtilityService_h
|
||||
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
/* For IDL files that don't want to include root IDL files. */
|
||||
#ifndef NS_NO_VTABLE
|
||||
#define NS_NO_VTABLE
|
||||
#endif
|
||||
class nsIDOMNode; /* forward declaration */
|
||||
|
||||
class nsIXFormsModelElement; /* forward declaration */
|
||||
|
||||
|
||||
/* starting interface: nsIXFormsUtilityService */
|
||||
#define NS_IXFORMSUTILITYSERVICE_IID_STR "4a744a59-8771-4065-959d-b8de3dad81da"
|
||||
|
||||
#define NS_IXFORMSUTILITYSERVICE_IID \
|
||||
{0x4a744a59, 0x8771, 0x4065, \
|
||||
{ 0x95, 0x9d, 0xb8, 0xde, 0x3d, 0xad, 0x81, 0xda }}
|
||||
|
||||
#define NS_XFORMS_UTILITY_CONTRACTID "@mozilla.org/xforms-utility-service;1"
|
||||
|
||||
/* Use this macro when declaring classes that implement this interface. */
|
||||
#define NS_DECL_NSIXFORMSUTILITYSERVICE \
|
||||
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);
|
||||
|
||||
/**
|
||||
* Private interface implemented by the nsXFormsUtilityService in XForms extension.
|
||||
* Defining it here to prevent XPath requiring XForms extension.
|
||||
*/
|
||||
class NS_NO_VTABLE nsIXFormsUtilityService : public nsISupports {
|
||||
public:
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IXFORMSUTILITYSERVICE_IID)
|
||||
|
||||
/**
|
||||
* Function to get the corresponding model element from a xforms node or
|
||||
* a xforms instance data node.
|
||||
*/
|
||||
/* nsIDOMNode getModelFromNode (in nsIDOMNode node); */
|
||||
NS_IMETHOD GetModelFromNode(nsIDOMNode *node, nsIDOMNode **_retval) = 0;
|
||||
|
||||
/**
|
||||
* Function to see if the given node is associated with the given model.
|
||||
* Right now this function is only called by XPath in the case of the
|
||||
* instance() function.
|
||||
* The provided node can be an instance node from an instance
|
||||
* document and thus be associated to the model in that way (model elements
|
||||
* contain instance elements). Otherwise the node will be an XForms element
|
||||
* that was used as the context node of the XPath expression (i.e the
|
||||
* XForms control has an attribute that contains an XPath expression).
|
||||
* Form controls are associated with model elements either explicitly through
|
||||
* single-node binding or implicitly (if model cannot by calculated, it
|
||||
* will use the first model element encountered in the document). The model
|
||||
* can also be inherited from a containing element like xforms:group or
|
||||
* xforms:repeat.
|
||||
*/
|
||||
/* PRBool isNodeAssocWithModel (in nsIDOMNode aNode, in nsIDOMNode aModel); */
|
||||
NS_IMETHOD IsNodeAssocWithModel(nsIDOMNode *aNode, nsIDOMNode *aModel, PRBool *_retval) = 0;
|
||||
|
||||
/**
|
||||
* Function to get the instance document root for the instance element with
|
||||
* the given id. The instance element must be associated with the given
|
||||
* model.
|
||||
*/
|
||||
/* nsIDOMNode getInstanceDocumentRoot (in DOMString aID, in nsIDOMNode aModelNode); */
|
||||
NS_IMETHOD GetInstanceDocumentRoot(const nsAString & aID, nsIDOMNode *aModelNode, nsIDOMNode **_retval) = 0;
|
||||
|
||||
/**
|
||||
* Function to ensure that aValue is of the schema type aType. Will basically
|
||||
* be a forwarder to the nsISchemaValidator function of the same name.
|
||||
*/
|
||||
/* 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;
|
||||
|
||||
};
|
||||
|
||||
#define NS_ERROR_XFORMS_CALCUATION_EXCEPTION \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GENERAL, 3001)
|
||||
|
||||
#endif /* nsIXFormsUtilityService_h */
|
@ -0,0 +1,97 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla XForms support.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Aaron Reed <aaronr@us.ibm.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsIXFormsXPathEvaluator_h
|
||||
#define nsIXFormsXPathEvaluator_h
|
||||
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
/* For IDL files that don't want to include root IDL files. */
|
||||
#ifndef NS_NO_VTABLE
|
||||
#define NS_NO_VTABLE
|
||||
#endif
|
||||
class nsIDOMNode; /* forward declaration */
|
||||
class nsIDOMXPathExpression; /* forward declaration */
|
||||
|
||||
/* starting interface: nsIXFormsXPathEvaluator */
|
||||
#define NS_XFORMS_XPATH_EVALUATOR_CONTRACTID "@mozilla.org/dom/xforms-xpath-evaluator;1"
|
||||
/* a7e127c6-31ff-40b4-8780-15d6938b33d3 */
|
||||
#define TRANSFORMIIX_XFORMS_XPATH_EVALUATOR_CID \
|
||||
{ 0xa7e127c6, 0x31ff, 0x40b4, { 0x87, 0x80, 0x15, 0xd6, 0x93, 0x8b, 0x33, 0xd3 } }
|
||||
|
||||
/* 60050a4a-4c99-4bad-8c47-3b9b96caf2b4 */
|
||||
#define TRANSFORMIIX_XFORMS_XPATH_EVALUATOR_IID \
|
||||
{ 0x60050a4a, 0x4c99, 0x4bad, { 0x8c, 0x47, 0x3b, 0x9b, 0x96, 0xca, 0xf2, 0xb4 } }
|
||||
|
||||
/* Use this macro when declaring classes that implement this interface. */
|
||||
#define NS_DECL_NSIXFORMXPATHEVALUATOR \
|
||||
NS_IMETHOD CreateExpression(const nsAString & aExpression, nsIDOMNode *aResolverNode,nsIDOMXPathExpression **aResult); \
|
||||
NS_IMETHOD Evaluate(const nsAString & aExpression, nsIDOMNode *aContextNode, nsIDOMNode *aResolverNode, PRUint16 aType, nsISupports *aInResult, nsISupports **aResult);
|
||||
|
||||
/**
|
||||
* Private interface implemented by the nsXFormsXPathEvaluator in Transformiix
|
||||
* and will move to the XForms extension when XPath is made extensible. We
|
||||
* are using this interface instead of nsIDOMXPathEvaluator since we can
|
||||
* don't really need all of that overhead. For example, this interface uses
|
||||
* a resolver node from the xforms document rather than forcing XForms to
|
||||
* create a namespace resolver node prior to creating the expression or
|
||||
* running an evaluation.
|
||||
*/
|
||||
class NS_NO_VTABLE nsIXFormsXPathEvaluator : public nsISupports {
|
||||
public:
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(TRANSFORMIIX_XFORMS_XPATH_EVALUATOR_IID)
|
||||
|
||||
/**
|
||||
* Function to create a nsIDOMXPathExpression from the provided expression
|
||||
* string. aResolverNode is the xforms node that the expression is
|
||||
* associated with.
|
||||
*/
|
||||
NS_IMETHOD CreateExpression(const nsAString & aExpression, nsIDOMNode *aResolverNode, nsIDOMXPathExpression **aResult) = 0;
|
||||
|
||||
/**
|
||||
* Function to evaluate the given expression. aResolverNode is the xforms
|
||||
* node that the expression is associated with. The other parameters are as
|
||||
* required by DOM's XPathEvaluator.
|
||||
*/
|
||||
NS_IMETHOD Evaluate(const nsAString & aExpression, nsIDOMNode *aContextNode, nsIDOMNode *aResolverNode, PRUint16 aType, nsISupports *aInResult, nsISupports **aResult) = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif /* nsIXFormsXPathEvaluator_h */
|
274
extensions/transformiix/source/xpath/nsXFormsXPathEvaluator.cpp
Normal file
274
extensions/transformiix/source/xpath/nsXFormsXPathEvaluator.cpp
Normal file
@ -0,0 +1,274 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla XForms support.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Aaron Reed <aaronr@us.ibm.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsXFormsXPathEvaluator.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIDOMClassInfo.h"
|
||||
#include "nsXPathException.h"
|
||||
#include "nsXPathExpression.h"
|
||||
#include "nsXPathNSResolver.h"
|
||||
#include "nsXPathResult.h"
|
||||
#include "nsContentCID.h"
|
||||
#include "Expr.h"
|
||||
#include "ExprParser.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "txURIUtils.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsDOMString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "txError.h"
|
||||
#include "txAtoms.h"
|
||||
#include "XFormsFunctions.h"
|
||||
#include "nsIDOM3Node.h"
|
||||
|
||||
extern nsINameSpaceManager* gTxNameSpaceManager;
|
||||
|
||||
NS_IMPL_ADDREF(nsXFormsXPathEvaluator)
|
||||
NS_IMPL_RELEASE(nsXFormsXPathEvaluator)
|
||||
NS_INTERFACE_MAP_BEGIN(nsXFormsXPathEvaluator)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIXFormsXPathEvaluator)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXFormsXPathEvaluator)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
nsXFormsXPathEvaluator::nsXFormsXPathEvaluator()
|
||||
{
|
||||
}
|
||||
|
||||
nsXFormsXPathEvaluator::~nsXFormsXPathEvaluator()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsXPathEvaluator::CreateExpression(const nsAString & aExpression,
|
||||
nsIDOMNode *aResolverNode,
|
||||
nsIDOMXPathExpression **aResult)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!mRecycler) {
|
||||
nsRefPtr<txResultRecycler> recycler = new txResultRecycler;
|
||||
NS_ENSURE_TRUE(recycler, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = recycler->init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mRecycler = recycler;
|
||||
}
|
||||
|
||||
XFormsParseContextImpl pContext(aResolverNode);
|
||||
|
||||
nsAutoPtr<Expr> expression;
|
||||
rv = txExprParser::createExpr(PromiseFlatString(aExpression), &pContext,
|
||||
getter_Transfers(expression));
|
||||
if (NS_FAILED(rv)) {
|
||||
if (rv == NS_ERROR_DOM_NAMESPACE_ERR) {
|
||||
return NS_ERROR_DOM_NAMESPACE_ERR;
|
||||
}
|
||||
|
||||
return NS_ERROR_DOM_INVALID_EXPRESSION_ERR;
|
||||
}
|
||||
|
||||
*aResult = new nsXPathExpression(expression, mRecycler);
|
||||
if (!*aResult) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsXPathEvaluator::Evaluate(const nsAString & aExpression,
|
||||
nsIDOMNode *aContextNode,
|
||||
nsIDOMNode *aResolverNode,
|
||||
PRUint16 aType,
|
||||
nsISupports *aInResult,
|
||||
nsISupports **aResult)
|
||||
{
|
||||
// XXX Need to check document of aContextNode if created by
|
||||
// QI'ing a document.
|
||||
|
||||
nsCOMPtr<nsIDOMXPathExpression> expression;
|
||||
nsresult rv = CreateExpression(aExpression, aResolverNode,
|
||||
getter_AddRefs(expression));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return expression->Evaluate(aContextNode, aType, aInResult, aResult);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Implementation of txIParseContext private to nsXFormsXPathEvaluator
|
||||
* XFormsParseContextImpl bases on a nsIDOMXPathNSResolver
|
||||
*/
|
||||
|
||||
nsresult nsXFormsXPathEvaluator::XFormsParseContextImpl::resolveNamespacePrefix
|
||||
(nsIAtom* aPrefix, PRInt32& aID)
|
||||
{
|
||||
aID = kNameSpaceID_Unknown;
|
||||
|
||||
if (!mResolverNode) {
|
||||
return NS_ERROR_DOM_NAMESPACE_ERR;
|
||||
}
|
||||
|
||||
nsAutoString prefix;
|
||||
if (aPrefix) {
|
||||
aPrefix->ToString(prefix);
|
||||
}
|
||||
|
||||
nsVoidableString ns;
|
||||
nsresult rv;
|
||||
// begin - taken directly from nsXPathNSResolver::LookupNamespaceURI
|
||||
if (prefix.EqualsLiteral("xml")) {
|
||||
ns.AssignLiteral("http://www.w3.org/XML/1998/namespace");
|
||||
rv = NS_OK;
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIDOM3Node> dom3Node = do_QueryInterface(mResolverNode);
|
||||
NS_ASSERTION(dom3Node, "Need a node to resolve namespaces.");
|
||||
if( dom3Node ) {
|
||||
rv = dom3Node->LookupNamespaceURI(prefix, ns);
|
||||
}
|
||||
else {
|
||||
SetDOMStringToNull(ns);
|
||||
rv = NS_OK;
|
||||
}
|
||||
}
|
||||
// end - taken directly from nsXPathNSResolver::LookupNamespaceURI
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (DOMStringIsNull(ns)) {
|
||||
return NS_ERROR_DOM_NAMESPACE_ERR;
|
||||
}
|
||||
|
||||
if (ns.IsEmpty()) {
|
||||
aID = kNameSpaceID_None;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// get the namespaceID for the URI
|
||||
return gTxNameSpaceManager->RegisterNameSpace(ns, aID);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXFormsXPathEvaluator::XFormsParseContextImpl::resolveFunctionCall(
|
||||
nsIAtom* aName,
|
||||
PRInt32 aNamespaceID,
|
||||
FunctionCall*& aFnCall)
|
||||
{
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
PRBool isOutOfMem = PR_TRUE;
|
||||
|
||||
if (aName == txXPathAtoms::avg) {
|
||||
aFnCall = new XFormsFunctionCall(XFormsFunctionCall::AVG);
|
||||
}
|
||||
else if (aName == txXPathAtoms::booleanFromString) {
|
||||
aFnCall = new XFormsFunctionCall(XFormsFunctionCall::BOOLEANFROMSTRING);
|
||||
}
|
||||
else if (aName == txXPathAtoms::countNonEmpty) {
|
||||
aFnCall = new XFormsFunctionCall(XFormsFunctionCall::COUNTNONEMPTY);
|
||||
}
|
||||
else if (aName == txXPathAtoms::daysFromDate) {
|
||||
aFnCall = new XFormsFunctionCall(XFormsFunctionCall::DAYSFROMDATE);
|
||||
}
|
||||
else if (aName == txXPathAtoms::ifFunc) {
|
||||
aFnCall = new XFormsFunctionCall(XFormsFunctionCall::IF);
|
||||
}
|
||||
else if (aName == txXPathAtoms::index) {
|
||||
aFnCall = new XFormsFunctionCall(XFormsFunctionCall::INDEX);
|
||||
}
|
||||
else if (aName == txXPathAtoms::instance) {
|
||||
NS_ENSURE_TRUE(mResolverNode, NS_ERROR_FAILURE);
|
||||
aFnCall = new XFormsFunctionCall(XFormsFunctionCall::INSTANCE,
|
||||
mResolverNode);
|
||||
}
|
||||
else if (aName == txXPathAtoms::max) {
|
||||
aFnCall = new XFormsFunctionCall(XFormsFunctionCall::MAX);
|
||||
}
|
||||
else if (aName == txXPathAtoms::min) {
|
||||
aFnCall = new XFormsFunctionCall(XFormsFunctionCall::MIN);
|
||||
}
|
||||
else if (aName == txXPathAtoms::months) {
|
||||
aFnCall = new XFormsFunctionCall(XFormsFunctionCall::MONTHS);
|
||||
}
|
||||
else if (aName == txXPathAtoms::now) {
|
||||
aFnCall = new XFormsFunctionCall(XFormsFunctionCall::NOW);
|
||||
}
|
||||
else if (aName == txXPathAtoms::property) {
|
||||
aFnCall = new XFormsFunctionCall(XFormsFunctionCall::PROPERTY);
|
||||
}
|
||||
else if (aName == txXPathAtoms::seconds) {
|
||||
aFnCall = new XFormsFunctionCall(XFormsFunctionCall::SECONDS);
|
||||
}
|
||||
else if (aName == txXPathAtoms::secondsFromDateTime) {
|
||||
aFnCall = new XFormsFunctionCall(XFormsFunctionCall::SECONDSFROMDATETIME);
|
||||
}
|
||||
else {
|
||||
// didn't find functioncall here, aFnCall should be null
|
||||
isOutOfMem = PR_FALSE;
|
||||
}
|
||||
|
||||
if (aFnCall)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
else if (isOutOfMem) {
|
||||
NS_ERROR("XPath FunctionLib failed on out-of-memory");
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
|
||||
}
|
||||
|
||||
PRBool nsXFormsXPathEvaluator::XFormsParseContextImpl::caseInsensitiveNameTests()
|
||||
{
|
||||
// This will always be false since this handles XForms, which is XML-based,
|
||||
// so case sensitive.
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool nsXFormsXPathEvaluator::XFormsParseContextImpl::fcp()
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
nsXFormsXPathEvaluator::XFormsParseContextImpl::SetErrorOffset(PRUint32 aOffset)
|
||||
{
|
||||
}
|
102
extensions/transformiix/source/xpath/nsXFormsXPathEvaluator.h
Normal file
102
extensions/transformiix/source/xpath/nsXFormsXPathEvaluator.h
Normal file
@ -0,0 +1,102 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla XForms support.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Aaron Reed <aaronr@us.ibm.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsXFormsXPathEvaluator_h__
|
||||
#define nsXFormsXPathEvaluator_h__
|
||||
|
||||
#include "nsIXFormsXPathEvaluator.h"
|
||||
#include "txIXPathContext.h"
|
||||
#include "nsIXPathEvaluatorInternal.h"
|
||||
#include "nsIWeakReference.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "txResultRecycler.h"
|
||||
|
||||
|
||||
class nsIDOMDocument;
|
||||
class nsIDOMXPathExpression;
|
||||
|
||||
/**
|
||||
* A class for evaluating an XPath expression string
|
||||
*/
|
||||
class nsXFormsXPathEvaluator : public nsIXFormsXPathEvaluator
|
||||
{
|
||||
public:
|
||||
nsXFormsXPathEvaluator();
|
||||
virtual ~nsXFormsXPathEvaluator();
|
||||
|
||||
// nsISupports interface
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIXFormsXPathEvaluator interface
|
||||
NS_DECL_NSIXFORMXPATHEVALUATOR
|
||||
|
||||
private:
|
||||
// txIParseContext implementation
|
||||
class XFormsParseContextImpl : public txIParseContext
|
||||
{
|
||||
public:
|
||||
XFormsParseContextImpl(nsIDOMNode* aResolverNode)
|
||||
: mResolverNode(aResolverNode), mLastError(NS_OK)
|
||||
{
|
||||
}
|
||||
|
||||
~XFormsParseContextImpl()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult getError()
|
||||
{
|
||||
return mLastError;
|
||||
}
|
||||
|
||||
nsresult resolveNamespacePrefix(nsIAtom* aPrefix, PRInt32& aID);
|
||||
nsresult resolveFunctionCall(nsIAtom* aName, PRInt32 aID,
|
||||
FunctionCall*& aFunction);
|
||||
PRBool caseInsensitiveNameTests();
|
||||
PRBool fcp();
|
||||
void SetErrorOffset(PRUint32 aOffset);
|
||||
|
||||
private:
|
||||
nsIDOMNode* mResolverNode;
|
||||
nsresult mLastError;
|
||||
};
|
||||
|
||||
nsRefPtr<txResultRecycler> mRecycler;
|
||||
};
|
||||
|
||||
#endif
|
225
extensions/xforms/nsXFormsUtilityService.cpp
Normal file
225
extensions/xforms/nsXFormsUtilityService.cpp
Normal file
@ -0,0 +1,225 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla XForms support.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Aaron Reed <aaronr@us.ibm.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsXFormsUtilityService.h"
|
||||
#include "nsXFormsUtils.h"
|
||||
#include "nsIXTFElement.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIXFormsModelElement.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIInstanceElementPrivate.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsXFormsUtilityService, nsIXFormsUtilityService)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsUtilityService::GetModelFromNode(nsIDOMNode *aNode,
|
||||
nsIDOMNode **aModel)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(aNode);
|
||||
NS_ASSERTION(aModel, "no return buffer, we'll crash soon");
|
||||
*aModel = nsnull;
|
||||
|
||||
nsAutoString namespaceURI;
|
||||
aNode->GetNamespaceURI(namespaceURI);
|
||||
|
||||
// If the node is in the XForms namespace and XTF based, then it should
|
||||
// be able to be handled by GetModel. Otherwise it is probably an instance
|
||||
// node in a instance document.
|
||||
if (!namespaceURI.EqualsLiteral(NS_NAMESPACE_XFORMS)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIModelElementPrivate> modelPriv = nsXFormsUtils::GetModel(element);
|
||||
nsCOMPtr<nsIDOMNode> modelElement = do_QueryInterface(modelPriv);
|
||||
if( modelElement ) {
|
||||
NS_IF_ADDREF(*aModel = modelElement);
|
||||
}
|
||||
|
||||
// No model found
|
||||
NS_ENSURE_TRUE(*aModel, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function to see if the given node is associated with the given model.
|
||||
* Right now this function is only called by XPath in the case of the
|
||||
* instance() function.
|
||||
* The provided node can be an instance node from an instance
|
||||
* document and thus be associated to the model in that way (model elements
|
||||
* contain instance elements). Otherwise the node will be an XForms element
|
||||
* that was used as the context node of the XPath expression (i.e the
|
||||
* XForms control has an attribute that contains an XPath expression).
|
||||
* Form controls are associated with model elements either explicitly through
|
||||
* single-node binding or implicitly (if model cannot by calculated, it
|
||||
* will use the first model element encountered in the document). The model
|
||||
* can also be inherited from a containing element like xforms:group or
|
||||
* xforms:repeat.
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsXFormsUtilityService::IsNodeAssocWithModel( nsIDOMNode *aNode,
|
||||
nsIDOMNode *aModel,
|
||||
PRBool *aModelAssocWithNode)
|
||||
{
|
||||
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(aNode);
|
||||
|
||||
nsAutoString namespaceURI;
|
||||
aNode->GetNamespaceURI(namespaceURI);
|
||||
|
||||
// If the node is in the XForms namespace and XTF based, then it should
|
||||
// be able to be handled by GetModel. Otherwise it is probably an instance
|
||||
// node in a instance document.
|
||||
if (namespaceURI.EqualsLiteral(NS_NAMESPACE_XFORMS)) {
|
||||
nsCOMPtr<nsIModelElementPrivate> modelPriv = nsXFormsUtils::GetModel(element);
|
||||
nsCOMPtr<nsIDOMNode> modelNode = do_QueryInterface(modelPriv);
|
||||
|
||||
if (modelNode && (modelNode == aModel)) {
|
||||
*aModelAssocWithNode = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
*aModelAssocWithNode = PR_FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// We are assuming that if the node coming in isn't a proper XForms element,
|
||||
// then it is an instance element in an instance doc. Now we just have
|
||||
// to determine if the given model contains this instance document.
|
||||
nsCOMPtr<nsIDOMDocument> document;
|
||||
aNode->GetOwnerDocument(getter_AddRefs(document));
|
||||
*aModelAssocWithNode = PR_FALSE;
|
||||
|
||||
// Guess that we'd better make sure that it is a model
|
||||
nsCOMPtr<nsIXFormsModelElement> modelEle = do_QueryInterface(aModel);
|
||||
if (modelEle) {
|
||||
// OK, we know that this is a model element. So now we have to go
|
||||
// instance element by instance element and find the associated
|
||||
// document. If it is equal to the document that contains aNode,
|
||||
// then aNode is associated with this aModel element and we can return
|
||||
// true.
|
||||
nsCOMPtr<nsIDOMNodeList> children;
|
||||
aModel->GetChildNodes(getter_AddRefs(children));
|
||||
|
||||
if (!children)
|
||||
return NS_OK;
|
||||
|
||||
PRUint32 childCount = 0;
|
||||
children->GetLength(&childCount);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
nsCOMPtr<nsIInstanceElementPrivate> instElement;
|
||||
nsCOMPtr<nsIDOMDocument> instDocument;
|
||||
|
||||
for (PRUint32 i = 0; i < childCount; ++i) {
|
||||
children->Item(i, getter_AddRefs(node));
|
||||
NS_ASSERTION(node, "incorrect NodeList length?");
|
||||
|
||||
instElement = do_QueryInterface(node);
|
||||
if (!instElement)
|
||||
continue;
|
||||
|
||||
instElement->GetDocument(getter_AddRefs(instDocument));
|
||||
if (instDocument) {
|
||||
if (instDocument == document) {
|
||||
*aModelAssocWithNode = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsUtilityService::GetInstanceDocumentRoot(const nsAString& aID,
|
||||
nsIDOMNode *aModelNode,
|
||||
nsIDOMNode **aInstanceRoot)
|
||||
{
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
NS_ASSERTION(aInstanceRoot, "no return buffer, we'll crash soon");
|
||||
*aInstanceRoot = nsnull;
|
||||
|
||||
if (aID.IsEmpty()) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXFormsModelElement> modelElement = do_QueryInterface(aModelNode);
|
||||
nsCOMPtr<nsIDOMDocument> doc;
|
||||
rv = modelElement->GetInstanceDocument(aID, getter_AddRefs(doc));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
rv = doc->GetDocumentElement(getter_AddRefs(element));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (element) {
|
||||
NS_IF_ADDREF(*aInstanceRoot = element);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Gotta do this via the service since we don't want transformiix to require
|
||||
* any of the new extensions, like schema-validation
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsXFormsUtilityService::ValidateString(const nsAString & aValue,
|
||||
const nsAString & aType,
|
||||
const nsAString & aNamespace,
|
||||
PRBool *aResult)
|
||||
{
|
||||
|
||||
// XXX TODO This function needs to call the XForms validator layer from
|
||||
// bug 274083 when it goes into the build.
|
||||
|
||||
#if 0
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
nsXFormsSchemaValidator *validator = new nsXFormsSchemaValidator();
|
||||
*aResult = validator->ValidateString(aValue, aType, aNamespace);
|
||||
return rv;
|
||||
#endif
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
47
extensions/xforms/nsXFormsUtilityService.h
Normal file
47
extensions/xforms/nsXFormsUtilityService.h
Normal file
@ -0,0 +1,47 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla XForms support.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Aaron Reed <aaronr@us.ibm.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIXFormsUtilityService.h"
|
||||
|
||||
class nsXFormsUtilityService : public nsIXFormsUtilityService
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIXFORMSUTILITYSERVICE
|
||||
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user