зеркало из https://github.com/mozilla/gecko-dev.git
Fix for bug 278981 (Extension mechanism for XPath extension functions). r=sicking, sr=jst.
This commit is contained in:
Родитель
74b982040d
Коммит
a9c63c4a75
|
@ -47,14 +47,11 @@
|
||||||
#define NS_NO_VTABLE
|
#define NS_NO_VTABLE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class nsIDOMNode; /* forward declaration */
|
|
||||||
|
|
||||||
/* nsIXFormsUtilityService */
|
/* nsIXFormsUtilityService */
|
||||||
#define NS_IXFORMSUTILITYSERVICE_IID_STR "4a744a59-8771-4065-959d-b8de3dad81da"
|
#define NS_IXFORMSUTILITYSERVICE_IID_STR "f7276415-bb3e-4170-b746-aa57f68d7006"
|
||||||
|
|
||||||
#define NS_IXFORMSUTILITYSERVICE_IID \
|
#define NS_IXFORMSUTILITYSERVICE_IID \
|
||||||
{0x4a744a59, 0x8771, 0x4065, \
|
{ 0xf7276415, 0xbb3e, 0x4170, \
|
||||||
{ 0x95, 0x9d, 0xb8, 0xde, 0x3d, 0xad, 0x81, 0xda }}
|
{ 0xb7, 0x46, 0xaa, 0x57, 0xf6, 0x8d, 0x70, 0x06 } }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private interface implemented by the nsXFormsUtilityService in XForms
|
* Private interface implemented by the nsXFormsUtilityService in XForms
|
||||||
|
@ -64,87 +61,6 @@ class NS_NO_VTABLE nsIXFormsUtilityService : public nsISupports {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IXFORMSUTILITYSERVICE_IID)
|
NS_DECLARE_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 **aModel) = 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 *aModelAssocWithNode) = 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 **aInstanceRoot) = 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 *aResult) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to retrieve the index from the given repeat element.
|
|
||||||
*/
|
|
||||||
/* long getRepeatIndex (in nsIDOMNode aRepeat); */
|
|
||||||
NS_IMETHOD GetRepeatIndex(nsIDOMNode *aRepeat, PRInt32 *aIndex) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to retrieve the number of months represented by the
|
|
||||||
* xsd:duration provided in aValue
|
|
||||||
*/
|
|
||||||
/* long getMonths (in DOMString aValue); */
|
|
||||||
NS_IMETHOD GetMonths(const nsAString& aValue, PRInt32 *aMonths) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to retrieve the number of seconds represented by the
|
|
||||||
* xsd:duration provided in aValue
|
|
||||||
*/
|
|
||||||
/* double getSeconds (in DOMString aValue); */
|
|
||||||
NS_IMETHOD GetSeconds(const nsAString& aValue, double *aSeconds) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to retrieve the number of seconds represented by the
|
|
||||||
* xsd:dateTime provided in aValue
|
|
||||||
*/
|
|
||||||
/* double getSecondsFromDateTime (in DOMString aValue); */
|
|
||||||
NS_IMETHOD GetSecondsFromDateTime(const nsAString& aValue,
|
|
||||||
double *aSeconds) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to retrieve the number of days represented by the
|
|
||||||
* xsd:dateTime provided in aValue
|
|
||||||
*/
|
|
||||||
/* long getDaysFromDateTime (in DOMString aValue); */
|
|
||||||
NS_IMETHOD GetDaysFromDateTime(const nsAString& aValue, PRInt32 *aDays) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIXFormsUtilityService,
|
NS_DEFINE_STATIC_IID_ACCESSOR(nsIXFormsUtilityService,
|
||||||
|
|
|
@ -39,9 +39,11 @@
|
||||||
#ifndef nsIXPathEvaluatorInternal_h__
|
#ifndef nsIXPathEvaluatorInternal_h__
|
||||||
#define nsIXPathEvaluatorInternal_h__
|
#define nsIXPathEvaluatorInternal_h__
|
||||||
|
|
||||||
#include "nsISupports.h"
|
#include "nsCOMArray.h"
|
||||||
|
|
||||||
class nsIDOMDocument;
|
class nsIDOMDocument;
|
||||||
|
class nsIDOMXPathExpression;
|
||||||
|
class nsIDOMXPathNSResolver;
|
||||||
|
|
||||||
#define NS_IXPATHEVALUATORINTERNAL_IID \
|
#define NS_IXPATHEVALUATORINTERNAL_IID \
|
||||||
{0xb4b72daa, 0x65d6, 0x440f, \
|
{0xb4b72daa, 0x65d6, 0x440f, \
|
||||||
|
@ -57,6 +59,13 @@ public:
|
||||||
* Sets the document this evaluator corresponds to
|
* Sets the document this evaluator corresponds to
|
||||||
*/
|
*/
|
||||||
NS_IMETHOD SetDocument(nsIDOMDocument* aDocument) = 0;
|
NS_IMETHOD SetDocument(nsIDOMDocument* aDocument) = 0;
|
||||||
|
|
||||||
|
NS_IMETHOD CreateExpression(const nsAString &aExpression,
|
||||||
|
nsIDOMXPathNSResolver *aResolver,
|
||||||
|
nsStringArray *aNamespaceURIs,
|
||||||
|
nsCStringArray *aContractIDs,
|
||||||
|
nsCOMArray<nsISupports> *aState,
|
||||||
|
nsIDOMXPathExpression **aResult) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIXPathEvaluatorInternal,
|
NS_DEFINE_STATIC_IID_ACCESSOR(nsIXPathEvaluatorInternal,
|
||||||
|
|
|
@ -47,6 +47,7 @@ XPIDL_MODULE = content_xslt
|
||||||
|
|
||||||
EXPORTS = \
|
EXPORTS = \
|
||||||
nsIDocumentTransformer.h \
|
nsIDocumentTransformer.h \
|
||||||
|
txDouble.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
XPIDLSRCS = \
|
XPIDLSRCS = \
|
||||||
|
@ -54,6 +55,8 @@ XPIDLSRCS = \
|
||||||
nsIXSLTProcessor.idl \
|
nsIXSLTProcessor.idl \
|
||||||
nsIXSLTProcessorObsolete.idl \
|
nsIXSLTProcessorObsolete.idl \
|
||||||
nsIXSLTProcessorPrivate.idl \
|
nsIXSLTProcessorPrivate.idl \
|
||||||
|
txIFunctionEvaluationContext.idl \
|
||||||
|
txINodeSet.idl \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
/* -*- 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.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Peter Van der Beken.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Peter Van der Beken <peterv@propagandism.org>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 __txdouble_h__
|
||||||
|
#define __txdouble_h__
|
||||||
|
|
||||||
|
//A trick to handle IEEE floating point exceptions on FreeBSD - E.D.
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#include <ieeefp.h>
|
||||||
|
#ifdef __alpha__
|
||||||
|
fp_except_t allmask = FP_X_INV|FP_X_OFL|FP_X_UFL|FP_X_DZ|FP_X_IMP;
|
||||||
|
#else
|
||||||
|
fp_except_t allmask = FP_X_INV|FP_X_OFL|FP_X_UFL|FP_X_DZ|FP_X_IMP|FP_X_DNML;
|
||||||
|
#endif
|
||||||
|
fp_except_t oldmask = fpsetmask(~allmask);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Macros to workaround math-bugs bugs in various platforms
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stefan Hanske <sh990154@mail.uni-greifswald.de> reports:
|
||||||
|
* ARM is a little endian architecture but 64 bit double words are stored
|
||||||
|
* differently: the 32 bit words are in little endian byte order, the two words
|
||||||
|
* are stored in big endian`s way.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(__arm) || defined(__arm32__) || defined(__arm26__) || defined(__arm__)
|
||||||
|
#define CPU_IS_ARM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (__GNUC__ == 2 && __GNUC_MINOR__ > 95) || __GNUC__ > 2
|
||||||
|
/**
|
||||||
|
* This version of the macros is safe for the alias optimizations
|
||||||
|
* that gcc does, but uses gcc-specific extensions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef union txdpun {
|
||||||
|
PRFloat64 d;
|
||||||
|
struct {
|
||||||
|
#if defined(IS_LITTLE_ENDIAN) && !defined(CPU_IS_ARM)
|
||||||
|
PRUint32 lo, hi;
|
||||||
|
#else
|
||||||
|
PRUint32 hi, lo;
|
||||||
|
#endif
|
||||||
|
} s;
|
||||||
|
} txdpun;
|
||||||
|
|
||||||
|
#define TX_DOUBLE_HI32(x) (__extension__ ({ txdpun u; u.d = (x); u.s.hi; }))
|
||||||
|
#define TX_DOUBLE_LO32(x) (__extension__ ({ txdpun u; u.d = (x); u.s.lo; }))
|
||||||
|
|
||||||
|
#else // __GNUC__
|
||||||
|
|
||||||
|
/* We don't know of any non-gcc compilers that perform alias optimization,
|
||||||
|
* so this code should work.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(IS_LITTLE_ENDIAN) && !defined(CPU_IS_ARM)
|
||||||
|
#define TX_DOUBLE_HI32(x) (((PRUint32 *)&(x))[1])
|
||||||
|
#define TX_DOUBLE_LO32(x) (((PRUint32 *)&(x))[0])
|
||||||
|
#else
|
||||||
|
#define TX_DOUBLE_HI32(x) (((PRUint32 *)&(x))[0])
|
||||||
|
#define TX_DOUBLE_LO32(x) (((PRUint32 *)&(x))[1])
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __GNUC__
|
||||||
|
|
||||||
|
#define TX_DOUBLE_HI32_SIGNBIT 0x80000000
|
||||||
|
#define TX_DOUBLE_HI32_EXPMASK 0x7ff00000
|
||||||
|
#define TX_DOUBLE_HI32_MANTMASK 0x000fffff
|
||||||
|
|
||||||
|
#define TX_DOUBLE_IS_NaN(x) \
|
||||||
|
((TX_DOUBLE_HI32(x) & TX_DOUBLE_HI32_EXPMASK) == TX_DOUBLE_HI32_EXPMASK && \
|
||||||
|
(TX_DOUBLE_LO32(x) || (TX_DOUBLE_HI32(x) & TX_DOUBLE_HI32_MANTMASK)))
|
||||||
|
|
||||||
|
#ifdef IS_BIG_ENDIAN
|
||||||
|
#define TX_DOUBLE_NaN {TX_DOUBLE_HI32_EXPMASK | TX_DOUBLE_HI32_MANTMASK, \
|
||||||
|
0xffffffff}
|
||||||
|
#else
|
||||||
|
#define TX_DOUBLE_NaN {0xffffffff, \
|
||||||
|
TX_DOUBLE_HI32_EXPMASK | TX_DOUBLE_HI32_MANTMASK}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
#define TX_DOUBLE_COMPARE(LVAL, OP, RVAL) \
|
||||||
|
(!TX_DOUBLE_IS_NaN(LVAL) && !TX_DOUBLE_IS_NaN(RVAL) && (LVAL) OP (RVAL))
|
||||||
|
#else
|
||||||
|
#define TX_DOUBLE_COMPARE(LVAL, OP, RVAL) ((LVAL) OP (RVAL))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __txdouble_h__ */
|
|
@ -0,0 +1,51 @@
|
||||||
|
/* -*- Mode: IDL; 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.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Peter Van der Beken.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Peter Van der Beken <peterv@propagandism.org>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 "domstubs.idl"
|
||||||
|
|
||||||
|
interface txINodeSet;
|
||||||
|
|
||||||
|
[scriptable, uuid(0ecbb00c-6a78-11d9-9791-000a95dc234c)]
|
||||||
|
interface txIFunctionEvaluationContext : nsISupports
|
||||||
|
{
|
||||||
|
readonly attribute PRUint32 position;
|
||||||
|
readonly attribute PRUint32 size;
|
||||||
|
readonly attribute nsIDOMNode contextNode;
|
||||||
|
readonly attribute nsISupports state;
|
||||||
|
};
|
|
@ -0,0 +1,57 @@
|
||||||
|
/* -*- Mode: IDL; 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.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Peter Van der Beken.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Peter Van der Beken <peterv@propagandism.org>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 "domstubs.idl"
|
||||||
|
|
||||||
|
%{ C++
|
||||||
|
class txAExprResult;
|
||||||
|
%}
|
||||||
|
|
||||||
|
[ptr] native txAExprResultPtr(txAExprResult);
|
||||||
|
|
||||||
|
[scriptable, uuid(15d424c0-6b47-11d9-9791-000a95dc234c)]
|
||||||
|
interface txINodeSet : nsISupports
|
||||||
|
{
|
||||||
|
nsIDOMNode item(in unsigned long index);
|
||||||
|
double itemAsNumber(in unsigned long index);
|
||||||
|
DOMString itemAsString(in unsigned long index);
|
||||||
|
readonly attribute unsigned long length;
|
||||||
|
void add(in nsIDOMNode node);
|
||||||
|
[noscript, notxpcom] txAExprResultPtr getTxNodeSet();
|
||||||
|
};
|
|
@ -42,6 +42,7 @@
|
||||||
#include "nscore.h"
|
#include "nscore.h"
|
||||||
#include "nsDebug.h"
|
#include "nsDebug.h"
|
||||||
#include "prtypes.h"
|
#include "prtypes.h"
|
||||||
|
#include "txDouble.h"
|
||||||
|
|
||||||
class nsAString;
|
class nsAString;
|
||||||
|
|
||||||
|
|
|
@ -49,81 +49,12 @@
|
||||||
* Utility class for doubles
|
* Utility class for doubles
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//A trick to handle IEEE floating point exceptions on FreeBSD - E.D.
|
|
||||||
#ifdef __FreeBSD__
|
|
||||||
#include <ieeefp.h>
|
|
||||||
#ifdef __alpha__
|
|
||||||
fp_except_t allmask = FP_X_INV|FP_X_OFL|FP_X_UFL|FP_X_DZ|FP_X_IMP;
|
|
||||||
#else
|
|
||||||
fp_except_t allmask = FP_X_INV|FP_X_OFL|FP_X_UFL|FP_X_DZ|FP_X_IMP|FP_X_DNML;
|
|
||||||
#endif
|
|
||||||
fp_except_t oldmask = fpsetmask(~allmask);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Macros to workaround math-bugs bugs in various platforms
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stefan Hanske <sh990154@mail.uni-greifswald.de> reports:
|
|
||||||
* ARM is a little endian architecture but 64 bit double words are stored
|
|
||||||
* differently: the 32 bit words are in little endian byte order, the two words
|
|
||||||
* are stored in big endian`s way.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__arm) || defined(__arm32__) || defined(_arm26__) || defined(__arm__)
|
|
||||||
#define CPU_IS_ARM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (__GNUC__ == 2 && __GNUC_MINOR__ > 95) || __GNUC__ > 2
|
|
||||||
/**
|
|
||||||
* This version of the macros is safe for the alias optimizations
|
|
||||||
* that gcc does, but uses gcc-specific extensions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef union txdpun {
|
|
||||||
PRFloat64 d;
|
|
||||||
struct {
|
|
||||||
#if defined(IS_LITTLE_ENDIAN) && !defined(CPU_IS_ARM)
|
|
||||||
PRUint32 lo, hi;
|
|
||||||
#else
|
|
||||||
PRUint32 hi, lo;
|
|
||||||
#endif
|
|
||||||
} s;
|
|
||||||
} txdpun;
|
|
||||||
|
|
||||||
#define TX_DOUBLE_HI32(x) (__extension__ ({ txdpun u; u.d = (x); u.s.hi; }))
|
|
||||||
#define TX_DOUBLE_LO32(x) (__extension__ ({ txdpun u; u.d = (x); u.s.lo; }))
|
|
||||||
|
|
||||||
#else // __GNUC__
|
|
||||||
|
|
||||||
/* We don't know of any non-gcc compilers that perform alias optimization,
|
|
||||||
* so this code should work.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(IS_LITTLE_ENDIAN) && !defined(CPU_IS_ARM)
|
|
||||||
#define TX_DOUBLE_HI32(x) (((PRUint32 *)&(x))[1])
|
|
||||||
#define TX_DOUBLE_LO32(x) (((PRUint32 *)&(x))[0])
|
|
||||||
#else
|
|
||||||
#define TX_DOUBLE_HI32(x) (((PRUint32 *)&(x))[0])
|
|
||||||
#define TX_DOUBLE_LO32(x) (((PRUint32 *)&(x))[1])
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // __GNUC__
|
|
||||||
|
|
||||||
#define TX_DOUBLE_HI32_SIGNBIT 0x80000000
|
|
||||||
#define TX_DOUBLE_HI32_EXPMASK 0x7ff00000
|
|
||||||
#define TX_DOUBLE_HI32_MANTMASK 0x000fffff
|
|
||||||
|
|
||||||
//-- Initialize Double related constants
|
//-- Initialize Double related constants
|
||||||
|
const PRUint32 nanMask[2] = TX_DOUBLE_NaN;
|
||||||
#ifdef IS_BIG_ENDIAN
|
#ifdef IS_BIG_ENDIAN
|
||||||
const PRUint32 nanMask[2] = {TX_DOUBLE_HI32_EXPMASK | TX_DOUBLE_HI32_MANTMASK,
|
|
||||||
0xffffffff};
|
|
||||||
const PRUint32 infMask[2] = {TX_DOUBLE_HI32_EXPMASK, 0};
|
const PRUint32 infMask[2] = {TX_DOUBLE_HI32_EXPMASK, 0};
|
||||||
const PRUint32 negInfMask[2] = {TX_DOUBLE_HI32_EXPMASK | TX_DOUBLE_HI32_SIGNBIT, 0};
|
const PRUint32 negInfMask[2] = {TX_DOUBLE_HI32_EXPMASK | TX_DOUBLE_HI32_SIGNBIT, 0};
|
||||||
#else
|
#else
|
||||||
const PRUint32 nanMask[2] = {0xffffffff,
|
|
||||||
TX_DOUBLE_HI32_EXPMASK | TX_DOUBLE_HI32_MANTMASK};
|
|
||||||
const PRUint32 infMask[2] = {0, TX_DOUBLE_HI32_EXPMASK};
|
const PRUint32 infMask[2] = {0, TX_DOUBLE_HI32_EXPMASK};
|
||||||
const PRUint32 negInfMask[2] = {0, TX_DOUBLE_HI32_EXPMASK | TX_DOUBLE_HI32_SIGNBIT};
|
const PRUint32 negInfMask[2] = {0, TX_DOUBLE_HI32_EXPMASK | TX_DOUBLE_HI32_SIGNBIT};
|
||||||
#endif
|
#endif
|
||||||
|
@ -147,8 +78,7 @@ MBool Double::isInfinite(double aDbl)
|
||||||
*/
|
*/
|
||||||
MBool Double::isNaN(double aDbl)
|
MBool Double::isNaN(double aDbl)
|
||||||
{
|
{
|
||||||
return ((TX_DOUBLE_HI32(aDbl) & TX_DOUBLE_HI32_EXPMASK) == TX_DOUBLE_HI32_EXPMASK &&
|
return TX_DOUBLE_IS_NaN(aDbl);
|
||||||
(TX_DOUBLE_LO32(aDbl) || (TX_DOUBLE_HI32(aDbl) & TX_DOUBLE_HI32_MANTMASK)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -101,20 +101,13 @@ CPPSRCS += nsXPathEvaluator.cpp \
|
||||||
nsXPathNSResolver.cpp \
|
nsXPathNSResolver.cpp \
|
||||||
nsXPathResult.cpp \
|
nsXPathResult.cpp \
|
||||||
nsXPath1Scheme.cpp \
|
nsXPath1Scheme.cpp \
|
||||||
txMozillaXPathTreeWalker.cpp
|
txMozillaXPathTreeWalker.cpp \
|
||||||
|
txNodeSetAdaptor.cpp \
|
||||||
|
txXPCOMExtensionFunction.cpp
|
||||||
else
|
else
|
||||||
CPPSRCS += txStandaloneXPathTreeWalker.cpp
|
CPPSRCS += txStandaloneXPathTreeWalker.cpp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef DISABLE_XFORMS_HOOKS # Dummy var, nobody sets it!
|
|
||||||
ifndef MOZ_XSLT_STANDALONE
|
|
||||||
EXPORTS = nsIXFormsXPathEvaluator.h
|
|
||||||
|
|
||||||
CPPSRCS += nsXFormsXPathEvaluator.cpp \
|
|
||||||
txXFormsFunctionCall.cpp
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
# we don't want the shared lib, but we want to force the creation of a
|
# we don't want the shared lib, but we want to force the creation of a
|
||||||
# static lib.
|
# static lib.
|
||||||
FORCE_STATIC_LIB = 1
|
FORCE_STATIC_LIB = 1
|
||||||
|
|
|
@ -1,102 +0,0 @@
|
||||||
/* -*- 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 nsIDOMNSXPathExpression; /* forward declaration */
|
|
||||||
|
|
||||||
/* starting interface: nsIXFormsXPathEvaluator */
|
|
||||||
#define NS_XFORMS_XPATH_EVALUATOR_CONTRACTID "@mozilla.org/dom/xforms-xpath-evaluator;1"
|
|
||||||
/* 4cdd884f-f949-4d82-bb78-b8edd9f1420c */
|
|
||||||
#define TRANSFORMIIX_XFORMS_XPATH_EVALUATOR_CID \
|
|
||||||
{ 0x4cdd884f, 0xf949, 0x4d82, \
|
|
||||||
{0xbb, 0x78, 0xb8, 0xed, 0xd9, 0xf1, 0x42, 0x0c} }
|
|
||||||
|
|
||||||
/* 61e5a446-73f7-432e-a2d6-d94d4a51aed8 */
|
|
||||||
#define TRANSFORMIIX_XFORMS_XPATH_EVALUATOR_IID \
|
|
||||||
{ 0x61e5a446, 0x73f7, 0x432e, \
|
|
||||||
{0xa2, 0xd6, 0xd9, 0x4d, 0x4a, 0x51, 0xae, 0xd8} }
|
|
||||||
|
|
||||||
/* Use this macro when declaring classes that implement this interface. */
|
|
||||||
#define NS_DECL_NSIXFORMXPATHEVALUATOR \
|
|
||||||
NS_IMETHOD CreateExpression(const nsAString & aExpression, nsIDOMNode *aResolverNode, nsIDOMNSXPathExpression **aResult); \
|
|
||||||
NS_IMETHOD Evaluate(const nsAString & aExpression, nsIDOMNode *aContextNode, PRUint32 aContextPosition, PRUint32 aContextSize, 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_DECLARE_STATIC_IID_ACCESSOR(TRANSFORMIIX_XFORMS_XPATH_EVALUATOR_IID)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to create a nsIDOMNSXPathExpression from the provided expression
|
|
||||||
* string. aResolverNode is the xforms node that the expression is
|
|
||||||
* associated with.
|
|
||||||
*/
|
|
||||||
NS_IMETHOD CreateExpression(const nsAString & aExpression, nsIDOMNode *aResolverNode, nsIDOMNSXPathExpression **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, PRUint32 aContextPosition, PRUint32 aContextSize, nsIDOMNode *aResolverNode, PRUint16 aType, nsISupports *aInResult, nsISupports **aResult) = 0;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIXFormsXPathEvaluator,
|
|
||||||
TRANSFORMIIX_XFORMS_XPATH_EVALUATOR_IID)
|
|
||||||
|
|
||||||
#endif /* nsIXFormsXPathEvaluator_h */
|
|
|
@ -1,272 +0,0 @@
|
||||||
/* -*- 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 "nsXPathExpression.h"
|
|
||||||
#include "nsXPathNSResolver.h"
|
|
||||||
#include "nsXPathResult.h"
|
|
||||||
#include "nsContentCID.h"
|
|
||||||
#include "txExpr.h"
|
|
||||||
#include "txExprParser.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 "txXFormsFunctions.h"
|
|
||||||
#include "nsIDOM3Node.h"
|
|
||||||
#include "nsContentUtils.h"
|
|
||||||
|
|
||||||
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,
|
|
||||||
nsIDOMNSXPathExpression **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,
|
|
||||||
PRUint32 aPosition,
|
|
||||||
PRUint32 aSize,
|
|
||||||
nsIDOMNode *aResolverNode,
|
|
||||||
PRUint16 aType,
|
|
||||||
nsISupports *aInResult,
|
|
||||||
nsISupports **aResult)
|
|
||||||
{
|
|
||||||
// XXX Need to check document of aContextNode if created by
|
|
||||||
// QI'ing a document.
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNSXPathExpression> expression;
|
|
||||||
nsresult rv = CreateExpression(aExpression, aResolverNode,
|
|
||||||
getter_AddRefs(expression));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
return expression->EvaluateWithContext(aContextNode, aPosition, aSize,
|
|
||||||
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 nsContentUtils::NameSpaceManager()->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::_if) {
|
|
||||||
aFnCall = new XFormsFunctionCall(XFormsFunctionCall::IF);
|
|
||||||
}
|
|
||||||
else if (aName == txXPathAtoms::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);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsXFormsXPathEvaluator::XFormsParseContextImpl::SetErrorOffset(PRUint32 aOffset)
|
|
||||||
{
|
|
||||||
}
|
|
|
@ -59,16 +59,23 @@
|
||||||
class nsXPathEvaluatorParseContext : public txIParseContext
|
class nsXPathEvaluatorParseContext : public txIParseContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsXPathEvaluatorParseContext(nsIDOMXPathNSResolver *aResolver,
|
nsXPathEvaluatorParseContext(nsXPathEvaluator &aEvaluator,
|
||||||
|
nsIDOMXPathNSResolver* aResolver,
|
||||||
|
nsTArray<PRInt32> *aNamespaceIDs,
|
||||||
|
nsCStringArray *aContractIDs,
|
||||||
|
nsCOMArray<nsISupports> *aState,
|
||||||
PRBool aIsCaseSensitive)
|
PRBool aIsCaseSensitive)
|
||||||
: mResolver(aResolver),
|
: mEvaluator(aEvaluator),
|
||||||
|
mResolver(aResolver),
|
||||||
|
mNamespaceIDs(aNamespaceIDs),
|
||||||
|
mContractIDs(aContractIDs),
|
||||||
|
mState(aState),
|
||||||
mLastError(NS_OK),
|
mLastError(NS_OK),
|
||||||
mIsCaseSensitive(aIsCaseSensitive)
|
mIsCaseSensitive(aIsCaseSensitive)
|
||||||
{
|
{
|
||||||
}
|
NS_ASSERTION(mContractIDs ||
|
||||||
|
(!mNamespaceIDs || mNamespaceIDs->Length() == 0),
|
||||||
~nsXPathEvaluatorParseContext()
|
"Need contract IDs if there are namespaces.");
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult getError()
|
nsresult getError()
|
||||||
|
@ -83,7 +90,11 @@ public:
|
||||||
void SetErrorOffset(PRUint32 aOffset);
|
void SetErrorOffset(PRUint32 aOffset);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
nsXPathEvaluator &mEvaluator;
|
||||||
nsIDOMXPathNSResolver* mResolver;
|
nsIDOMXPathNSResolver* mResolver;
|
||||||
|
nsTArray<PRInt32> *mNamespaceIDs;
|
||||||
|
nsCStringArray *mContractIDs;
|
||||||
|
nsCOMArray<nsISupports> *mState;
|
||||||
nsresult mLastError;
|
nsresult mLastError;
|
||||||
PRBool mIsCaseSensitive;
|
PRBool mIsCaseSensitive;
|
||||||
};
|
};
|
||||||
|
@ -113,38 +124,8 @@ nsXPathEvaluator::CreateExpression(const nsAString & aExpression,
|
||||||
nsIDOMXPathNSResolver *aResolver,
|
nsIDOMXPathNSResolver *aResolver,
|
||||||
nsIDOMXPathExpression **aResult)
|
nsIDOMXPathExpression **aResult)
|
||||||
{
|
{
|
||||||
nsresult rv = NS_OK;
|
return CreateExpression(aExpression, aResolver, (nsTArray<PRInt32>*)nsnull,
|
||||||
if (!mRecycler) {
|
nsnull, nsnull, aResult);
|
||||||
nsRefPtr<txResultRecycler> recycler = new txResultRecycler;
|
|
||||||
NS_ENSURE_TRUE(recycler, NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
|
|
||||||
rv = recycler->init();
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
mRecycler = recycler;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
|
|
||||||
nsXPathEvaluatorParseContext pContext(aResolver,
|
|
||||||
!doc || doc->IsCaseSensitive());
|
|
||||||
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
|
NS_IMETHODIMP
|
||||||
|
@ -172,7 +153,6 @@ nsXPathEvaluator::Evaluate(const nsAString & aExpression,
|
||||||
{
|
{
|
||||||
// XXX Need to check document of aContextNode if created by
|
// XXX Need to check document of aContextNode if created by
|
||||||
// QI'ing a document.
|
// QI'ing a document.
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMXPathExpression> expression;
|
nsCOMPtr<nsIDOMXPathExpression> expression;
|
||||||
nsresult rv = CreateExpression(aExpression, aResolver,
|
nsresult rv = CreateExpression(aExpression, aResolver,
|
||||||
getter_AddRefs(expression));
|
getter_AddRefs(expression));
|
||||||
|
@ -189,6 +169,85 @@ nsXPathEvaluator::SetDocument(nsIDOMDocument* aDocument)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXPathEvaluator::CreateExpression(const nsAString & aExpression,
|
||||||
|
nsIDOMXPathNSResolver *aResolver,
|
||||||
|
nsStringArray *aNamespaceURIs,
|
||||||
|
nsCStringArray *aContractIDs,
|
||||||
|
nsCOMArray<nsISupports> *aState,
|
||||||
|
nsIDOMXPathExpression **aResult)
|
||||||
|
{
|
||||||
|
nsTArray<PRInt32> namespaceIDs;
|
||||||
|
if (aNamespaceURIs) {
|
||||||
|
PRInt32 count = aNamespaceURIs->Count();
|
||||||
|
|
||||||
|
if (!aContractIDs || aContractIDs->Count() != count) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!namespaceIDs.SetLength(count)) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRInt32 i;
|
||||||
|
for (i = 0; i < count; ++i) {
|
||||||
|
if (aContractIDs->CStringAt(i)->IsEmpty()) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsContentUtils::NameSpaceManager()->RegisterNameSpace(*aNamespaceURIs->StringAt(i), namespaceIDs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return CreateExpression(aExpression, aResolver, &namespaceIDs, aContractIDs,
|
||||||
|
aState, aResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsXPathEvaluator::CreateExpression(const nsAString & aExpression,
|
||||||
|
nsIDOMXPathNSResolver *aResolver,
|
||||||
|
nsTArray<PRInt32> *aNamespaceIDs,
|
||||||
|
nsCStringArray *aContractIDs,
|
||||||
|
nsCOMArray<nsISupports> *aState,
|
||||||
|
nsIDOMXPathExpression **aResult)
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
|
||||||
|
nsXPathEvaluatorParseContext pContext(*this, aResolver, aNamespaceIDs,
|
||||||
|
aContractIDs, aState,
|
||||||
|
!doc || doc->IsCaseSensitive());
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Implementation of txIParseContext private to nsXPathEvaluator, based on a
|
* Implementation of txIParseContext private to nsXPathEvaluator, based on a
|
||||||
* nsIDOMXPathNSResolver
|
* nsIDOMXPathNSResolver
|
||||||
|
@ -226,12 +285,31 @@ nsresult nsXPathEvaluatorParseContext::resolveNamespacePrefix
|
||||||
return nsContentUtils::NameSpaceManager()->RegisterNameSpace(ns, aID);
|
return nsContentUtils::NameSpaceManager()->RegisterNameSpace(ns, aID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern nsresult
|
||||||
|
TX_ResolveFunctionCallXPCOM(const nsCString &aContractID, PRInt32 aNamespaceID,
|
||||||
|
nsIAtom *aName, nsISupports *aState,
|
||||||
|
FunctionCall *&aFunction);
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsXPathEvaluatorParseContext::resolveFunctionCall(nsIAtom* aName,
|
nsXPathEvaluatorParseContext::resolveFunctionCall(nsIAtom* aName,
|
||||||
PRInt32 aID,
|
PRInt32 aID,
|
||||||
FunctionCall*& aFn)
|
FunctionCall*& aFn)
|
||||||
{
|
{
|
||||||
return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
|
nsresult rv = NS_ERROR_XPATH_UNKNOWN_FUNCTION;
|
||||||
|
|
||||||
|
PRUint32 i, count = mNamespaceIDs ? mNamespaceIDs->Length() : 0;
|
||||||
|
for (i = 0; i < count; ++i) {
|
||||||
|
if (mNamespaceIDs->ElementAt(i) == aID) {
|
||||||
|
nsISupports *state = mState ? mState->SafeObjectAt(i) : nsnull;
|
||||||
|
rv = TX_ResolveFunctionCallXPCOM(*mContractIDs->CStringAt(i), aID,
|
||||||
|
aName, state, aFn);
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool nsXPathEvaluatorParseContext::caseInsensitiveNameTests()
|
PRBool nsXPathEvaluatorParseContext::caseInsensitiveNameTests()
|
||||||
|
|
|
@ -43,8 +43,10 @@
|
||||||
#include "nsIXPathEvaluatorInternal.h"
|
#include "nsIXPathEvaluatorInternal.h"
|
||||||
#include "nsIWeakReference.h"
|
#include "nsIWeakReference.h"
|
||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsString.h"
|
||||||
#include "txResultRecycler.h"
|
#include "txResultRecycler.h"
|
||||||
#include "nsAgg.h"
|
#include "nsAgg.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class for evaluating an XPath expression string
|
* A class for evaluating an XPath expression string
|
||||||
|
@ -68,8 +70,21 @@ public:
|
||||||
|
|
||||||
// nsIXPathEvaluatorInternal interface
|
// nsIXPathEvaluatorInternal interface
|
||||||
NS_IMETHOD SetDocument(nsIDOMDocument* aDocument);
|
NS_IMETHOD SetDocument(nsIDOMDocument* aDocument);
|
||||||
|
NS_IMETHOD CreateExpression(const nsAString &aExpression,
|
||||||
|
nsIDOMXPathNSResolver *aResolver,
|
||||||
|
nsStringArray *aNamespaceURIs,
|
||||||
|
nsCStringArray *aContractIDs,
|
||||||
|
nsCOMArray<nsISupports> *aState,
|
||||||
|
nsIDOMXPathExpression **aResult);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
nsresult CreateExpression(const nsAString & aExpression,
|
||||||
|
nsIDOMXPathNSResolver *aResolver,
|
||||||
|
nsTArray<PRInt32> *aNamespaceIDs,
|
||||||
|
nsCStringArray *aContractIDs,
|
||||||
|
nsCOMArray<nsISupports> *aState,
|
||||||
|
nsIDOMXPathExpression **aResult);
|
||||||
|
|
||||||
nsWeakPtr mDocument;
|
nsWeakPtr mDocument;
|
||||||
nsRefPtr<txResultRecycler> mRecycler;
|
nsRefPtr<txResultRecycler> mRecycler;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
/* -*- 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.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Peter Van der Beken.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Peter Van der Beken <peterv@propagandism.org>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 "txNodeSetAdaptor.h"
|
||||||
|
#include "txXPathTreeWalker.h"
|
||||||
|
|
||||||
|
txNodeSetAdaptor::txNodeSetAdaptor()
|
||||||
|
: mWritable(PR_TRUE)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
txNodeSetAdaptor::txNodeSetAdaptor(txNodeSet *aNodeSet)
|
||||||
|
: mNodeSet(aNodeSet),
|
||||||
|
mWritable(PR_FALSE)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(aNodeSet,
|
||||||
|
"Don't create an adaptor if you don't have a txNodeSet");
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(txNodeSetAdaptor, txINodeSet)
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
txNodeSetAdaptor::Init()
|
||||||
|
{
|
||||||
|
if (!mNodeSet) {
|
||||||
|
mNodeSet = new txNodeSet(nsnull);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mNodeSet ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
txNodeSetAdaptor::Item(PRUint32 aIndex, nsIDOMNode **aResult)
|
||||||
|
{
|
||||||
|
*aResult = nsnull;
|
||||||
|
|
||||||
|
if (aIndex > (PRUint32)mNodeSet->size()) {
|
||||||
|
return NS_ERROR_ILLEGAL_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return txXPathNativeNode::getNode(mNodeSet->get(aIndex), aResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
txNodeSetAdaptor::ItemAsNumber(PRUint32 aIndex, double *aResult)
|
||||||
|
{
|
||||||
|
if (aIndex > (PRUint32)mNodeSet->size()) {
|
||||||
|
return NS_ERROR_ILLEGAL_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoString result;
|
||||||
|
txXPathNodeUtils::appendNodeValue(mNodeSet->get(aIndex), result);
|
||||||
|
|
||||||
|
*aResult = Double::toDouble(result);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
txNodeSetAdaptor::ItemAsString(PRUint32 aIndex, nsAString &aResult)
|
||||||
|
{
|
||||||
|
if (aIndex > (PRUint32)mNodeSet->size()) {
|
||||||
|
return NS_ERROR_ILLEGAL_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
txXPathNodeUtils::appendNodeValue(mNodeSet->get(aIndex), aResult);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
txNodeSetAdaptor::GetLength(PRUint32 *aLength)
|
||||||
|
{
|
||||||
|
*aLength = (PRUint32)mNodeSet->size();
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
txNodeSetAdaptor::Add(nsIDOMNode *aNode)
|
||||||
|
{
|
||||||
|
NS_ENSURE_TRUE(mWritable, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsAutoPtr<txXPathNode> node(txXPathNativeNode::createXPathNode(aNode));
|
||||||
|
|
||||||
|
return node ? mNodeSet->add(*node) : NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
txAExprResult*
|
||||||
|
txNodeSetAdaptor::GetTxNodeSet()
|
||||||
|
{
|
||||||
|
return mNodeSet;
|
||||||
|
}
|
|
@ -12,15 +12,16 @@
|
||||||
* for the specific language governing rights and limitations under the
|
* for the specific language governing rights and limitations under the
|
||||||
* License.
|
* License.
|
||||||
*
|
*
|
||||||
* The Original Code is Mozilla XForms support.
|
* The Original Code is mozilla.org code.
|
||||||
*
|
*
|
||||||
* The Initial Developer of the Original Code is
|
* The Initial Developer of the Original Code is
|
||||||
* IBM Corporation.
|
* Peter Van der Beken.
|
||||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||||
* the Initial Developer. All Rights Reserved.
|
* the Initial Developer. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
* Aaron Reed <aaronr@us.ibm.com>
|
* Peter Van der Beken <peterv@propagandism.org>
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* 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
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
@ -36,66 +37,30 @@
|
||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
#ifndef nsXFormsXPathEvaluator_h__
|
#ifndef txNodeSetAdaptor_h__
|
||||||
#define nsXFormsXPathEvaluator_h__
|
#define txNodeSetAdaptor_h__
|
||||||
|
|
||||||
#include "nsIXFormsXPathEvaluator.h"
|
#include "txINodeSet.h"
|
||||||
#include "txIXPathContext.h"
|
#include "txNodeSet.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
|
* Implements an XPCOM wrapper around an XPath NodeSet.
|
||||||
*/
|
*/
|
||||||
class nsXFormsXPathEvaluator : public nsIXFormsXPathEvaluator
|
|
||||||
|
class txNodeSetAdaptor : public txINodeSet
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsXFormsXPathEvaluator();
|
txNodeSetAdaptor();
|
||||||
virtual ~nsXFormsXPathEvaluator();
|
txNodeSetAdaptor(txNodeSet *aNodeSet);
|
||||||
|
|
||||||
|
nsresult Init();
|
||||||
|
|
||||||
// nsISupports interface
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_TXINODESET
|
||||||
// nsIXFormsXPathEvaluator interface
|
|
||||||
NS_DECL_NSIXFORMXPATHEVALUATOR
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// txIParseContext implementation
|
nsRefPtr<txNodeSet> mNodeSet;
|
||||||
class XFormsParseContextImpl : public txIParseContext
|
PRBool mWritable;
|
||||||
{
|
|
||||||
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();
|
|
||||||
void SetErrorOffset(PRUint32 aOffset);
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsIDOMNode* mResolverNode;
|
|
||||||
nsresult mLastError;
|
|
||||||
};
|
|
||||||
|
|
||||||
nsRefPtr<txResultRecycler> mRecycler;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif // txNodeSetAdaptor_h__
|
|
@ -37,6 +37,7 @@
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
#include "txExpr.h"
|
#include "txExpr.h"
|
||||||
|
#include "txDouble.h"
|
||||||
#include "txNodeSet.h"
|
#include "txNodeSet.h"
|
||||||
#include "txIXPathContext.h"
|
#include "txIXPathContext.h"
|
||||||
#include "txXPathTreeWalker.h"
|
#include "txXPathTreeWalker.h"
|
||||||
|
@ -118,14 +119,7 @@ RelationalExpr::compareResults(txIEvalContext* aContext, txAExprResult* aLeft,
|
||||||
rtype == txAExprResult::NUMBER) {
|
rtype == txAExprResult::NUMBER) {
|
||||||
double lval = aLeft->numberValue();
|
double lval = aLeft->numberValue();
|
||||||
double rval = aRight->numberValue();
|
double rval = aRight->numberValue();
|
||||||
#if defined(XP_WIN)
|
result = TX_DOUBLE_COMPARE(lval, ==, rval);
|
||||||
if (Double::isNaN(lval) || Double::isNaN(rval))
|
|
||||||
result = PR_FALSE;
|
|
||||||
else
|
|
||||||
result = lval == rval;
|
|
||||||
#else
|
|
||||||
result = lval == rval;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise compare as strings. Try to use the stringobject in
|
// Otherwise compare as strings. Try to use the stringobject in
|
||||||
|
@ -157,27 +151,22 @@ RelationalExpr::compareResults(txIEvalContext* aContext, txAExprResult* aLeft,
|
||||||
|
|
||||||
double leftDbl = aLeft->numberValue();
|
double leftDbl = aLeft->numberValue();
|
||||||
double rightDbl = aRight->numberValue();
|
double rightDbl = aRight->numberValue();
|
||||||
#if defined(XP_WIN)
|
|
||||||
if (Double::isNaN(leftDbl) || Double::isNaN(rightDbl))
|
|
||||||
return PR_FALSE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (mOp) {
|
switch (mOp) {
|
||||||
case LESS_THAN:
|
case LESS_THAN:
|
||||||
{
|
{
|
||||||
return leftDbl < rightDbl;
|
return TX_DOUBLE_COMPARE(leftDbl, <, rightDbl);
|
||||||
}
|
}
|
||||||
case LESS_OR_EQUAL:
|
case LESS_OR_EQUAL:
|
||||||
{
|
{
|
||||||
return leftDbl <= rightDbl;
|
return TX_DOUBLE_COMPARE(leftDbl, <=, rightDbl);
|
||||||
}
|
}
|
||||||
case GREATER_THAN:
|
case GREATER_THAN:
|
||||||
{
|
{
|
||||||
return leftDbl > rightDbl;
|
return TX_DOUBLE_COMPARE(leftDbl, >, rightDbl);
|
||||||
}
|
}
|
||||||
case GREATER_OR_EQUAL:
|
case GREATER_OR_EQUAL:
|
||||||
{
|
{
|
||||||
return leftDbl >= rightDbl;
|
return TX_DOUBLE_COMPARE(leftDbl, >=, rightDbl);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,647 +0,0 @@
|
||||||
/* -*- 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 ***** */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* XFormsFunctionCall
|
|
||||||
* A representation of the XPath NodeSet funtions
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "txExpr.h"
|
|
||||||
#include "nsAutoPtr.h"
|
|
||||||
#include "txNodeSet.h"
|
|
||||||
#include "txAtoms.h"
|
|
||||||
#include "txIXPathContext.h"
|
|
||||||
#include "txTokenizer.h"
|
|
||||||
#include "txXFormsFunctions.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"
|
|
||||||
#include "txXPathTreeWalker.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;
|
|
||||||
|
|
||||||
Expr *expr1 = NS_STATIC_CAST(Expr*, iter.next());
|
|
||||||
|
|
||||||
nsAutoString booleanValue;
|
|
||||||
expr1->evaluateToString(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);
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
Expr *expr1 = NS_STATIC_CAST(Expr*, iter.next());
|
|
||||||
|
|
||||||
nsAutoString date;
|
|
||||||
expr1->evaluateToString(aContext, date);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIXFormsUtilityService>xformsService =
|
|
||||||
do_GetService("@mozilla.org/xforms-utility-service;1", &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
PRInt32 result = 0;
|
|
||||||
double res = Double::NaN;
|
|
||||||
nsresult rv = xformsService->GetDaysFromDateTime(date, &result);
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
res = result;
|
|
||||||
}
|
|
||||||
else if (rv != NS_ERROR_ILLEGAL_VALUE) {
|
|
||||||
// if we failed for a reason other than the parameter value, pass that
|
|
||||||
// up the chain
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return aContext->recycler()->getNumberResult(res, aResult);
|
|
||||||
}
|
|
||||||
case IF:
|
|
||||||
{
|
|
||||||
if (!requireParams(3, 3, aContext))
|
|
||||||
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
|
|
||||||
|
|
||||||
Expr *expr1 = NS_STATIC_CAST(Expr*, iter.next());
|
|
||||||
|
|
||||||
PRBool test;
|
|
||||||
nsAutoString valueToReturn;
|
|
||||||
expr1->evaluateToBool(aContext, test);
|
|
||||||
|
|
||||||
// grab 'true' value to return
|
|
||||||
Expr *getvalue = NS_STATIC_CAST(Expr*, iter.next());
|
|
||||||
|
|
||||||
if (!test) {
|
|
||||||
// grab 'false' value to return
|
|
||||||
getvalue = NS_STATIC_CAST(Expr*, iter.next());
|
|
||||||
}
|
|
||||||
getvalue->evaluateToString(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;
|
|
||||||
|
|
||||||
Expr *expr1 = NS_STATIC_CAST(Expr*, iter.next());
|
|
||||||
|
|
||||||
nsAutoString indexId;
|
|
||||||
expr1->evaluateToString(aContext, indexId);
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// indexId should be the id of a nsIXFormsRepeatElement
|
|
||||||
nsCOMPtr<nsIDOMElement> 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.
|
|
||||||
nsCOMPtr<nsIXFormsUtilityService>xformsService =
|
|
||||||
do_GetService("@mozilla.org/xforms-utility-service;1", &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
PRInt32 index = 0;
|
|
||||||
double res = Double::NaN;
|
|
||||||
rv = xformsService->GetRepeatIndex(repeatEle, &index);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (index >= 0) {
|
|
||||||
// repeat's index is 1-based. If it is 0, then that is still ok since
|
|
||||||
// repeat's index can be 0 if uninitialized or if the nodeset that it
|
|
||||||
// is bound to is empty (either initially or due to delete remove all
|
|
||||||
// of the instance nodes). If index == -1, then repeatEle isn't an
|
|
||||||
// XForms repeat element, so we need to return NaN per spec.
|
|
||||||
res = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
return aContext->recycler()->getNumberResult(res, aResult);
|
|
||||||
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
|
|
||||||
Expr *expr1 = NS_STATIC_CAST(Expr*, iter.next());
|
|
||||||
|
|
||||||
nsAutoString instanceId;
|
|
||||||
expr1->evaluateToString(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);
|
|
||||||
if (instanceRoot) {
|
|
||||||
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;
|
|
||||||
|
|
||||||
Expr *expr1 = NS_STATIC_CAST(Expr*, iter.next());
|
|
||||||
|
|
||||||
nsAutoString duration;
|
|
||||||
expr1->evaluateToString(aContext, duration);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIXFormsUtilityService>xformsService =
|
|
||||||
do_GetService("@mozilla.org/xforms-utility-service;1", &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
PRInt32 result = 0;
|
|
||||||
double res = Double::NaN;
|
|
||||||
nsresult rv = xformsService->GetMonths(duration, &result);
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
res = result;
|
|
||||||
}
|
|
||||||
else if (rv != NS_ERROR_ILLEGAL_VALUE) {
|
|
||||||
// if we failed for a reason other than the parameter value, pass that
|
|
||||||
// up the chain
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return aContext->recycler()->getNumberResult(res, aResult);
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
|
|
||||||
Expr *expr1 = NS_STATIC_CAST(Expr*, iter.next());
|
|
||||||
|
|
||||||
nsAutoString property;
|
|
||||||
expr1->evaluateToString(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:
|
|
||||||
{
|
|
||||||
if (!requireParams(1, 1, aContext))
|
|
||||||
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
|
|
||||||
|
|
||||||
Expr *expr1 = NS_STATIC_CAST(Expr*, iter.next());
|
|
||||||
|
|
||||||
nsAutoString duration;
|
|
||||||
expr1->evaluateToString(aContext, duration);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIXFormsUtilityService>xformsService =
|
|
||||||
do_GetService("@mozilla.org/xforms-utility-service;1", &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
double res;
|
|
||||||
nsresult rv = xformsService->GetSeconds(duration, &res);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
if (rv != NS_ERROR_ILLEGAL_VALUE) {
|
|
||||||
// if we failed for a reason other than the parameter value, pass that
|
|
||||||
// up the chain
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
res = Double::NaN;
|
|
||||||
}
|
|
||||||
|
|
||||||
return aContext->recycler()->getNumberResult(res, aResult);
|
|
||||||
}
|
|
||||||
case SECONDSFROMDATETIME:
|
|
||||||
{
|
|
||||||
if (!requireParams(1, 1, aContext))
|
|
||||||
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
|
|
||||||
|
|
||||||
Expr *expr1 = NS_STATIC_CAST(Expr*, iter.next());
|
|
||||||
|
|
||||||
nsAutoString dateTime;
|
|
||||||
expr1->evaluateToString(aContext, dateTime);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIXFormsUtilityService>xformsService =
|
|
||||||
do_GetService("@mozilla.org/xforms-utility-service;1", &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
double res;
|
|
||||||
nsresult rv = xformsService->GetSecondsFromDateTime(dateTime, &res);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
if (rv != NS_ERROR_ILLEGAL_VALUE) {
|
|
||||||
// if we failed for a reason other than the parameter value, pass that
|
|
||||||
// up the chain
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
res = Double::NaN;
|
|
||||||
}
|
|
||||||
|
|
||||||
return aContext->recycler()->getNumberResult(res, aResult);
|
|
||||||
}
|
|
||||||
} /* switch() */
|
|
||||||
|
|
||||||
aContext->receiveError(NS_LITERAL_STRING("Internal error"),
|
|
||||||
NS_ERROR_UNEXPECTED);
|
|
||||||
return NS_ERROR_UNEXPECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr::ResultType
|
|
||||||
XFormsFunctionCall::getReturnType()
|
|
||||||
{
|
|
||||||
// It doesn't really matter what we return here, but it might
|
|
||||||
// be a good idea to try to keep this as unoptimizable as possible
|
|
||||||
return ANY_RESULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool
|
|
||||||
XFormsFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
|
||||||
{
|
|
||||||
// It doesn't really matter what we return here, but it might
|
|
||||||
// be a good idea to try to keep this as unoptimizable as possible
|
|
||||||
return PR_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#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::_if;
|
|
||||||
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
|
|
|
@ -0,0 +1,587 @@
|
||||||
|
/* -*- 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.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Peter Van der Beken.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Peter Van der Beken <peterv@propagandism.org>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 "nsAutoPtr.h"
|
||||||
|
#include "nsComponentManagerUtils.h"
|
||||||
|
#include "nsDependentString.h"
|
||||||
|
#include "nsIAtom.h"
|
||||||
|
#include "nsIInterfaceInfoManager.h"
|
||||||
|
#include "nsServiceManagerUtils.h"
|
||||||
|
#include "txExpr.h"
|
||||||
|
#include "txIFunctionEvaluationContext.h"
|
||||||
|
#include "txIXPathContext.h"
|
||||||
|
#include "txNodeSetAdaptor.h"
|
||||||
|
#include "txXPathTreeWalker.h"
|
||||||
|
#include "xptcall.h"
|
||||||
|
|
||||||
|
class txFunctionEvaluationContext : public txIFunctionEvaluationContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
txFunctionEvaluationContext(txIEvalContext *aContext, nsISupports *aState);
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_TXIFUNCTIONEVALUATIONCONTEXT
|
||||||
|
|
||||||
|
void ClearContext()
|
||||||
|
{
|
||||||
|
mContext = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
txIEvalContext *mContext;
|
||||||
|
nsCOMPtr<nsISupports> mState;
|
||||||
|
};
|
||||||
|
|
||||||
|
txFunctionEvaluationContext::txFunctionEvaluationContext(txIEvalContext *aContext,
|
||||||
|
nsISupports *aState)
|
||||||
|
: mContext(aContext),
|
||||||
|
mState(aState)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(txFunctionEvaluationContext, txIFunctionEvaluationContext)
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
txFunctionEvaluationContext::GetPosition(PRUint32 *aPosition)
|
||||||
|
{
|
||||||
|
NS_ENSURE_TRUE(mContext, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
*aPosition = mContext->position();
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
txFunctionEvaluationContext::GetSize(PRUint32 *aSize)
|
||||||
|
{
|
||||||
|
NS_ENSURE_TRUE(mContext, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
*aSize = mContext->size();
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
txFunctionEvaluationContext::GetContextNode(nsIDOMNode **aNode)
|
||||||
|
{
|
||||||
|
NS_ENSURE_TRUE(mContext, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
return txXPathNativeNode::getNode(mContext->getContextNode(), aNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
txFunctionEvaluationContext::GetState(nsISupports **aState)
|
||||||
|
{
|
||||||
|
NS_IF_ADDREF(*aState = mState);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum txArgumentType {
|
||||||
|
BOOLEAN = nsXPTType::T_BOOL,
|
||||||
|
NUMBER = nsXPTType::T_DOUBLE,
|
||||||
|
STRING = nsXPTType::T_DOMSTRING,
|
||||||
|
NODESET,
|
||||||
|
CONTEXT,
|
||||||
|
UNKNOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
class txXPCOMExtensionFunctionCall : public FunctionCall
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
txXPCOMExtensionFunctionCall(nsISupports *aHelper, const nsIID &aIID,
|
||||||
|
PRUint16 aMethodIndex,
|
||||||
|
#ifdef TX_TO_STRING
|
||||||
|
PRInt32 aNamespaceID, nsIAtom *aName,
|
||||||
|
#endif
|
||||||
|
nsISupports *aState);
|
||||||
|
|
||||||
|
TX_DECL_FUNCTION;
|
||||||
|
|
||||||
|
private:
|
||||||
|
txArgumentType GetParamType(const nsXPTParamInfo &aParam,
|
||||||
|
nsIInterfaceInfo *aInfo);
|
||||||
|
|
||||||
|
nsCOMPtr<nsISupports> mHelper;
|
||||||
|
nsIID mIID;
|
||||||
|
PRUint16 mMethodIndex;
|
||||||
|
#ifdef TX_TO_STRING
|
||||||
|
PRInt32 mNamespaceID;
|
||||||
|
nsCOMPtr<nsIAtom> mName;
|
||||||
|
#endif
|
||||||
|
nsCOMPtr<nsISupports> mState;
|
||||||
|
};
|
||||||
|
|
||||||
|
txXPCOMExtensionFunctionCall::txXPCOMExtensionFunctionCall(nsISupports *aHelper,
|
||||||
|
const nsIID &aIID,
|
||||||
|
PRUint16 aMethodIndex,
|
||||||
|
#ifdef TX_TO_STRING
|
||||||
|
PRInt32 aNamespaceID,
|
||||||
|
nsIAtom *aName,
|
||||||
|
#endif
|
||||||
|
nsISupports *aState)
|
||||||
|
: mHelper(aHelper),
|
||||||
|
mIID(aIID),
|
||||||
|
mMethodIndex(aMethodIndex),
|
||||||
|
#ifdef TX_TO_STRING
|
||||||
|
mNamespaceID(aNamespaceID),
|
||||||
|
mName(aName),
|
||||||
|
#endif
|
||||||
|
mState(aState)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
class txInterfacesArrayHolder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
txInterfacesArrayHolder(nsIID **aArray, PRUint32 aCount) : mArray(aArray),
|
||||||
|
mCount(aCount)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~txInterfacesArrayHolder()
|
||||||
|
{
|
||||||
|
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(mCount, mArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsIID **mArray;
|
||||||
|
PRUint32 mCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
static nsresult
|
||||||
|
LookupFunction(const char *aContractID, nsIAtom* aName, nsIID &aIID,
|
||||||
|
PRUint16 &aMethodIndex)
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
nsCOMPtr<nsIClassInfo> classInfo = do_GetClassObject(aContractID, &rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIInterfaceInfoManager> iim =
|
||||||
|
do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID);
|
||||||
|
NS_ENSURE_TRUE(iim, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsIID** iidArray = nsnull;
|
||||||
|
PRUint32 iidCount = 0;
|
||||||
|
rv = classInfo->GetInterfaces(&iidCount, &iidArray);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
txInterfacesArrayHolder holder(iidArray, iidCount);
|
||||||
|
|
||||||
|
// Remove any minus signs and uppercase the following letter (so
|
||||||
|
// foo-bar becomes fooBar). Note that if there are any names that already
|
||||||
|
// have uppercase letters they might cause false matches (both fooBar and
|
||||||
|
// foo-bar matching fooBar).
|
||||||
|
const char *name;
|
||||||
|
aName->GetUTF8String(&name);
|
||||||
|
nsCAutoString methodName;
|
||||||
|
char letter;
|
||||||
|
PRBool upperNext = PR_FALSE;
|
||||||
|
while ((letter = *name)) {
|
||||||
|
if (letter == '-') {
|
||||||
|
upperNext = PR_TRUE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
methodName.Append(upperNext ? nsCRT::ToUpper(letter) : letter);
|
||||||
|
upperNext = PR_FALSE;
|
||||||
|
}
|
||||||
|
++name;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRUint32 i;
|
||||||
|
for (i = 0; i < iidCount; ++i) {
|
||||||
|
nsIID *iid = iidArray[i];
|
||||||
|
|
||||||
|
nsCOMPtr<nsIInterfaceInfo> info;
|
||||||
|
rv = iim->GetInfoForIID(iid, getter_AddRefs(info));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
PRUint16 methodIndex;
|
||||||
|
const nsXPTMethodInfo *methodInfo;
|
||||||
|
rv = info->GetMethodInfoForName(methodName.get(), &methodIndex,
|
||||||
|
&methodInfo);
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
// Exclude notxpcom and hidden. Also check that we have at least a
|
||||||
|
// return value (the xpidl compiler ensures that that return value
|
||||||
|
// is the last argument).
|
||||||
|
PRUint8 paramCount = methodInfo->GetParamCount();
|
||||||
|
if (methodInfo->IsNotXPCOM() || methodInfo->IsHidden() ||
|
||||||
|
paramCount == 0 ||
|
||||||
|
!methodInfo->GetParam(paramCount - 1).IsRetval()) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
aIID = *iid;
|
||||||
|
aMethodIndex = methodIndex;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
nsresult
|
||||||
|
TX_ResolveFunctionCallXPCOM(const nsCString &aContractID, PRInt32 aNamespaceID,
|
||||||
|
nsIAtom* aName, nsISupports *aState,
|
||||||
|
FunctionCall *&aFunction)
|
||||||
|
{
|
||||||
|
nsIID iid;
|
||||||
|
PRUint16 methodIndex;
|
||||||
|
nsresult rv = LookupFunction(aContractID.get(), aName, iid, methodIndex);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsISupports> helper;
|
||||||
|
rv = CallGetService(aContractID.get(), iid, getter_AddRefs(helper));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
aFunction = new txXPCOMExtensionFunctionCall(helper, iid, methodIndex,
|
||||||
|
#ifdef TX_TO_STRING
|
||||||
|
aNamespaceID, aName,
|
||||||
|
#endif
|
||||||
|
aState);
|
||||||
|
|
||||||
|
return aFunction ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
txArgumentType
|
||||||
|
txXPCOMExtensionFunctionCall::GetParamType(const nsXPTParamInfo &aParam,
|
||||||
|
nsIInterfaceInfo *aInfo)
|
||||||
|
{
|
||||||
|
PRUint8 tag = aParam.GetType().TagPart();
|
||||||
|
switch (tag) {
|
||||||
|
case nsXPTType::T_BOOL:
|
||||||
|
case nsXPTType::T_DOUBLE:
|
||||||
|
case nsXPTType::T_DOMSTRING:
|
||||||
|
{
|
||||||
|
return txArgumentType(tag);
|
||||||
|
}
|
||||||
|
case nsXPTType::T_INTERFACE:
|
||||||
|
case nsXPTType::T_INTERFACE_IS:
|
||||||
|
{
|
||||||
|
nsIID iid;
|
||||||
|
aInfo->GetIIDForParamNoAlloc(mMethodIndex, &aParam, &iid);
|
||||||
|
if (iid.Equals(NS_GET_IID(txINodeSet))) {
|
||||||
|
return NODESET;
|
||||||
|
}
|
||||||
|
if (iid.Equals(NS_GET_IID(txIFunctionEvaluationContext))) {
|
||||||
|
return CONTEXT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// XXX Error!
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class txParamArrayHolder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
txParamArrayHolder()
|
||||||
|
: mCount(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~txParamArrayHolder();
|
||||||
|
|
||||||
|
PRBool Init(PRUint8 aCount);
|
||||||
|
operator nsXPTCVariant*() const
|
||||||
|
{
|
||||||
|
return mArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsAutoArrayPtr<nsXPTCVariant> mArray;
|
||||||
|
PRUint8 mCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
txParamArrayHolder::~txParamArrayHolder()
|
||||||
|
{
|
||||||
|
PRUint8 i;
|
||||||
|
for (i = 0; i < mCount; ++i) {
|
||||||
|
nsXPTCVariant &variant = mArray[i];
|
||||||
|
if (variant.IsValInterface()) {
|
||||||
|
NS_STATIC_CAST(nsISupports*, variant.val.p)->Release();
|
||||||
|
}
|
||||||
|
else if (variant.IsValDOMString()) {
|
||||||
|
delete (nsAString*)variant.val.p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
txParamArrayHolder::Init(PRUint8 aCount)
|
||||||
|
{
|
||||||
|
mCount = aCount;
|
||||||
|
mArray = new nsXPTCVariant[mCount];
|
||||||
|
if (!mArray) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(mArray, 0, mCount * sizeof(nsXPTCVariant));
|
||||||
|
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
txXPCOMExtensionFunctionCall::evaluate(txIEvalContext* aContext,
|
||||||
|
txAExprResult** aResult)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIInterfaceInfoManager> iim =
|
||||||
|
do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID);
|
||||||
|
NS_ENSURE_TRUE(iim, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIInterfaceInfo> info;
|
||||||
|
nsresult rv = iim->GetInfoForIID(&mIID, getter_AddRefs(info));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
const nsXPTMethodInfo *methodInfo;
|
||||||
|
rv = info->GetMethodInfo(mMethodIndex, &methodInfo);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
PRUint8 paramCount = methodInfo->GetParamCount();
|
||||||
|
PRUint8 inArgs = paramCount - 1;
|
||||||
|
|
||||||
|
txParamArrayHolder invokeParams;
|
||||||
|
if (!invokeParams.Init(paramCount)) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nsXPTParamInfo ¶mInfo = methodInfo->GetParam(0);
|
||||||
|
txArgumentType type = GetParamType(paramInfo, info);
|
||||||
|
if (type == UNKNOWN) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
txFunctionEvaluationContext *context;
|
||||||
|
PRUint8 i = 0;
|
||||||
|
if (type == CONTEXT) {
|
||||||
|
if (paramInfo.IsOut()) {
|
||||||
|
// We don't support out values.
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create context wrapper.
|
||||||
|
context = new txFunctionEvaluationContext(aContext, mState);
|
||||||
|
if (!context) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsXPTCVariant &invokeParam = invokeParams[0];
|
||||||
|
invokeParam.type = paramInfo.GetType();
|
||||||
|
invokeParam.SetValIsInterface();
|
||||||
|
NS_ADDREF((txIFunctionEvaluationContext*&)invokeParam.val.p = context);
|
||||||
|
|
||||||
|
// Skip first argument, since it's the context.
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
context = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX varargs
|
||||||
|
if (!requireParams(inArgs - i, inArgs - i, aContext)) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
txListIterator iter(¶ms);
|
||||||
|
for (; i < inArgs; ++i) {
|
||||||
|
Expr* expr = NS_STATIC_CAST(Expr*, iter.next());
|
||||||
|
|
||||||
|
const nsXPTParamInfo ¶mInfo = methodInfo->GetParam(i);
|
||||||
|
txArgumentType type = GetParamType(paramInfo, info);
|
||||||
|
if (type == UNKNOWN) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsXPTCVariant &invokeParam = invokeParams[i];
|
||||||
|
if (paramInfo.IsOut()) {
|
||||||
|
// We don't support out values.
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
invokeParam.type = paramInfo.GetType();
|
||||||
|
switch (type) {
|
||||||
|
case NODESET:
|
||||||
|
{
|
||||||
|
nsRefPtr<txNodeSet> nodes;
|
||||||
|
rv = evaluateToNodeSet(expr, aContext, getter_AddRefs(nodes));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
txNodeSetAdaptor *adaptor = new txNodeSetAdaptor(nodes);
|
||||||
|
if (!adaptor) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<txINodeSet> nodeSet = adaptor;
|
||||||
|
rv = adaptor->Init();
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
invokeParam.SetValIsInterface();
|
||||||
|
nodeSet.swap((txINodeSet*&)invokeParam.val.p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BOOLEAN:
|
||||||
|
{
|
||||||
|
rv = expr->evaluateToBool(aContext, invokeParam.val.b);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NUMBER:
|
||||||
|
{
|
||||||
|
invokeParam.val.d = evaluateToNumber(expr, aContext);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case STRING:
|
||||||
|
{
|
||||||
|
nsString *value = new nsString();
|
||||||
|
if (!value) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = expr->evaluateToString(aContext, *value);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
invokeParam.SetValIsDOMString();
|
||||||
|
invokeParam.val.p = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONTEXT:
|
||||||
|
case UNKNOWN:
|
||||||
|
{
|
||||||
|
// We only support passing the context as the *first* argument.
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const nsXPTParamInfo &returnInfo = methodInfo->GetParam(inArgs);
|
||||||
|
txArgumentType returnType = GetParamType(returnInfo, info);
|
||||||
|
if (returnType == UNKNOWN) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsXPTCVariant &returnParam = invokeParams[inArgs];
|
||||||
|
returnParam.type = returnInfo.GetType();
|
||||||
|
if (returnType == STRING) {
|
||||||
|
nsString *value = new nsString();
|
||||||
|
if (!value) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
returnParam.SetValIsDOMString();
|
||||||
|
returnParam.val.p = value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
returnParam.SetPtrIsData();
|
||||||
|
returnParam.ptr = &returnParam.val;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = XPTC_InvokeByIndex(mHelper, mMethodIndex, paramCount, invokeParams);
|
||||||
|
|
||||||
|
// In case someone is holding on to the txFunctionEvaluationContext which
|
||||||
|
// could thus stay alive longer than this function.
|
||||||
|
if (context) {
|
||||||
|
context->ClearContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
switch (returnType) {
|
||||||
|
case NODESET:
|
||||||
|
{
|
||||||
|
txINodeSet *nodeSet = NS_STATIC_CAST(txINodeSet*,
|
||||||
|
returnParam.val.p);
|
||||||
|
|
||||||
|
NS_ADDREF(*aResult = nodeSet->GetTxNodeSet());
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
case BOOLEAN:
|
||||||
|
{
|
||||||
|
aContext->recycler()->getBoolResult(returnParam.val.b, aResult);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
case NUMBER:
|
||||||
|
{
|
||||||
|
return aContext->recycler()->getNumberResult(returnParam.val.d,
|
||||||
|
aResult);
|
||||||
|
}
|
||||||
|
case STRING:
|
||||||
|
{
|
||||||
|
nsString *returned = NS_STATIC_CAST(nsString*,
|
||||||
|
returnParam.val.p);
|
||||||
|
return aContext->recycler()->getStringResult(*returned, aResult);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// Huh?
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr::ResultType
|
||||||
|
txXPCOMExtensionFunctionCall::getReturnType()
|
||||||
|
{
|
||||||
|
// It doesn't really matter what we return here, but it might
|
||||||
|
// be a good idea to try to keep this as unoptimizable as possible
|
||||||
|
return ANY_RESULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
txXPCOMExtensionFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
||||||
|
{
|
||||||
|
// It doesn't really matter what we return here, but it might
|
||||||
|
// be a good idea to try to keep this as unoptimizable as possible
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TX_TO_STRING
|
||||||
|
nsresult
|
||||||
|
txXPCOMExtensionFunctionCall::getNameAtom(nsIAtom** aAtom)
|
||||||
|
{
|
||||||
|
NS_ADDREF(*aAtom = mName);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -148,6 +148,7 @@ XPIDLSRCS = \
|
||||||
nsIXFormsCopyElement.idl \
|
nsIXFormsCopyElement.idl \
|
||||||
nsIXFormsEphemeralMessageUI.idl \
|
nsIXFormsEphemeralMessageUI.idl \
|
||||||
nsIXFormsRangeConditionAccessors.idl \
|
nsIXFormsRangeConditionAccessors.idl \
|
||||||
|
nsIXFormsXPathFunctions.idl \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
# XForms source files
|
# XForms source files
|
||||||
|
@ -208,6 +209,7 @@ CPPSRCS = \
|
||||||
nsXFormsRangeAccessors.cpp \
|
nsXFormsRangeAccessors.cpp \
|
||||||
nsXFormsCopyElement.cpp \
|
nsXFormsCopyElement.cpp \
|
||||||
nsXFormsRangeConditionAccessors.cpp \
|
nsXFormsRangeConditionAccessors.cpp \
|
||||||
|
nsXFormsXPathFunctions.cpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
# Standard Mozilla make rules
|
# Standard Mozilla make rules
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
/* -*- Mode: IDL; 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.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Peter Van der Beken.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Peter Van der Beken <peterv@propagandism.org>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 "nsISupports.idl"
|
||||||
|
#include "txIFunctionEvaluationContext.idl"
|
||||||
|
|
||||||
|
[scriptable, uuid(cc846954-69a0-11d9-9791-000a95dc234c)]
|
||||||
|
interface nsIXFormsXPathFunctions : nsISupports
|
||||||
|
{
|
||||||
|
double avg(in txINodeSet aNodeSet);
|
||||||
|
boolean booleanFromString(in DOMString aString);
|
||||||
|
double countNonEmpty(in txINodeSet aNodeSet);
|
||||||
|
double daysFromDate(in DOMString aDateTime);
|
||||||
|
DOMString if(in boolean aValue, in DOMString aIfString, in DOMString aElseString);
|
||||||
|
double index(in txIFunctionEvaluationContext aContext, in DOMString aId);
|
||||||
|
txINodeSet instance(in txIFunctionEvaluationContext aContext, in DOMString aString);
|
||||||
|
double max(in txINodeSet aNodeSet);
|
||||||
|
double min(in txINodeSet aNodeSet);
|
||||||
|
double months(in DOMString aDuration);
|
||||||
|
DOMString now();
|
||||||
|
DOMString property(in DOMString aProperty);
|
||||||
|
double seconds(in DOMString aDuration);
|
||||||
|
double secondsFromDateTime(in DOMString aDateTime);
|
||||||
|
};
|
|
@ -380,14 +380,16 @@ nsXFormsMDGEngine::Recalculate(nsCOMArray<nsIDOMNode> *aChangedNodes)
|
||||||
switch (g->mType) {
|
switch (g->mType) {
|
||||||
case eModel_calculate:
|
case eModel_calculate:
|
||||||
if (g->HasExpr()) {
|
if (g->HasExpr()) {
|
||||||
nsCOMPtr<nsIDOMXPathResult> xpath_res;
|
nsCOMPtr<nsISupports> result;
|
||||||
rv = g->mExpression->EvaluateWithContext(g->mContextNode,
|
rv = g->mExpression->EvaluateWithContext(g->mContextNode,
|
||||||
g->mContextPosition,
|
g->mContextPosition,
|
||||||
g->mContextSize,
|
g->mContextSize,
|
||||||
nsIDOMXPathResult::STRING_TYPE,
|
nsIDOMXPathResult::STRING_TYPE,
|
||||||
nsnull,
|
nsnull,
|
||||||
getter_AddRefs(xpath_res));
|
getter_AddRefs(result));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMXPathResult> xpath_res = do_QueryInterface(result);
|
||||||
NS_ENSURE_STATE(xpath_res);
|
NS_ENSURE_STATE(xpath_res);
|
||||||
|
|
||||||
nsAutoString nodeval;
|
nsAutoString nodeval;
|
||||||
|
@ -1039,7 +1041,7 @@ nsXFormsMDGEngine::BooleanExpression(nsXFormsMDGNode* aNode, PRBool& state)
|
||||||
NS_ENSURE_ARG_POINTER(aNode);
|
NS_ENSURE_ARG_POINTER(aNode);
|
||||||
NS_ENSURE_TRUE(aNode->mExpression, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(aNode->mExpression, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
nsISupports* retval;
|
nsCOMPtr<nsISupports> retval;
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
rv = aNode->mExpression->EvaluateWithContext(aNode->mContextNode,
|
rv = aNode->mExpression->EvaluateWithContext(aNode->mContextNode,
|
||||||
|
@ -1047,7 +1049,7 @@ nsXFormsMDGEngine::BooleanExpression(nsXFormsMDGNode* aNode, PRBool& state)
|
||||||
aNode->mContextSize,
|
aNode->mContextSize,
|
||||||
nsIDOMXPathResult::BOOLEAN_TYPE,
|
nsIDOMXPathResult::BOOLEAN_TYPE,
|
||||||
nsnull,
|
nsnull,
|
||||||
&retval);
|
getter_AddRefs(retval));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMXPathResult> xpath_res = do_QueryInterface(retval);
|
nsCOMPtr<nsIDOMXPathResult> xpath_res = do_QueryInterface(retval);
|
||||||
|
|
|
@ -55,7 +55,9 @@
|
||||||
#include "nsIDOMXMLDocument.h"
|
#include "nsIDOMXMLDocument.h"
|
||||||
#include "nsIDOMEventReceiver.h"
|
#include "nsIDOMEventReceiver.h"
|
||||||
#include "nsIDOMXPathResult.h"
|
#include "nsIDOMXPathResult.h"
|
||||||
#include "nsIXFormsXPathEvaluator.h"
|
#include "nsIDOMXPathEvaluator.h"
|
||||||
|
#include "nsIXPathEvaluatorInternal.h"
|
||||||
|
#include "nsIDOMXPathExpression.h"
|
||||||
#include "nsIDOMXPathNSResolver.h"
|
#include "nsIDOMXPathNSResolver.h"
|
||||||
#include "nsIDOMNSXPathExpression.h"
|
#include "nsIDOMNSXPathExpression.h"
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
|
@ -1983,10 +1985,10 @@ nsXFormsModelElement::ProcessBindElements()
|
||||||
firstInstanceDoc->GetDocumentElement(getter_AddRefs(firstInstanceRoot));
|
firstInstanceDoc->GetDocumentElement(getter_AddRefs(firstInstanceRoot));
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsCOMPtr<nsIXFormsXPathEvaluator> xpath =
|
nsCOMPtr<nsIDOMXPathEvaluator> xpath = do_QueryInterface(firstInstanceDoc,
|
||||||
do_CreateInstance("@mozilla.org/dom/xforms-xpath-evaluator;1", &rv);
|
&rv);
|
||||||
NS_ENSURE_TRUE(xpath, rv);
|
NS_ENSURE_TRUE(rv, rv);
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNodeList> children;
|
nsCOMPtr<nsIDOMNodeList> children;
|
||||||
mElement->GetChildNodes(getter_AddRefs(children));
|
mElement->GetChildNodes(getter_AddRefs(children));
|
||||||
|
|
||||||
|
@ -2266,19 +2268,26 @@ nsXFormsModelElement::MaybeNotifyCompletion()
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
|
nsXFormsModelElement::ProcessBind(nsIDOMXPathEvaluator *aEvaluator,
|
||||||
nsIDOMNode *aContextNode,
|
nsIDOMNode *aContextNode,
|
||||||
PRInt32 aContextPosition,
|
PRInt32 aContextPosition,
|
||||||
PRInt32 aContextSize,
|
PRInt32 aContextSize,
|
||||||
nsIDOMElement *aBindElement,
|
nsIDOMElement *aBindElement,
|
||||||
PRBool aIsOuter)
|
PRBool aIsOuter)
|
||||||
{
|
{
|
||||||
// Get the model item properties specified by this \<bind\>.
|
// Get the model item properties specified by this \<bind\>.
|
||||||
nsCOMPtr<nsIDOMNSXPathExpression> props[eModel__count];
|
nsCOMPtr<nsIDOMXPathExpression> props[eModel__count];
|
||||||
nsAutoString propStrings[eModel__count];
|
nsAutoString propStrings[eModel__count];
|
||||||
nsresult rv;
|
|
||||||
nsAutoString attrStr;
|
nsAutoString attrStr;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMXPathNSResolver> resolver;
|
||||||
|
nsresult rv = aEvaluator->CreateNSResolver(aBindElement,
|
||||||
|
getter_AddRefs(resolver));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIXPathEvaluatorInternal> eval = do_QueryInterface(aEvaluator, &rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
for (PRUint32 i = 0; i < eModel__count; ++i) {
|
for (PRUint32 i = 0; i < eModel__count; ++i) {
|
||||||
sModelPropsList[i]->ToString(attrStr);
|
sModelPropsList[i]->ToString(attrStr);
|
||||||
|
|
||||||
|
@ -2286,8 +2295,9 @@ nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
|
||||||
if (!propStrings[i].IsEmpty() &&
|
if (!propStrings[i].IsEmpty() &&
|
||||||
i != eModel_type &&
|
i != eModel_type &&
|
||||||
i != eModel_p3ptype) {
|
i != eModel_p3ptype) {
|
||||||
rv = aEvaluator->CreateExpression(propStrings[i], aBindElement,
|
rv = nsXFormsUtils::CreateExpression(eval, propStrings[i], resolver,
|
||||||
getter_AddRefs(props[i]));
|
aBindElement,
|
||||||
|
getter_AddRefs(props[i]));
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
const PRUnichar *strings[] = { propStrings[i].get() };
|
const PRUnichar *strings[] = { propStrings[i].get() };
|
||||||
nsXFormsUtils::ReportError(NS_LITERAL_STRING("mipParseError"),
|
nsXFormsUtils::ReportError(NS_LITERAL_STRING("mipParseError"),
|
||||||
|
@ -2301,21 +2311,21 @@ nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
|
||||||
// Find the nodeset that this bind applies to.
|
// Find the nodeset that this bind applies to.
|
||||||
nsCOMPtr<nsIDOMXPathResult> result;
|
nsCOMPtr<nsIDOMXPathResult> result;
|
||||||
|
|
||||||
nsAutoString expr;
|
nsAutoString exprString;
|
||||||
aBindElement->GetAttribute(NS_LITERAL_STRING("nodeset"), expr);
|
aBindElement->GetAttribute(NS_LITERAL_STRING("nodeset"), exprString);
|
||||||
if (expr.IsEmpty()) {
|
if (exprString.IsEmpty()) {
|
||||||
expr = NS_LITERAL_STRING(".");
|
exprString = NS_LITERAL_STRING(".");
|
||||||
}
|
}
|
||||||
rv = aEvaluator->Evaluate(expr, aContextNode, aContextPosition, aContextSize,
|
|
||||||
aBindElement,
|
rv = nsXFormsUtils::EvaluateXPath(eval, exprString, aContextNode, resolver,
|
||||||
nsIDOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE,
|
aBindElement,
|
||||||
nsnull, getter_AddRefs(result));
|
nsIDOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE,
|
||||||
|
aContextPosition, aContextSize,
|
||||||
|
nsnull, getter_AddRefs(result));
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
if (rv == NS_ERROR_DOM_INVALID_EXPRESSION_ERR) {
|
if (rv == NS_ERROR_DOM_INVALID_EXPRESSION_ERR) {
|
||||||
// the xpath expression isn't valid xpath
|
// the xpath expression isn't valid xpath
|
||||||
|
const PRUnichar *strings[] = { exprString.get() };
|
||||||
const nsPromiseFlatString& flat = PromiseFlatString(expr);
|
|
||||||
const PRUnichar *strings[] = { flat.get() };
|
|
||||||
nsXFormsUtils::ReportError(NS_LITERAL_STRING("exprParseError"),
|
nsXFormsUtils::ReportError(NS_LITERAL_STRING("exprParseError"),
|
||||||
strings, 1, aBindElement, nsnull);
|
strings, 1, aBindElement, nsnull);
|
||||||
nsXFormsUtils::DispatchEvent(mElement, eEvent_ComputeException);
|
nsXFormsUtils::DispatchEvent(mElement, eEvent_ComputeException);
|
||||||
|
@ -2323,7 +2333,7 @@ nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("xforms-binding-exception: XPath Evaluation failed\n");
|
printf("xforms-binding-exception: XPath Evaluation failed\n");
|
||||||
#endif
|
#endif
|
||||||
const PRUnichar *strings[] = { expr.get() };
|
const PRUnichar *strings[] = { exprString.get() };
|
||||||
nsXFormsUtils::ReportError(NS_LITERAL_STRING("nodesetEvaluateError"),
|
nsXFormsUtils::ReportError(NS_LITERAL_STRING("nodesetEvaluateError"),
|
||||||
strings, 1, aBindElement, aBindElement);
|
strings, 1, aBindElement, aBindElement);
|
||||||
nsXFormsUtils::DispatchEvent(mElement, eEvent_BindingException);
|
nsXFormsUtils::DispatchEvent(mElement, eEvent_BindingException);
|
||||||
|
@ -2367,7 +2377,7 @@ nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
|
||||||
|
|
||||||
// Apply MIPs
|
// Apply MIPs
|
||||||
nsXFormsXPathParser parser;
|
nsXFormsXPathParser parser;
|
||||||
nsXFormsXPathAnalyzer analyzer(aEvaluator, aBindElement);
|
nsXFormsXPathAnalyzer analyzer(eval, resolver, aBindElement);
|
||||||
PRBool multiMIP = PR_FALSE;
|
PRBool multiMIP = PR_FALSE;
|
||||||
for (PRUint32 j = 0; j < eModel__count; ++j) {
|
for (PRUint32 j = 0; j < eModel__count; ++j) {
|
||||||
if (propStrings[j].IsEmpty())
|
if (propStrings[j].IsEmpty())
|
||||||
|
@ -2402,7 +2412,7 @@ nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// the rest of the MIPs are given to the MDG
|
// the rest of the MIPs are given to the MDG
|
||||||
nsCOMPtr<nsIDOMNSXPathExpression> expr = props[j];
|
nsCOMPtr<nsIDOMNSXPathExpression> expr = do_QueryInterface(props[j]);
|
||||||
|
|
||||||
// Get node dependencies
|
// Get node dependencies
|
||||||
nsAutoPtr<nsXFormsXPathNode> xNode(parser.Parse(propStrings[j]));
|
nsAutoPtr<nsXFormsXPathNode> xNode(parser.Parse(propStrings[j]));
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
|
|
||||||
class nsIDOMElement;
|
class nsIDOMElement;
|
||||||
class nsIDOMNode;
|
class nsIDOMNode;
|
||||||
class nsIXFormsXPathEvaluator;
|
class nsIDOMXPathEvaluator;
|
||||||
class nsIDOMXPathResult;
|
class nsIDOMXPathResult;
|
||||||
class nsXFormsControl;
|
class nsXFormsControl;
|
||||||
class nsXFormsModelInstanceDocuments;
|
class nsXFormsModelInstanceDocuments;
|
||||||
|
@ -310,12 +310,12 @@ private:
|
||||||
NS_HIDDEN_(nsresult) ConstructDone();
|
NS_HIDDEN_(nsresult) ConstructDone();
|
||||||
NS_HIDDEN_(void) MaybeNotifyCompletion();
|
NS_HIDDEN_(void) MaybeNotifyCompletion();
|
||||||
|
|
||||||
NS_HIDDEN_(nsresult) ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
|
NS_HIDDEN_(nsresult) ProcessBind(nsIDOMXPathEvaluator *aEvaluator,
|
||||||
nsIDOMNode *aContextNode,
|
nsIDOMNode *aContextNode,
|
||||||
PRInt32 aContextPosition,
|
PRInt32 aContextPosition,
|
||||||
PRInt32 aContextSize,
|
PRInt32 aContextSize,
|
||||||
nsIDOMElement *aBindElement,
|
nsIDOMElement *aBindElement,
|
||||||
PRBool aIsOuter = PR_FALSE);
|
PRBool aIsOuter = PR_FALSE);
|
||||||
|
|
||||||
NS_HIDDEN_(void) RemoveModelFromDocument();
|
NS_HIDDEN_(void) RemoveModelFromDocument();
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,8 @@
|
||||||
#include "nsXFormsUtils.h"
|
#include "nsXFormsUtils.h"
|
||||||
#include "nsICategoryManager.h"
|
#include "nsICategoryManager.h"
|
||||||
#include "nsIServiceManager.h"
|
#include "nsIServiceManager.h"
|
||||||
|
#include "nsIClassInfoImpl.h"
|
||||||
|
#include "nsXFormsXPathFunctions.h"
|
||||||
|
|
||||||
// bb0d9c8b-3096-4b66-92a0-6c1ddf80e65f
|
// bb0d9c8b-3096-4b66-92a0-6c1ddf80e65f
|
||||||
#define NS_XFORMSUTILITYSERVICE_CID \
|
#define NS_XFORMSUTILITYSERVICE_CID \
|
||||||
|
@ -52,9 +54,15 @@
|
||||||
#define NS_XFORMSUTILITYSERVICE_CONTRACTID \
|
#define NS_XFORMSUTILITYSERVICE_CONTRACTID \
|
||||||
"@mozilla.org/xforms-utility-service;1"
|
"@mozilla.org/xforms-utility-service;1"
|
||||||
|
|
||||||
|
#define XFORMSXPATHFUNCTIONS_CID \
|
||||||
|
{ 0x8edc8cf1, 0x69a3, 0x11d9, { 0x97, 0x91, 0x00, 0x0a, 0x95, 0xdc, 0x23, 0x4c } }
|
||||||
|
#define XFORMSXPATHFUNCTIONS_CONTRACTID \
|
||||||
|
"@mozilla.org/xforms-xpath-functions;1"
|
||||||
|
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXFormsElementFactory)
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXFormsElementFactory)
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXFormsUtilityService)
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXFormsUtilityService)
|
||||||
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXFormsXPathFunctions)
|
||||||
|
NS_DECL_CLASSINFO(nsXFormsXPathFunctions)
|
||||||
|
|
||||||
static NS_IMETHODIMP
|
static NS_IMETHODIMP
|
||||||
RegisterXFormsModule(nsIComponentManager *aCompMgr,
|
RegisterXFormsModule(nsIComponentManager *aCompMgr,
|
||||||
|
@ -132,6 +140,15 @@ static const nsModuleComponentInfo components[] = {
|
||||||
NS_XFORMSUTILITYSERVICE_CID,
|
NS_XFORMSUTILITYSERVICE_CID,
|
||||||
NS_XFORMSUTILITYSERVICE_CONTRACTID,
|
NS_XFORMSUTILITYSERVICE_CONTRACTID,
|
||||||
nsXFormsUtilityServiceConstructor
|
nsXFormsUtilityServiceConstructor
|
||||||
|
},
|
||||||
|
{ "XForms XPath extension functions",
|
||||||
|
XFORMSXPATHFUNCTIONS_CID,
|
||||||
|
XFORMSXPATHFUNCTIONS_CONTRACTID,
|
||||||
|
nsXFormsXPathFunctionsConstructor,
|
||||||
|
nsnull, nsnull, nsnull,
|
||||||
|
NS_CI_INTERFACE_GETTER_NAME(nsXFormsXPathFunctions),
|
||||||
|
nsnull,
|
||||||
|
&NS_CLASSINFO_NAME(nsXFormsXPathFunctions)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -36,389 +36,6 @@
|
||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
#include "nsIServiceManager.h"
|
|
||||||
#include "nsXFormsUtilityService.h"
|
#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"
|
|
||||||
#include "nsIXFormsRepeatElement.h"
|
|
||||||
#include "nsISchemaValidator.h"
|
|
||||||
#include "nsISchemaDuration.h"
|
|
||||||
#include "nsXFormsSchemaValidator.h"
|
|
||||||
#include "prdtoa.h"
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(nsXFormsUtilityService, nsIXFormsUtilityService)
|
NS_IMPL_ISUPPORTS1(nsXFormsUtilityService, nsIXFormsUtilityService)
|
||||||
|
|
||||||
/* I don't know why Doron didn't put this in the .idl so that it could be added
|
|
||||||
* to the generated .h file. Put it here for now
|
|
||||||
*/
|
|
||||||
#define NS_SCHEMAVALIDATOR_CONTRACTID "@mozilla.org/schemavalidator;1"
|
|
||||||
|
|
||||||
|
|
||||||
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<nsIDOMNode> modelNode;
|
|
||||||
|
|
||||||
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<nsIDOMElement> element = do_QueryInterface(aNode);
|
|
||||||
nsCOMPtr<nsIModelElementPrivate> modelPriv = nsXFormsUtils::GetModel(element);
|
|
||||||
modelNode = do_QueryInterface(modelPriv);
|
|
||||||
} 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<nsIDOMNode> instNode;
|
|
||||||
nsresult rv =
|
|
||||||
nsXFormsUtils::GetInstanceNodeForData(aNode, getter_AddRefs(instNode));
|
|
||||||
if (NS_SUCCEEDED(rv) && instNode) {
|
|
||||||
instNode->GetParentNode(getter_AddRefs(modelNode));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modelNode && (modelNode == aModel)) {
|
|
||||||
*aModelAssocWithNode = PR_TRUE;
|
|
||||||
} else {
|
|
||||||
*aModelAssocWithNode = PR_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
|
|
||||||
NS_ASSERTION(aResult, "no return buffer for result so we'll crash soon");
|
|
||||||
*aResult = PR_FALSE;
|
|
||||||
|
|
||||||
nsXFormsSchemaValidator *validator = new nsXFormsSchemaValidator();
|
|
||||||
if (validator) {
|
|
||||||
*aResult = validator->ValidateString(aValue, aType, aNamespace);
|
|
||||||
delete validator;
|
|
||||||
}
|
|
||||||
return *aResult ? NS_OK : NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsXFormsUtilityService::GetRepeatIndex(nsIDOMNode *aRepeat, PRInt32 *aIndex)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(aIndex, "no return buffer for index, we'll crash soon");
|
|
||||||
*aIndex = 0;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIXFormsRepeatElement> repeatEle = do_QueryInterface(aRepeat);
|
|
||||||
if (!repeatEle) {
|
|
||||||
// if aRepeat isn't a repeat element, then setting aIndex to -1 to tell
|
|
||||||
// XPath to return NaN. Per 7.8.5 in the spec (1.0, 2nd edition)
|
|
||||||
*aIndex = -1;
|
|
||||||
} else {
|
|
||||||
PRUint32 retIndex = 0;
|
|
||||||
nsresult rv = repeatEle->GetIndex(&retIndex);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
*aIndex = retIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsXFormsUtilityService::GetMonths(const nsAString & aValue,
|
|
||||||
PRInt32 * aMonths)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(aMonths, "no return buffer for months, we'll crash soon");
|
|
||||||
|
|
||||||
*aMonths = 0;
|
|
||||||
nsCOMPtr<nsISchemaDuration> duration;
|
|
||||||
nsCOMPtr<nsISchemaValidator> schemaValidator =
|
|
||||||
do_CreateInstance(NS_SCHEMAVALIDATOR_CONTRACTID);
|
|
||||||
NS_ENSURE_TRUE(schemaValidator, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
nsresult rv = schemaValidator->ValidateBuiltinTypeDuration(aValue,
|
|
||||||
getter_AddRefs(duration));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
PRInt32 sumMonths;
|
|
||||||
PRUint32 years;
|
|
||||||
PRUint32 months;
|
|
||||||
|
|
||||||
duration->GetYears(&years);
|
|
||||||
duration->GetMonths(&months);
|
|
||||||
|
|
||||||
sumMonths = months + years*12;
|
|
||||||
PRBool negative;
|
|
||||||
duration->GetNegative(&negative);
|
|
||||||
if (negative) {
|
|
||||||
// according to the spec, "the sign of the result will match the sign
|
|
||||||
// of the duration"
|
|
||||||
sumMonths *= -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*aMonths = sumMonths;
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsXFormsUtilityService::GetSeconds(const nsAString & aValue,
|
|
||||||
double * aSeconds)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsISchemaDuration> duration;
|
|
||||||
nsCOMPtr<nsISchemaValidator> schemaValidator =
|
|
||||||
do_CreateInstance(NS_SCHEMAVALIDATOR_CONTRACTID);
|
|
||||||
NS_ENSURE_TRUE(schemaValidator, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
nsresult rv = schemaValidator->ValidateBuiltinTypeDuration(aValue,
|
|
||||||
getter_AddRefs(duration));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
double sumSeconds;
|
|
||||||
PRUint32 days;
|
|
||||||
PRUint32 hours;
|
|
||||||
PRUint32 minutes;
|
|
||||||
PRUint32 seconds;
|
|
||||||
double fractSecs;
|
|
||||||
|
|
||||||
duration->GetDays(&days);
|
|
||||||
duration->GetHours(&hours);
|
|
||||||
duration->GetMinutes(&minutes);
|
|
||||||
duration->GetSeconds(&seconds);
|
|
||||||
duration->GetFractionSeconds(&fractSecs);
|
|
||||||
|
|
||||||
sumSeconds = seconds + minutes*60 + hours*3600 + days*24*3600 + fractSecs;
|
|
||||||
|
|
||||||
PRBool negative;
|
|
||||||
duration->GetNegative(&negative);
|
|
||||||
if (negative) {
|
|
||||||
// according to the spec, "the sign of the result will match the sign
|
|
||||||
// of the duration"
|
|
||||||
sumSeconds *= -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*aSeconds = sumSeconds;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsXFormsUtilityService::GetSecondsFromDateTime(const nsAString & aValue,
|
|
||||||
double * aSeconds)
|
|
||||||
{
|
|
||||||
PRTime dateTime;
|
|
||||||
nsCOMPtr<nsISchemaValidator> schemaValidator =
|
|
||||||
do_CreateInstance(NS_SCHEMAVALIDATOR_CONTRACTID);
|
|
||||||
NS_ENSURE_TRUE(schemaValidator, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
nsresult rv = schemaValidator->ValidateBuiltinTypeDateTime(aValue, &dateTime);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
PRTime secs64 = dateTime, remain64;
|
|
||||||
PRInt64 usecPerSec;
|
|
||||||
PRInt32 secs32, remain32;
|
|
||||||
|
|
||||||
// convert from PRTime (microseconds from epoch) to seconds.
|
|
||||||
LL_I2L(usecPerSec, PR_USEC_PER_SEC);
|
|
||||||
LL_MOD(remain64, secs64, usecPerSec); /* remainder after conversion */
|
|
||||||
LL_DIV(secs64, secs64, usecPerSec); /* Conversion in whole seconds */
|
|
||||||
|
|
||||||
// convert whole seconds and remainder to PRInt32
|
|
||||||
LL_L2I(secs32, secs64);
|
|
||||||
LL_L2I(remain32, remain64);
|
|
||||||
|
|
||||||
// ready the result to send back to transformiix land now in case there are
|
|
||||||
// no fractional seconds or we end up having a problem parsing them out. If
|
|
||||||
// we do, we'll just ignore the fractional seconds.
|
|
||||||
double totalSeconds = secs32;
|
|
||||||
*aSeconds = totalSeconds;
|
|
||||||
|
|
||||||
// We're not getting fractional seconds back in the PRTime we get from
|
|
||||||
// the schemaValidator. We'll have to figure out the fractions from
|
|
||||||
// the original value. Since ValidateBuiltinTypeDateTime returned
|
|
||||||
// successful for us to get this far, we know that the value is in
|
|
||||||
// the proper format.
|
|
||||||
int findFractionalSeconds = aValue.FindChar('.');
|
|
||||||
if (findFractionalSeconds < 0) {
|
|
||||||
// no fractions of seconds, so we are good to go as we are
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
const nsAString& fraction = Substring(aValue, findFractionalSeconds+1,
|
|
||||||
aValue.Length());
|
|
||||||
|
|
||||||
PRBool done = PR_FALSE;
|
|
||||||
PRUnichar currentChar;
|
|
||||||
nsCAutoString fractionResult;
|
|
||||||
nsAString::const_iterator start, end, buffStart;
|
|
||||||
fraction.BeginReading(start);
|
|
||||||
fraction.BeginReading(buffStart);
|
|
||||||
fraction.EndReading(end);
|
|
||||||
|
|
||||||
while ((start != end) && !done) {
|
|
||||||
currentChar = *start++;
|
|
||||||
|
|
||||||
// Time is usually terminated with Z or followed by a time zone
|
|
||||||
// (i.e. -05:00). Time can also be terminated by the end of the string, so
|
|
||||||
// test for that as well. All of this specified at:
|
|
||||||
// http://www.w3.org/TR/xmlschema-2/#dateTime
|
|
||||||
if ((currentChar == 'Z') || (currentChar == '+') || (currentChar == '-') ||
|
|
||||||
(start == end)) {
|
|
||||||
fractionResult.AssignLiteral("0.");
|
|
||||||
AppendUTF16toUTF8(Substring(buffStart.get(), start.get()-1),
|
|
||||||
fractionResult);
|
|
||||||
} else if ((currentChar > '9') || (currentChar < '0')) {
|
|
||||||
// has to be a numerical character or else abort. This should have been
|
|
||||||
// caught by the schemavalidator, but it is worth double checking.
|
|
||||||
done = PR_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fractionResult.IsEmpty()) {
|
|
||||||
// couldn't successfully parse the fractional seconds, so we'll just return
|
|
||||||
// without them.
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert the result string that we have to a double and add it to the total
|
|
||||||
totalSeconds += PR_strtod(fractionResult.get(), nsnull);
|
|
||||||
*aSeconds = totalSeconds;
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsXFormsUtilityService::GetDaysFromDateTime(const nsAString & aValue,
|
|
||||||
PRInt32 * aDays)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(aDays, "no return buffer for days, we'll crash soon");
|
|
||||||
*aDays = 0;
|
|
||||||
|
|
||||||
PRTime date;
|
|
||||||
nsCOMPtr<nsISchemaValidator> schemaValidator =
|
|
||||||
do_CreateInstance(NS_SCHEMAVALIDATOR_CONTRACTID);
|
|
||||||
NS_ENSURE_TRUE(schemaValidator, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
// aValue could be a xsd:date or a xsd:dateTime. If it is a dateTime, we
|
|
||||||
// should ignore the hours, minutes, and seconds according to 7.10.2 in
|
|
||||||
// the spec. So search for such things now. If they are there, strip 'em.
|
|
||||||
int findTime = aValue.FindChar('T');
|
|
||||||
|
|
||||||
nsAutoString dateString;
|
|
||||||
dateString.Assign(aValue);
|
|
||||||
if (findTime >= 0) {
|
|
||||||
dateString.Assign(Substring(dateString, 0, findTime));
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult rv = schemaValidator->ValidateBuiltinTypeDate(dateString, &date);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
PRTime secs64 = date;
|
|
||||||
PRInt64 usecPerSec;
|
|
||||||
PRInt32 secs32;
|
|
||||||
|
|
||||||
// convert from PRTime (microseconds from epoch) to seconds. Shouldn't
|
|
||||||
// have to worry about remainders since input is a date. Smallest value
|
|
||||||
// is in whole days.
|
|
||||||
LL_I2L(usecPerSec, PR_USEC_PER_SEC);
|
|
||||||
LL_DIV(secs64, secs64, usecPerSec);
|
|
||||||
|
|
||||||
// convert whole seconds to PRInt32
|
|
||||||
LL_L2I(secs32, secs64);
|
|
||||||
|
|
||||||
// convert whole seconds to days. 86400 seconds in a day.
|
|
||||||
*aDays = secs32/86400;
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -42,24 +42,4 @@ class nsXFormsUtilityService : public nsIXFormsUtilityService
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
// nsIXFormsUtilityService
|
|
||||||
NS_IMETHOD GetModelFromNode(nsIDOMNode *node, nsIDOMNode **aModel);
|
|
||||||
|
|
||||||
NS_IMETHOD IsNodeAssocWithModel(nsIDOMNode *aNode, nsIDOMNode *aModel,
|
|
||||||
PRBool *aModelAssocWithNode);
|
|
||||||
|
|
||||||
NS_IMETHOD GetInstanceDocumentRoot(const nsAString& aID,
|
|
||||||
nsIDOMNode *aModelNode,
|
|
||||||
nsIDOMNode **aInstanceRoot);
|
|
||||||
|
|
||||||
NS_IMETHOD ValidateString(const nsAString& aValue, const nsAString & aType,
|
|
||||||
const nsAString& aNamespace, PRBool *aResult);
|
|
||||||
|
|
||||||
NS_IMETHOD GetRepeatIndex(nsIDOMNode *aRepeat, PRInt32 *aIndex);
|
|
||||||
NS_IMETHOD GetMonths(const nsAString& aValue, PRInt32 *aMonths);
|
|
||||||
NS_IMETHOD GetSeconds(const nsAString& aValue, double *aSeconds);
|
|
||||||
NS_IMETHOD GetSecondsFromDateTime(const nsAString& aValue, double *aSeconds);
|
|
||||||
NS_IMETHOD GetDaysFromDateTime(const nsAString& aValue, PRInt32 *aDays);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -45,9 +45,11 @@
|
||||||
#include "nsIDocument.h"
|
#include "nsIDocument.h"
|
||||||
#include "nsINameSpaceManager.h"
|
#include "nsINameSpaceManager.h"
|
||||||
#include "nsIDOMNodeList.h"
|
#include "nsIDOMNodeList.h"
|
||||||
#include "nsIXFormsXPathEvaluator.h"
|
#include "nsIDOMXPathEvaluator.h"
|
||||||
|
#include "nsIDOMXPathExpression.h"
|
||||||
#include "nsIDOMXPathResult.h"
|
#include "nsIDOMXPathResult.h"
|
||||||
#include "nsIDOMXPathNSResolver.h"
|
#include "nsIDOMXPathNSResolver.h"
|
||||||
|
#include "nsIXPathEvaluatorInternal.h"
|
||||||
#include "nsIDOMDocument.h"
|
#include "nsIDOMDocument.h"
|
||||||
#include "nsIDOMText.h"
|
#include "nsIDOMText.h"
|
||||||
#include "nsIModelElementPrivate.h"
|
#include "nsIModelElementPrivate.h"
|
||||||
|
@ -79,16 +81,20 @@
|
||||||
#include "nsIScriptSecurityManager.h"
|
#include "nsIScriptSecurityManager.h"
|
||||||
#include "nsIPermissionManager.h"
|
#include "nsIPermissionManager.h"
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "nsIXFormsUtilityService.h"
|
|
||||||
#include "nsIDOMAttr.h"
|
#include "nsIDOMAttr.h"
|
||||||
#include "nsIDOM3Node.h"
|
#include "nsIDOM3Node.h"
|
||||||
#include "nsIConsoleService.h"
|
#include "nsIConsoleService.h"
|
||||||
#include "nsIStringBundle.h"
|
#include "nsIStringBundle.h"
|
||||||
|
#include "nsIXFormsRepeatElement.h"
|
||||||
#include "nsIDOMNSEvent.h"
|
#include "nsIDOMNSEvent.h"
|
||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
#include "nsIPrivateDOMEvent.h"
|
#include "nsIPrivateDOMEvent.h"
|
||||||
#include "nsIDOMNamedNodeMap.h"
|
#include "nsIDOMNamedNodeMap.h"
|
||||||
#include "nsIParserService.h"
|
#include "nsIParserService.h"
|
||||||
|
#include "nsISchemaValidator.h"
|
||||||
|
#include "nsISchemaDuration.h"
|
||||||
|
#include "nsXFormsSchemaValidator.h"
|
||||||
|
#include "prdtoa.h"
|
||||||
|
|
||||||
#include "nsIPrefBranch.h"
|
#include "nsIPrefBranch.h"
|
||||||
#include "nsIPrefService.h"
|
#include "nsIPrefService.h"
|
||||||
|
@ -418,6 +424,26 @@ nsXFormsUtils::GetModel(nsIDOMElement *aElement,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ nsresult
|
||||||
|
nsXFormsUtils::CreateExpression(nsIXPathEvaluatorInternal *aEvaluator,
|
||||||
|
const nsAString &aExpression,
|
||||||
|
nsIDOMXPathNSResolver *aResolver,
|
||||||
|
nsISupports *aState,
|
||||||
|
nsIDOMXPathExpression **aResult)
|
||||||
|
{
|
||||||
|
nsStringArray ns;
|
||||||
|
nsCStringArray contractid;
|
||||||
|
nsCOMArray<nsISupports> state;
|
||||||
|
|
||||||
|
ns.AppendString(EmptyString());
|
||||||
|
contractid.AppendCString(NS_LITERAL_CSTRING("@mozilla.org/xforms-xpath-functions;1"));
|
||||||
|
state.AppendObject(aState);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMXPathExpression> expression;
|
||||||
|
return aEvaluator->CreateExpression(aExpression, aResolver, &ns, &contractid,
|
||||||
|
&state, aResult);
|
||||||
|
}
|
||||||
|
|
||||||
/* static */ nsresult
|
/* static */ nsresult
|
||||||
nsXFormsUtils::EvaluateXPath(const nsAString &aExpression,
|
nsXFormsUtils::EvaluateXPath(const nsAString &aExpression,
|
||||||
nsIDOMNode *aContextNode,
|
nsIDOMNode *aContextNode,
|
||||||
|
@ -432,13 +458,21 @@ nsXFormsUtils::EvaluateXPath(const nsAString &aExpression,
|
||||||
NS_ENSURE_ARG_POINTER(aResult);
|
NS_ENSURE_ARG_POINTER(aResult);
|
||||||
*aResult = nsnull;
|
*aResult = nsnull;
|
||||||
|
|
||||||
nsCOMPtr<nsIXFormsXPathEvaluator> eval =
|
nsCOMPtr<nsIDOMDocument> doc;
|
||||||
do_CreateInstance("@mozilla.org/dom/xforms-xpath-evaluator;1");
|
aContextNode->GetOwnerDocument(getter_AddRefs(doc));
|
||||||
NS_ENSURE_STATE(eval);
|
|
||||||
|
nsCOMPtr<nsIDOMXPathEvaluator> eval = do_QueryInterface(doc);
|
||||||
|
nsCOMPtr<nsIXPathEvaluatorInternal> evalInternal = do_QueryInterface(eval);
|
||||||
|
NS_ENSURE_STATE(eval && evalInternal);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMXPathNSResolver> resolver;
|
||||||
|
nsresult rv = eval->CreateNSResolver(aResolverNode, getter_AddRefs(resolver));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMXPathExpression> expression;
|
||||||
|
rv = CreateExpression(evalInternal, aExpression, resolver, aResolverNode,
|
||||||
|
getter_AddRefs(expression));
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNSXPathExpression> expression;
|
|
||||||
nsresult rv = eval->CreateExpression(aExpression, aResolverNode,
|
|
||||||
getter_AddRefs(expression));
|
|
||||||
PRBool throwException = PR_FALSE;
|
PRBool throwException = PR_FALSE;
|
||||||
if (!expression) {
|
if (!expression) {
|
||||||
const nsPromiseFlatString& flat = PromiseFlatString(aExpression);
|
const nsPromiseFlatString& flat = PromiseFlatString(aExpression);
|
||||||
|
@ -447,13 +481,17 @@ nsXFormsUtils::EvaluateXPath(const nsAString &aExpression,
|
||||||
strings, 1, aContextNode, nsnull);
|
strings, 1, aContextNode, nsnull);
|
||||||
throwException = PR_TRUE;
|
throwException = PR_TRUE;
|
||||||
} else {
|
} else {
|
||||||
|
nsCOMPtr<nsIDOMNSXPathExpression> nsExpr =
|
||||||
|
do_QueryInterface(expression, &rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsCOMPtr<nsISupports> supResult;
|
nsCOMPtr<nsISupports> supResult;
|
||||||
rv = expression->EvaluateWithContext(aContextNode,
|
rv = nsExpr->EvaluateWithContext(aContextNode,
|
||||||
aContextPosition,
|
aContextPosition,
|
||||||
aContextSize,
|
aContextSize,
|
||||||
aResultType,
|
aResultType,
|
||||||
nsnull,
|
nsnull,
|
||||||
getter_AddRefs(supResult));
|
getter_AddRefs(supResult));
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv) && supResult) {
|
if (NS_SUCCEEDED(rv) && supResult) {
|
||||||
/// @todo beaufour: This is somewhat "hackish". Hopefully, this will
|
/// @todo beaufour: This is somewhat "hackish". Hopefully, this will
|
||||||
|
@ -461,11 +499,11 @@ nsXFormsUtils::EvaluateXPath(const nsAString &aExpression,
|
||||||
/// @see http://bugzilla.mozilla.org/show_bug.cgi?id=265212
|
/// @see http://bugzilla.mozilla.org/show_bug.cgi?id=265212
|
||||||
if (aSet) {
|
if (aSet) {
|
||||||
nsXFormsXPathParser parser;
|
nsXFormsXPathParser parser;
|
||||||
nsXFormsXPathAnalyzer analyzer(eval, aResolverNode);
|
nsXFormsXPathAnalyzer analyzer(evalInternal, resolver, aResolverNode);
|
||||||
nsAutoPtr<nsXFormsXPathNode> xNode(parser.Parse(aExpression));
|
nsAutoPtr<nsXFormsXPathNode> xNode(parser.Parse(aExpression));
|
||||||
rv = analyzer.Analyze(aContextNode,
|
rv = analyzer.Analyze(aContextNode,
|
||||||
xNode,
|
xNode,
|
||||||
expression,
|
nsExpr,
|
||||||
&aExpression,
|
&aExpression,
|
||||||
aSet,
|
aSet,
|
||||||
aContextPosition,
|
aContextPosition,
|
||||||
|
@ -481,7 +519,7 @@ nsXFormsUtils::EvaluateXPath(const nsAString &aExpression,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rv == NS_ERROR_XFORMS_CALCUATION_EXCEPTION) {
|
if (rv == NS_ERROR_XFORMS_CALCULATION_EXCEPTION) {
|
||||||
const nsPromiseFlatString& flat = PromiseFlatString(aExpression);
|
const nsPromiseFlatString& flat = PromiseFlatString(aExpression);
|
||||||
const PRUnichar *strings[] = { flat.get() };
|
const PRUnichar *strings[] = { flat.get() };
|
||||||
nsXFormsUtils::ReportError(NS_LITERAL_STRING("exprEvaluateError"),
|
nsXFormsUtils::ReportError(NS_LITERAL_STRING("exprEvaluateError"),
|
||||||
|
@ -493,7 +531,8 @@ nsXFormsUtils::EvaluateXPath(const nsAString &aExpression,
|
||||||
// Throw xforms-compute-exception
|
// Throw xforms-compute-exception
|
||||||
if (throwException) {
|
if (throwException) {
|
||||||
nsCOMPtr<nsIDOMElement> resolverElement = do_QueryInterface(aResolverNode);
|
nsCOMPtr<nsIDOMElement> resolverElement = do_QueryInterface(aResolverNode);
|
||||||
nsCOMPtr<nsIModelElementPrivate> modelPriv = nsXFormsUtils::GetModel(resolverElement);
|
nsCOMPtr<nsIModelElementPrivate> modelPriv =
|
||||||
|
nsXFormsUtils::GetModel(resolverElement);
|
||||||
nsCOMPtr<nsIDOMNode> model = do_QueryInterface(modelPriv);
|
nsCOMPtr<nsIDOMNode> model = do_QueryInterface(modelPriv);
|
||||||
DispatchEvent(model, eEvent_ComputeException, nsnull, resolverElement);
|
DispatchEvent(model, eEvent_ComputeException, nsnull, resolverElement);
|
||||||
}
|
}
|
||||||
|
@ -501,6 +540,36 @@ nsXFormsUtils::EvaluateXPath(const nsAString &aExpression,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ nsresult
|
||||||
|
nsXFormsUtils::EvaluateXPath(nsIXPathEvaluatorInternal *aEvaluator,
|
||||||
|
const nsAString &aExpression,
|
||||||
|
nsIDOMNode *aContextNode,
|
||||||
|
nsIDOMXPathNSResolver *aResolver,
|
||||||
|
nsISupports *aState,
|
||||||
|
PRUint16 aResultType,
|
||||||
|
PRInt32 aContextPosition,
|
||||||
|
PRInt32 aContextSize,
|
||||||
|
nsIDOMXPathResult *aInResult,
|
||||||
|
nsIDOMXPathResult **aResult)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIDOMXPathExpression> expression;
|
||||||
|
nsresult rv = CreateExpression(aEvaluator, aExpression, aResolver, aState,
|
||||||
|
getter_AddRefs(expression));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMNSXPathExpression> nsExpression =
|
||||||
|
do_QueryInterface(expression, &rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsISupports> supResult;
|
||||||
|
rv = nsExpression->EvaluateWithContext(aContextNode, aContextPosition,
|
||||||
|
aContextSize, aResultType,
|
||||||
|
aInResult, getter_AddRefs(supResult));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return CallQueryInterface(supResult, aResult);
|
||||||
|
}
|
||||||
|
|
||||||
/* static */ nsresult
|
/* static */ nsresult
|
||||||
nsXFormsUtils::EvaluateNodeBinding(nsIDOMElement *aElement,
|
nsXFormsUtils::EvaluateNodeBinding(nsIDOMElement *aElement,
|
||||||
PRUint32 aElementFlags,
|
PRUint32 aElementFlags,
|
||||||
|
@ -2233,3 +2302,326 @@ nsXFormsUtils::GetWindowFromDocument(nsIDOMDocument *aDoc,
|
||||||
NS_ADDREF(*aWindow = internal);
|
NS_ADDREF(*aWindow = internal);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ nsresult
|
||||||
|
nsXFormsUtils::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* static */ PRBool
|
||||||
|
nsXFormsUtils::IsNodeAssocWithModel(nsIDOMNode *aNode, nsIDOMNode *aModel)
|
||||||
|
{
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMNode> modelNode;
|
||||||
|
|
||||||
|
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<nsIDOMElement> element = do_QueryInterface(aNode);
|
||||||
|
nsCOMPtr<nsIModelElementPrivate> modelPriv = GetModel(element);
|
||||||
|
modelNode = do_QueryInterface(modelPriv);
|
||||||
|
} 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<nsIDOMNode> instNode;
|
||||||
|
nsresult rv =
|
||||||
|
nsXFormsUtils::GetInstanceNodeForData(aNode, getter_AddRefs(instNode));
|
||||||
|
if (NS_SUCCEEDED(rv) && instNode) {
|
||||||
|
instNode->GetParentNode(getter_AddRefs(modelNode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return modelNode && (modelNode == aModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ nsresult
|
||||||
|
nsXFormsUtils::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);
|
||||||
|
|
||||||
|
NS_IF_ADDREF(*aInstanceRoot = element);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ PRBool
|
||||||
|
nsXFormsUtils::ValidateString(const nsAString &aValue, const nsAString & aType,
|
||||||
|
const nsAString & aNamespace)
|
||||||
|
{
|
||||||
|
nsXFormsSchemaValidator validator;
|
||||||
|
|
||||||
|
return validator.ValidateString(aValue, aType, aNamespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ nsresult
|
||||||
|
nsXFormsUtils::GetRepeatIndex(nsIDOMNode *aRepeat, PRInt32 *aIndex)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(aIndex, "no return buffer for index, we'll crash soon");
|
||||||
|
*aIndex = 0;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIXFormsRepeatElement> repeatEle = do_QueryInterface(aRepeat);
|
||||||
|
if (!repeatEle) {
|
||||||
|
// if aRepeat isn't a repeat element, then setting aIndex to -1 to tell
|
||||||
|
// XPath to return NaN. Per 7.8.5 in the spec (1.0, 2nd edition)
|
||||||
|
*aIndex = -1;
|
||||||
|
} else {
|
||||||
|
PRUint32 retIndex = 0;
|
||||||
|
nsresult rv = repeatEle->GetIndex(&retIndex);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
*aIndex = retIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ nsresult
|
||||||
|
nsXFormsUtils::GetMonths(const nsAString & aValue, PRInt32 * aMonths)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(aMonths, "no return buffer for months, we'll crash soon");
|
||||||
|
|
||||||
|
*aMonths = 0;
|
||||||
|
nsCOMPtr<nsISchemaDuration> duration;
|
||||||
|
nsCOMPtr<nsISchemaValidator> schemaValidator =
|
||||||
|
do_CreateInstance("@mozilla.org/schemavalidator;1");
|
||||||
|
NS_ENSURE_TRUE(schemaValidator, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsresult rv = schemaValidator->ValidateBuiltinTypeDuration(aValue,
|
||||||
|
getter_AddRefs(duration));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
PRInt32 sumMonths;
|
||||||
|
PRUint32 years;
|
||||||
|
PRUint32 months;
|
||||||
|
|
||||||
|
duration->GetYears(&years);
|
||||||
|
duration->GetMonths(&months);
|
||||||
|
|
||||||
|
sumMonths = months + years*12;
|
||||||
|
PRBool negative;
|
||||||
|
duration->GetNegative(&negative);
|
||||||
|
if (negative) {
|
||||||
|
// according to the spec, "the sign of the result will match the sign
|
||||||
|
// of the duration"
|
||||||
|
sumMonths *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aMonths = sumMonths;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ nsresult
|
||||||
|
nsXFormsUtils::GetSeconds(const nsAString & aValue, double * aSeconds)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsISchemaDuration> duration;
|
||||||
|
nsCOMPtr<nsISchemaValidator> schemaValidator =
|
||||||
|
do_CreateInstance("@mozilla.org/schemavalidator;1");
|
||||||
|
NS_ENSURE_TRUE(schemaValidator, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsresult rv = schemaValidator->ValidateBuiltinTypeDuration(aValue,
|
||||||
|
getter_AddRefs(duration));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
double sumSeconds;
|
||||||
|
PRUint32 days;
|
||||||
|
PRUint32 hours;
|
||||||
|
PRUint32 minutes;
|
||||||
|
PRUint32 seconds;
|
||||||
|
double fractSecs;
|
||||||
|
|
||||||
|
duration->GetDays(&days);
|
||||||
|
duration->GetHours(&hours);
|
||||||
|
duration->GetMinutes(&minutes);
|
||||||
|
duration->GetSeconds(&seconds);
|
||||||
|
duration->GetFractionSeconds(&fractSecs);
|
||||||
|
|
||||||
|
sumSeconds = seconds + minutes*60 + hours*3600 + days*24*3600 + fractSecs;
|
||||||
|
|
||||||
|
PRBool negative;
|
||||||
|
duration->GetNegative(&negative);
|
||||||
|
if (negative) {
|
||||||
|
// according to the spec, "the sign of the result will match the sign
|
||||||
|
// of the duration"
|
||||||
|
sumSeconds *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aSeconds = sumSeconds;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ nsresult
|
||||||
|
nsXFormsUtils::GetSecondsFromDateTime(const nsAString & aValue,
|
||||||
|
double * aSeconds)
|
||||||
|
{
|
||||||
|
PRTime dateTime;
|
||||||
|
nsCOMPtr<nsISchemaValidator> schemaValidator =
|
||||||
|
do_CreateInstance("@mozilla.org/schemavalidator;1");
|
||||||
|
NS_ENSURE_TRUE(schemaValidator, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsresult rv = schemaValidator->ValidateBuiltinTypeDateTime(aValue, &dateTime);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
PRTime secs64 = dateTime, remain64;
|
||||||
|
PRInt64 usecPerSec;
|
||||||
|
PRInt32 secs32, remain32;
|
||||||
|
|
||||||
|
// convert from PRTime (microseconds from epoch) to seconds.
|
||||||
|
LL_I2L(usecPerSec, PR_USEC_PER_SEC);
|
||||||
|
LL_MOD(remain64, secs64, usecPerSec); /* remainder after conversion */
|
||||||
|
LL_DIV(secs64, secs64, usecPerSec); /* Conversion in whole seconds */
|
||||||
|
|
||||||
|
// convert whole seconds and remainder to PRInt32
|
||||||
|
LL_L2I(secs32, secs64);
|
||||||
|
LL_L2I(remain32, remain64);
|
||||||
|
|
||||||
|
// ready the result to send back to transformiix land now in case there are
|
||||||
|
// no fractional seconds or we end up having a problem parsing them out. If
|
||||||
|
// we do, we'll just ignore the fractional seconds.
|
||||||
|
double totalSeconds = secs32;
|
||||||
|
*aSeconds = totalSeconds;
|
||||||
|
|
||||||
|
// We're not getting fractional seconds back in the PRTime we get from
|
||||||
|
// the schemaValidator. We'll have to figure out the fractions from
|
||||||
|
// the original value. Since ValidateBuiltinTypeDateTime returned
|
||||||
|
// successful for us to get this far, we know that the value is in
|
||||||
|
// the proper format.
|
||||||
|
int findFractionalSeconds = aValue.FindChar('.');
|
||||||
|
if (findFractionalSeconds < 0) {
|
||||||
|
// no fractions of seconds, so we are good to go as we are
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nsAString& fraction = Substring(aValue, findFractionalSeconds+1,
|
||||||
|
aValue.Length());
|
||||||
|
|
||||||
|
PRBool done = PR_FALSE;
|
||||||
|
PRUnichar currentChar;
|
||||||
|
nsCAutoString fractionResult;
|
||||||
|
nsAString::const_iterator start, end, buffStart;
|
||||||
|
fraction.BeginReading(start);
|
||||||
|
fraction.BeginReading(buffStart);
|
||||||
|
fraction.EndReading(end);
|
||||||
|
|
||||||
|
while ((start != end) && !done) {
|
||||||
|
currentChar = *start++;
|
||||||
|
|
||||||
|
// Time is usually terminated with Z or followed by a time zone
|
||||||
|
// (i.e. -05:00). Time can also be terminated by the end of the string, so
|
||||||
|
// test for that as well. All of this specified at:
|
||||||
|
// http://www.w3.org/TR/xmlschema-2/#dateTime
|
||||||
|
if ((currentChar == 'Z') || (currentChar == '+') || (currentChar == '-') ||
|
||||||
|
(start == end)) {
|
||||||
|
fractionResult.AssignLiteral("0.");
|
||||||
|
AppendUTF16toUTF8(Substring(buffStart.get(), start.get()-1),
|
||||||
|
fractionResult);
|
||||||
|
} else if ((currentChar > '9') || (currentChar < '0')) {
|
||||||
|
// has to be a numerical character or else abort. This should have been
|
||||||
|
// caught by the schemavalidator, but it is worth double checking.
|
||||||
|
done = PR_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fractionResult.IsEmpty()) {
|
||||||
|
// couldn't successfully parse the fractional seconds, so we'll just return
|
||||||
|
// without them.
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert the result string that we have to a double and add it to the total
|
||||||
|
totalSeconds += PR_strtod(fractionResult.get(), nsnull);
|
||||||
|
*aSeconds = totalSeconds;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ nsresult
|
||||||
|
nsXFormsUtils::GetDaysFromDateTime(const nsAString & aValue, PRInt32 * aDays)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(aDays, "no return buffer for days, we'll crash soon");
|
||||||
|
*aDays = 0;
|
||||||
|
|
||||||
|
PRTime date;
|
||||||
|
nsCOMPtr<nsISchemaValidator> schemaValidator =
|
||||||
|
do_CreateInstance("@mozilla.org/schemavalidator;1");
|
||||||
|
NS_ENSURE_TRUE(schemaValidator, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
// aValue could be a xsd:date or a xsd:dateTime. If it is a dateTime, we
|
||||||
|
// should ignore the hours, minutes, and seconds according to 7.10.2 in
|
||||||
|
// the spec. So search for such things now. If they are there, strip 'em.
|
||||||
|
PRInt32 findTime = aValue.FindChar('T');
|
||||||
|
|
||||||
|
nsAutoString dateString;
|
||||||
|
dateString.Assign(aValue);
|
||||||
|
if (findTime >= 0) {
|
||||||
|
dateString.Assign(Substring(dateString, 0, findTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = schemaValidator->ValidateBuiltinTypeDate(dateString, &date);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
PRTime secs64 = date;
|
||||||
|
PRInt64 usecPerSec;
|
||||||
|
PRInt32 secs32;
|
||||||
|
|
||||||
|
// convert from PRTime (microseconds from epoch) to seconds. Shouldn't
|
||||||
|
// have to worry about remainders since input is a date. Smallest value
|
||||||
|
// is in whole days.
|
||||||
|
LL_I2L(usecPerSec, PR_USEC_PER_SEC);
|
||||||
|
LL_DIV(secs64, secs64, usecPerSec);
|
||||||
|
|
||||||
|
// convert whole seconds to PRInt32
|
||||||
|
LL_L2I(secs32, secs64);
|
||||||
|
|
||||||
|
// convert whole seconds to days. 86400 seconds in a day.
|
||||||
|
*aDays = secs32/86400;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -57,6 +57,10 @@ class nsIURI;
|
||||||
class nsString;
|
class nsString;
|
||||||
class nsIMutableArray;
|
class nsIMutableArray;
|
||||||
class nsIDOMEvent;
|
class nsIDOMEvent;
|
||||||
|
class nsIDOMXPathEvaluator;
|
||||||
|
class nsIDOMXPathExpression;
|
||||||
|
class nsIDOMXPathNSResolver;
|
||||||
|
class nsIXPathEvaluatorInternal;
|
||||||
|
|
||||||
#define NS_NAMESPACE_XFORMS "http://www.w3.org/2002/xforms"
|
#define NS_NAMESPACE_XFORMS "http://www.w3.org/2002/xforms"
|
||||||
#define NS_NAMESPACE_XHTML "http://www.w3.org/1999/xhtml"
|
#define NS_NAMESPACE_XHTML "http://www.w3.org/1999/xhtml"
|
||||||
|
@ -66,6 +70,9 @@ class nsIDOMEvent;
|
||||||
#define NS_NAMESPACE_SOAP_ENVELOPE "http://schemas.xmlsoap.org/soap/envelope/"
|
#define NS_NAMESPACE_SOAP_ENVELOPE "http://schemas.xmlsoap.org/soap/envelope/"
|
||||||
#define NS_NAMESPACE_MOZ_XFORMS_LAZY "http://www.mozilla.org/projects/xforms/2005/lazy"
|
#define NS_NAMESPACE_MOZ_XFORMS_LAZY "http://www.mozilla.org/projects/xforms/2005/lazy"
|
||||||
|
|
||||||
|
#define NS_ERROR_XFORMS_CALCULATION_EXCEPTION \
|
||||||
|
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GENERAL, 3001)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error codes
|
* Error codes
|
||||||
*/
|
*/
|
||||||
|
@ -236,7 +243,7 @@ public:
|
||||||
* and returned (addrefed) in |aModel|
|
* and returned (addrefed) in |aModel|
|
||||||
*
|
*
|
||||||
* The return value is an XPathResult as returned from
|
* The return value is an XPathResult as returned from
|
||||||
* nsIXFormsXPathEvaluator::Evaluate().
|
* nsIDOMXPathEvaluator::Evaluate().
|
||||||
*/
|
*/
|
||||||
static NS_HIDDEN_(nsresult)
|
static NS_HIDDEN_(nsresult)
|
||||||
EvaluateNodeBinding(nsIDOMElement *aElement,
|
EvaluateNodeBinding(nsIDOMElement *aElement,
|
||||||
|
@ -251,10 +258,17 @@ public:
|
||||||
nsCOMArray<nsIDOMNode> *aDeps = nsnull,
|
nsCOMArray<nsIDOMNode> *aDeps = nsnull,
|
||||||
nsStringArray *aIndexesUsed = nsnull);
|
nsStringArray *aIndexesUsed = nsnull);
|
||||||
|
|
||||||
|
static NS_HIDDEN_(nsresult)
|
||||||
|
CreateExpression(nsIXPathEvaluatorInternal *aEvaluator,
|
||||||
|
const nsAString &aExpression,
|
||||||
|
nsIDOMXPathNSResolver *aResolver,
|
||||||
|
nsISupports *aState,
|
||||||
|
nsIDOMXPathExpression **aResult);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method for doing XPath evaluations. This gets a
|
* Convenience method for doing XPath evaluations. This gets a
|
||||||
* nsIXFormsXPathEvaluator from |aContextNode|'s ownerDocument, and calls
|
* nsIDOMXPathEvaluator from |aContextNode|'s ownerDocument, and calls
|
||||||
* nsIXFormsXPathEvaluator::Evalute using the given expression, context node,
|
* nsIDOMXPathEvaluator::Evaluate using the given expression, context node,
|
||||||
* namespace resolver, and result type.
|
* namespace resolver, and result type.
|
||||||
*/
|
*/
|
||||||
static NS_HIDDEN_(nsresult)
|
static NS_HIDDEN_(nsresult)
|
||||||
|
@ -268,6 +282,18 @@ public:
|
||||||
nsCOMArray<nsIDOMNode> *aSet = nsnull,
|
nsCOMArray<nsIDOMNode> *aSet = nsnull,
|
||||||
nsStringArray *aIndexesUsed = nsnull);
|
nsStringArray *aIndexesUsed = nsnull);
|
||||||
|
|
||||||
|
static NS_HIDDEN_(nsresult)
|
||||||
|
EvaluateXPath(nsIXPathEvaluatorInternal *aEvaluator,
|
||||||
|
const nsAString &aExpression,
|
||||||
|
nsIDOMNode *aContextNode,
|
||||||
|
nsIDOMXPathNSResolver *aResolver,
|
||||||
|
nsISupports *aState,
|
||||||
|
PRUint16 aResultType,
|
||||||
|
PRInt32 aContextPosition,
|
||||||
|
PRInt32 aContextSize,
|
||||||
|
nsIDOMXPathResult *aInResult,
|
||||||
|
nsIDOMXPathResult **aResult);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a node in the instance data, get its string value according
|
* Given a node in the instance data, get its string value according
|
||||||
* to section 8.1.1 of the XForms specification.
|
* to section 8.1.1 of the XForms specification.
|
||||||
|
@ -552,6 +578,63 @@ public:
|
||||||
static NS_HIDDEN_(nsresult) GetWindowFromDocument(nsIDOMDocument *aDoc,
|
static NS_HIDDEN_(nsresult) GetWindowFromDocument(nsIDOMDocument *aDoc,
|
||||||
nsIDOMWindowInternal **aWindow);
|
nsIDOMWindowInternal **aWindow);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to get the corresponding model element from a xforms node or
|
||||||
|
* a xforms instance data node.
|
||||||
|
*/
|
||||||
|
static NS_HIDDEN_(nsresult) GetModelFromNode(nsIDOMNode *aNode,
|
||||||
|
nsIDOMNode **aResult);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
static NS_HIDDEN_(PRBool) IsNodeAssocWithModel(nsIDOMNode *aNode,
|
||||||
|
nsIDOMNode *aModel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
static NS_HIDDEN_(nsresult) GetInstanceDocumentRoot(const nsAString &aID,
|
||||||
|
nsIDOMNode *aModelNode,
|
||||||
|
nsIDOMNode **aResult);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to ensure that aValue is of the schema type aType. Will basically
|
||||||
|
* be a forwarder to the nsISchemaValidator function of the same name.
|
||||||
|
*/
|
||||||
|
static NS_HIDDEN_(PRBool) ValidateString(const nsAString &aValue,
|
||||||
|
const nsAString & aType,
|
||||||
|
const nsAString & aNamespace);
|
||||||
|
|
||||||
|
static NS_HIDDEN_(nsresult) GetRepeatIndex(nsIDOMNode *aRepeat,
|
||||||
|
PRInt32 *aIndex);
|
||||||
|
|
||||||
|
static NS_HIDDEN_(nsresult) GetMonths(const nsAString & aValue,
|
||||||
|
PRInt32 * aMonths);
|
||||||
|
|
||||||
|
static NS_HIDDEN_(nsresult) GetSeconds(const nsAString & aValue,
|
||||||
|
double * aSeconds);
|
||||||
|
|
||||||
|
static NS_HIDDEN_(nsresult) GetSecondsFromDateTime(const nsAString & aValue,
|
||||||
|
double * aSeconds);
|
||||||
|
|
||||||
|
static NS_HIDDEN_(nsresult) GetDaysFromDateTime(const nsAString & aValue,
|
||||||
|
PRInt32 * aDays);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Do same origin checks on aBaseDocument and aTestURI. Hosts can be
|
* Do same origin checks on aBaseDocument and aTestURI. Hosts can be
|
||||||
|
|
|
@ -45,9 +45,12 @@
|
||||||
//#define DEBUG_XF_ANALYZER
|
//#define DEBUG_XF_ANALYZER
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsXFormsXPathAnalyzer::nsXFormsXPathAnalyzer(nsIXFormsXPathEvaluator *aEvaluator,
|
nsXFormsXPathAnalyzer::nsXFormsXPathAnalyzer(nsIXPathEvaluatorInternal *aEvaluator,
|
||||||
nsIDOMNode *aResolver)
|
nsIDOMXPathNSResolver *aResolver,
|
||||||
: mEvaluator(aEvaluator), mResolver(aResolver)
|
nsISupports *aState)
|
||||||
|
: mEvaluator(aEvaluator),
|
||||||
|
mResolver(aResolver),
|
||||||
|
mState(aState)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(nsXFormsXPathAnalyzer);
|
MOZ_COUNT_CTOR(nsXFormsXPathAnalyzer);
|
||||||
}
|
}
|
||||||
|
@ -174,9 +177,10 @@ nsXFormsXPathAnalyzer::AnalyzeRecursively(nsIDOMNode *aContextNode,
|
||||||
xp = Substring(*mCurExprString, aNode->mStartIndex,
|
xp = Substring(*mCurExprString, aNode->mStartIndex,
|
||||||
aNode->mEndIndex - aNode->mStartIndex);
|
aNode->mEndIndex - aNode->mStartIndex);
|
||||||
}
|
}
|
||||||
rv = mEvaluator->Evaluate(xp, aContextNode, mCurPosition, mCurSize,
|
rv = nsXFormsUtils::EvaluateXPath(mEvaluator, xp, aContextNode, mResolver,
|
||||||
mResolver, nsIDOMXPathResult::ANY_TYPE,
|
mState, nsIDOMXPathResult::ANY_TYPE,
|
||||||
nsnull, getter_AddRefs(result));
|
mCurPosition, mCurSize, nsnull,
|
||||||
|
getter_AddRefs(result));
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
const PRUnichar *strings[] = { xp.get() };
|
const PRUnichar *strings[] = { xp.get() };
|
||||||
nsXFormsUtils::ReportError(NS_LITERAL_STRING("exprEvaluateError"),
|
nsXFormsUtils::ReportError(NS_LITERAL_STRING("exprEvaluateError"),
|
||||||
|
@ -194,10 +198,13 @@ nsXFormsXPathAnalyzer::AnalyzeRecursively(nsIDOMNode *aContextNode,
|
||||||
nsDependentSubstring indexExpr = Substring(xp,
|
nsDependentSubstring indexExpr = Substring(xp,
|
||||||
indexSize,
|
indexSize,
|
||||||
xp.Length() - indexSize - 1); // remove final ')' too
|
xp.Length() - indexSize - 1); // remove final ')' too
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMXPathResult> stringRes;
|
nsCOMPtr<nsIDOMXPathResult> stringRes;
|
||||||
rv = mEvaluator->Evaluate(indexExpr, aContextNode, mCurPosition, mCurSize,
|
rv = nsXFormsUtils::EvaluateXPath(mEvaluator, indexExpr, aContextNode,
|
||||||
mResolver, nsIDOMXPathResult::STRING_TYPE,
|
mResolver, mState,
|
||||||
nsnull, getter_AddRefs(stringRes));
|
nsIDOMXPathResult::STRING_TYPE,
|
||||||
|
mCurPosition, mCurSize, nsnull,
|
||||||
|
getter_AddRefs(stringRes));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsAutoString indexId;
|
nsAutoString indexId;
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
#include "nsCOMArray.h"
|
#include "nsCOMArray.h"
|
||||||
#include "nsXFormsXPathNode.h"
|
#include "nsXFormsXPathNode.h"
|
||||||
#include "nsIDOMNSXPathExpression.h"
|
#include "nsIDOMNSXPathExpression.h"
|
||||||
#include "nsIXFormsXPathEvaluator.h"
|
#include "nsIXPathEvaluatorInternal.h"
|
||||||
#include "nsIDOMXPathNSResolver.h"
|
#include "nsIDOMXPathNSResolver.h"
|
||||||
#include "nsIDOMNode.h"
|
#include "nsIDOMNode.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
|
@ -58,8 +58,9 @@
|
||||||
*/
|
*/
|
||||||
class nsXFormsXPathAnalyzer {
|
class nsXFormsXPathAnalyzer {
|
||||||
private:
|
private:
|
||||||
nsCOMPtr<nsIXFormsXPathEvaluator> mEvaluator;
|
nsCOMPtr<nsIXPathEvaluatorInternal> mEvaluator;
|
||||||
nsCOMPtr<nsIDOMNode> mResolver;
|
nsCOMPtr<nsIDOMXPathNSResolver> mResolver;
|
||||||
|
nsCOMPtr<nsISupports> mState;
|
||||||
|
|
||||||
nsCOMArray<nsIDOMNode> *mCurSet;
|
nsCOMArray<nsIDOMNode> *mCurSet;
|
||||||
nsCOMPtr<nsIDOMNSXPathExpression> mCurExpression;
|
nsCOMPtr<nsIDOMNSXPathExpression> mCurExpression;
|
||||||
|
@ -74,8 +75,9 @@ private:
|
||||||
PRBool aCollect = PR_FALSE);
|
PRBool aCollect = PR_FALSE);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
nsXFormsXPathAnalyzer(nsIXFormsXPathEvaluator *aEvaluator,
|
nsXFormsXPathAnalyzer(nsIXPathEvaluatorInternal *aEvaluator,
|
||||||
nsIDOMNode *aResolver);
|
nsIDOMXPathNSResolver *aResolver,
|
||||||
|
nsISupports *aState);
|
||||||
~nsXFormsXPathAnalyzer();
|
~nsXFormsXPathAnalyzer();
|
||||||
|
|
||||||
nsresult Analyze(nsIDOMNode *aContextNode,
|
nsresult Analyze(nsIDOMNode *aContextNode,
|
||||||
|
|
|
@ -0,0 +1,426 @@
|
||||||
|
/* -*- 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 "nsXFormsXPathFunctions.h"
|
||||||
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsComponentManagerUtils.h"
|
||||||
|
#include "nsIDOMDocument.h"
|
||||||
|
#include "nsIDOMElement.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
#include "nsXFormsUtils.h"
|
||||||
|
#include "prprf.h"
|
||||||
|
#include "txDouble.h"
|
||||||
|
#include "txIFunctionEvaluationContext.h"
|
||||||
|
#include "txINodeSet.h"
|
||||||
|
#include "nsIClassInfoImpl.h"
|
||||||
|
|
||||||
|
#define NS_NAMESPACE_XFORMS "http://www.w3.org/2002/xforms"
|
||||||
|
|
||||||
|
static const PRUint32 nanMask[2] = TX_DOUBLE_NaN;
|
||||||
|
#define kNaN *((double*)nanMask)
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1_CI(nsXFormsXPathFunctions, nsIXFormsXPathFunctions)
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXFormsXPathFunctions::Avg(txINodeSet *aNodeSet, double *aResult)
|
||||||
|
{
|
||||||
|
PRUint32 length;
|
||||||
|
nsresult rv = aNodeSet->GetLength(&length);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
double total = 0;
|
||||||
|
PRUint32 i;
|
||||||
|
for (i = 0; i < length; ++i) {
|
||||||
|
double item;
|
||||||
|
rv = aNodeSet->ItemAsNumber(i, &item);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (TX_DOUBLE_IS_NaN(item)) {
|
||||||
|
// This will make aResult be set to kNaN below.
|
||||||
|
i = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
total += item;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aResult = (i > 0) ? (total / i) : kNaN;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXFormsXPathFunctions::BooleanFromString(const nsAString & aString,
|
||||||
|
PRBool *aResult)
|
||||||
|
{
|
||||||
|
*aResult = aString.EqualsLiteral("1") ||
|
||||||
|
aString.LowerCaseEqualsLiteral("true");
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXFormsXPathFunctions::CountNonEmpty(txINodeSet *aNodeSet, double *aResult)
|
||||||
|
{
|
||||||
|
PRUint32 length;
|
||||||
|
nsresult rv = aNodeSet->GetLength(&length);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
double result = 0;
|
||||||
|
PRUint32 i;
|
||||||
|
for (i = 0; i < length; ++i) {
|
||||||
|
nsAutoString item;
|
||||||
|
rv = aNodeSet->ItemAsString(i, item);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (!item.IsEmpty()) {
|
||||||
|
++result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*aResult = result;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXFormsXPathFunctions::DaysFromDate(const nsAString &aDateTime,
|
||||||
|
double *aResult)
|
||||||
|
{
|
||||||
|
PRInt32 result = 0;
|
||||||
|
nsresult rv = nsXFormsUtils::GetDaysFromDateTime(aDateTime, &result);
|
||||||
|
if (rv == NS_ERROR_ILLEGAL_VALUE) {
|
||||||
|
*aResult = kNaN;
|
||||||
|
rv = NS_OK;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*aResult = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXFormsXPathFunctions::If(PRBool aValue, const nsAString &aIfString,
|
||||||
|
const nsAString &aElseString, nsAString &aResult)
|
||||||
|
{
|
||||||
|
// XXX Avoid evaluating aIfString and aElseString until after checking
|
||||||
|
// aValue. Probably needs vararg support.
|
||||||
|
aResult = aValue ? aIfString : aElseString;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXFormsXPathFunctions::Index(txIFunctionEvaluationContext *aContext,
|
||||||
|
const nsAString &aID, double *aResult)
|
||||||
|
{
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
nsCOMPtr<nsISupports> state;
|
||||||
|
aContext->GetState(getter_AddRefs(state));
|
||||||
|
nsCOMPtr<nsIDOMNode> resolverNode = do_QueryInterface(state);
|
||||||
|
NS_ENSURE_TRUE(resolverNode, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
// here document is the XForms document
|
||||||
|
nsCOMPtr<nsIDOMDocument> document;
|
||||||
|
resolverNode->GetOwnerDocument(getter_AddRefs(document));
|
||||||
|
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
// aID should be the id of a nsIXFormsRepeatElement
|
||||||
|
nsCOMPtr<nsIDOMElement> repeatEle;
|
||||||
|
nsresult rv = document->GetElementById(aID, getter_AddRefs(repeatEle));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// now get the index value from the xforms:repeat.
|
||||||
|
PRInt32 index;
|
||||||
|
rv = nsXFormsUtils::GetRepeatIndex(repeatEle, &index);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// repeat's index is 1-based. If it is 0, then that is still ok since
|
||||||
|
// repeat's index can be 0 if uninitialized or if the nodeset that it
|
||||||
|
// is bound to is empty (either initially or due to delete remove all
|
||||||
|
// of the instance nodes). If index == -1, then repeatEle isn't an
|
||||||
|
// XForms repeat element, so we need to return NaN per spec.
|
||||||
|
*aResult = index >= 0 ? index : kNaN;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXFormsXPathFunctions::Instance(txIFunctionEvaluationContext *aContext,
|
||||||
|
const nsAString &aInstanceId,
|
||||||
|
txINodeSet **aResult)
|
||||||
|
{
|
||||||
|
*aResult = nsnull;
|
||||||
|
|
||||||
|
// The state is the node in the XForms document that contained
|
||||||
|
// the expression we are evaluating. We'll use this to get the
|
||||||
|
// document. If this isn't here, then something is wrong. Bail.
|
||||||
|
nsCOMPtr<nsISupports> state;
|
||||||
|
aContext->GetState(getter_AddRefs(state));
|
||||||
|
nsCOMPtr<nsIDOMNode> resolverNode = do_QueryInterface(state);
|
||||||
|
NS_ENSURE_TRUE(resolverNode, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
// here document is the XForms document
|
||||||
|
nsCOMPtr<nsIDOMDocument> document;
|
||||||
|
resolverNode->GetOwnerDocument(getter_AddRefs(document));
|
||||||
|
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMElement> instEle;
|
||||||
|
nsresult rv = document->GetElementById(aInstanceId,
|
||||||
|
getter_AddRefs(instEle));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
PRBool foundInstance = PR_FALSE;
|
||||||
|
if (instEle) {
|
||||||
|
nsAutoString localname, namespaceURI;
|
||||||
|
instEle->GetLocalName(localname);
|
||||||
|
instEle->GetNamespaceURI(namespaceURI);
|
||||||
|
|
||||||
|
foundInstance = localname.EqualsLiteral("instance") &&
|
||||||
|
namespaceURI.EqualsLiteral(NS_NAMESPACE_XFORMS);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<txINodeSet> result =
|
||||||
|
do_CreateInstance("@mozilla.org/transformiix-nodeset;1", &rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (!foundInstance) {
|
||||||
|
// We didn't find an instance element with the given id. Return the
|
||||||
|
// empty result set.
|
||||||
|
result.swap(*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 = 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<nsIDOMNode> instNode, modelInstance;
|
||||||
|
instNode = do_QueryInterface(instEle);
|
||||||
|
rv = nsXFormsUtils::GetModelFromNode(instNode,
|
||||||
|
getter_AddRefs(modelInstance));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
PRBool modelContainsNode =
|
||||||
|
nsXFormsUtils::IsNodeAssocWithModel(xfContextNode, modelInstance);
|
||||||
|
|
||||||
|
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> root;
|
||||||
|
rv = nsXFormsUtils::GetInstanceDocumentRoot(aInstanceId,
|
||||||
|
modelInstance,
|
||||||
|
getter_AddRefs(root));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (root) {
|
||||||
|
result->Add(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.swap(*aResult);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX where we need to do the work
|
||||||
|
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXFormsXPathFunctions::Max(txINodeSet *aNodeSet, double *aResult)
|
||||||
|
{
|
||||||
|
PRUint32 length;
|
||||||
|
nsresult rv = aNodeSet->GetLength(&length);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
double result = kNaN;
|
||||||
|
PRUint32 i;
|
||||||
|
for (i = 0; i < length; ++i) {
|
||||||
|
double item;
|
||||||
|
rv = aNodeSet->ItemAsNumber(i, &item);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (!TX_DOUBLE_COMPARE(item, <=, result)) {
|
||||||
|
result = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TX_DOUBLE_IS_NaN(result)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*aResult = result;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXFormsXPathFunctions::Min(txINodeSet *aNodeSet, double *aResult)
|
||||||
|
{
|
||||||
|
PRUint32 length;
|
||||||
|
nsresult rv = aNodeSet->GetLength(&length);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
double result = kNaN;
|
||||||
|
PRUint32 i;
|
||||||
|
for (i = 0; i < length; ++i) {
|
||||||
|
double item;
|
||||||
|
rv = aNodeSet->ItemAsNumber(i, &item);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (!TX_DOUBLE_COMPARE(item, >=, result)) {
|
||||||
|
result = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TX_DOUBLE_IS_NaN(result)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*aResult = result;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXFormsXPathFunctions::Months(const nsAString & aDuration, double *aResult)
|
||||||
|
{
|
||||||
|
PRInt32 result = 0;
|
||||||
|
nsresult rv = nsXFormsUtils::GetMonths(aDuration, &result);
|
||||||
|
if (rv == NS_ERROR_ILLEGAL_VALUE) {
|
||||||
|
*aResult = kNaN;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aResult = result;
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXFormsXPathFunctions::Now(nsAString & aResult)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
aResult.AssignASCII(ctime);
|
||||||
|
AppendASCIItoUTF16(zone_location, aResult);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXFormsXPathFunctions::Property(const nsAString &aProperty,
|
||||||
|
nsAString &aResult)
|
||||||
|
{
|
||||||
|
// This function can handle "version" and "conformance-level"
|
||||||
|
// which is all that the XForms 1.0 spec is worried about
|
||||||
|
if (aProperty.EqualsLiteral("version")) {
|
||||||
|
aResult.AssignLiteral("1.0");
|
||||||
|
}
|
||||||
|
else if (aProperty.EqualsLiteral("conformance-level")) {
|
||||||
|
aResult.AssignLiteral("basic");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
aResult.Truncate();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXFormsXPathFunctions::Seconds(const nsAString &aDuration, double *aResult)
|
||||||
|
{
|
||||||
|
nsresult rv = nsXFormsUtils::GetSeconds(aDuration, aResult);
|
||||||
|
if (rv == NS_ERROR_ILLEGAL_VALUE) {
|
||||||
|
*aResult = kNaN;
|
||||||
|
rv = NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXFormsXPathFunctions::SecondsFromDateTime(const nsAString &aDateTime,
|
||||||
|
double *aResult)
|
||||||
|
{
|
||||||
|
nsresult rv = nsXFormsUtils::GetSecondsFromDateTime(aDateTime, aResult);
|
||||||
|
if (rv == NS_ERROR_ILLEGAL_VALUE) {
|
||||||
|
*aResult = kNaN;
|
||||||
|
rv = NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
|
@ -36,49 +36,11 @@
|
||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
#ifndef TRANSFRMX_XFORMS_FUNCTIONS_H
|
#include "nsIXFormsXPathFunctions.h"
|
||||||
#define TRANSFRMX_XFORMS_FUNCTIONS_H
|
|
||||||
|
|
||||||
#include "txExpr.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 {
|
|
||||||
|
|
||||||
|
class nsXFormsXPathFunctions : public nsIXFormsXPathFunctions
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
enum XFormsFunctions {
|
NS_DECL_NSIXFORMSXPATHFUNCTIONS
|
||||||
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
|
|
|
@ -108,10 +108,9 @@
|
||||||
// Transformiix stuff
|
// Transformiix stuff
|
||||||
#include "nsXPathEvaluator.h"
|
#include "nsXPathEvaluator.h"
|
||||||
#include "txMozillaXSLTProcessor.h"
|
#include "txMozillaXSLTProcessor.h"
|
||||||
|
#include "txNodeSetAdaptor.h"
|
||||||
#include "txXSLTProcessor.h"
|
#include "txXSLTProcessor.h"
|
||||||
#include "nsXPath1Scheme.h"
|
#include "nsXPath1Scheme.h"
|
||||||
#include "nsXFormsXPathEvaluator.h"
|
|
||||||
#include "txXSLTProcessor.h"
|
|
||||||
|
|
||||||
#include "nsDOMParser.h"
|
#include "nsDOMParser.h"
|
||||||
#include "nsDOMSerializer.h"
|
#include "nsDOMSerializer.h"
|
||||||
|
@ -200,12 +199,19 @@ static void Shutdown();
|
||||||
#define TRANSFORMIIX_XPATH1_SCHEME_CID \
|
#define TRANSFORMIIX_XPATH1_SCHEME_CID \
|
||||||
{ 0xc351177, 0x159, 0x4500, { 0x86, 0xb0, 0xa2, 0x19, 0xdf, 0xde, 0x42, 0x58 } }
|
{ 0xc351177, 0x159, 0x4500, { 0x86, 0xb0, 0xa2, 0x19, 0xdf, 0xde, 0x42, 0x58 } }
|
||||||
|
|
||||||
|
/* 5d5d92cd-6bf8-11d9-bf4a-000a95dc234c */
|
||||||
|
#define TRANSFORMIIX_NODESET_CID \
|
||||||
|
{ 0x5d5d92cd, 0x6bf8, 0x11d9, { 0xbf, 0x4a, 0x0, 0x0a, 0x95, 0xdc, 0x23, 0x4c } }
|
||||||
|
|
||||||
|
#define TRANSFORMIIX_NODESET_CONTRACTID \
|
||||||
|
"@mozilla.org/transformiix-nodeset;1"
|
||||||
|
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPath1SchemeProcessor)
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPath1SchemeProcessor)
|
||||||
|
|
||||||
// Factory Constructor
|
// Factory Constructor
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR(txMozillaXSLTProcessor)
|
NS_GENERIC_FACTORY_CONSTRUCTOR(txMozillaXSLTProcessor)
|
||||||
NS_GENERIC_AGGREGATED_CONSTRUCTOR_INIT(nsXPathEvaluator, Init)
|
NS_GENERIC_AGGREGATED_CONSTRUCTOR_INIT(nsXPathEvaluator, Init)
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXFormsXPathEvaluator)
|
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(txNodeSetAdaptor, Init)
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMSerializer)
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMSerializer)
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXMLHttpRequest)
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXMLHttpRequest)
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMParser)
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMParser)
|
||||||
|
@ -1253,16 +1259,16 @@ static const nsModuleComponentInfo gComponents[] = {
|
||||||
NS_XPATH_EVALUATOR_CONTRACTID,
|
NS_XPATH_EVALUATOR_CONTRACTID,
|
||||||
nsXPathEvaluatorConstructor },
|
nsXPathEvaluatorConstructor },
|
||||||
|
|
||||||
{ "XFormsXPathEvaluator",
|
|
||||||
TRANSFORMIIX_XFORMS_XPATH_EVALUATOR_CID,
|
|
||||||
NS_XFORMS_XPATH_EVALUATOR_CONTRACTID,
|
|
||||||
nsXFormsXPathEvaluatorConstructor },
|
|
||||||
|
|
||||||
{ "XPath1 XPointer Scheme Processor",
|
{ "XPath1 XPointer Scheme Processor",
|
||||||
TRANSFORMIIX_XPATH1_SCHEME_CID,
|
TRANSFORMIIX_XPATH1_SCHEME_CID,
|
||||||
NS_XPOINTER_SCHEME_PROCESSOR_BASE "xpath1",
|
NS_XPOINTER_SCHEME_PROCESSOR_BASE "xpath1",
|
||||||
nsXPath1SchemeProcessorConstructor },
|
nsXPath1SchemeProcessorConstructor },
|
||||||
|
|
||||||
|
{ "Transformiix NodeSet",
|
||||||
|
TRANSFORMIIX_NODESET_CID,
|
||||||
|
TRANSFORMIIX_NODESET_CONTRACTID,
|
||||||
|
txNodeSetAdaptorConstructor },
|
||||||
|
|
||||||
{ "XML Serializer",
|
{ "XML Serializer",
|
||||||
NS_XMLSERIALIZER_CID,
|
NS_XMLSERIALIZER_CID,
|
||||||
NS_XMLSERIALIZER_CONTRACTID,
|
NS_XMLSERIALIZER_CONTRACTID,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче