mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-02 12:07:52 +00:00
Fix for bug 278981 (Extension mechanism for XPath extension functions). r=sicking, sr=jst.
This commit is contained in:
parent
74b982040d
commit
a9c63c4a75
@ -47,14 +47,11 @@
|
||||
#define NS_NO_VTABLE
|
||||
#endif
|
||||
|
||||
class nsIDOMNode; /* forward declaration */
|
||||
|
||||
/* 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 \
|
||||
{0x4a744a59, 0x8771, 0x4065, \
|
||||
{ 0x95, 0x9d, 0xb8, 0xde, 0x3d, 0xad, 0x81, 0xda }}
|
||||
{ 0xf7276415, 0xbb3e, 0x4170, \
|
||||
{ 0xb7, 0x46, 0xaa, 0x57, 0xf6, 0x8d, 0x70, 0x06 } }
|
||||
|
||||
/**
|
||||
* Private interface implemented by the nsXFormsUtilityService in XForms
|
||||
@ -64,87 +61,6 @@ class NS_NO_VTABLE nsIXFormsUtilityService : public nsISupports {
|
||||
public:
|
||||
|
||||
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,
|
||||
|
@ -39,9 +39,11 @@
|
||||
#ifndef nsIXPathEvaluatorInternal_h__
|
||||
#define nsIXPathEvaluatorInternal_h__
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsCOMArray.h"
|
||||
|
||||
class nsIDOMDocument;
|
||||
class nsIDOMXPathExpression;
|
||||
class nsIDOMXPathNSResolver;
|
||||
|
||||
#define NS_IXPATHEVALUATORINTERNAL_IID \
|
||||
{0xb4b72daa, 0x65d6, 0x440f, \
|
||||
@ -57,6 +59,13 @@ public:
|
||||
* Sets the document this evaluator corresponds to
|
||||
*/
|
||||
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,
|
||||
|
@ -47,6 +47,7 @@ XPIDL_MODULE = content_xslt
|
||||
|
||||
EXPORTS = \
|
||||
nsIDocumentTransformer.h \
|
||||
txDouble.h \
|
||||
$(NULL)
|
||||
|
||||
XPIDLSRCS = \
|
||||
@ -54,6 +55,8 @@ XPIDLSRCS = \
|
||||
nsIXSLTProcessor.idl \
|
||||
nsIXSLTProcessorObsolete.idl \
|
||||
nsIXSLTProcessorPrivate.idl \
|
||||
txIFunctionEvaluationContext.idl \
|
||||
txINodeSet.idl \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
128
content/xslt/public/txDouble.h
Normal file
128
content/xslt/public/txDouble.h
Normal file
@ -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__ */
|
51
content/xslt/public/txIFunctionEvaluationContext.idl
Normal file
51
content/xslt/public/txIFunctionEvaluationContext.idl
Normal file
@ -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;
|
||||
};
|
57
content/xslt/public/txINodeSet.idl
Normal file
57
content/xslt/public/txINodeSet.idl
Normal file
@ -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 "nsDebug.h"
|
||||
#include "prtypes.h"
|
||||
#include "txDouble.h"
|
||||
|
||||
class nsAString;
|
||||
|
||||
|
@ -49,81 +49,12 @@
|
||||
* 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
|
||||
const PRUint32 nanMask[2] = TX_DOUBLE_NaN;
|
||||
#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 negInfMask[2] = {TX_DOUBLE_HI32_EXPMASK | TX_DOUBLE_HI32_SIGNBIT, 0};
|
||||
#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 negInfMask[2] = {0, TX_DOUBLE_HI32_EXPMASK | TX_DOUBLE_HI32_SIGNBIT};
|
||||
#endif
|
||||
@ -147,8 +78,7 @@ MBool Double::isInfinite(double aDbl)
|
||||
*/
|
||||
MBool Double::isNaN(double aDbl)
|
||||
{
|
||||
return ((TX_DOUBLE_HI32(aDbl) & TX_DOUBLE_HI32_EXPMASK) == TX_DOUBLE_HI32_EXPMASK &&
|
||||
(TX_DOUBLE_LO32(aDbl) || (TX_DOUBLE_HI32(aDbl) & TX_DOUBLE_HI32_MANTMASK)));
|
||||
return TX_DOUBLE_IS_NaN(aDbl);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -101,20 +101,13 @@ CPPSRCS += nsXPathEvaluator.cpp \
|
||||
nsXPathNSResolver.cpp \
|
||||
nsXPathResult.cpp \
|
||||
nsXPath1Scheme.cpp \
|
||||
txMozillaXPathTreeWalker.cpp
|
||||
txMozillaXPathTreeWalker.cpp \
|
||||
txNodeSetAdaptor.cpp \
|
||||
txXPCOMExtensionFunction.cpp
|
||||
else
|
||||
CPPSRCS += txStandaloneXPathTreeWalker.cpp
|
||||
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
|
||||
# static lib.
|
||||
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
|
||||
{
|
||||
public:
|
||||
nsXPathEvaluatorParseContext(nsIDOMXPathNSResolver *aResolver,
|
||||
nsXPathEvaluatorParseContext(nsXPathEvaluator &aEvaluator,
|
||||
nsIDOMXPathNSResolver* aResolver,
|
||||
nsTArray<PRInt32> *aNamespaceIDs,
|
||||
nsCStringArray *aContractIDs,
|
||||
nsCOMArray<nsISupports> *aState,
|
||||
PRBool aIsCaseSensitive)
|
||||
: mResolver(aResolver),
|
||||
: mEvaluator(aEvaluator),
|
||||
mResolver(aResolver),
|
||||
mNamespaceIDs(aNamespaceIDs),
|
||||
mContractIDs(aContractIDs),
|
||||
mState(aState),
|
||||
mLastError(NS_OK),
|
||||
mIsCaseSensitive(aIsCaseSensitive)
|
||||
{
|
||||
}
|
||||
|
||||
~nsXPathEvaluatorParseContext()
|
||||
{
|
||||
NS_ASSERTION(mContractIDs ||
|
||||
(!mNamespaceIDs || mNamespaceIDs->Length() == 0),
|
||||
"Need contract IDs if there are namespaces.");
|
||||
}
|
||||
|
||||
nsresult getError()
|
||||
@ -83,7 +90,11 @@ public:
|
||||
void SetErrorOffset(PRUint32 aOffset);
|
||||
|
||||
private:
|
||||
nsXPathEvaluator &mEvaluator;
|
||||
nsIDOMXPathNSResolver* mResolver;
|
||||
nsTArray<PRInt32> *mNamespaceIDs;
|
||||
nsCStringArray *mContractIDs;
|
||||
nsCOMArray<nsISupports> *mState;
|
||||
nsresult mLastError;
|
||||
PRBool mIsCaseSensitive;
|
||||
};
|
||||
@ -113,38 +124,8 @@ nsXPathEvaluator::CreateExpression(const nsAString & aExpression,
|
||||
nsIDOMXPathNSResolver *aResolver,
|
||||
nsIDOMXPathExpression **aResult)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!mRecycler) {
|
||||
nsRefPtr<txResultRecycler> recycler = new txResultRecycler;
|
||||
NS_ENSURE_TRUE(recycler, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = recycler->init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mRecycler = recycler;
|
||||
}
|
||||
|
||||
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;
|
||||
return CreateExpression(aExpression, aResolver, (nsTArray<PRInt32>*)nsnull,
|
||||
nsnull, nsnull, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -172,7 +153,6 @@ nsXPathEvaluator::Evaluate(const nsAString & aExpression,
|
||||
{
|
||||
// XXX Need to check document of aContextNode if created by
|
||||
// QI'ing a document.
|
||||
|
||||
nsCOMPtr<nsIDOMXPathExpression> expression;
|
||||
nsresult rv = CreateExpression(aExpression, aResolver,
|
||||
getter_AddRefs(expression));
|
||||
@ -189,6 +169,85 @@ nsXPathEvaluator::SetDocument(nsIDOMDocument* aDocument)
|
||||
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
|
||||
* nsIDOMXPathNSResolver
|
||||
@ -226,12 +285,31 @@ nsresult nsXPathEvaluatorParseContext::resolveNamespacePrefix
|
||||
return nsContentUtils::NameSpaceManager()->RegisterNameSpace(ns, aID);
|
||||
}
|
||||
|
||||
extern nsresult
|
||||
TX_ResolveFunctionCallXPCOM(const nsCString &aContractID, PRInt32 aNamespaceID,
|
||||
nsIAtom *aName, nsISupports *aState,
|
||||
FunctionCall *&aFunction);
|
||||
|
||||
nsresult
|
||||
nsXPathEvaluatorParseContext::resolveFunctionCall(nsIAtom* aName,
|
||||
PRInt32 aID,
|
||||
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()
|
||||
|
@ -43,8 +43,10 @@
|
||||
#include "nsIXPathEvaluatorInternal.h"
|
||||
#include "nsIWeakReference.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "txResultRecycler.h"
|
||||
#include "nsAgg.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
/**
|
||||
* A class for evaluating an XPath expression string
|
||||
@ -68,8 +70,21 @@ public:
|
||||
|
||||
// nsIXPathEvaluatorInternal interface
|
||||
NS_IMETHOD SetDocument(nsIDOMDocument* aDocument);
|
||||
NS_IMETHOD CreateExpression(const nsAString &aExpression,
|
||||
nsIDOMXPathNSResolver *aResolver,
|
||||
nsStringArray *aNamespaceURIs,
|
||||
nsCStringArray *aContractIDs,
|
||||
nsCOMArray<nsISupports> *aState,
|
||||
nsIDOMXPathExpression **aResult);
|
||||
|
||||
private:
|
||||
nsresult CreateExpression(const nsAString & aExpression,
|
||||
nsIDOMXPathNSResolver *aResolver,
|
||||
nsTArray<PRInt32> *aNamespaceIDs,
|
||||
nsCStringArray *aContractIDs,
|
||||
nsCOMArray<nsISupports> *aState,
|
||||
nsIDOMXPathExpression **aResult);
|
||||
|
||||
nsWeakPtr mDocument;
|
||||
nsRefPtr<txResultRecycler> mRecycler;
|
||||
};
|
||||
|
129
content/xslt/src/xpath/txNodeSetAdaptor.cpp
Normal file
129
content/xslt/src/xpath/txNodeSetAdaptor.cpp
Normal file
@ -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
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla XForms support.
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* Peter Van der Beken.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -36,66 +37,30 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsXFormsXPathEvaluator_h__
|
||||
#define nsXFormsXPathEvaluator_h__
|
||||
#ifndef txNodeSetAdaptor_h__
|
||||
#define txNodeSetAdaptor_h__
|
||||
|
||||
#include "nsIXFormsXPathEvaluator.h"
|
||||
#include "txIXPathContext.h"
|
||||
#include "nsIXPathEvaluatorInternal.h"
|
||||
#include "nsIWeakReference.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "txResultRecycler.h"
|
||||
|
||||
|
||||
class nsIDOMDocument;
|
||||
class nsIDOMXPathExpression;
|
||||
#include "txINodeSet.h"
|
||||
#include "txNodeSet.h"
|
||||
|
||||
/**
|
||||
* 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:
|
||||
nsXFormsXPathEvaluator();
|
||||
virtual ~nsXFormsXPathEvaluator();
|
||||
txNodeSetAdaptor();
|
||||
txNodeSetAdaptor(txNodeSet *aNodeSet);
|
||||
|
||||
nsresult Init();
|
||||
|
||||
// nsISupports interface
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIXFormsXPathEvaluator interface
|
||||
NS_DECL_NSIXFORMXPATHEVALUATOR
|
||||
NS_DECL_TXINODESET
|
||||
|
||||
private:
|
||||
// txIParseContext implementation
|
||||
class XFormsParseContextImpl : public txIParseContext
|
||||
{
|
||||
public:
|
||||
XFormsParseContextImpl(nsIDOMNode* aResolverNode)
|
||||
: mResolverNode(aResolverNode), mLastError(NS_OK)
|
||||
{
|
||||
}
|
||||
|
||||
~XFormsParseContextImpl()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult getError()
|
||||
{
|
||||
return mLastError;
|
||||
}
|
||||
|
||||
nsresult resolveNamespacePrefix(nsIAtom* aPrefix, PRInt32& aID);
|
||||
nsresult resolveFunctionCall(nsIAtom* aName, PRInt32 aID,
|
||||
FunctionCall*& aFunction);
|
||||
PRBool caseInsensitiveNameTests();
|
||||
void SetErrorOffset(PRUint32 aOffset);
|
||||
|
||||
private:
|
||||
nsIDOMNode* mResolverNode;
|
||||
nsresult mLastError;
|
||||
};
|
||||
|
||||
nsRefPtr<txResultRecycler> mRecycler;
|
||||
nsRefPtr<txNodeSet> mNodeSet;
|
||||
PRBool mWritable;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // txNodeSetAdaptor_h__
|
@ -37,6 +37,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "txExpr.h"
|
||||
#include "txDouble.h"
|
||||
#include "txNodeSet.h"
|
||||
#include "txIXPathContext.h"
|
||||
#include "txXPathTreeWalker.h"
|
||||
@ -118,14 +119,7 @@ RelationalExpr::compareResults(txIEvalContext* aContext, txAExprResult* aLeft,
|
||||
rtype == txAExprResult::NUMBER) {
|
||||
double lval = aLeft->numberValue();
|
||||
double rval = aRight->numberValue();
|
||||
#if defined(XP_WIN)
|
||||
if (Double::isNaN(lval) || Double::isNaN(rval))
|
||||
result = PR_FALSE;
|
||||
else
|
||||
result = lval == rval;
|
||||
#else
|
||||
result = lval == rval;
|
||||
#endif
|
||||
result = TX_DOUBLE_COMPARE(lval, ==, rval);
|
||||
}
|
||||
|
||||
// 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 rightDbl = aRight->numberValue();
|
||||
#if defined(XP_WIN)
|
||||
if (Double::isNaN(leftDbl) || Double::isNaN(rightDbl))
|
||||
return PR_FALSE;
|
||||
#endif
|
||||
|
||||
switch (mOp) {
|
||||
case LESS_THAN:
|
||||
{
|
||||
return leftDbl < rightDbl;
|
||||
return TX_DOUBLE_COMPARE(leftDbl, <, rightDbl);
|
||||
}
|
||||
case LESS_OR_EQUAL:
|
||||
{
|
||||
return leftDbl <= rightDbl;
|
||||
return TX_DOUBLE_COMPARE(leftDbl, <=, rightDbl);
|
||||
}
|
||||
case GREATER_THAN:
|
||||
{
|
||||
return leftDbl > rightDbl;
|
||||
return TX_DOUBLE_COMPARE(leftDbl, >, rightDbl);
|
||||
}
|
||||
case GREATER_OR_EQUAL:
|
||||
{
|
||||
return leftDbl >= rightDbl;
|
||||
return TX_DOUBLE_COMPARE(leftDbl, >=, rightDbl);
|
||||
}
|
||||
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
|
587
content/xslt/src/xpath/txXPCOMExtensionFunction.cpp
Normal file
587
content/xslt/src/xpath/txXPCOMExtensionFunction.cpp
Normal file
@ -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 \
|
||||
nsIXFormsEphemeralMessageUI.idl \
|
||||
nsIXFormsRangeConditionAccessors.idl \
|
||||
nsIXFormsXPathFunctions.idl \
|
||||
$(NULL)
|
||||
|
||||
# XForms source files
|
||||
@ -208,6 +209,7 @@ CPPSRCS = \
|
||||
nsXFormsRangeAccessors.cpp \
|
||||
nsXFormsCopyElement.cpp \
|
||||
nsXFormsRangeConditionAccessors.cpp \
|
||||
nsXFormsXPathFunctions.cpp \
|
||||
$(NULL)
|
||||
|
||||
# Standard Mozilla make rules
|
||||
|
60
extensions/xforms/nsIXFormsXPathFunctions.idl
Normal file
60
extensions/xforms/nsIXFormsXPathFunctions.idl
Normal file
@ -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) {
|
||||
case eModel_calculate:
|
||||
if (g->HasExpr()) {
|
||||
nsCOMPtr<nsIDOMXPathResult> xpath_res;
|
||||
nsCOMPtr<nsISupports> result;
|
||||
rv = g->mExpression->EvaluateWithContext(g->mContextNode,
|
||||
g->mContextPosition,
|
||||
g->mContextSize,
|
||||
nsIDOMXPathResult::STRING_TYPE,
|
||||
nsnull,
|
||||
getter_AddRefs(xpath_res));
|
||||
getter_AddRefs(result));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDOMXPathResult> xpath_res = do_QueryInterface(result);
|
||||
NS_ENSURE_STATE(xpath_res);
|
||||
|
||||
nsAutoString nodeval;
|
||||
@ -1039,7 +1041,7 @@ nsXFormsMDGEngine::BooleanExpression(nsXFormsMDGNode* aNode, PRBool& state)
|
||||
NS_ENSURE_ARG_POINTER(aNode);
|
||||
NS_ENSURE_TRUE(aNode->mExpression, NS_ERROR_FAILURE);
|
||||
|
||||
nsISupports* retval;
|
||||
nsCOMPtr<nsISupports> retval;
|
||||
nsresult rv;
|
||||
|
||||
rv = aNode->mExpression->EvaluateWithContext(aNode->mContextNode,
|
||||
@ -1047,7 +1049,7 @@ nsXFormsMDGEngine::BooleanExpression(nsXFormsMDGNode* aNode, PRBool& state)
|
||||
aNode->mContextSize,
|
||||
nsIDOMXPathResult::BOOLEAN_TYPE,
|
||||
nsnull,
|
||||
&retval);
|
||||
getter_AddRefs(retval));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDOMXPathResult> xpath_res = do_QueryInterface(retval);
|
||||
|
@ -55,7 +55,9 @@
|
||||
#include "nsIDOMXMLDocument.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIDOMXPathResult.h"
|
||||
#include "nsIXFormsXPathEvaluator.h"
|
||||
#include "nsIDOMXPathEvaluator.h"
|
||||
#include "nsIXPathEvaluatorInternal.h"
|
||||
#include "nsIDOMXPathExpression.h"
|
||||
#include "nsIDOMXPathNSResolver.h"
|
||||
#include "nsIDOMNSXPathExpression.h"
|
||||
#include "nsIContent.h"
|
||||
@ -1983,10 +1985,10 @@ nsXFormsModelElement::ProcessBindElements()
|
||||
firstInstanceDoc->GetDocumentElement(getter_AddRefs(firstInstanceRoot));
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIXFormsXPathEvaluator> xpath =
|
||||
do_CreateInstance("@mozilla.org/dom/xforms-xpath-evaluator;1", &rv);
|
||||
NS_ENSURE_TRUE(xpath, rv);
|
||||
|
||||
nsCOMPtr<nsIDOMXPathEvaluator> xpath = do_QueryInterface(firstInstanceDoc,
|
||||
&rv);
|
||||
NS_ENSURE_TRUE(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDOMNodeList> children;
|
||||
mElement->GetChildNodes(getter_AddRefs(children));
|
||||
|
||||
@ -2266,19 +2268,26 @@ nsXFormsModelElement::MaybeNotifyCompletion()
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
|
||||
nsIDOMNode *aContextNode,
|
||||
PRInt32 aContextPosition,
|
||||
PRInt32 aContextSize,
|
||||
nsIDOMElement *aBindElement,
|
||||
PRBool aIsOuter)
|
||||
nsXFormsModelElement::ProcessBind(nsIDOMXPathEvaluator *aEvaluator,
|
||||
nsIDOMNode *aContextNode,
|
||||
PRInt32 aContextPosition,
|
||||
PRInt32 aContextSize,
|
||||
nsIDOMElement *aBindElement,
|
||||
PRBool aIsOuter)
|
||||
{
|
||||
// Get the model item properties specified by this \<bind\>.
|
||||
nsCOMPtr<nsIDOMNSXPathExpression> props[eModel__count];
|
||||
nsCOMPtr<nsIDOMXPathExpression> props[eModel__count];
|
||||
nsAutoString propStrings[eModel__count];
|
||||
nsresult rv;
|
||||
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) {
|
||||
sModelPropsList[i]->ToString(attrStr);
|
||||
|
||||
@ -2286,8 +2295,9 @@ nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
|
||||
if (!propStrings[i].IsEmpty() &&
|
||||
i != eModel_type &&
|
||||
i != eModel_p3ptype) {
|
||||
rv = aEvaluator->CreateExpression(propStrings[i], aBindElement,
|
||||
getter_AddRefs(props[i]));
|
||||
rv = nsXFormsUtils::CreateExpression(eval, propStrings[i], resolver,
|
||||
aBindElement,
|
||||
getter_AddRefs(props[i]));
|
||||
if (NS_FAILED(rv)) {
|
||||
const PRUnichar *strings[] = { propStrings[i].get() };
|
||||
nsXFormsUtils::ReportError(NS_LITERAL_STRING("mipParseError"),
|
||||
@ -2301,21 +2311,21 @@ nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
|
||||
// Find the nodeset that this bind applies to.
|
||||
nsCOMPtr<nsIDOMXPathResult> result;
|
||||
|
||||
nsAutoString expr;
|
||||
aBindElement->GetAttribute(NS_LITERAL_STRING("nodeset"), expr);
|
||||
if (expr.IsEmpty()) {
|
||||
expr = NS_LITERAL_STRING(".");
|
||||
nsAutoString exprString;
|
||||
aBindElement->GetAttribute(NS_LITERAL_STRING("nodeset"), exprString);
|
||||
if (exprString.IsEmpty()) {
|
||||
exprString = NS_LITERAL_STRING(".");
|
||||
}
|
||||
rv = aEvaluator->Evaluate(expr, aContextNode, aContextPosition, aContextSize,
|
||||
aBindElement,
|
||||
nsIDOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE,
|
||||
nsnull, getter_AddRefs(result));
|
||||
|
||||
rv = nsXFormsUtils::EvaluateXPath(eval, exprString, aContextNode, resolver,
|
||||
aBindElement,
|
||||
nsIDOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE,
|
||||
aContextPosition, aContextSize,
|
||||
nsnull, getter_AddRefs(result));
|
||||
if (NS_FAILED(rv)) {
|
||||
if (rv == NS_ERROR_DOM_INVALID_EXPRESSION_ERR) {
|
||||
// the xpath expression isn't valid xpath
|
||||
|
||||
const nsPromiseFlatString& flat = PromiseFlatString(expr);
|
||||
const PRUnichar *strings[] = { flat.get() };
|
||||
const PRUnichar *strings[] = { exprString.get() };
|
||||
nsXFormsUtils::ReportError(NS_LITERAL_STRING("exprParseError"),
|
||||
strings, 1, aBindElement, nsnull);
|
||||
nsXFormsUtils::DispatchEvent(mElement, eEvent_ComputeException);
|
||||
@ -2323,7 +2333,7 @@ nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
|
||||
#ifdef DEBUG
|
||||
printf("xforms-binding-exception: XPath Evaluation failed\n");
|
||||
#endif
|
||||
const PRUnichar *strings[] = { expr.get() };
|
||||
const PRUnichar *strings[] = { exprString.get() };
|
||||
nsXFormsUtils::ReportError(NS_LITERAL_STRING("nodesetEvaluateError"),
|
||||
strings, 1, aBindElement, aBindElement);
|
||||
nsXFormsUtils::DispatchEvent(mElement, eEvent_BindingException);
|
||||
@ -2367,7 +2377,7 @@ nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
|
||||
|
||||
// Apply MIPs
|
||||
nsXFormsXPathParser parser;
|
||||
nsXFormsXPathAnalyzer analyzer(aEvaluator, aBindElement);
|
||||
nsXFormsXPathAnalyzer analyzer(eval, resolver, aBindElement);
|
||||
PRBool multiMIP = PR_FALSE;
|
||||
for (PRUint32 j = 0; j < eModel__count; ++j) {
|
||||
if (propStrings[j].IsEmpty())
|
||||
@ -2402,7 +2412,7 @@ nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
|
||||
}
|
||||
} else {
|
||||
// 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
|
||||
nsAutoPtr<nsXFormsXPathNode> xNode(parser.Parse(propStrings[j]));
|
||||
|
@ -60,7 +60,7 @@
|
||||
|
||||
class nsIDOMElement;
|
||||
class nsIDOMNode;
|
||||
class nsIXFormsXPathEvaluator;
|
||||
class nsIDOMXPathEvaluator;
|
||||
class nsIDOMXPathResult;
|
||||
class nsXFormsControl;
|
||||
class nsXFormsModelInstanceDocuments;
|
||||
@ -310,12 +310,12 @@ private:
|
||||
NS_HIDDEN_(nsresult) ConstructDone();
|
||||
NS_HIDDEN_(void) MaybeNotifyCompletion();
|
||||
|
||||
NS_HIDDEN_(nsresult) ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
|
||||
nsIDOMNode *aContextNode,
|
||||
PRInt32 aContextPosition,
|
||||
PRInt32 aContextSize,
|
||||
nsIDOMElement *aBindElement,
|
||||
PRBool aIsOuter = PR_FALSE);
|
||||
NS_HIDDEN_(nsresult) ProcessBind(nsIDOMXPathEvaluator *aEvaluator,
|
||||
nsIDOMNode *aContextNode,
|
||||
PRInt32 aContextPosition,
|
||||
PRInt32 aContextSize,
|
||||
nsIDOMElement *aBindElement,
|
||||
PRBool aIsOuter = PR_FALSE);
|
||||
|
||||
NS_HIDDEN_(void) RemoveModelFromDocument();
|
||||
|
||||
|
@ -44,6 +44,8 @@
|
||||
#include "nsXFormsUtils.h"
|
||||
#include "nsICategoryManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
#include "nsXFormsXPathFunctions.h"
|
||||
|
||||
// bb0d9c8b-3096-4b66-92a0-6c1ddf80e65f
|
||||
#define NS_XFORMSUTILITYSERVICE_CID \
|
||||
@ -52,9 +54,15 @@
|
||||
#define NS_XFORMSUTILITYSERVICE_CONTRACTID \
|
||||
"@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(nsXFormsUtilityService)
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXFormsXPathFunctions)
|
||||
NS_DECL_CLASSINFO(nsXFormsXPathFunctions)
|
||||
|
||||
static NS_IMETHODIMP
|
||||
RegisterXFormsModule(nsIComponentManager *aCompMgr,
|
||||
@ -132,6 +140,15 @@ static const nsModuleComponentInfo components[] = {
|
||||
NS_XFORMSUTILITYSERVICE_CID,
|
||||
NS_XFORMSUTILITYSERVICE_CONTRACTID,
|
||||
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 ***** */
|
||||
|
||||
#include "nsIServiceManager.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)
|
||||
|
||||
/* 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:
|
||||
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 "nsINameSpaceManager.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIXFormsXPathEvaluator.h"
|
||||
#include "nsIDOMXPathEvaluator.h"
|
||||
#include "nsIDOMXPathExpression.h"
|
||||
#include "nsIDOMXPathResult.h"
|
||||
#include "nsIDOMXPathNSResolver.h"
|
||||
#include "nsIXPathEvaluatorInternal.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMText.h"
|
||||
#include "nsIModelElementPrivate.h"
|
||||
@ -79,16 +81,20 @@
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIXFormsUtilityService.h"
|
||||
#include "nsIDOMAttr.h"
|
||||
#include "nsIDOM3Node.h"
|
||||
#include "nsIConsoleService.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIXFormsRepeatElement.h"
|
||||
#include "nsIDOMNSEvent.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsIDOMNamedNodeMap.h"
|
||||
#include "nsIParserService.h"
|
||||
#include "nsISchemaValidator.h"
|
||||
#include "nsISchemaDuration.h"
|
||||
#include "nsXFormsSchemaValidator.h"
|
||||
#include "prdtoa.h"
|
||||
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefService.h"
|
||||
@ -418,6 +424,26 @@ nsXFormsUtils::GetModel(nsIDOMElement *aElement,
|
||||
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
|
||||
nsXFormsUtils::EvaluateXPath(const nsAString &aExpression,
|
||||
nsIDOMNode *aContextNode,
|
||||
@ -432,13 +458,21 @@ nsXFormsUtils::EvaluateXPath(const nsAString &aExpression,
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
*aResult = nsnull;
|
||||
|
||||
nsCOMPtr<nsIXFormsXPathEvaluator> eval =
|
||||
do_CreateInstance("@mozilla.org/dom/xforms-xpath-evaluator;1");
|
||||
NS_ENSURE_STATE(eval);
|
||||
nsCOMPtr<nsIDOMDocument> doc;
|
||||
aContextNode->GetOwnerDocument(getter_AddRefs(doc));
|
||||
|
||||
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;
|
||||
if (!expression) {
|
||||
const nsPromiseFlatString& flat = PromiseFlatString(aExpression);
|
||||
@ -447,13 +481,17 @@ nsXFormsUtils::EvaluateXPath(const nsAString &aExpression,
|
||||
strings, 1, aContextNode, nsnull);
|
||||
throwException = PR_TRUE;
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMNSXPathExpression> nsExpr =
|
||||
do_QueryInterface(expression, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsISupports> supResult;
|
||||
rv = expression->EvaluateWithContext(aContextNode,
|
||||
aContextPosition,
|
||||
aContextSize,
|
||||
aResultType,
|
||||
nsnull,
|
||||
getter_AddRefs(supResult));
|
||||
rv = nsExpr->EvaluateWithContext(aContextNode,
|
||||
aContextPosition,
|
||||
aContextSize,
|
||||
aResultType,
|
||||
nsnull,
|
||||
getter_AddRefs(supResult));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && supResult) {
|
||||
/// @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
|
||||
if (aSet) {
|
||||
nsXFormsXPathParser parser;
|
||||
nsXFormsXPathAnalyzer analyzer(eval, aResolverNode);
|
||||
nsXFormsXPathAnalyzer analyzer(evalInternal, resolver, aResolverNode);
|
||||
nsAutoPtr<nsXFormsXPathNode> xNode(parser.Parse(aExpression));
|
||||
rv = analyzer.Analyze(aContextNode,
|
||||
xNode,
|
||||
expression,
|
||||
nsExpr,
|
||||
&aExpression,
|
||||
aSet,
|
||||
aContextPosition,
|
||||
@ -481,7 +519,7 @@ nsXFormsUtils::EvaluateXPath(const nsAString &aExpression,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (rv == NS_ERROR_XFORMS_CALCUATION_EXCEPTION) {
|
||||
if (rv == NS_ERROR_XFORMS_CALCULATION_EXCEPTION) {
|
||||
const nsPromiseFlatString& flat = PromiseFlatString(aExpression);
|
||||
const PRUnichar *strings[] = { flat.get() };
|
||||
nsXFormsUtils::ReportError(NS_LITERAL_STRING("exprEvaluateError"),
|
||||
@ -493,7 +531,8 @@ nsXFormsUtils::EvaluateXPath(const nsAString &aExpression,
|
||||
// Throw xforms-compute-exception
|
||||
if (throwException) {
|
||||
nsCOMPtr<nsIDOMElement> resolverElement = do_QueryInterface(aResolverNode);
|
||||
nsCOMPtr<nsIModelElementPrivate> modelPriv = nsXFormsUtils::GetModel(resolverElement);
|
||||
nsCOMPtr<nsIModelElementPrivate> modelPriv =
|
||||
nsXFormsUtils::GetModel(resolverElement);
|
||||
nsCOMPtr<nsIDOMNode> model = do_QueryInterface(modelPriv);
|
||||
DispatchEvent(model, eEvent_ComputeException, nsnull, resolverElement);
|
||||
}
|
||||
@ -501,6 +540,36 @@ nsXFormsUtils::EvaluateXPath(const nsAString &aExpression,
|
||||
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
|
||||
nsXFormsUtils::EvaluateNodeBinding(nsIDOMElement *aElement,
|
||||
PRUint32 aElementFlags,
|
||||
@ -2233,3 +2302,326 @@ nsXFormsUtils::GetWindowFromDocument(nsIDOMDocument *aDoc,
|
||||
NS_ADDREF(*aWindow = internal);
|
||||
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 nsIMutableArray;
|
||||
class nsIDOMEvent;
|
||||
class nsIDOMXPathEvaluator;
|
||||
class nsIDOMXPathExpression;
|
||||
class nsIDOMXPathNSResolver;
|
||||
class nsIXPathEvaluatorInternal;
|
||||
|
||||
#define NS_NAMESPACE_XFORMS "http://www.w3.org/2002/xforms"
|
||||
#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_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
|
||||
*/
|
||||
@ -236,7 +243,7 @@ public:
|
||||
* and returned (addrefed) in |aModel|
|
||||
*
|
||||
* The return value is an XPathResult as returned from
|
||||
* nsIXFormsXPathEvaluator::Evaluate().
|
||||
* nsIDOMXPathEvaluator::Evaluate().
|
||||
*/
|
||||
static NS_HIDDEN_(nsresult)
|
||||
EvaluateNodeBinding(nsIDOMElement *aElement,
|
||||
@ -251,10 +258,17 @@ public:
|
||||
nsCOMArray<nsIDOMNode> *aDeps = 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
|
||||
* nsIXFormsXPathEvaluator from |aContextNode|'s ownerDocument, and calls
|
||||
* nsIXFormsXPathEvaluator::Evalute using the given expression, context node,
|
||||
* nsIDOMXPathEvaluator from |aContextNode|'s ownerDocument, and calls
|
||||
* nsIDOMXPathEvaluator::Evaluate using the given expression, context node,
|
||||
* namespace resolver, and result type.
|
||||
*/
|
||||
static NS_HIDDEN_(nsresult)
|
||||
@ -268,6 +282,18 @@ public:
|
||||
nsCOMArray<nsIDOMNode> *aSet = 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
|
||||
* to section 8.1.1 of the XForms specification.
|
||||
@ -552,6 +578,63 @@ public:
|
||||
static NS_HIDDEN_(nsresult) GetWindowFromDocument(nsIDOMDocument *aDoc,
|
||||
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:
|
||||
/**
|
||||
* Do same origin checks on aBaseDocument and aTestURI. Hosts can be
|
||||
|
@ -45,9 +45,12 @@
|
||||
//#define DEBUG_XF_ANALYZER
|
||||
#endif
|
||||
|
||||
nsXFormsXPathAnalyzer::nsXFormsXPathAnalyzer(nsIXFormsXPathEvaluator *aEvaluator,
|
||||
nsIDOMNode *aResolver)
|
||||
: mEvaluator(aEvaluator), mResolver(aResolver)
|
||||
nsXFormsXPathAnalyzer::nsXFormsXPathAnalyzer(nsIXPathEvaluatorInternal *aEvaluator,
|
||||
nsIDOMXPathNSResolver *aResolver,
|
||||
nsISupports *aState)
|
||||
: mEvaluator(aEvaluator),
|
||||
mResolver(aResolver),
|
||||
mState(aState)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsXFormsXPathAnalyzer);
|
||||
}
|
||||
@ -174,9 +177,10 @@ nsXFormsXPathAnalyzer::AnalyzeRecursively(nsIDOMNode *aContextNode,
|
||||
xp = Substring(*mCurExprString, aNode->mStartIndex,
|
||||
aNode->mEndIndex - aNode->mStartIndex);
|
||||
}
|
||||
rv = mEvaluator->Evaluate(xp, aContextNode, mCurPosition, mCurSize,
|
||||
mResolver, nsIDOMXPathResult::ANY_TYPE,
|
||||
nsnull, getter_AddRefs(result));
|
||||
rv = nsXFormsUtils::EvaluateXPath(mEvaluator, xp, aContextNode, mResolver,
|
||||
mState, nsIDOMXPathResult::ANY_TYPE,
|
||||
mCurPosition, mCurSize, nsnull,
|
||||
getter_AddRefs(result));
|
||||
if (NS_FAILED(rv)) {
|
||||
const PRUnichar *strings[] = { xp.get() };
|
||||
nsXFormsUtils::ReportError(NS_LITERAL_STRING("exprEvaluateError"),
|
||||
@ -194,10 +198,13 @@ nsXFormsXPathAnalyzer::AnalyzeRecursively(nsIDOMNode *aContextNode,
|
||||
nsDependentSubstring indexExpr = Substring(xp,
|
||||
indexSize,
|
||||
xp.Length() - indexSize - 1); // remove final ')' too
|
||||
|
||||
nsCOMPtr<nsIDOMXPathResult> stringRes;
|
||||
rv = mEvaluator->Evaluate(indexExpr, aContextNode, mCurPosition, mCurSize,
|
||||
mResolver, nsIDOMXPathResult::STRING_TYPE,
|
||||
nsnull, getter_AddRefs(stringRes));
|
||||
rv = nsXFormsUtils::EvaluateXPath(mEvaluator, indexExpr, aContextNode,
|
||||
mResolver, mState,
|
||||
nsIDOMXPathResult::STRING_TYPE,
|
||||
mCurPosition, mCurSize, nsnull,
|
||||
getter_AddRefs(stringRes));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoString indexId;
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsXFormsXPathNode.h"
|
||||
#include "nsIDOMNSXPathExpression.h"
|
||||
#include "nsIXFormsXPathEvaluator.h"
|
||||
#include "nsIXPathEvaluatorInternal.h"
|
||||
#include "nsIDOMXPathNSResolver.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsCOMPtr.h"
|
||||
@ -58,8 +58,9 @@
|
||||
*/
|
||||
class nsXFormsXPathAnalyzer {
|
||||
private:
|
||||
nsCOMPtr<nsIXFormsXPathEvaluator> mEvaluator;
|
||||
nsCOMPtr<nsIDOMNode> mResolver;
|
||||
nsCOMPtr<nsIXPathEvaluatorInternal> mEvaluator;
|
||||
nsCOMPtr<nsIDOMXPathNSResolver> mResolver;
|
||||
nsCOMPtr<nsISupports> mState;
|
||||
|
||||
nsCOMArray<nsIDOMNode> *mCurSet;
|
||||
nsCOMPtr<nsIDOMNSXPathExpression> mCurExpression;
|
||||
@ -74,8 +75,9 @@ private:
|
||||
PRBool aCollect = PR_FALSE);
|
||||
|
||||
public:
|
||||
nsXFormsXPathAnalyzer(nsIXFormsXPathEvaluator *aEvaluator,
|
||||
nsIDOMNode *aResolver);
|
||||
nsXFormsXPathAnalyzer(nsIXPathEvaluatorInternal *aEvaluator,
|
||||
nsIDOMXPathNSResolver *aResolver,
|
||||
nsISupports *aState);
|
||||
~nsXFormsXPathAnalyzer();
|
||||
|
||||
nsresult Analyze(nsIDOMNode *aContextNode,
|
||||
|
426
extensions/xforms/nsXFormsXPathFunctions.cpp
Normal file
426
extensions/xforms/nsXFormsXPathFunctions.cpp
Normal file
@ -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 ***** */
|
||||
|
||||
#ifndef TRANSFRMX_XFORMS_FUNCTIONS_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 {
|
||||
#include "nsIXFormsXPathFunctions.h"
|
||||
|
||||
class nsXFormsXPathFunctions : public nsIXFormsXPathFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
enum XFormsFunctions {
|
||||
AVG, // avg()
|
||||
BOOLEANFROMSTRING, // boolean-from-string()
|
||||
COUNTNONEMPTY, // count-non-empty()
|
||||
DAYSFROMDATE, // days-from-date()
|
||||
IF, // if()
|
||||
INDEX, // index()
|
||||
INSTANCE, // instance()
|
||||
MAX, // max()
|
||||
MIN, // min()
|
||||
MONTHS, // months()
|
||||
NOW, // now()
|
||||
PROPERTY, // property()
|
||||
SECONDS, // seconds()
|
||||
SECONDSFROMDATETIME // seconds-from-dateTime()
|
||||
};
|
||||
|
||||
/*
|
||||
* Creates a Number function of the given type
|
||||
*/
|
||||
XFormsFunctionCall(XFormsFunctions aType, nsIDOMNode *resolverNode=nsnull);
|
||||
|
||||
TX_DECL_FUNCTION;
|
||||
|
||||
private:
|
||||
XFormsFunctions mType;
|
||||
nsCOMPtr<nsIDOMNode> mResolverNode;
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIXFORMSXPATHFUNCTIONS
|
||||
};
|
||||
|
||||
#endif
|
@ -108,10 +108,9 @@
|
||||
// Transformiix stuff
|
||||
#include "nsXPathEvaluator.h"
|
||||
#include "txMozillaXSLTProcessor.h"
|
||||
#include "txNodeSetAdaptor.h"
|
||||
#include "txXSLTProcessor.h"
|
||||
#include "nsXPath1Scheme.h"
|
||||
#include "nsXFormsXPathEvaluator.h"
|
||||
#include "txXSLTProcessor.h"
|
||||
|
||||
#include "nsDOMParser.h"
|
||||
#include "nsDOMSerializer.h"
|
||||
@ -200,12 +199,19 @@ static void Shutdown();
|
||||
#define TRANSFORMIIX_XPATH1_SCHEME_CID \
|
||||
{ 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)
|
||||
|
||||
// Factory Constructor
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(txMozillaXSLTProcessor)
|
||||
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(nsXMLHttpRequest)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMParser)
|
||||
@ -1253,16 +1259,16 @@ static const nsModuleComponentInfo gComponents[] = {
|
||||
NS_XPATH_EVALUATOR_CONTRACTID,
|
||||
nsXPathEvaluatorConstructor },
|
||||
|
||||
{ "XFormsXPathEvaluator",
|
||||
TRANSFORMIIX_XFORMS_XPATH_EVALUATOR_CID,
|
||||
NS_XFORMS_XPATH_EVALUATOR_CONTRACTID,
|
||||
nsXFormsXPathEvaluatorConstructor },
|
||||
|
||||
{ "XPath1 XPointer Scheme Processor",
|
||||
TRANSFORMIIX_XPATH1_SCHEME_CID,
|
||||
NS_XPOINTER_SCHEME_PROCESSOR_BASE "xpath1",
|
||||
nsXPath1SchemeProcessorConstructor },
|
||||
|
||||
{ "Transformiix NodeSet",
|
||||
TRANSFORMIIX_NODESET_CID,
|
||||
TRANSFORMIIX_NODESET_CONTRACTID,
|
||||
txNodeSetAdaptorConstructor },
|
||||
|
||||
{ "XML Serializer",
|
||||
NS_XMLSERIALIZER_CID,
|
||||
NS_XMLSERIALIZER_CONTRACTID,
|
||||
|
Loading…
x
Reference in New Issue
Block a user