Fix for bug 193678 (support exslt:common - exslt:common functions implementation). r/sr=sicking.

This commit is contained in:
peterv%propagandism.org 2006-11-16 21:42:25 +00:00
Родитель f9da27583e
Коммит 53885d7e4f
19 изменённых файлов: 546 добавлений и 128 удалений

Просмотреть файл

@ -503,6 +503,7 @@ GK_ATOM(nextBidi, "NextBidi")
GK_ATOM(no, "no")
GK_ATOM(nobr, "nobr")
GK_ATOM(node, "node")
GK_ATOM(nodeSet, "node-set")
GK_ATOM(noembed, "noembed")
GK_ATOM(noframes, "noframes")
GK_ATOM(nohref, "nohref")
@ -516,6 +517,7 @@ GK_ATOM(_not, "not")
GK_ATOM(nowrap, "nowrap")
GK_ATOM(number, "number")
GK_ATOM(object, "object")
GK_ATOM(objectType, "object-type")
GK_ATOM(observer, "observer")
GK_ATOM(observes, "observes")
GK_ATOM(odd, "odd")

Просмотреть файл

@ -61,7 +61,7 @@ public:
return NS_ERROR_FAILURE;
}
nsresult
resolveFunctionCall(nsIAtom* aName, PRInt32 aID, FunctionCall*& aFunction)
resolveFunctionCall(nsIAtom* aName, PRInt32 aID, FunctionCall** aFunction)
{
return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
}

Просмотреть файл

