diff --git a/mozilla/content/base/src/nsGkAtomList.h b/mozilla/content/base/src/nsGkAtomList.h index c65a3caf454..0e1c431dabb 100755 --- a/mozilla/content/base/src/nsGkAtomList.h +++ b/mozilla/content/base/src/nsGkAtomList.h @@ -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") diff --git a/mozilla/content/xslt/src/main/txTestExpr.cpp b/mozilla/content/xslt/src/main/txTestExpr.cpp index 8da3559c898..bbb88341faf 100644 --- a/mozilla/content/xslt/src/main/txTestExpr.cpp +++ b/mozilla/content/xslt/src/main/txTestExpr.cpp @@ -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; } diff --git a/mozilla/content/xslt/src/xpath/nsXPathEvaluator.cpp b/mozilla/content/xslt/src/xpath/nsXPathEvaluator.cpp index 63e1c1e8841..0d4890d05da 100644 --- a/mozilla/content/xslt/src/xpath/nsXPathEvaluator.cpp +++ b/mozilla/content/xslt/src/xpath/nsXPathEvaluator.cpp @@ -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; diff --git a/mozilla/content/xslt/src/xpath/txExprParser.cpp b/mozilla/content/xslt/src/xpath/txExprParser.cpp index 99b10c3333a..72306191b6b 100644 --- a/mozilla/content/xslt/src/xpath/txExprParser.cpp +++ b/mozilla/content/xslt/src/xpath/txExprParser.cpp @@ -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() diff --git a/mozilla/content/xslt/src/xpath/txExprResult.h b/mozilla/content/xslt/src/xpath/txExprResult.h index fd4ae44fa25..50ce82c60be 100644 --- a/mozilla/content/xslt/src/xpath/txExprResult.h +++ b/mozilla/content/xslt/src/xpath/txExprResult.h @@ -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, diff --git a/mozilla/content/xslt/src/xpath/txIXPathContext.h b/mozilla/content/xslt/src/xpath/txIXPathContext.h index 86ac85e581c..f6c71784354 100644 --- a/mozilla/content/xslt/src/xpath/txIXPathContext.h +++ b/mozilla/content/xslt/src/xpath/txIXPathContext.h @@ -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 diff --git a/mozilla/content/xslt/src/xpath/txNodeSetAdaptor.cpp b/mozilla/content/xslt/src/xpath/txNodeSetAdaptor.cpp index b4e1d20b9a8..6020a60452d 100644 --- a/mozilla/content/xslt/src/xpath/txNodeSetAdaptor.cpp +++ b/mozilla/content/xslt/src/xpath/txNodeSetAdaptor.cpp @@ -117,7 +117,8 @@ txNodeSetAdaptor::Add(nsIDOMNode *aNode) { NS_ENSURE_TRUE(mWritable, NS_ERROR_FAILURE); - nsAutoPtr node(txXPathNativeNode::createXPathNode(aNode)); + nsAutoPtr node(txXPathNativeNode::createXPathNode(aNode, + PR_TRUE)); return node ? mNodeSet->add(*node) : NS_ERROR_OUT_OF_MEMORY; } diff --git a/mozilla/content/xslt/src/xpath/txXPCOMExtensionFunction.cpp b/mozilla/content/xslt/src/xpath/txXPCOMExtensionFunction.cpp index 566b3097fd4..8400955d751 100644 --- a/mozilla/content/xslt/src/xpath/txXPCOMExtensionFunction.cpp +++ b/mozilla/content/xslt/src/xpath/txXPCOMExtensionFunction.cpp @@ -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 diff --git a/mozilla/content/xslt/src/xslt/Makefile.in b/mozilla/content/xslt/src/xslt/Makefile.in index eece02f7a30..09c9674865f 100644 --- a/mozilla/content/xslt/src/xslt/Makefile.in +++ b/mozilla/content/xslt/src/xslt/Makefile.in @@ -84,6 +84,7 @@ CPPSRCS = \ txXPathResultComparator.cpp \ txBufferingHandler.cpp \ txExecutionState.cpp \ + txEXSLTFunctions.cpp \ txInstructions.cpp \ txOutputFormat.cpp \ txRtfHandler.cpp \ diff --git a/mozilla/content/xslt/src/xslt/txEXSLTFunctions.cpp b/mozilla/content/xslt/src/xslt/txEXSLTFunctions.cpp new file mode 100644 index 00000000000..7e1ac55f015 --- /dev/null +++ b/mozilla/content/xslt/src/xslt/txEXSLTFunctions.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 + * + * + * 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 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 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 text; + nsresult rv = NS_NewTextNode(getter_AddRefs(text), doc->NodeInfoManager()); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr 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(¶ms); + Expr* param1 = NS_STATIC_CAST(Expr*, iter.next()); + + nsRefPtr exprResult; + nsresult rv = param1->evaluate(aContext, getter_AddRefs(exprResult)); + NS_ENSURE_SUCCESS(rv, rv); + + if (exprResult->getResultType() == txAExprResult::NODESET) { + exprResult.swap(*aResult); + } + else { + nsRefPtr 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 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(¶ms); + Expr* param1 = NS_STATIC_CAST(Expr*, iter.next()); + + nsRefPtr exprResult; + nsresult rv = param1->evaluate(aContext, getter_AddRefs(exprResult)); + NS_ENSURE_SUCCESS(rv, rv); + + nsRefPtr 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; +} diff --git a/mozilla/content/xslt/src/xslt/txExecutionState.cpp b/mozilla/content/xslt/src/xslt/txExecutionState.cpp index da60bb17b3c..97d3cb2a8ae 100644 --- a/mozilla/content/xslt/src/xslt/txExecutionState.cpp +++ b/mozilla/content/xslt/src/xslt/txExecutionState.cpp @@ -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) { diff --git a/mozilla/content/xslt/src/xslt/txExecutionState.h b/mozilla/content/xslt/src/xslt/txExecutionState.h index 43b0483eabd..7281de886d6 100644 --- a/mozilla/content/xslt/src/xslt/txExecutionState.h +++ b/mozilla/content/xslt/src/xslt/txExecutionState.h @@ -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(); diff --git a/mozilla/content/xslt/src/xslt/txMozillaXMLOutput.cpp b/mozilla/content/xslt/src/xslt/txMozillaXMLOutput.cpp index 871672ac914..ec4f2cdfd6f 100644 --- a/mozilla/content/xslt/src/xslt/txMozillaXMLOutput.cpp +++ b/mozilla/content/xslt/src/xslt/txMozillaXMLOutput.cpp @@ -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 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 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 sele = do_QueryInterface(mOpenedElement); - sele->WillCallDoneAddingChildren(); + } + else if (aNsID == kNameSpaceID_SVG && + aLocalName == txHTMLAtoms::script) { + nsCOMPtr sele = do_QueryInterface(mOpenedElement); + sele->WillCallDoneAddingChildren(); + } } if (mCreatingNewDocument) { diff --git a/mozilla/content/xslt/src/xslt/txMozillaXMLOutput.h b/mozilla/content/xslt/src/xslt/txMozillaXMLOutput.h index b659386ffc4..6062e1f4125 100644 --- a/mozilla/content/xslt/src/xslt/txMozillaXMLOutput.h +++ b/mozilla/content/xslt/src/xslt/txMozillaXMLOutput.h @@ -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 }; }; diff --git a/mozilla/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp b/mozilla/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp index a3d6c9bb66f..fe39820c8d7 100644 --- a/mozilla/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp +++ b/mozilla/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp @@ -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; - }; diff --git a/mozilla/content/xslt/src/xslt/txRtfHandler.h b/mozilla/content/xslt/src/xslt/txRtfHandler.h index f3dc3fa518e..e1d8fd80eca 100644 --- a/mozilla/content/xslt/src/xslt/txRtfHandler.h +++ b/mozilla/content/xslt/src/xslt/txRtfHandler.h @@ -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 mBuffer; + nsAutoPtr mNode; }; class txRtfHandler : public txBufferingHandler diff --git a/mozilla/content/xslt/src/xslt/txStylesheetCompiler.cpp b/mozilla/content/xslt/src/xslt/txStylesheetCompiler.cpp index ae78f9f3a25..94b44944148 100644 --- a/mozilla/content/xslt/src/xslt/txStylesheetCompiler.cpp +++ b/mozilla/content/xslt/src/xslt/txStylesheetCompiler.cpp @@ -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 diff --git a/mozilla/content/xslt/src/xslt/txStylesheetCompiler.h b/mozilla/content/xslt/src/xslt/txStylesheetCompiler.h index bf724bb1b2b..c468123f3f9 100644 --- a/mozilla/content/xslt/src/xslt/txStylesheetCompiler.h +++ b/mozilla/content/xslt/src/xslt/txStylesheetCompiler.h @@ -140,7 +140,7 @@ public: // txIParseContext nsresult resolveNamespacePrefix(nsIAtom* aPrefix, PRInt32& aID); nsresult resolveFunctionCall(nsIAtom* aName, PRInt32 aID, - FunctionCall*& aFunction); + FunctionCall** aFunction); PRBool caseInsensitiveNameTests(); /** diff --git a/mozilla/content/xslt/src/xslt/txXSLTEnvironmentFunctionCall.cpp b/mozilla/content/xslt/src/xslt/txXSLTEnvironmentFunctionCall.cpp index a6379d7c187..84a5390045f 100755 --- a/mozilla/content/xslt/src/xslt/txXSLTEnvironmentFunctionCall.cpp +++ b/mozilla/content/xslt/src/xslt/txXSLTEnvironmentFunctionCall.cpp @@ -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;