LCOV - code coverage report
Current view: directory - content/xslt/src/xslt - txMozillaXSLTProcessor.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 657 15 2.3 %
Date: 2012-06-02 Functions: 80 4 5.0 %

       1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is TransforMiiX XSLT processor code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2002
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Peter Van der Beken <peterv@propagandism.org>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      27                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #include "txMozillaXSLTProcessor.h"
      40                 : #include "nsContentCID.h"
      41                 : #include "nsDOMError.h"
      42                 : #include "nsIChannel.h"
      43                 : #include "mozilla/dom/Element.h"
      44                 : #include "nsIDOMElement.h"
      45                 : #include "nsIDOMText.h"
      46                 : #include "nsIDocument.h"
      47                 : #include "nsDOMClassInfoID.h"
      48                 : #include "nsIDOMDocument.h"
      49                 : #include "nsIDOMDocumentFragment.h"
      50                 : #include "nsIDOMNodeList.h"
      51                 : #include "nsIIOService.h"
      52                 : #include "nsILoadGroup.h"
      53                 : #include "nsIStringBundle.h"
      54                 : #include "nsIURI.h"
      55                 : #include "nsNetUtil.h"
      56                 : #include "nsXPathResult.h"
      57                 : #include "txExecutionState.h"
      58                 : #include "txMozillaTextOutput.h"
      59                 : #include "txMozillaXMLOutput.h"
      60                 : #include "txURIUtils.h"
      61                 : #include "txXMLUtils.h"
      62                 : #include "txUnknownHandler.h"
      63                 : #include "txXSLTProcessor.h"
      64                 : #include "nsIPrincipal.h"
      65                 : #include "nsThreadUtils.h"
      66                 : #include "jsapi.h"
      67                 : #include "txExprParser.h"
      68                 : #include "nsIErrorService.h"
      69                 : #include "nsIScriptSecurityManager.h"
      70                 : #include "nsJSUtils.h"
      71                 : 
      72                 : using namespace mozilla::dom;
      73                 : 
      74                 : static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID);
      75                 : 
      76                 : /**
      77                 :  * Output Handler Factories
      78                 :  */
      79                 : class txToDocHandlerFactory : public txAOutputHandlerFactory
      80               0 : {
      81                 : public:
      82               0 :     txToDocHandlerFactory(txExecutionState* aEs,
      83                 :                           nsIDOMDocument* aSourceDocument,
      84                 :                           nsITransformObserver* aObserver)
      85               0 :         : mEs(aEs), mSourceDocument(aSourceDocument), mObserver(aObserver)
      86                 :     {
      87               0 :     }
      88                 : 
      89                 :     TX_DECL_TXAOUTPUTHANDLERFACTORY
      90                 : 
      91                 : private:
      92                 :     txExecutionState* mEs;
      93                 :     nsCOMPtr<nsIDOMDocument> mSourceDocument;
      94                 :     nsCOMPtr<nsITransformObserver> mObserver;
      95                 : };
      96                 : 
      97                 : class txToFragmentHandlerFactory : public txAOutputHandlerFactory
      98               0 : {
      99                 : public:
     100               0 :     txToFragmentHandlerFactory(nsIDOMDocumentFragment* aFragment)
     101               0 :         : mFragment(aFragment)
     102                 :     {
     103               0 :     }
     104                 : 
     105                 :     TX_DECL_TXAOUTPUTHANDLERFACTORY
     106                 : 
     107                 : private:
     108                 :     nsCOMPtr<nsIDOMDocumentFragment> mFragment;
     109                 : };
     110                 : 
     111                 : nsresult
     112               0 : txToDocHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
     113                 :                                          txAXMLEventHandler** aHandler)
     114                 : {
     115               0 :     *aHandler = nsnull;
     116               0 :     switch (aFormat->mMethod) {
     117                 :         case eMethodNotSet:
     118                 :         case eXMLOutput:
     119                 :         {
     120               0 :             *aHandler = new txUnknownHandler(mEs);
     121               0 :             return NS_OK;
     122                 :         }
     123                 : 
     124                 :         case eHTMLOutput:
     125                 :         {
     126                 :             nsAutoPtr<txMozillaXMLOutput> handler(
     127               0 :                 new txMozillaXMLOutput(aFormat, mObserver));
     128                 : 
     129               0 :             nsresult rv = handler->createResultDocument(EmptyString(),
     130                 :                                                         kNameSpaceID_None,
     131               0 :                                                         mSourceDocument);
     132               0 :             if (NS_SUCCEEDED(rv)) {
     133               0 :                 *aHandler = handler.forget();
     134                 :             }
     135                 : 
     136               0 :             return rv;
     137                 :         }
     138                 : 
     139                 :         case eTextOutput:
     140                 :         {
     141                 :             nsAutoPtr<txMozillaTextOutput> handler(
     142               0 :                 new txMozillaTextOutput(mObserver));
     143                 : 
     144               0 :             nsresult rv = handler->createResultDocument(mSourceDocument);
     145               0 :             if (NS_SUCCEEDED(rv)) {
     146               0 :                 *aHandler = handler.forget();
     147                 :             }
     148                 : 
     149               0 :             return rv;
     150                 :         }
     151                 :     }
     152                 : 
     153                 :     NS_RUNTIMEABORT("Unknown output method");
     154                 : 
     155                 :     return NS_ERROR_FAILURE;
     156                 : }
     157                 : 
     158                 : nsresult
     159               0 : txToDocHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
     160                 :                                          const nsSubstring& aName,
     161                 :                                          PRInt32 aNsID,
     162                 :                                          txAXMLEventHandler** aHandler)
     163                 : {
     164               0 :     *aHandler = nsnull;
     165               0 :     switch (aFormat->mMethod) {
     166                 :         case eMethodNotSet:
     167                 :         {
     168               0 :             NS_ERROR("How can method not be known when root element is?");
     169               0 :             return NS_ERROR_UNEXPECTED;
     170                 :         }
     171                 : 
     172                 :         case eXMLOutput:
     173                 :         case eHTMLOutput:
     174                 :         {
     175                 :             nsAutoPtr<txMozillaXMLOutput> handler(
     176               0 :                 new txMozillaXMLOutput(aFormat, mObserver));
     177                 : 
     178                 :             nsresult rv = handler->createResultDocument(aName, aNsID,
     179               0 :                                                         mSourceDocument);
     180               0 :             if (NS_SUCCEEDED(rv)) {
     181               0 :                 *aHandler = handler.forget();
     182                 :             }
     183                 : 
     184               0 :             return rv;
     185                 :         }
     186                 : 
     187                 :         case eTextOutput:
     188                 :         {
     189                 :             nsAutoPtr<txMozillaTextOutput> handler(
     190               0 :                 new txMozillaTextOutput(mObserver));
     191                 : 
     192               0 :             nsresult rv = handler->createResultDocument(mSourceDocument);
     193               0 :             if (NS_SUCCEEDED(rv)) {
     194               0 :                 *aHandler = handler.forget();
     195                 :             }
     196                 : 
     197               0 :             return rv;
     198                 :         }
     199                 :     }
     200                 : 
     201                 :     NS_RUNTIMEABORT("Unknown output method");
     202                 : 
     203                 :     return NS_ERROR_FAILURE;
     204                 : }
     205                 : 
     206                 : nsresult
     207               0 : txToFragmentHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
     208                 :                                               txAXMLEventHandler** aHandler)
     209                 : {
     210               0 :     *aHandler = nsnull;
     211               0 :     switch (aFormat->mMethod) {
     212                 :         case eMethodNotSet:
     213                 :         {
     214               0 :             txOutputFormat format;
     215               0 :             format.merge(*aFormat);
     216               0 :             nsCOMPtr<nsIDOMDocument> domdoc;
     217               0 :             mFragment->GetOwnerDocument(getter_AddRefs(domdoc));
     218               0 :             NS_ASSERTION(domdoc, "unable to get ownerdocument");
     219               0 :             nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
     220                 : 
     221               0 :             if (doc && doc->IsHTML()) {
     222               0 :                 format.mMethod = eHTMLOutput;
     223                 :             } else {
     224               0 :                 format.mMethod = eXMLOutput;
     225                 :             }
     226                 : 
     227               0 :             *aHandler = new txMozillaXMLOutput(&format, mFragment, false);
     228                 :             break;
     229                 :         }
     230                 : 
     231                 :         case eXMLOutput:
     232                 :         case eHTMLOutput:
     233                 :         {
     234               0 :             *aHandler = new txMozillaXMLOutput(aFormat, mFragment, false);
     235               0 :             break;
     236                 :         }
     237                 : 
     238                 :         case eTextOutput:
     239                 :         {
     240               0 :             *aHandler = new txMozillaTextOutput(mFragment);
     241               0 :             break;
     242                 :         }
     243                 :     }
     244               0 :     NS_ENSURE_TRUE(*aHandler, NS_ERROR_OUT_OF_MEMORY);
     245               0 :     return NS_OK;
     246                 : }
     247                 : 
     248                 : nsresult
     249               0 : txToFragmentHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
     250                 :                                               const nsSubstring& aName,
     251                 :                                               PRInt32 aNsID,
     252                 :                                               txAXMLEventHandler** aHandler)
     253                 : {
     254               0 :     *aHandler = nsnull;
     255               0 :     NS_ASSERTION(aFormat->mMethod != eMethodNotSet,
     256                 :                  "How can method not be known when root element is?");
     257               0 :     NS_ENSURE_TRUE(aFormat->mMethod != eMethodNotSet, NS_ERROR_UNEXPECTED);
     258               0 :     return createHandlerWith(aFormat, aHandler);
     259                 : }
     260                 : 
     261                 : class txVariable : public txIGlobalParameter
     262               0 : {
     263                 : public:
     264               0 :     txVariable(nsIVariant *aValue) : mValue(aValue)
     265                 :     {
     266               0 :         NS_ASSERTION(aValue, "missing value");
     267               0 :     }
     268               0 :     txVariable(txAExprResult* aValue) : mTxValue(aValue)
     269                 :     {
     270               0 :         NS_ASSERTION(aValue, "missing value");
     271               0 :     }
     272               0 :     nsresult getValue(txAExprResult** aValue)
     273                 :     {
     274               0 :         NS_ASSERTION(mValue || mTxValue, "variablevalue is null");
     275                 : 
     276               0 :         if (!mTxValue) {
     277               0 :             nsresult rv = Convert(mValue, getter_AddRefs(mTxValue));
     278               0 :             NS_ENSURE_SUCCESS(rv, rv);
     279                 :         }
     280                 : 
     281               0 :         *aValue = mTxValue;
     282               0 :         NS_ADDREF(*aValue);
     283                 : 
     284               0 :         return NS_OK;
     285                 :     }
     286               0 :     nsresult getValue(nsIVariant** aValue)
     287                 :     {
     288               0 :         *aValue = mValue;
     289               0 :         NS_ADDREF(*aValue);
     290               0 :         return NS_OK;
     291                 :     }
     292               0 :     nsIVariant* getValue()
     293                 :     {
     294               0 :         return mValue;
     295                 :     }
     296               0 :     void setValue(nsIVariant* aValue)
     297                 :     {
     298               0 :         NS_ASSERTION(aValue, "setting variablevalue to null");
     299               0 :         mValue = aValue;
     300               0 :         mTxValue = nsnull;
     301               0 :     }
     302               0 :     void setValue(txAExprResult* aValue)
     303                 :     {
     304               0 :         NS_ASSERTION(aValue, "setting variablevalue to null");
     305               0 :         mValue = nsnull;
     306               0 :         mTxValue = aValue;
     307               0 :     }
     308                 : 
     309                 : private:
     310                 :     static nsresult Convert(nsIVariant *aValue, txAExprResult** aResult);
     311                 : 
     312                 :     nsCOMPtr<nsIVariant> mValue;
     313                 :     nsRefPtr<txAExprResult> mTxValue;
     314                 : };
     315                 : 
     316                 : /**
     317                 :  * txMozillaXSLTProcessor
     318                 :  */
     319                 : 
     320            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(txMozillaXSLTProcessor)
     321               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(txMozillaXSLTProcessor)
     322               0 :     NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mEmbeddedStylesheetRoot)
     323               0 :     NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSource)
     324               0 :     NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mPrincipal)
     325               0 :     tmp->mVariables.clear();
     326               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     327               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(txMozillaXSLTProcessor)
     328               0 :     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mEmbeddedStylesheetRoot)
     329               0 :     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSource)
     330               0 :     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mPrincipal)
     331               0 :     txOwningExpandedNameMap<txIGlobalParameter>::iterator iter(tmp->mVariables);
     332               0 :     while (iter.next()) {
     333               0 :         cb.NoteXPCOMChild(static_cast<txVariable*>(iter.value())->getValue());
     334                 :     }
     335               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     336                 : 
     337               0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(txMozillaXSLTProcessor)
     338               0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(txMozillaXSLTProcessor)
     339                 : 
     340                 : DOMCI_DATA(XSLTProcessor, txMozillaXSLTProcessor)
     341                 : 
     342               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(txMozillaXSLTProcessor)
     343               0 :     NS_INTERFACE_MAP_ENTRY(nsIXSLTProcessor)
     344               0 :     NS_INTERFACE_MAP_ENTRY(nsIXSLTProcessorPrivate)
     345               0 :     NS_INTERFACE_MAP_ENTRY(nsIDocumentTransformer)
     346               0 :     NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
     347               0 :     NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
     348               0 :     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXSLTProcessor)
     349               0 :     NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XSLTProcessor)
     350               0 : NS_INTERFACE_MAP_END
     351                 : 
     352               0 : txMozillaXSLTProcessor::txMozillaXSLTProcessor() : mStylesheetDocument(nsnull),
     353                 :                                                    mTransformResult(NS_OK),
     354                 :                                                    mCompileResult(NS_OK),
     355               0 :                                                    mFlags(0)
     356                 : {
     357               0 : }
     358                 : 
     359               0 : txMozillaXSLTProcessor::~txMozillaXSLTProcessor()
     360                 : {
     361               0 :     if (mStylesheetDocument) {
     362               0 :         mStylesheetDocument->RemoveMutationObserver(this);
     363                 :     }
     364               0 : }
     365                 : 
     366                 : NS_IMETHODIMP
     367               0 : txMozillaXSLTProcessor::SetTransformObserver(nsITransformObserver* aObserver)
     368                 : {
     369               0 :     mObserver = aObserver;
     370               0 :     return NS_OK;
     371                 : }
     372                 : 
     373                 : nsresult
     374               0 : txMozillaXSLTProcessor::SetSourceContentModel(nsIDOMNode* aSourceDOM)
     375                 : {
     376               0 :     mSource = aSourceDOM;
     377                 : 
     378               0 :     if (NS_FAILED(mTransformResult)) {
     379               0 :         notifyError();
     380               0 :         return NS_OK;
     381                 :     }
     382                 : 
     383               0 :     if (mStylesheet) {
     384               0 :         return DoTransform();
     385                 :     }
     386                 : 
     387               0 :     return NS_OK;
     388                 : }
     389                 : 
     390                 : NS_IMETHODIMP
     391               0 : txMozillaXSLTProcessor::AddXSLTParamNamespace(const nsString& aPrefix,
     392                 :                                               const nsString& aNamespace)
     393                 : {
     394               0 :     nsCOMPtr<nsIAtom> pre = do_GetAtom(aPrefix);
     395               0 :     return mParamNamespaceMap.mapNamespace(pre, aNamespace);
     396                 : }
     397                 : 
     398                 : 
     399                 : class txXSLTParamContext : public txIParseContext,
     400                 :                            public txIEvalContext
     401               0 : {
     402                 : public:
     403               0 :     txXSLTParamContext(txNamespaceMap *aResolver, const txXPathNode& aContext,
     404                 :                        txResultRecycler* aRecycler)
     405                 :         : mResolver(aResolver),
     406                 :           mContext(aContext),
     407               0 :           mRecycler(aRecycler)
     408                 :     {
     409               0 :     }
     410                 : 
     411                 :     // txIParseContext
     412               0 :     nsresult resolveNamespacePrefix(nsIAtom* aPrefix, PRInt32& aID)
     413                 :     {
     414               0 :         aID = mResolver->lookupNamespace(aPrefix);
     415                 :         return aID == kNameSpaceID_Unknown ? NS_ERROR_DOM_NAMESPACE_ERR :
     416               0 :                                              NS_OK;
     417                 :     }
     418               0 :     nsresult resolveFunctionCall(nsIAtom* aName, PRInt32 aID,
     419                 :                                  FunctionCall** aFunction)
     420                 :     {
     421               0 :         return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
     422                 :     }
     423               0 :     bool caseInsensitiveNameTests()
     424                 :     {
     425               0 :         return false;
     426                 :     }
     427               0 :     void SetErrorOffset(PRUint32 aOffset)
     428                 :     {
     429               0 :     }
     430                 : 
     431                 :     // txIEvalContext
     432               0 :     nsresult getVariable(PRInt32 aNamespace, nsIAtom* aLName,
     433                 :                          txAExprResult*& aResult)
     434                 :     {
     435               0 :         aResult = nsnull;
     436               0 :         return NS_ERROR_INVALID_ARG;
     437                 :     }
     438               0 :     bool isStripSpaceAllowed(const txXPathNode& aNode)
     439                 :     {
     440               0 :         return false;
     441                 :     }
     442               0 :     void* getPrivateContext()
     443                 :     {
     444               0 :         return nsnull;
     445                 :     }
     446               0 :     txResultRecycler* recycler()
     447                 :     {
     448               0 :         return mRecycler;
     449                 :     }
     450               0 :     void receiveError(const nsAString& aMsg, nsresult aRes)
     451                 :     {
     452               0 :     }
     453               0 :     const txXPathNode& getContextNode()
     454                 :     {
     455               0 :       return mContext;
     456                 :     }
     457               0 :     PRUint32 size()
     458                 :     {
     459               0 :       return 1;
     460                 :     }
     461               0 :     PRUint32 position()
     462                 :     {
     463               0 :       return 1;
     464                 :     }
     465                 : 
     466                 : private:
     467                 :     txNamespaceMap *mResolver;
     468                 :     const txXPathNode& mContext;
     469                 :     txResultRecycler* mRecycler;
     470                 : };
     471                 : 
     472                 : 
     473                 : NS_IMETHODIMP
     474               0 : txMozillaXSLTProcessor::AddXSLTParam(const nsString& aName,
     475                 :                                      const nsString& aNamespace,
     476                 :                                      const nsString& aSelect,
     477                 :                                      const nsString& aValue,
     478                 :                                      nsIDOMNode* aContext)
     479                 : {
     480               0 :     nsresult rv = NS_OK;
     481                 : 
     482               0 :     if (aSelect.IsVoid() == aValue.IsVoid()) {
     483                 :         // Ignore if neither or both are specified
     484               0 :         return NS_ERROR_FAILURE;
     485                 :     }
     486                 : 
     487               0 :     nsRefPtr<txAExprResult> value;
     488               0 :     if (!aSelect.IsVoid()) {
     489                 : 
     490                 :         // Set up context
     491                 :         nsAutoPtr<txXPathNode> contextNode(
     492               0 :           txXPathNativeNode::createXPathNode(aContext));
     493               0 :         NS_ENSURE_TRUE(contextNode, NS_ERROR_OUT_OF_MEMORY);
     494                 : 
     495               0 :         if (!mRecycler) {
     496               0 :             mRecycler = new txResultRecycler;
     497               0 :             NS_ENSURE_TRUE(mRecycler, NS_ERROR_OUT_OF_MEMORY);
     498                 : 
     499               0 :             rv = mRecycler->init();
     500               0 :             NS_ENSURE_SUCCESS(rv, rv);
     501                 :         }
     502                 : 
     503               0 :         txXSLTParamContext paramContext(&mParamNamespaceMap, *contextNode,
     504               0 :                                         mRecycler);
     505                 : 
     506                 :         // Parse
     507               0 :         nsAutoPtr<Expr> expr;
     508                 :         rv = txExprParser::createExpr(aSelect, &paramContext,
     509               0 :                                       getter_Transfers(expr));
     510               0 :         NS_ENSURE_SUCCESS(rv, rv);
     511                 : 
     512                 :         // Evaluate
     513               0 :         rv = expr->evaluate(&paramContext, getter_AddRefs(value));
     514               0 :         NS_ENSURE_SUCCESS(rv, rv);
     515                 :     }
     516                 :     else {
     517               0 :         value = new StringResult(aValue, nsnull);
     518               0 :         NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
     519                 :     }
     520                 : 
     521               0 :     nsCOMPtr<nsIAtom> name = do_GetAtom(aName);
     522               0 :     PRInt32 nsId = kNameSpaceID_Unknown;
     523               0 :     rv = nsContentUtils::NameSpaceManager()->
     524               0 :         RegisterNameSpace(aNamespace, nsId);
     525               0 :     NS_ENSURE_SUCCESS(rv, rv);
     526                 : 
     527               0 :     txExpandedName varName(nsId, name);
     528               0 :     txVariable* var = static_cast<txVariable*>(mVariables.get(varName));
     529               0 :     if (var) {
     530               0 :         var->setValue(value);
     531                 :         
     532               0 :         return NS_OK;
     533                 :     }
     534                 : 
     535               0 :     var = new txVariable(value);
     536               0 :     NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
     537                 : 
     538               0 :     return mVariables.add(varName, var);
     539                 : }
     540                 : 
     541                 : class nsTransformBlockerEvent : public nsRunnable {
     542                 : public:
     543                 :   nsRefPtr<txMozillaXSLTProcessor> mProcessor;
     544                 : 
     545               0 :   nsTransformBlockerEvent(txMozillaXSLTProcessor *processor)
     546               0 :     : mProcessor(processor)
     547               0 :   {}
     548                 : 
     549               0 :   ~nsTransformBlockerEvent()
     550               0 :   {
     551                 :     nsCOMPtr<nsIDocument> document =
     552               0 :         do_QueryInterface(mProcessor->GetSourceContentModel());
     553               0 :     document->UnblockOnload(true);
     554               0 :   }
     555                 : 
     556               0 :   NS_IMETHOD Run()
     557                 :   {
     558               0 :     mProcessor->TransformToDoc(nsnull);
     559               0 :     return NS_OK;
     560                 :   }
     561                 : };
     562                 : 
     563                 : nsresult
     564               0 : txMozillaXSLTProcessor::DoTransform()
     565                 : {
     566               0 :     NS_ENSURE_TRUE(mSource, NS_ERROR_UNEXPECTED);
     567               0 :     NS_ENSURE_TRUE(mStylesheet, NS_ERROR_UNEXPECTED);
     568               0 :     NS_ASSERTION(mObserver, "no observer");
     569               0 :     NS_ASSERTION(NS_IsMainThread(), "should only be on main thread");
     570                 : 
     571                 :     nsresult rv;
     572               0 :     nsCOMPtr<nsIDocument> document = do_QueryInterface(mSource, &rv);
     573               0 :     NS_ENSURE_SUCCESS(rv, rv);
     574                 : 
     575               0 :     nsCOMPtr<nsIRunnable> event = new nsTransformBlockerEvent(this);
     576               0 :     if (!event) {
     577               0 :         return NS_ERROR_OUT_OF_MEMORY;
     578                 :     }
     579                 : 
     580               0 :     document->BlockOnload();
     581                 : 
     582               0 :     rv = NS_DispatchToCurrentThread(event);
     583               0 :     if (NS_FAILED(rv)) {
     584                 :         // XXX Maybe we should just display the source document in this case?
     585                 :         //     Also, set up context information, see bug 204655.
     586               0 :         reportError(rv, nsnull, nsnull);
     587                 :     }
     588                 : 
     589               0 :     return rv;
     590                 : }
     591                 : 
     592                 : NS_IMETHODIMP
     593               0 : txMozillaXSLTProcessor::ImportStylesheet(nsIDOMNode *aStyle)
     594                 : {
     595               0 :     NS_ENSURE_TRUE(aStyle, NS_ERROR_NULL_POINTER);
     596                 :     
     597                 :     // We don't support importing multiple stylesheets yet.
     598               0 :     NS_ENSURE_TRUE(!mStylesheetDocument && !mStylesheet,
     599                 :                    NS_ERROR_NOT_IMPLEMENTED);
     600                 : 
     601               0 :     if (!nsContentUtils::CanCallerAccess(aStyle)) {
     602               0 :         return NS_ERROR_DOM_SECURITY_ERR;
     603                 :     }
     604                 :     
     605               0 :     nsCOMPtr<nsINode> styleNode = do_QueryInterface(aStyle);
     606               0 :     NS_ENSURE_TRUE(styleNode &&
     607                 :                    (styleNode->IsElement() ||
     608                 :                     styleNode->IsNodeOfType(nsINode::eDOCUMENT)),
     609                 :                    NS_ERROR_INVALID_ARG);
     610                 : 
     611                 :     nsresult rv = TX_CompileStylesheet(styleNode, this, mPrincipal,
     612               0 :                                        getter_AddRefs(mStylesheet));
     613                 :     // XXX set up exception context, bug 204658
     614               0 :     NS_ENSURE_SUCCESS(rv, rv);
     615                 : 
     616               0 :     if (styleNode->IsElement()) {
     617               0 :         mStylesheetDocument = styleNode->OwnerDoc();
     618               0 :         NS_ENSURE_TRUE(mStylesheetDocument, NS_ERROR_UNEXPECTED);
     619                 : 
     620               0 :         mEmbeddedStylesheetRoot = static_cast<nsIContent*>(styleNode.get());
     621                 :     }
     622                 :     else {
     623               0 :         mStylesheetDocument = static_cast<nsIDocument*>(styleNode.get());
     624                 :     }
     625                 : 
     626               0 :     mStylesheetDocument->AddMutationObserver(this);
     627                 : 
     628               0 :     return NS_OK;
     629                 : }
     630                 : 
     631                 : NS_IMETHODIMP
     632               0 : txMozillaXSLTProcessor::TransformToDocument(nsIDOMNode *aSource,
     633                 :                                             nsIDOMDocument **aResult)
     634                 : {
     635               0 :     NS_ENSURE_ARG(aSource);
     636               0 :     NS_ENSURE_ARG_POINTER(aResult);
     637               0 :     NS_ENSURE_SUCCESS(mCompileResult, mCompileResult);
     638                 : 
     639               0 :     if (!nsContentUtils::CanCallerAccess(aSource)) {
     640               0 :         return NS_ERROR_DOM_SECURITY_ERR;
     641                 :     }
     642                 : 
     643               0 :     nsresult rv = ensureStylesheet();
     644               0 :     NS_ENSURE_SUCCESS(rv, rv);
     645                 : 
     646               0 :     mSource = aSource;
     647                 : 
     648               0 :     return TransformToDoc(aResult);
     649                 : }
     650                 : 
     651                 : nsresult
     652               0 : txMozillaXSLTProcessor::TransformToDoc(nsIDOMDocument **aResult)
     653                 : {
     654               0 :     nsAutoPtr<txXPathNode> sourceNode(txXPathNativeNode::createXPathNode(mSource));
     655               0 :     if (!sourceNode) {
     656               0 :         return NS_ERROR_OUT_OF_MEMORY;
     657                 :     }
     658                 : 
     659               0 :     nsCOMPtr<nsIDOMDocument> sourceDOMDocument;
     660               0 :     mSource->GetOwnerDocument(getter_AddRefs(sourceDOMDocument));
     661               0 :     if (!sourceDOMDocument) {
     662               0 :         sourceDOMDocument = do_QueryInterface(mSource);
     663                 :     }
     664                 : 
     665               0 :     txExecutionState es(mStylesheet, IsLoadDisabled());
     666                 : 
     667                 :     // XXX Need to add error observers
     668                 : 
     669               0 :     txToDocHandlerFactory handlerFactory(&es, sourceDOMDocument, mObserver);
     670               0 :     es.mOutputHandlerFactory = &handlerFactory;
     671                 : 
     672               0 :     nsresult rv = es.init(*sourceNode, &mVariables);
     673                 : 
     674                 :     // Process root of XML source document
     675               0 :     if (NS_SUCCEEDED(rv)) {
     676               0 :         rv = txXSLTProcessor::execute(es);
     677                 :     }
     678                 :     
     679               0 :     nsresult endRv = es.end(rv);
     680               0 :     if (NS_SUCCEEDED(rv)) {
     681               0 :       rv = endRv;
     682                 :     }
     683                 :     
     684               0 :     if (NS_SUCCEEDED(rv)) {
     685               0 :         if (aResult) {
     686                 :             txAOutputXMLEventHandler* handler =
     687               0 :                 static_cast<txAOutputXMLEventHandler*>(es.mOutputHandler);
     688               0 :             handler->getOutputDocument(aResult);
     689               0 :             nsCOMPtr<nsIDocument> doc = do_QueryInterface(*aResult);
     690               0 :             doc->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
     691                 :         }
     692                 :     }
     693               0 :     else if (mObserver) {
     694                 :         // XXX set up context information, bug 204655
     695               0 :         reportError(rv, nsnull, nsnull);
     696                 :     }
     697                 : 
     698               0 :     return rv;
     699                 : }
     700                 : 
     701                 : NS_IMETHODIMP
     702               0 : txMozillaXSLTProcessor::TransformToFragment(nsIDOMNode *aSource,
     703                 :                                             nsIDOMDocument *aOutput,
     704                 :                                             nsIDOMDocumentFragment **aResult)
     705                 : {
     706               0 :     NS_ENSURE_ARG(aSource);
     707               0 :     NS_ENSURE_ARG(aOutput);
     708               0 :     NS_ENSURE_ARG_POINTER(aResult);
     709               0 :     NS_ENSURE_SUCCESS(mCompileResult, mCompileResult);
     710                 : 
     711               0 :     if (!nsContentUtils::CanCallerAccess(aSource) ||
     712               0 :         !nsContentUtils::CanCallerAccess(aOutput)) {
     713               0 :         return NS_ERROR_DOM_SECURITY_ERR;
     714                 :     }
     715                 : 
     716               0 :     nsresult rv = ensureStylesheet();
     717               0 :     NS_ENSURE_SUCCESS(rv, rv);
     718                 : 
     719               0 :     nsAutoPtr<txXPathNode> sourceNode(txXPathNativeNode::createXPathNode(aSource));
     720               0 :     if (!sourceNode) {
     721               0 :         return NS_ERROR_OUT_OF_MEMORY;
     722                 :     }
     723                 : 
     724               0 :     txExecutionState es(mStylesheet, IsLoadDisabled());
     725                 : 
     726                 :     // XXX Need to add error observers
     727                 : 
     728               0 :     rv = aOutput->CreateDocumentFragment(aResult);
     729               0 :     NS_ENSURE_SUCCESS(rv, rv);
     730               0 :     txToFragmentHandlerFactory handlerFactory(*aResult);
     731               0 :     es.mOutputHandlerFactory = &handlerFactory;
     732                 : 
     733               0 :     rv = es.init(*sourceNode, &mVariables);
     734                 : 
     735                 :     // Process root of XML source document
     736               0 :     if (NS_SUCCEEDED(rv)) {
     737               0 :         rv = txXSLTProcessor::execute(es);
     738                 :     }
     739                 :     // XXX setup exception context, bug 204658
     740               0 :     nsresult endRv = es.end(rv);
     741               0 :     if (NS_SUCCEEDED(rv)) {
     742               0 :       rv = endRv;
     743                 :     }
     744                 : 
     745               0 :     return rv;
     746                 : }
     747                 : 
     748                 : NS_IMETHODIMP
     749               0 : txMozillaXSLTProcessor::SetParameter(const nsAString & aNamespaceURI,
     750                 :                                      const nsAString & aLocalName,
     751                 :                                      nsIVariant *aValue)
     752                 : {
     753               0 :     NS_ENSURE_ARG(aValue);
     754                 : 
     755               0 :     nsCOMPtr<nsIVariant> value = aValue;
     756                 : 
     757                 :     PRUint16 dataType;
     758               0 :     value->GetDataType(&dataType);
     759               0 :     switch (dataType) {
     760                 :         // Number
     761                 :         case nsIDataType::VTYPE_INT8:
     762                 :         case nsIDataType::VTYPE_INT16:
     763                 :         case nsIDataType::VTYPE_INT32:
     764                 :         case nsIDataType::VTYPE_INT64:
     765                 :         case nsIDataType::VTYPE_UINT8:
     766                 :         case nsIDataType::VTYPE_UINT16:
     767                 :         case nsIDataType::VTYPE_UINT32:
     768                 :         case nsIDataType::VTYPE_UINT64:
     769                 :         case nsIDataType::VTYPE_FLOAT:
     770                 :         case nsIDataType::VTYPE_DOUBLE:
     771                 : 
     772                 :         // Boolean
     773                 :         case nsIDataType::VTYPE_BOOL:
     774                 : 
     775                 :         // String
     776                 :         case nsIDataType::VTYPE_CHAR:
     777                 :         case nsIDataType::VTYPE_WCHAR:
     778                 :         case nsIDataType::VTYPE_DOMSTRING:
     779                 :         case nsIDataType::VTYPE_CHAR_STR:
     780                 :         case nsIDataType::VTYPE_WCHAR_STR:
     781                 :         case nsIDataType::VTYPE_STRING_SIZE_IS:
     782                 :         case nsIDataType::VTYPE_WSTRING_SIZE_IS:
     783                 :         case nsIDataType::VTYPE_UTF8STRING:
     784                 :         case nsIDataType::VTYPE_CSTRING:
     785                 :         case nsIDataType::VTYPE_ASTRING:
     786                 :         {
     787               0 :             break;
     788                 :         }
     789                 : 
     790                 :         // Nodeset
     791                 :         case nsIDataType::VTYPE_INTERFACE:
     792                 :         case nsIDataType::VTYPE_INTERFACE_IS:
     793                 :         {
     794               0 :             nsCOMPtr<nsISupports> supports;
     795               0 :             nsresult rv = value->GetAsISupports(getter_AddRefs(supports));
     796               0 :             NS_ENSURE_SUCCESS(rv, rv);
     797                 : 
     798               0 :             nsCOMPtr<nsIDOMNode> node = do_QueryInterface(supports);
     799               0 :             if (node) {
     800               0 :                 if (!nsContentUtils::CanCallerAccess(node)) {
     801               0 :                     return NS_ERROR_DOM_SECURITY_ERR;
     802                 :                 }
     803                 : 
     804                 :                 break;
     805                 :             }
     806                 : 
     807               0 :             nsCOMPtr<nsIXPathResult> xpathResult = do_QueryInterface(supports);
     808               0 :             if (xpathResult) {
     809               0 :                 nsRefPtr<txAExprResult> result;
     810               0 :                 nsresult rv = xpathResult->GetExprResult(getter_AddRefs(result));
     811               0 :                 NS_ENSURE_SUCCESS(rv, rv);
     812                 : 
     813               0 :                 if (result->getResultType() == txAExprResult::NODESET) {
     814                 :                     txNodeSet *nodeSet =
     815                 :                         static_cast<txNodeSet*>
     816               0 :                                    (static_cast<txAExprResult*>(result));
     817                 : 
     818               0 :                     nsCOMPtr<nsIDOMNode> node;
     819               0 :                     PRInt32 i, count = nodeSet->size();
     820               0 :                     for (i = 0; i < count; ++i) {
     821               0 :                         rv = txXPathNativeNode::getNode(nodeSet->get(i),
     822               0 :                                                         getter_AddRefs(node));
     823               0 :                         NS_ENSURE_SUCCESS(rv, rv);
     824                 : 
     825               0 :                         if (!nsContentUtils::CanCallerAccess(node)) {
     826               0 :                             return NS_ERROR_DOM_SECURITY_ERR;
     827                 :                         }
     828                 :                     }
     829                 :                 }
     830                 : 
     831                 :                 // Clone the nsXPathResult so that mutations don't affect this
     832                 :                 // variable.
     833               0 :                 nsCOMPtr<nsIXPathResult> clone;
     834               0 :                 rv = xpathResult->Clone(getter_AddRefs(clone));
     835               0 :                 NS_ENSURE_SUCCESS(rv, rv);
     836                 : 
     837                 :                 nsCOMPtr<nsIWritableVariant> variant =
     838               0 :                     do_CreateInstance("@mozilla.org/variant;1", &rv);
     839               0 :                 NS_ENSURE_SUCCESS(rv, rv);
     840                 : 
     841               0 :                 rv = variant->SetAsISupports(clone);
     842               0 :                 NS_ENSURE_SUCCESS(rv, rv);
     843                 : 
     844               0 :                 value = variant;
     845                 : 
     846               0 :                 break;
     847                 :             }
     848                 : 
     849               0 :             nsCOMPtr<nsIDOMNodeList> nodeList = do_QueryInterface(supports);
     850               0 :             if (nodeList) {
     851                 :                 PRUint32 length;
     852               0 :                 nodeList->GetLength(&length);
     853                 : 
     854               0 :                 nsCOMPtr<nsIDOMNode> node;
     855                 :                 PRUint32 i;
     856               0 :                 for (i = 0; i < length; ++i) {
     857               0 :                     nodeList->Item(i, getter_AddRefs(node));
     858                 : 
     859               0 :                     if (!nsContentUtils::CanCallerAccess(node)) {
     860               0 :                         return NS_ERROR_DOM_SECURITY_ERR;
     861                 :                     }
     862                 :                 }
     863                 : 
     864               0 :                 break;
     865                 :             }
     866                 : 
     867                 :             // Random JS Objects will be converted to a string.
     868                 :             nsCOMPtr<nsIXPConnectJSObjectHolder> holder =
     869               0 :                 do_QueryInterface(supports);
     870               0 :             if (holder) {
     871                 :                 break;
     872                 :             }
     873                 : 
     874                 :             // We don't know how to handle this type of param.
     875               0 :             return NS_ERROR_ILLEGAL_VALUE;
     876                 :         }
     877                 : 
     878                 :         case nsIDataType::VTYPE_ARRAY:
     879                 :         {
     880                 :             PRUint16 type;
     881                 :             nsIID iid;
     882                 :             PRUint32 count;
     883                 :             void* array;
     884               0 :             nsresult rv = value->GetAsArray(&type, &iid, &count, &array);
     885               0 :             NS_ENSURE_SUCCESS(rv, rv);
     886                 : 
     887               0 :             if (type != nsIDataType::VTYPE_INTERFACE &&
     888                 :                 type != nsIDataType::VTYPE_INTERFACE_IS) {
     889               0 :                 nsMemory::Free(array);
     890                 : 
     891                 :                 // We only support arrays of DOM nodes.
     892               0 :                 return NS_ERROR_ILLEGAL_VALUE;
     893                 :             }
     894                 : 
     895               0 :             nsISupports** values = static_cast<nsISupports**>(array);
     896                 : 
     897                 :             PRUint32 i;
     898               0 :             for (i = 0; i < count; ++i) {
     899               0 :                 nsISupports *supports = values[i];
     900               0 :                 nsCOMPtr<nsIDOMNode> node = do_QueryInterface(supports);
     901                 : 
     902               0 :                 if (node) {
     903               0 :                     rv = nsContentUtils::CanCallerAccess(node) ? NS_OK :
     904               0 :                          NS_ERROR_DOM_SECURITY_ERR;
     905                 :                 }
     906                 :                 else {
     907                 :                     // We only support arrays of DOM nodes.
     908               0 :                     rv = NS_ERROR_ILLEGAL_VALUE;
     909                 :                 }
     910                 : 
     911               0 :                 if (NS_FAILED(rv)) {
     912               0 :                     while (i < count) {
     913               0 :                         NS_IF_RELEASE(values[i]);
     914               0 :                         ++i;
     915                 :                     }
     916               0 :                     nsMemory::Free(array);
     917                 : 
     918               0 :                     return rv;
     919                 :                 }
     920                 : 
     921               0 :                 NS_RELEASE(supports);
     922                 :             }
     923                 : 
     924               0 :             nsMemory::Free(array);
     925                 : 
     926               0 :             break;
     927                 :         }
     928                 : 
     929                 :         default:
     930                 :         {
     931               0 :             return NS_ERROR_FAILURE;
     932                 :         }        
     933                 :     }
     934                 : 
     935               0 :     PRInt32 nsId = kNameSpaceID_Unknown;
     936               0 :     nsresult rv = nsContentUtils::NameSpaceManager()->
     937               0 :         RegisterNameSpace(aNamespaceURI, nsId);
     938               0 :     NS_ENSURE_SUCCESS(rv, rv);
     939               0 :     nsCOMPtr<nsIAtom> localName = do_GetAtom(aLocalName);
     940               0 :     txExpandedName varName(nsId, localName);
     941                 : 
     942               0 :     txVariable* var = static_cast<txVariable*>(mVariables.get(varName));
     943               0 :     if (var) {
     944               0 :         var->setValue(value);
     945               0 :         return NS_OK;
     946                 :     }
     947                 : 
     948               0 :     var = new txVariable(value);
     949               0 :     NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
     950                 : 
     951               0 :     return mVariables.add(varName, var);
     952                 : }
     953                 : 
     954                 : NS_IMETHODIMP
     955               0 : txMozillaXSLTProcessor::GetParameter(const nsAString& aNamespaceURI,
     956                 :                                      const nsAString& aLocalName,
     957                 :                                      nsIVariant **aResult)
     958                 : {
     959               0 :     PRInt32 nsId = kNameSpaceID_Unknown;
     960               0 :     nsresult rv = nsContentUtils::NameSpaceManager()->
     961               0 :         RegisterNameSpace(aNamespaceURI, nsId);
     962               0 :     NS_ENSURE_SUCCESS(rv, rv);
     963               0 :     nsCOMPtr<nsIAtom> localName = do_GetAtom(aLocalName);
     964               0 :     txExpandedName varName(nsId, localName);
     965                 : 
     966               0 :     txVariable* var = static_cast<txVariable*>(mVariables.get(varName));
     967               0 :     if (var) {
     968               0 :         return var->getValue(aResult);
     969                 :     }
     970               0 :     return NS_OK;
     971                 : }
     972                 : 
     973                 : NS_IMETHODIMP
     974               0 : txMozillaXSLTProcessor::RemoveParameter(const nsAString& aNamespaceURI,
     975                 :                                         const nsAString& aLocalName)
     976                 : {
     977               0 :     PRInt32 nsId = kNameSpaceID_Unknown;
     978               0 :     nsresult rv = nsContentUtils::NameSpaceManager()->
     979               0 :         RegisterNameSpace(aNamespaceURI, nsId);
     980               0 :     NS_ENSURE_SUCCESS(rv, rv);
     981               0 :     nsCOMPtr<nsIAtom> localName = do_GetAtom(aLocalName);
     982               0 :     txExpandedName varName(nsId, localName);
     983                 : 
     984               0 :     mVariables.remove(varName);
     985               0 :     return NS_OK;
     986                 : }
     987                 : 
     988                 : NS_IMETHODIMP
     989               0 : txMozillaXSLTProcessor::ClearParameters()
     990                 : {
     991               0 :     mVariables.clear();
     992                 : 
     993               0 :     return NS_OK;
     994                 : }
     995                 : 
     996                 : NS_IMETHODIMP
     997               0 : txMozillaXSLTProcessor::Reset()
     998                 : {
     999               0 :     if (mStylesheetDocument) {
    1000               0 :         mStylesheetDocument->RemoveMutationObserver(this);
    1001                 :     }
    1002               0 :     mStylesheet = nsnull;
    1003               0 :     mStylesheetDocument = nsnull;
    1004               0 :     mEmbeddedStylesheetRoot = nsnull;
    1005               0 :     mCompileResult = NS_OK;
    1006               0 :     mVariables.clear();
    1007                 : 
    1008               0 :     return NS_OK;
    1009                 : }
    1010                 : 
    1011                 : NS_IMETHODIMP
    1012               0 : txMozillaXSLTProcessor::SetFlags(PRUint32 aFlags)
    1013                 : {
    1014               0 :     NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(),
    1015                 :                    NS_ERROR_DOM_SECURITY_ERR);
    1016                 : 
    1017               0 :     mFlags = aFlags;
    1018                 : 
    1019               0 :     return NS_OK;
    1020                 : }
    1021                 : 
    1022                 : NS_IMETHODIMP
    1023               0 : txMozillaXSLTProcessor::GetFlags(PRUint32* aFlags)
    1024                 : {
    1025               0 :     NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(),
    1026                 :                    NS_ERROR_DOM_SECURITY_ERR);
    1027                 : 
    1028               0 :     *aFlags = mFlags;
    1029                 : 
    1030               0 :     return NS_OK;
    1031                 : }
    1032                 : 
    1033                 : NS_IMETHODIMP
    1034               0 : txMozillaXSLTProcessor::LoadStyleSheet(nsIURI* aUri, nsILoadGroup* aLoadGroup)
    1035                 : {
    1036               0 :     nsresult rv = TX_LoadSheet(aUri, this, aLoadGroup, mPrincipal);
    1037               0 :     if (NS_FAILED(rv) && mObserver) {
    1038                 :         // This is most likely a network or security error, just
    1039                 :         // use the uri as context.
    1040               0 :         nsCAutoString spec;
    1041               0 :         aUri->GetSpec(spec);
    1042               0 :         CopyUTF8toUTF16(spec, mSourceText);
    1043                 :         nsresult status = NS_ERROR_GET_MODULE(rv) == NS_ERROR_MODULE_XSLT ? rv :
    1044               0 :                           NS_ERROR_XSLT_NETWORK_ERROR;
    1045               0 :         reportError(status, nsnull, nsnull);
    1046                 :     }
    1047               0 :     return rv;
    1048                 : }
    1049                 : 
    1050                 : nsresult
    1051               0 : txMozillaXSLTProcessor::setStylesheet(txStylesheet* aStylesheet)
    1052                 : {
    1053               0 :     mStylesheet = aStylesheet;
    1054               0 :     if (mSource) {
    1055               0 :         return DoTransform();
    1056                 :     }
    1057               0 :     return NS_OK;
    1058                 : }
    1059                 : 
    1060                 : void
    1061               0 : txMozillaXSLTProcessor::reportError(nsresult aResult,
    1062                 :                                     const PRUnichar *aErrorText,
    1063                 :                                     const PRUnichar *aSourceText)
    1064                 : {
    1065               0 :     if (!mObserver) {
    1066               0 :         return;
    1067                 :     }
    1068                 : 
    1069               0 :     mTransformResult = aResult;
    1070                 : 
    1071               0 :     if (aErrorText) {
    1072               0 :         mErrorText.Assign(aErrorText);
    1073                 :     }
    1074                 :     else {
    1075                 :         nsCOMPtr<nsIStringBundleService> sbs =
    1076               0 :             mozilla::services::GetStringBundleService();
    1077               0 :         if (sbs) {
    1078               0 :             nsXPIDLString errorText;
    1079               0 :             sbs->FormatStatusMessage(aResult, EmptyString().get(),
    1080               0 :                                      getter_Copies(errorText));
    1081                 : 
    1082               0 :             nsXPIDLString errorMessage;
    1083               0 :             nsCOMPtr<nsIStringBundle> bundle;
    1084               0 :             sbs->CreateBundle(XSLT_MSGS_URL, getter_AddRefs(bundle));
    1085                 : 
    1086               0 :             if (bundle) {
    1087               0 :                 const PRUnichar* error[] = { errorText.get() };
    1088               0 :                 if (mStylesheet) {
    1089               0 :                     bundle->FormatStringFromName(NS_LITERAL_STRING("TransformError").get(),
    1090                 :                                                  error, 1,
    1091               0 :                                                  getter_Copies(errorMessage));
    1092                 :                 }
    1093                 :                 else {
    1094               0 :                     bundle->FormatStringFromName(NS_LITERAL_STRING("LoadingError").get(),
    1095                 :                                                  error, 1,
    1096               0 :                                                  getter_Copies(errorMessage));
    1097                 :                 }
    1098                 :             }
    1099               0 :             mErrorText.Assign(errorMessage);
    1100                 :         }
    1101                 :     }
    1102                 : 
    1103               0 :     if (aSourceText) {
    1104               0 :         mSourceText.Assign(aSourceText);
    1105                 :     }
    1106                 : 
    1107               0 :     if (mSource) {
    1108               0 :         notifyError();
    1109                 :     }
    1110                 : }
    1111                 : 
    1112                 : void
    1113               0 : txMozillaXSLTProcessor::notifyError()
    1114                 : {
    1115                 :     nsresult rv;
    1116                 :     nsCOMPtr<nsIDOMDocument> errorDocument = do_CreateInstance(kXMLDocumentCID,
    1117               0 :                                                                &rv);
    1118               0 :     if (NS_FAILED(rv)) {
    1119                 :         return;
    1120                 :     }
    1121                 : 
    1122                 :     // Set up the document
    1123               0 :     nsCOMPtr<nsIDocument> document = do_QueryInterface(errorDocument);
    1124               0 :     if (!document) {
    1125                 :         return;
    1126                 :     }
    1127               0 :     URIUtils::ResetWithSource(document, mSource);
    1128                 : 
    1129               0 :     NS_NAMED_LITERAL_STRING(ns, "http://www.mozilla.org/newlayout/xml/parsererror.xml");
    1130                 : 
    1131               0 :     nsCOMPtr<nsIDOMElement> element;
    1132               0 :     rv = errorDocument->CreateElementNS(ns, NS_LITERAL_STRING("parsererror"),
    1133               0 :                                         getter_AddRefs(element));
    1134               0 :     if (NS_FAILED(rv)) {
    1135                 :         return;
    1136                 :     }
    1137                 : 
    1138               0 :     nsCOMPtr<nsIDOMNode> resultNode;
    1139               0 :     rv = errorDocument->AppendChild(element, getter_AddRefs(resultNode));
    1140               0 :     if (NS_FAILED(rv)) {
    1141                 :         return;
    1142                 :     }
    1143                 : 
    1144               0 :     nsCOMPtr<nsIDOMText> text;
    1145               0 :     rv = errorDocument->CreateTextNode(mErrorText, getter_AddRefs(text));
    1146               0 :     if (NS_FAILED(rv)) {
    1147                 :         return;
    1148                 :     }
    1149                 : 
    1150               0 :     rv = element->AppendChild(text, getter_AddRefs(resultNode));
    1151               0 :     if (NS_FAILED(rv)) {
    1152                 :         return;
    1153                 :     }
    1154                 : 
    1155               0 :     if (!mSourceText.IsEmpty()) {
    1156               0 :         nsCOMPtr<nsIDOMElement> sourceElement;
    1157               0 :         rv = errorDocument->CreateElementNS(ns,
    1158               0 :                                             NS_LITERAL_STRING("sourcetext"),
    1159               0 :                                             getter_AddRefs(sourceElement));
    1160               0 :         if (NS_FAILED(rv)) {
    1161                 :             return;
    1162                 :         }
    1163                 :     
    1164               0 :         rv = element->AppendChild(sourceElement, getter_AddRefs(resultNode));
    1165               0 :         if (NS_FAILED(rv)) {
    1166                 :             return;
    1167                 :         }
    1168                 : 
    1169               0 :         rv = errorDocument->CreateTextNode(mSourceText, getter_AddRefs(text));
    1170               0 :         if (NS_FAILED(rv)) {
    1171                 :             return;
    1172                 :         }
    1173                 :     
    1174               0 :         rv = sourceElement->AppendChild(text, getter_AddRefs(resultNode));
    1175               0 :         if (NS_FAILED(rv)) {
    1176                 :             return;
    1177                 :         }
    1178                 :     }
    1179                 : 
    1180               0 :     mObserver->OnTransformDone(mTransformResult, document);
    1181                 : }
    1182                 : 
    1183                 : nsresult
    1184               0 : txMozillaXSLTProcessor::ensureStylesheet()
    1185                 : {
    1186               0 :     if (mStylesheet) {
    1187               0 :         return NS_OK;
    1188                 :     }
    1189                 : 
    1190               0 :     NS_ENSURE_TRUE(mStylesheetDocument, NS_ERROR_NOT_INITIALIZED);
    1191                 : 
    1192               0 :     nsINode* style = mEmbeddedStylesheetRoot;
    1193               0 :     if (!style) {
    1194               0 :         style = mStylesheetDocument;
    1195                 :     }
    1196                 : 
    1197                 :     return TX_CompileStylesheet(style, this, mPrincipal,
    1198               0 :                                 getter_AddRefs(mStylesheet));
    1199                 : }
    1200                 : 
    1201                 : void
    1202               0 : txMozillaXSLTProcessor::NodeWillBeDestroyed(const nsINode* aNode)
    1203                 : {
    1204               0 :     nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
    1205               0 :     if (NS_FAILED(mCompileResult)) {
    1206                 :         return;
    1207                 :     }
    1208                 : 
    1209               0 :     mCompileResult = ensureStylesheet();
    1210               0 :     mStylesheetDocument = nsnull;
    1211               0 :     mEmbeddedStylesheetRoot = nsnull;
    1212                 : }
    1213                 : 
    1214                 : void
    1215               0 : txMozillaXSLTProcessor::CharacterDataChanged(nsIDocument* aDocument,
    1216                 :                                              nsIContent *aContent,
    1217                 :                                              CharacterDataChangeInfo* aInfo)
    1218                 : {
    1219               0 :     mStylesheet = nsnull;
    1220               0 : }
    1221                 : 
    1222                 : void
    1223               0 : txMozillaXSLTProcessor::AttributeChanged(nsIDocument* aDocument,
    1224                 :                                          Element* aElement,
    1225                 :                                          PRInt32 aNameSpaceID,
    1226                 :                                          nsIAtom* aAttribute,
    1227                 :                                          PRInt32 aModType)
    1228                 : {
    1229               0 :     mStylesheet = nsnull;
    1230               0 : }
    1231                 : 
    1232                 : void
    1233               0 : txMozillaXSLTProcessor::ContentAppended(nsIDocument* aDocument,
    1234                 :                                         nsIContent* aContainer,
    1235                 :                                         nsIContent* aFirstNewContent,
    1236                 :                                         PRInt32 /* unused */)
    1237                 : {
    1238               0 :     mStylesheet = nsnull;
    1239               0 : }
    1240                 : 
    1241                 : void
    1242               0 : txMozillaXSLTProcessor::ContentInserted(nsIDocument* aDocument,
    1243                 :                                         nsIContent* aContainer,
    1244                 :                                         nsIContent* aChild,
    1245                 :                                         PRInt32 /* unused */)
    1246                 : {
    1247               0 :     mStylesheet = nsnull;
    1248               0 : }
    1249                 : 
    1250                 : void
    1251               0 : txMozillaXSLTProcessor::ContentRemoved(nsIDocument* aDocument,
    1252                 :                                        nsIContent* aContainer,
    1253                 :                                        nsIContent* aChild,
    1254                 :                                        PRInt32 aIndexInContainer,
    1255                 :                                        nsIContent* aPreviousSibling)
    1256                 : {
    1257               0 :     mStylesheet = nsnull;
    1258               0 : }
    1259                 : 
    1260                 : NS_IMETHODIMP
    1261               0 : txMozillaXSLTProcessor::Initialize(nsISupports* aOwner, JSContext* cx,
    1262                 :                                    JSObject* obj, PRUint32 argc, jsval* argv)
    1263                 : {
    1264               0 :     nsCOMPtr<nsIPrincipal> prin;
    1265               0 :     nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
    1266               0 :     NS_ENSURE_TRUE(secMan, NS_ERROR_UNEXPECTED);
    1267                 : 
    1268               0 :     nsresult rv = secMan->GetSubjectPrincipal(getter_AddRefs(prin));
    1269               0 :     NS_ENSURE_SUCCESS(rv, rv);
    1270               0 :     NS_ENSURE_TRUE(prin, NS_ERROR_UNEXPECTED);
    1271                 : 
    1272               0 :     return Init(prin);
    1273                 : }
    1274                 : 
    1275                 : NS_IMETHODIMP
    1276               0 : txMozillaXSLTProcessor::Init(nsIPrincipal* aPrincipal)
    1277                 : {
    1278               0 :     NS_ENSURE_ARG_POINTER(aPrincipal);
    1279               0 :     mPrincipal = aPrincipal;
    1280                 : 
    1281               0 :     return NS_OK;
    1282                 : }
    1283                 : 
    1284                 : /* static*/
    1285                 : nsresult
    1286            1404 : txMozillaXSLTProcessor::Startup()
    1287                 : {
    1288            1404 :     if (!txXSLTProcessor::init()) {
    1289               0 :         return NS_ERROR_OUT_OF_MEMORY;
    1290                 :     }
    1291                 : 
    1292                 :     nsCOMPtr<nsIErrorService> errorService =
    1293            2808 :         do_GetService(NS_ERRORSERVICE_CONTRACTID);
    1294            1404 :     if (errorService) {
    1295            1404 :         errorService->RegisterErrorStringBundle(NS_ERROR_MODULE_XSLT,
    1296            1404 :                                                 XSLT_MSGS_URL);
    1297                 :     }
    1298                 : 
    1299            1404 :     return NS_OK;
    1300                 : }
    1301                 : 
    1302                 : /* static*/
    1303                 : void
    1304            1403 : txMozillaXSLTProcessor::Shutdown()
    1305                 : {
    1306            1403 :     txXSLTProcessor::shutdown();
    1307                 : 
    1308                 :     nsCOMPtr<nsIErrorService> errorService =
    1309            2806 :         do_GetService(NS_ERRORSERVICE_CONTRACTID);
    1310            1403 :     if (errorService) {
    1311            1110 :         errorService->UnregisterErrorStringBundle(NS_ERROR_MODULE_XSLT);
    1312                 :     }
    1313            1403 : }
    1314                 : 
    1315                 : /* static*/
    1316                 : nsresult
    1317               0 : txVariable::Convert(nsIVariant *aValue, txAExprResult** aResult)
    1318                 : {
    1319               0 :     *aResult = nsnull;
    1320                 : 
    1321                 :     PRUint16 dataType;
    1322               0 :     aValue->GetDataType(&dataType);
    1323               0 :     switch (dataType) {
    1324                 :         // Number
    1325                 :         case nsIDataType::VTYPE_INT8:
    1326                 :         case nsIDataType::VTYPE_INT16:
    1327                 :         case nsIDataType::VTYPE_INT32:
    1328                 :         case nsIDataType::VTYPE_INT64:
    1329                 :         case nsIDataType::VTYPE_UINT8:
    1330                 :         case nsIDataType::VTYPE_UINT16:
    1331                 :         case nsIDataType::VTYPE_UINT32:
    1332                 :         case nsIDataType::VTYPE_UINT64:
    1333                 :         case nsIDataType::VTYPE_FLOAT:
    1334                 :         case nsIDataType::VTYPE_DOUBLE:
    1335                 :         {
    1336                 :             double value;
    1337               0 :             nsresult rv = aValue->GetAsDouble(&value);
    1338               0 :             NS_ENSURE_SUCCESS(rv, rv);
    1339                 : 
    1340               0 :             *aResult = new NumberResult(value, nsnull);
    1341               0 :             NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
    1342                 : 
    1343               0 :             NS_ADDREF(*aResult);
    1344                 : 
    1345               0 :             return NS_OK;
    1346                 :         }
    1347                 : 
    1348                 :         // Boolean
    1349                 :         case nsIDataType::VTYPE_BOOL:
    1350                 :         {
    1351                 :             bool value;
    1352               0 :             nsresult rv = aValue->GetAsBool(&value);
    1353               0 :             NS_ENSURE_SUCCESS(rv, rv);
    1354                 : 
    1355               0 :             *aResult = new BooleanResult(value);
    1356               0 :             NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
    1357                 : 
    1358               0 :             NS_ADDREF(*aResult);
    1359                 : 
    1360               0 :             return NS_OK;
    1361                 :         }
    1362                 : 
    1363                 :         // String
    1364                 :         case nsIDataType::VTYPE_CHAR:
    1365                 :         case nsIDataType::VTYPE_WCHAR:
    1366                 :         case nsIDataType::VTYPE_DOMSTRING:
    1367                 :         case nsIDataType::VTYPE_CHAR_STR:
    1368                 :         case nsIDataType::VTYPE_WCHAR_STR:
    1369                 :         case nsIDataType::VTYPE_STRING_SIZE_IS:
    1370                 :         case nsIDataType::VTYPE_WSTRING_SIZE_IS:
    1371                 :         case nsIDataType::VTYPE_UTF8STRING:
    1372                 :         case nsIDataType::VTYPE_CSTRING:
    1373                 :         case nsIDataType::VTYPE_ASTRING:
    1374                 :         {
    1375               0 :             nsAutoString value;
    1376               0 :             nsresult rv = aValue->GetAsAString(value);
    1377               0 :             NS_ENSURE_SUCCESS(rv, rv);
    1378                 : 
    1379               0 :             *aResult = new StringResult(value, nsnull);
    1380               0 :             NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
    1381                 : 
    1382               0 :             NS_ADDREF(*aResult);
    1383                 : 
    1384               0 :             return NS_OK;
    1385                 :         }
    1386                 : 
    1387                 :         // Nodeset
    1388                 :         case nsIDataType::VTYPE_INTERFACE:
    1389                 :         case nsIDataType::VTYPE_INTERFACE_IS:
    1390                 :         {
    1391               0 :             nsCOMPtr<nsISupports> supports;
    1392               0 :             nsresult rv = aValue->GetAsISupports(getter_AddRefs(supports));
    1393               0 :             NS_ENSURE_SUCCESS(rv, rv);
    1394                 : 
    1395               0 :             nsCOMPtr<nsIDOMNode> node = do_QueryInterface(supports);
    1396               0 :             if (node) {
    1397               0 :                 nsAutoPtr<txXPathNode> xpathNode(txXPathNativeNode::createXPathNode(node));
    1398               0 :                 if (!xpathNode) {
    1399               0 :                     return NS_ERROR_FAILURE;
    1400                 :                 }
    1401                 : 
    1402               0 :                 *aResult = new txNodeSet(*xpathNode, nsnull);
    1403               0 :                 if (!*aResult) {
    1404               0 :                     return NS_ERROR_OUT_OF_MEMORY;
    1405                 :                 }
    1406                 : 
    1407               0 :                 NS_ADDREF(*aResult);
    1408                 : 
    1409               0 :                 return NS_OK;
    1410                 :             }
    1411                 : 
    1412               0 :             nsCOMPtr<nsIXPathResult> xpathResult = do_QueryInterface(supports);
    1413               0 :             if (xpathResult) {
    1414               0 :                 return xpathResult->GetExprResult(aResult);
    1415                 :             }
    1416                 : 
    1417               0 :             nsCOMPtr<nsIDOMNodeList> nodeList = do_QueryInterface(supports);
    1418               0 :             if (nodeList) {
    1419               0 :                 nsRefPtr<txNodeSet> nodeSet = new txNodeSet(nsnull);
    1420               0 :                 if (!nodeSet) {
    1421               0 :                     return NS_ERROR_OUT_OF_MEMORY;
    1422                 :                 }
    1423                 : 
    1424                 :                 PRUint32 length;
    1425               0 :                 nodeList->GetLength(&length);
    1426                 : 
    1427               0 :                 nsCOMPtr<nsIDOMNode> node;
    1428                 :                 PRUint32 i;
    1429               0 :                 for (i = 0; i < length; ++i) {
    1430               0 :                     nodeList->Item(i, getter_AddRefs(node));
    1431                 : 
    1432                 :                     nsAutoPtr<txXPathNode> xpathNode(
    1433               0 :                         txXPathNativeNode::createXPathNode(node));
    1434               0 :                     if (!xpathNode) {
    1435               0 :                         return NS_ERROR_FAILURE;
    1436                 :                     }
    1437                 : 
    1438               0 :                     nodeSet->add(*xpathNode);
    1439                 :                 }
    1440                 : 
    1441               0 :                 NS_ADDREF(*aResult = nodeSet);
    1442                 : 
    1443               0 :                 return NS_OK;
    1444                 :             }
    1445                 : 
    1446                 :             // Convert random JS Objects to a string.
    1447                 :             nsCOMPtr<nsIXPConnectJSObjectHolder> holder =
    1448               0 :                 do_QueryInterface(supports);
    1449               0 :             if (holder) {
    1450               0 :                 JSContext* cx = nsContentUtils::GetCurrentJSContext();
    1451               0 :                 NS_ENSURE_TRUE(cx, NS_ERROR_NOT_AVAILABLE);
    1452                 : 
    1453                 :                 JSObject *jsobj;
    1454               0 :                 rv = holder->GetJSObject(&jsobj);
    1455               0 :                 NS_ENSURE_SUCCESS(rv, rv);
    1456                 : 
    1457               0 :                 JSString *str = JS_ValueToString(cx, OBJECT_TO_JSVAL(jsobj));
    1458               0 :                 NS_ENSURE_TRUE(str, NS_ERROR_FAILURE);
    1459                 : 
    1460               0 :                 nsDependentJSString value;
    1461               0 :                 NS_ENSURE_TRUE(value.init(cx, str), NS_ERROR_FAILURE);
    1462                 : 
    1463               0 :                 *aResult = new StringResult(value, nsnull);
    1464               0 :                 if (!*aResult) {
    1465               0 :                     return NS_ERROR_OUT_OF_MEMORY;
    1466                 :                 }
    1467                 : 
    1468               0 :                 NS_ADDREF(*aResult);
    1469                 : 
    1470               0 :                 return NS_OK;
    1471                 :             }
    1472                 : 
    1473               0 :             break;
    1474                 :         }
    1475                 : 
    1476                 :         case nsIDataType::VTYPE_ARRAY:
    1477                 :         {
    1478                 :             PRUint16 type;
    1479                 :             nsIID iid;
    1480                 :             PRUint32 count;
    1481                 :             void* array;
    1482               0 :             nsresult rv = aValue->GetAsArray(&type, &iid, &count, &array);
    1483               0 :             NS_ENSURE_SUCCESS(rv, rv);
    1484                 : 
    1485               0 :             NS_ASSERTION(type == nsIDataType::VTYPE_INTERFACE ||
    1486                 :                          type == nsIDataType::VTYPE_INTERFACE_IS,
    1487                 :                          "Huh, we checked this in SetParameter?");
    1488                 : 
    1489               0 :             nsISupports** values = static_cast<nsISupports**>(array);
    1490                 : 
    1491               0 :             nsRefPtr<txNodeSet> nodeSet = new txNodeSet(nsnull);
    1492               0 :             if (!nodeSet) {
    1493               0 :                 NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, values);
    1494                 : 
    1495               0 :                 return NS_ERROR_OUT_OF_MEMORY;
    1496                 :             }
    1497                 : 
    1498                 :             PRUint32 i;
    1499               0 :             for (i = 0; i < count; ++i) {
    1500               0 :                 nsISupports *supports = values[i];
    1501               0 :                 nsCOMPtr<nsIDOMNode> node = do_QueryInterface(supports);
    1502               0 :                 NS_ASSERTION(node, "Huh, we checked this in SetParameter?");
    1503                 : 
    1504                 :                 nsAutoPtr<txXPathNode> xpathNode(
    1505               0 :                     txXPathNativeNode::createXPathNode(node));
    1506               0 :                 if (!xpathNode) {
    1507               0 :                     while (i < count) {
    1508               0 :                         NS_RELEASE(values[i]);
    1509               0 :                         ++i;
    1510                 :                     }
    1511               0 :                     nsMemory::Free(array);
    1512                 : 
    1513               0 :                     return NS_ERROR_FAILURE;
    1514                 :                 }
    1515                 : 
    1516               0 :                 nodeSet->add(*xpathNode);
    1517                 : 
    1518               0 :                 NS_RELEASE(supports);
    1519                 :             }
    1520                 : 
    1521               0 :             nsMemory::Free(array);
    1522                 : 
    1523               0 :             NS_ADDREF(*aResult = nodeSet);
    1524                 : 
    1525               0 :             return NS_OK;
    1526                 :         }
    1527                 :     }
    1528                 : 
    1529               0 :     return NS_ERROR_ILLEGAL_VALUE;
    1530            4392 : }

Generated by: LCOV version 1.7