@ -85,7 +85,7 @@ public:
nsresult resolveNamespacePrefix(nsIAtom* aPrefix, PRInt32& aID);
nsresult resolveFunctionCall(nsIAtom* aName, PRInt32 aID,
FunctionCall*& aFunction);
FunctionCall** aFunction);
PRBool caseInsensitiveNameTests();
void SetErrorOffset(PRUint32 aOffset);
@ -288,12 +288,12 @@ nsresult nsXPathEvaluatorParseContext::resolveNamespacePrefix
extern nsresult
TX_ResolveFunctionCallXPCOM(const nsCString &aContractID, PRInt32 aNamespaceID,
nsIAtom *aName, nsISupports *aState,
FunctionCall *&aFunction);
FunctionCall **aFunction);
nsresult
nsXPathEvaluatorParseContext::resolveFunctionCall(nsIAtom* aName,
PRInt32 aID,
FunctionCall*& aFn)
FunctionCall** aFn)
{
nsresult rv = NS_ERROR_XPATH_UNKNOWN_FUNCTION;

Просмотреть файл

@ -465,7 +465,7 @@ txExprParser::createFunctionCall(txExprLexer& lexer, txIParseContext* aContext,
// check extension functions and xslt
if (!fnCall) {
rv = aContext->resolveFunctionCall(lName, namespaceID,
*getter_Transfers(fnCall));
getter_Transfers(fnCall));
if (rv == NS_ERROR_NOT_IMPLEMENTED) {
// this should just happen for unparsed-entity-uri()

Просмотреть файл

@ -59,7 +59,8 @@ class txAExprResult : public TxObject
public:
friend class txResultRecycler;
// Update txLiteralExpr::getReturnType if this enum is changed.
// Update txLiteralExpr::getReturnType and sTypes in txEXSLTFunctions.cpp if
// this enum is changed.
enum ResultType {
NODESET = 0,
BOOLEAN,

Просмотреть файл

@ -73,7 +73,7 @@ public:
* XSLT. XPath function calls are resolved by the Parser.
*/
virtual nsresult resolveFunctionCall(nsIAtom* aName, PRInt32 aID,
FunctionCall*& aFunction) = 0;
FunctionCall** aFunction) = 0;
/**
* Should nametests parsed in this context be case-sensitive

Просмотреть файл

@ -117,7 +117,8 @@ txNodeSetAdaptor::Add(nsIDOMNode *aNode)
{
NS_ENSURE_TRUE(mWritable, NS_ERROR_FAILURE);
nsAutoPtr<txXPathNode> node(txXPathNativeNode::createXPathNode(aNode));
nsAutoPtr<txXPathNode> node(txXPathNativeNode::createXPathNode(aNode,
PR_TRUE));
return node ? mNodeSet->add(*node) : NS_ERROR_OUT_OF_MEMORY;
}

Просмотреть файл

@ -260,7 +260,7 @@ LookupFunction(const char *aContractID, nsIAtom* aName, nsIID &aIID,
nsresult
TX_ResolveFunctionCallXPCOM(const nsCString &aContractID, PRInt32 aNamespaceID,
nsIAtom* aName, nsISupports *aState,
FunctionCall *&aFunction)
FunctionCall **aFunction)
{
nsIID iid;
PRUint16 methodIndex;
@ -271,13 +271,17 @@ TX_ResolveFunctionCallXPCOM(const nsCString &aContractID, PRInt32 aNamespaceID,
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);
if (!aFunction) {
return NS_OK;
}
return aFunction ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
*aFunction = new txXPCOMExtensionFunctionCall(helper, iid, methodIndex,
#ifdef TX_TO_STRING
aNamespaceID, aName,
#endif
aState);
return *aFunction ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
txArgumentType

Просмотреть файл

@ -84,6 +84,7 @@ CPPSRCS = \
txXPathResultComparator.cpp \
txBufferingHandler.cpp \
txExecutionState.cpp \
txEXSLTFunctions.cpp \
txInstructions.cpp \
txOutputFormat.cpp \
txRtfHandler.cpp \

Просмотреть файл

@ -0,0 +1,311 @@
/* -*- 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) 2003
* 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 "nsIAtom.h"
#include "txAtoms.h"
#include "txExecutionState.h"
#include "txExpr.h"
#include "txIXPathContext.h"
#include "txNodeSet.h"
#include "txOutputFormat.h"
#include "txRtfHandler.h"
#include "txXPathTreeWalker.h"
#ifndef TX_EXE
#include "nsComponentManagerUtils.h"
#include "nsContentCID.h"
#include "nsContentCreatorFunctions.h"
#include "nsIContent.h"
#include "nsIDOMDocumentFragment.h"
#include "nsIDOMText.h"
#include "txMozillaXMLOutput.h"
#endif
class txStylesheetCompilerState;
static nsresult
convertRtfToNode(txIEvalContext *aContext, txResultTreeFragment *aRtf)
{
txExecutionState* es =
NS_STATIC_CAST(txExecutionState*, aContext->getPrivateContext());
if (!es) {
NS_ERROR("Need txExecutionState!");
return NS_ERROR_UNEXPECTED;
}
const txXPathNode& document = es->getSourceDocument();
#ifdef TX_EXE
return NS_ERROR_NOT_IMPLEMENTED;
#else
nsIDocument *doc = txXPathNativeNode::getDocument(document);
nsCOMPtr<nsIDOMDocumentFragment> domFragment;
nsresult rv = NS_NewDocumentFragment(getter_AddRefs(domFragment),
doc->NodeInfoManager());
NS_ENSURE_SUCCESS(rv, rv);
txOutputFormat format;
txMozillaXMLOutput mozHandler(&format, domFragment, PR_TRUE);
rv = aRtf->flushToHandler(&mozHandler);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsINode> fragment = do_QueryInterface(domFragment, &rv);
NS_ENSURE_SUCCESS(rv, rv);
// The txResultTreeFragment will own this.
const txXPathNode* node = txXPathNativeNode::createXPathNode(domFragment,
PR_TRUE);
NS_ENSURE_TRUE(node, NS_ERROR_OUT_OF_MEMORY);
aRtf->setNode(node);
return NS_OK;
#endif
}
static nsresult
createTextNode(txIEvalContext *aContext, nsString& aValue,
txXPathNode* *aResult)
{
txExecutionState* es =
NS_STATIC_CAST(txExecutionState*, aContext->getPrivateContext());
if (!es) {
NS_ERROR("Need txExecutionState!");
return NS_ERROR_UNEXPECTED;
}
const txXPathNode& document = es->getSourceDocument();
#ifdef TX_EXE
return NS_ERROR_NOT_IMPLEMENTED;
#else
nsIDocument *doc = txXPathNativeNode::getDocument(document);
nsCOMPtr<nsIContent> text;
nsresult rv = NS_NewTextNode(getter_AddRefs(text), doc->NodeInfoManager());
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMText> domText = do_QueryInterface(text, &rv);
NS_ENSURE_SUCCESS(rv, rv);
*aResult = txXPathNativeNode::createXPathNode(domText, PR_TRUE);
NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
#endif
}
class txEXSLTNodeSetFunctionCall : public FunctionCall
{
public:
TX_DECL_FUNCTION;
};
nsresult
txEXSLTNodeSetFunctionCall::evaluate(txIEvalContext *aContext,
txAExprResult **aResult)
{
*aResult = nsnull;
if (!requireParams(1, 1, aContext)) {
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
}
txListIterator iter(&params);
Expr* param1 = NS_STATIC_CAST(Expr*, iter.next());
nsRefPtr<txAExprResult> exprResult;
nsresult rv = param1->evaluate(aContext, getter_AddRefs(exprResult));
NS_ENSURE_SUCCESS(rv, rv);
if (exprResult->getResultType() == txAExprResult::NODESET) {
exprResult.swap(*aResult);
}
else {
nsRefPtr<txNodeSet> nodeset;
rv = aContext->recycler()->getNodeSet(getter_AddRefs(nodeset));
NS_ENSURE_SUCCESS(rv, rv);
if (exprResult->getResultType() == txAExprResult::RESULT_TREE_FRAGMENT) {
txResultTreeFragment *rtf =
NS_STATIC_CAST(txResultTreeFragment*,
NS_STATIC_CAST(txAExprResult*, exprResult));
const txXPathNode *node = rtf->getNode();
if (!node) {
rv = convertRtfToNode(aContext, rtf);
NS_ENSURE_SUCCESS(rv, rv);
node = rtf->getNode();
}
nodeset->append(*node);
}
else {
nsAutoString value;
exprResult->stringValue(value);
nsAutoPtr<txXPathNode> node;
rv = createTextNode(aContext, value, getter_Transfers(node));
NS_ENSURE_SUCCESS(rv, rv);
nodeset->append(*node);
}
NS_ADDREF(*aResult = nodeset);
}
return NS_OK;
}
Expr::ResultType
txEXSLTNodeSetFunctionCall::getReturnType()
{
return Expr::NODESET_RESULT;
}
PRBool
txEXSLTNodeSetFunctionCall::isSensitiveTo(ContextSensitivity aContext)
{
return argsSensitiveTo(aContext);
}
#ifdef TX_TO_STRING
nsresult
txEXSLTNodeSetFunctionCall::getNameAtom(nsIAtom **aAtom)
{
NS_ADDREF(*aAtom = txXSLTAtoms::nodeSet);
return NS_OK;
}
#endif
class txEXSLTObjectTypeFunctionCall : public FunctionCall
{
public:
TX_DECL_FUNCTION;
};
// Need to update this array if types are added to the ResultType enum in
// txAExprResult.
static const char * const sTypes[] = {
"node-set",
"boolean",
"number",
"string",
"RTF"
};
nsresult
txEXSLTObjectTypeFunctionCall::evaluate(txIEvalContext *aContext,
txAExprResult **aResult)
{
*aResult = nsnull;
if (!requireParams(1, 1, aContext)) {
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
}
txListIterator iter(&params);
Expr* param1 = NS_STATIC_CAST(Expr*, iter.next());
nsRefPtr<txAExprResult> exprResult;
nsresult rv = param1->evaluate(aContext, getter_AddRefs(exprResult));
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<StringResult> strRes;
rv = aContext->recycler()->getStringResult(getter_AddRefs(strRes));
NS_ENSURE_SUCCESS(rv, rv);
AppendASCIItoUTF16(sTypes[exprResult->getResultType()], strRes->mValue);
NS_ADDREF(*aResult = strRes);
return NS_OK;
}
Expr::ResultType
txEXSLTObjectTypeFunctionCall::getReturnType()
{
return Expr::STRING_RESULT;
}
PRBool
txEXSLTObjectTypeFunctionCall::isSensitiveTo(ContextSensitivity aContext)
{
return argsSensitiveTo(aContext);
}
#ifdef TX_TO_STRING
nsresult
txEXSLTObjectTypeFunctionCall::getNameAtom(nsIAtom **aAtom)
{
NS_ADDREF(*aAtom = txXSLTAtoms::objectType);
return NS_OK;
}
#endif
extern nsresult
TX_ConstructEXSLTCommonFunction(nsIAtom *aName,
txStylesheetCompilerState* aState,
FunctionCall **aResult)
{
if (aName == txXSLTAtoms::nodeSet) {
if (aResult) {
*aResult = new txEXSLTNodeSetFunctionCall();
NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
}
return NS_OK;
}
if (aName == txXSLTAtoms::objectType) {
if (aResult) {
*aResult = new txEXSLTObjectTypeFunctionCall();
NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
}
return NS_OK;
}
return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
}

Просмотреть файл

@ -95,7 +95,6 @@ txExecutionState::txExecutionState(txStylesheet* aStylesheet,
mTemplateRuleCount(0),
mEvalContext(nsnull),
mInitialEvalContext(nsnull),
// mRTFDocument(nsnull),
mGlobalParams(nsnull),
mKeyHash(aStylesheet->getKeyMap()),
mDisableLoads(aDisableLoads)
@ -107,7 +106,6 @@ txExecutionState::~txExecutionState()
delete mResultHandler;
delete mLocalVariables;
delete mEvalContext;
// delete mRTFDocument;
PRInt32 i;
for (i = 0; i < mTemplateRuleCount; ++i) {

Просмотреть файл

@ -134,6 +134,13 @@ public:
const nsAString& aKeyValue, PRBool aIndexIfNotFound,
txNodeSet** aResult);
TemplateRule* getCurrentTemplateRule();
const txXPathNode& getSourceDocument()
{
NS_ASSERTION(mLoadedDocuments.mSourceDocument,
"Need a source document!");
return *mLoadedDocuments.mSourceDocument;
}
// state-modification functions
txInstruction* getNextInstruction();

Просмотреть файл

@ -90,7 +90,8 @@ txMozillaXMLOutput::txMozillaXMLOutput(const nsSubstring& aRootName,
mHaveBaseElement(PR_FALSE),
mCreatingNewDocument(PR_TRUE),
mOpenedElementIsHTML(PR_FALSE),
mRootContentCreated(PR_FALSE)
mRootContentCreated(PR_FALSE),
mNoFixup(PR_FALSE)
{
if (aObserver) {
mNotifier = new txTransformNotifier();
@ -106,7 +107,8 @@ txMozillaXMLOutput::txMozillaXMLOutput(const nsSubstring& aRootName,
}
txMozillaXMLOutput::txMozillaXMLOutput(txOutputFormat* aFormat,
nsIDOMDocumentFragment* aFragment)
nsIDOMDocumentFragment* aFragment,
PRBool aNoFixup)
: mTreeDepth(0),
mBadChildLevel(0),
mTableState(NORMAL),
@ -114,7 +116,8 @@ txMozillaXMLOutput::txMozillaXMLOutput(txOutputFormat* aFormat,
mHaveBaseElement(PR_FALSE),
mCreatingNewDocument(PR_FALSE),
mOpenedElementIsHTML(PR_FALSE),
mRootContentCreated(PR_FALSE)
mRootContentCreated(PR_FALSE),
mNoFixup(aNoFixup)
{
mOutputFormat.merge(*aFormat);
mOutputFormat.setFromDefaults();
@ -317,25 +320,27 @@ txMozillaXMLOutput::endElement()
mCurrentNode));
// Handle html-elements
if (element->IsNodeOfType(nsINode::eHTML)) {
rv = endHTMLElement(element);
NS_ENSURE_SUCCESS(rv, rv);
}
// Handle script elements
if (element->Tag() == nsGkAtoms::script &&
(element->IsNodeOfType(nsINode::eHTML) ||
element->GetNameSpaceID() == kNameSpaceID_SVG)) {
rv = element->DoneAddingChildren(PR_TRUE);
// If the act of insertion evaluated the script, we're fine.
// Else, add this script element to the array of loading scripts.
if (rv == NS_ERROR_HTMLPARSER_BLOCK) {
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(element);
rv = mNotifier->AddScriptElement(sele);
if (!mNoFixup) {
if (element->IsNodeOfType(nsINode::eHTML)) {
rv = endHTMLElement(element);
NS_ENSURE_SUCCESS(rv, rv);
}
// Handle script elements
if (element->Tag() == nsGkAtoms::script &&
(element->IsNodeOfType(nsINode::eHTML) ||
element->GetNameSpaceID() == kNameSpaceID_SVG)) {
rv = element->DoneAddingChildren(PR_TRUE);
// If the act of insertion evaluated the script, we're fine.
// Else, add this script element to the array of loading scripts.
if (rv == NS_ERROR_HTMLPARSER_BLOCK) {
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(element);
rv = mNotifier->AddScriptElement(sele);
NS_ENSURE_SUCCESS(rv, rv);
}
}
}
if (mCreatingNewDocument) {
@ -556,15 +561,18 @@ txMozillaXMLOutput::startElementInternal(nsIAtom* aPrefix,
NS_NewElement(getter_AddRefs(mOpenedElement), aElemType, ni);
// Set up the element and adjust state
if (aElemType == kNameSpaceID_XHTML) {
mOpenedElementIsHTML = aNsID != kNameSpaceID_XHTML;
rv = startHTMLElement(mOpenedElement, mOpenedElementIsHTML);
NS_ENSURE_SUCCESS(rv, rv);
if (!mNoFixup) {
if (aElemType == kNameSpaceID_XHTML) {
mOpenedElementIsHTML = aNsID != kNameSpaceID_XHTML;
rv = startHTMLElement(mOpenedElement, mOpenedElementIsHTML);
NS_ENSURE_SUCCESS(rv, rv);
}
else if (aNsID == kNameSpaceID_SVG && aLocalName == txHTMLAtoms::script) {
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(mOpenedElement);
sele->WillCallDoneAddingChildren();
}
else if (aNsID == kNameSpaceID_SVG &&
aLocalName == txHTMLAtoms::script) {
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(mOpenedElement);
sele->WillCallDoneAddingChildren();
}
}
if (mCreatingNewDocument) {

Просмотреть файл

@ -101,7 +101,8 @@ public:
nsIDOMDocument* aResultDocument,
nsITransformObserver* aObserver);
txMozillaXMLOutput(txOutputFormat* aFormat,
nsIDOMDocumentFragment* aFragment);
nsIDOMDocumentFragment* aFragment,
PRBool aNoFixup);
virtual ~txMozillaXMLOutput();
TX_DECL_TXAXMLEVENTHANDLER
@ -164,6 +165,8 @@ private:
// Set to true when we know there's a root content in our document.
PRPackedBool mRootContentCreated;
PRPackedBool mNoFixup;
enum txAction { eCloseElement = 1, eFlushText = 2 };
};

Просмотреть файл

@ -205,14 +205,14 @@ txToFragmentHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
format.mMethod = eHTMLOutput;
}
*aHandler = new txMozillaXMLOutput(&format, mFragment);
*aHandler = new txMozillaXMLOutput(&format, mFragment, PR_FALSE);
break;
}
case eXMLOutput:
case eHTMLOutput:
{
*aHandler = new txMozillaXMLOutput(aFormat, mFragment);
*aHandler = new txMozillaXMLOutput(aFormat, mFragment, PR_FALSE);
break;
}
@ -390,7 +390,7 @@ class txXSLTParamContext : public txIParseContext,
public txIEvalContext
{
public:
txXSLTParamContext(txNamespaceMap *aResolver, txXPathNode& aContext,
txXSLTParamContext(txNamespaceMap *aResolver, const txXPathNode& aContext,
txResultRecycler* aRecycler)
: mResolver(aResolver),
mContext(aContext),
@ -406,7 +406,7 @@ public:
NS_OK;
}
nsresult resolveFunctionCall(nsIAtom* aName, PRInt32 aID,
FunctionCall*& aFunction)
FunctionCall** aFunction)
{
return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
}
@ -455,9 +455,8 @@ public:
private:
txNamespaceMap *mResolver;
txXPathNode& mContext;
const txXPathNode& mContext;
txResultRecycler* mRecycler;
};

Просмотреть файл

@ -42,6 +42,7 @@
#include "txBufferingHandler.h"
#include "txExprResult.h"
#include "txXPathNode.h"
class txResultTreeFragment : public txAExprResult
{
@ -53,8 +54,20 @@ public:
nsresult flushToHandler(txAXMLEventHandler* aHandler);
void setNode(const txXPathNode* aNode)
{
NS_ASSERTION(!mNode, "Already converted!");
mNode = aNode;
}
const txXPathNode *getNode() const
{
return mNode;
}
private:
nsAutoPtr<txResultBuffer> mBuffer;
nsAutoPtr<const txXPathNode> mNode;
};
class txRtfHandler : public txBufferingHandler

Просмотреть файл

@ -938,80 +938,153 @@ txErrorFunctionCall::getNameAtom(nsIAtom** aAtom)
}
#endif
nsresult
txStylesheetCompilerState::resolveFunctionCall(nsIAtom* aName, PRInt32 aID,
FunctionCall*& aFunction)
static nsresult
TX_ConstructXSLTFunction(nsIAtom* aName, txStylesheetCompilerState* aState,
FunctionCall** aFunction)
{
aFunction = nsnull;
if (aName == txXSLTAtoms::document) {
if (aFunction) {
*aFunction =
new DocumentFunctionCall(aState->mElementContext->mBaseURI);
NS_ENSURE_TRUE(*aFunction, NS_ERROR_OUT_OF_MEMORY);
}
if (aID == kNameSpaceID_None) {
if (aName == txXSLTAtoms::document) {
aFunction = new DocumentFunctionCall(mElementContext->mBaseURI);
NS_ENSURE_TRUE(aFunction, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
return NS_OK;
}
if (aName == txXSLTAtoms::key) {
if (aFunction) {
*aFunction =
new txKeyFunctionCall(aState->mElementContext->mMappings);
NS_ENSURE_TRUE(*aFunction, NS_ERROR_OUT_OF_MEMORY);
}
if (aName == txXSLTAtoms::key) {
aFunction = new txKeyFunctionCall(mElementContext->mMappings);
NS_ENSURE_TRUE(aFunction, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
return NS_OK;
}
if (aName == txXSLTAtoms::formatNumber) {
if (aFunction) {
*aFunction =
new txFormatNumberFunctionCall(aState->mStylesheet,
aState->mElementContext->mMappings);
NS_ENSURE_TRUE(*aFunction, NS_ERROR_OUT_OF_MEMORY);
}
if (aName == txXSLTAtoms::formatNumber) {
aFunction = new txFormatNumberFunctionCall(mStylesheet,
mElementContext->mMappings);
NS_ENSURE_TRUE(aFunction, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
return NS_OK;
}
if (aName == txXSLTAtoms::current) {
if (aFunction) {
*aFunction = new CurrentFunctionCall();
NS_ENSURE_TRUE(*aFunction, NS_ERROR_OUT_OF_MEMORY);
}
if (aName == txXSLTAtoms::current) {
aFunction = new CurrentFunctionCall();
NS_ENSURE_TRUE(aFunction, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
return NS_OK;
}
if (aName == txXSLTAtoms::unparsedEntityUri) {
return NS_ERROR_NOT_IMPLEMENTED;
}
if (aName == txXSLTAtoms::generateId) {
if (aFunction) {
*aFunction = new GenerateIdFunctionCall();
NS_ENSURE_TRUE(*aFunction, NS_ERROR_OUT_OF_MEMORY);
}
if (aName == txXSLTAtoms::unparsedEntityUri) {
return NS_ERROR_NOT_IMPLEMENTED;
}
if (aName == txXSLTAtoms::generateId) {
aFunction = new GenerateIdFunctionCall();
NS_ENSURE_TRUE(aFunction, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
if (aName == txXSLTAtoms::systemProperty) {
aFunction = new txXSLTEnvironmentFunctionCall(
txXSLTEnvironmentFunctionCall::SYSTEM_PROPERTY,
mElementContext->mMappings);
NS_ENSURE_TRUE(aFunction, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
if (aName == txXSLTAtoms::elementAvailable) {
aFunction = new txXSLTEnvironmentFunctionCall(
txXSLTEnvironmentFunctionCall::ELEMENT_AVAILABLE,
mElementContext->mMappings);
NS_ENSURE_TRUE(aFunction, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
if (aName == txXSLTAtoms::functionAvailable) {
aFunction = new txXSLTEnvironmentFunctionCall(
txXSLTEnvironmentFunctionCall::FUNCTION_AVAILABLE,
mElementContext->mMappings);
NS_ENSURE_TRUE(aFunction, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
if (!fcp()) {
return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
return NS_OK;
}
txXSLTEnvironmentFunctionCall::eType type;
if (aName == txXSLTAtoms::systemProperty) {
type = txXSLTEnvironmentFunctionCall::SYSTEM_PROPERTY;
}
else if (aName == txXSLTAtoms::elementAvailable) {
type = txXSLTEnvironmentFunctionCall::ELEMENT_AVAILABLE;
}
else if (aName == txXSLTAtoms::functionAvailable) {
type = txXSLTEnvironmentFunctionCall::FUNCTION_AVAILABLE;
}
else {
return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
}
if (!aFunction) {
return NS_OK;
}
txNamespaceMap *map = aState->mElementContext->mMappings;
*aFunction = new txXSLTEnvironmentFunctionCall(type, map);
return *aFunction ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
typedef nsresult (*txFunctionFactory)(nsIAtom* aName,
txStylesheetCompilerState* aState,
FunctionCall** aResult);
struct txFunctionFactoryMapping
{
const char* const mNamespaceURI;
PRInt32 mNamespaceID;
txFunctionFactory mFactory;
};
extern nsresult
TX_ConstructEXSLTCommonFunction(nsIAtom *aName,
txStylesheetCompilerState* aState,
FunctionCall **aResult);
static txFunctionFactoryMapping kExtensionFunctions[] = {
{ "", kNameSpaceID_Unknown, TX_ConstructXSLTFunction },
{ "http://exslt.org/common", kNameSpaceID_Unknown,
TX_ConstructEXSLTCommonFunction }
};
static nsresult
findFunction(nsIAtom* aName, PRInt32 aNamespaceID,
txStylesheetCompilerState* aState, FunctionCall** aResult)
{
if (kExtensionFunctions[0].mNamespaceID == kNameSpaceID_Unknown) {
PRUint32 i;
for (i = 0; i < NS_ARRAY_LENGTH(kExtensionFunctions); ++i) {
txFunctionFactoryMapping& mapping = kExtensionFunctions[i];
NS_ConvertASCIItoUTF16 namespaceURI(mapping.mNamespaceURI);
mapping.mNamespaceID =
txNamespaceManager::getNamespaceID(namespaceURI);
}
}
aFunction = new txErrorFunctionCall(aName, aID);
PRUint32 i;
for (i = 0; i < NS_ARRAY_LENGTH(kExtensionFunctions); ++i) {
const txFunctionFactoryMapping& mapping = kExtensionFunctions[i];
if (mapping.mNamespaceID == aNamespaceID) {
return mapping.mFactory(aName, aState, aResult);
}
}
return aFunction ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
}
extern PRBool
TX_XSLTFunctionAvailable(nsIAtom* aName, PRInt32 aNameSpaceID)
{
return NS_SUCCEEDED(findFunction(aName, aNameSpaceID, nsnull, nsnull));
}
nsresult
txStylesheetCompilerState::resolveFunctionCall(nsIAtom* aName, PRInt32 aID,
FunctionCall **aFunction)
{
*aFunction = nsnull;
nsresult rv = findFunction(aName, aID, this, aFunction);
if (rv == NS_ERROR_XPATH_UNKNOWN_FUNCTION &&
(aID != kNameSpaceID_None || fcp())) {
*aFunction = new txErrorFunctionCall(aName, aID);
rv = *aFunction ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
return rv;
}
PRBool

Просмотреть файл

@ -140,7 +140,7 @@ public:
// txIParseContext
nsresult resolveNamespacePrefix(nsIAtom* aPrefix, PRInt32& aID);
nsresult resolveFunctionCall(nsIAtom* aName, PRInt32 aID,
FunctionCall*& aFunction);
FunctionCall** aFunction);
PRBool caseInsensitiveNameTests();
/**

Просмотреть файл

@ -129,18 +129,15 @@ txXSLTEnvironmentFunctionCall::evaluate(txIEvalContext* aContext,
}
case FUNCTION_AVAILABLE:
{
extern PRBool TX_XSLTFunctionAvailable(nsIAtom* aName,
PRInt32 aNameSpaceID);
txCoreFunctionCall::eType type;
PRBool val = qname.mNamespaceID == kNameSpaceID_None &&
(txCoreFunctionCall::getTypeFromAtom(qname.mLocalName, type) ||
qname.mLocalName == txXSLTAtoms::current ||
qname.mLocalName == txXSLTAtoms::document ||
qname.mLocalName == txXSLTAtoms::elementAvailable ||
qname.mLocalName == txXSLTAtoms::formatNumber ||
qname.mLocalName == txXSLTAtoms::functionAvailable ||
qname.mLocalName == txXSLTAtoms::generateId ||
qname.mLocalName == txXSLTAtoms::key ||
//qname.mLocalName == txXSLTAtoms::unparsedEntityUri ||
qname.mLocalName == txXSLTAtoms::systemProperty);
PRBool val = (qname.mNamespaceID == kNameSpaceID_None &&
txCoreFunctionCall::getTypeFromAtom(qname.mLocalName,
type)) ||
TX_XSLTFunctionAvailable(qname.mLocalName,
qname.mNamespaceID);
aContext->recycler()->getBoolResult(val, aResult);
break;