diff --git a/mozilla/extensions/transformiix/build/XSLTProcessorModule.cpp b/mozilla/extensions/transformiix/build/XSLTProcessorModule.cpp index f41b4c2c351..62b0966e6f5 100755 --- a/mozilla/extensions/transformiix/build/XSLTProcessorModule.cpp +++ b/mozilla/extensions/transformiix/build/XSLTProcessorModule.cpp @@ -26,6 +26,7 @@ #include "nsICategoryManager.h" #include "nsIDOMClassInfo.h" +#include "nsIErrorService.h" #include "nsIExceptionService.h" #include "nsIGenericFactory.h" #include "nsIScriptNameSpaceManager.h" @@ -220,6 +221,13 @@ Initialize(nsIModule* aSelf) return rv; } + nsCOMPtr errorService = + do_GetService(NS_ERRORSERVICE_CONTRACTID); + if (errorService) { + errorService->RegisterErrorStringBundle(NS_ERROR_MODULE_XSLT, + XSLT_MSGS_URL); + } + return NS_OK; } diff --git a/mozilla/extensions/transformiix/source/base/txError.h b/mozilla/extensions/transformiix/source/base/txError.h index 6a378188058..3e209998d77 100644 --- a/mozilla/extensions/transformiix/source/base/txError.h +++ b/mozilla/extensions/transformiix/source/base/txError.h @@ -51,34 +51,40 @@ #define NS_ERROR_XPATH_INVALID_ARG NS_ERROR_INVALID_ARG #define NS_ERROR_XSLT_INVALID_URL NS_ERROR_INVALID_ARG +#define NS_XSLT_GET_NEW_HANDLER \ + NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XSLT, 1) + #define NS_ERROR_XSLT_PARSE_FAILURE \ NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 1) #define NS_ERROR_XPATH_PARSE_FAILURE \ NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 2) -#define NS_ERROR_XSLT_GET_NEW_HANDLER \ +#define NS_ERROR_XSLT_ALREADY_SET \ NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 3) -#define NS_ERROR_XSLT_ALREADY_SET \ +#define NS_ERROR_XSLT_EXECUTION_FAILURE \ NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 4) -#define NS_ERROR_XSLT_EXECUTION_FAILURE \ +#define NS_ERROR_XPATH_UNKNOWN_FUNCTION \ NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 5) -#define NS_ERROR_XPATH_UNKNOWN_FUNCTION \ +#define NS_ERROR_XSLT_BAD_RECURSION \ NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 6) -#define NS_ERROR_XSLT_BAD_RECURSION \ +#define NS_ERROR_XSLT_BAD_VALUE \ NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 7) -#define NS_ERROR_XSLT_BAD_VALUE \ +#define NS_ERROR_XSLT_NODESET_EXPECTED \ NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 8) -#define NS_ERROR_XSLT_NODESET_EXPECTED \ +#define NS_ERROR_XSLT_ABORTED \ NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 9) -#define NS_ERROR_XSLT_ABORTED \ +#define NS_ERROR_XSLT_NETWORK_ERROR \ NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 10) +#define NS_ERROR_XSLT_WRONG_MIME_TYPE \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 11) + #endif // __TX_ERROR diff --git a/mozilla/extensions/transformiix/source/xml/parser/txXMLParser.cpp b/mozilla/extensions/transformiix/source/xml/parser/txXMLParser.cpp index 48017377fd4..b1d71bacb03 100644 --- a/mozilla/extensions/transformiix/source/xml/parser/txXMLParser.cpp +++ b/mozilla/extensions/transformiix/source/xml/parser/txXMLParser.cpp @@ -107,7 +107,7 @@ txParseDocumentFromURI(const nsAString& aHref, const nsAString& aReferrer, nsCOMPtr loader = do_GetService("@mozilla.org/content/syncload-dom-service;1", &rv); NS_ENSURE_SUCCESS(rv, rv); - rv = loader->LoadDocument(channel, loaderUri, getter_AddRefs(theDocument)); + rv = loader->LoadDocumentAsXML(channel, loaderUri, getter_AddRefs(theDocument)); if (NS_FAILED(rv) || !theDocument) { aErrMsg.Append(NS_LITERAL_STRING("Document load of ") + aHref + NS_LITERAL_STRING(" failed.")); diff --git a/mozilla/extensions/transformiix/source/xslt/Makefile.in b/mozilla/extensions/transformiix/source/xslt/Makefile.in index 717533680ae..3fdfa6f99a8 100644 --- a/mozilla/extensions/transformiix/source/xslt/Makefile.in +++ b/mozilla/extensions/transformiix/source/xslt/Makefile.in @@ -45,6 +45,10 @@ REQUIRES += dom \ docshell \ layout \ uconv \ + caps \ + windowwatcher \ + mimetype \ + intl \ $(NULL) else REQUIRES += expat \ diff --git a/mozilla/extensions/transformiix/source/xslt/txMozillaStylesheetCompiler.cpp b/mozilla/extensions/transformiix/source/xslt/txMozillaStylesheetCompiler.cpp index bff6fcbd1d2..992be9bcce7 100644 --- a/mozilla/extensions/transformiix/source/xslt/txMozillaStylesheetCompiler.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txMozillaStylesheetCompiler.cpp @@ -38,17 +38,25 @@ * ***** END LICENSE BLOCK ***** */ #include "nsCOMArray.h" +#include "nsIAuthPrompt.h" #include "nsICharsetAlias.h" #include "nsIDocument.h" #include "nsIExpatSink.h" +#include "nsIHttpEventSink.h" +#include "nsIInterfaceRequestor.h" #include "nsILoadGroup.h" #include "nsINameSpace.h" #include "nsINameSpaceManager.h" #include "nsINodeInfo.h" #include "nsIParser.h" +#include "nsIRequestObserver.h" +#include "nsIScriptSecurityManager.h" +#include "nsIStreamConverterService.h" #include "nsISyncLoadDOMService.h" #include "nsIURI.h" +#include "nsIWindowWatcher.h" #include "nsIXMLContentSink.h" +#include "nsMimeTypes.h" #include "nsNetUtil.h" #include "nsParserCIID.h" #include "txAtoms.h" @@ -57,16 +65,42 @@ #include "XMLUtils.h" static const char kLoadAsData[] = "loadAsData"; +static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID); + +static void +getSpec(nsIChannel* aChannel, nsAString& aSpec) +{ + if (!aChannel) { + return; + } + + nsCOMPtr uri; + aChannel->GetOriginalURI(getter_AddRefs(uri)); + if (!uri) { + return; + } + + nsCAutoString spec; + uri->GetSpec(spec); + aSpec.Append(NS_ConvertUTF8toUCS2(spec)); +} class txStylesheetSink : public nsIXMLContentSink, - public nsIExpatSink + public nsIExpatSink, + public nsIStreamListener, + public nsIHttpEventSink, + public nsIInterfaceRequestor { public: - txStylesheetSink(txStylesheetCompiler* aCompiler); + txStylesheetSink(txStylesheetCompiler* aCompiler, nsIParser* aParser); virtual ~txStylesheetSink(); NS_DECL_ISUPPORTS NS_DECL_NSIEXPATSINK + NS_DECL_NSISTREAMLISTENER + NS_DECL_NSIREQUESTOBSERVER + NS_DECL_NSIHTTPEVENTSINK + NS_DECL_NSIINTERFACEREQUESTOR // nsIContentSink NS_IMETHOD WillBuildModel(void) { return NS_OK; } @@ -79,22 +113,34 @@ public: private: nsRefPtr mCompiler; + nsCOMPtr mListener; + PRPackedBool mCheckedForXML; protected: // This exists soly to supress a warning from nsDerivedSafe txStylesheetSink(); }; -txStylesheetSink::txStylesheetSink(txStylesheetCompiler* aCompiler) - : mCompiler(aCompiler) +txStylesheetSink::txStylesheetSink(txStylesheetCompiler* aCompiler, + nsIParser* aParser) + : mCompiler(aCompiler), + mCheckedForXML(PR_FALSE) { + mListener = do_QueryInterface(aParser); } txStylesheetSink::~txStylesheetSink() { } -NS_IMPL_ISUPPORTS2(txStylesheetSink, nsIXMLContentSink, nsIExpatSink) +NS_IMPL_ISUPPORTS7(txStylesheetSink, + nsIXMLContentSink, + nsIContentSink, + nsIExpatSink, + nsIStreamListener, + nsIRequestObserver, + nsIHttpEventSink, + nsIInterfaceRequestor) NS_IMETHODIMP txStylesheetSink::HandleStartElement(const PRUnichar *aName, @@ -109,6 +155,7 @@ txStylesheetSink::HandleStartElement(const PRUnichar *aName, mCompiler->startElement(aName, aAtts, aAttsCount, (PRInt32)aIndex); if (NS_FAILED(rv)) { mCompiler->cancel(rv); + return rv; } @@ -121,6 +168,7 @@ txStylesheetSink::HandleEndElement(const PRUnichar *aName) nsresult rv = mCompiler->endElement(); if (NS_FAILED(rv)) { mCompiler->cancel(rv); + return rv; } @@ -181,7 +229,8 @@ NS_IMETHODIMP txStylesheetSink::ReportError(const PRUnichar *aErrorText, const PRUnichar *aSourceText) { - mCompiler->cancel(NS_ERROR_FAILURE); + mCompiler->cancel(NS_ERROR_FAILURE, aErrorText, aSourceText); + return NS_OK; } @@ -191,6 +240,176 @@ txStylesheetSink::DidBuildModel(PRInt32 aQualityLevel) return mCompiler->doneLoading(); } +NS_IMETHODIMP +txStylesheetSink::OnDataAvailable(nsIRequest *aRequest, nsISupports *aContext, + nsIInputStream *aInputStream, + PRUint32 aOffset, PRUint32 aCount) +{ + if (!mCheckedForXML) { + nsCOMPtr parser = do_QueryInterface(aContext); + nsCOMPtr dtd; + parser->GetDTD(getter_AddRefs(dtd)); + if (dtd) { + mCheckedForXML = PR_TRUE; + if (!(dtd->GetType() & NS_IPARSER_FLAG_XML)) { + nsCOMPtr channel = do_QueryInterface(aRequest); + nsAutoString spec; + getSpec(channel, spec); + mCompiler->cancel(NS_ERROR_XSLT_WRONG_MIME_TYPE, nsnull, + spec.get()); + + return NS_ERROR_XSLT_WRONG_MIME_TYPE; + } + } + } + + return mListener->OnDataAvailable(aRequest, aContext, aInputStream, + aOffset, aCount); +} + +NS_IMETHODIMP +txStylesheetSink::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext) +{ + nsAutoString charset(NS_LITERAL_STRING("UTF-8")); + PRInt32 charsetSource = kCharsetFromDocTypeDefault; + + nsCOMPtr channel = do_QueryInterface(aRequest); + + // check channel's charset... + nsCAutoString charsetVal; + nsresult rv = channel->GetContentCharset(charsetVal); + if (NS_SUCCEEDED(rv)) { + nsCOMPtr calias = + do_GetService(NS_CHARSETALIAS_CONTRACTID); + + if (calias) { + nsAutoString preferred; + rv = calias->GetPreferred(NS_ConvertASCIItoUCS2(charsetVal), + preferred); + if (NS_SUCCEEDED(rv)) { + charset = preferred; + charsetSource = kCharsetFromChannel; + } + } + } + + nsCOMPtr parser = do_QueryInterface(aContext); + parser->SetDocumentCharset(charset, charsetSource); + + nsCAutoString contentType; + channel->GetContentType(contentType); + + // Time to sniff! Note: this should go away once file channels do + // sniffing themselves. + nsCOMPtr uri; + channel->GetURI(getter_AddRefs(uri)); + PRBool sniff; + if (NS_SUCCEEDED(uri->SchemeIs("file", &sniff)) && sniff && + contentType.Equals(UNKNOWN_CONTENT_TYPE)) { + nsCOMPtr serv = + do_GetService("@mozilla.org/streamConverters;1", &rv); + if (NS_SUCCEEDED(rv)) { + NS_ConvertASCIItoUCS2 from(UNKNOWN_CONTENT_TYPE); + nsCOMPtr converter; + rv = serv->AsyncConvertData(from.get(), + NS_LITERAL_STRING("*/*").get(), + mListener, + aContext, + getter_AddRefs(converter)); + if (NS_SUCCEEDED(rv)) { + mListener = converter; + } + } + } + + return mListener->OnStartRequest(aRequest, aContext); +} + +NS_IMETHODIMP +txStylesheetSink::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext, + nsresult aStatusCode) +{ + PRBool success = PR_TRUE; + + nsCOMPtr httpChannel = do_QueryInterface(aRequest); + if (httpChannel) { + httpChannel->GetRequestSucceeded(&success); + } + + nsresult result = aStatusCode; + if (!success) { + // XXX We sometimes want to use aStatusCode here, but the parser resets + // it to NS_ERROR_NOINTERFACE because we don't implement + // nsIHTMLContentSink. + result = NS_ERROR_XSLT_NETWORK_ERROR; + } + else if (!mCheckedForXML) { + nsCOMPtr parser = do_QueryInterface(aContext); + nsCOMPtr dtd; + parser->GetDTD(getter_AddRefs(dtd)); + if (dtd && !(dtd->GetType() & NS_IPARSER_FLAG_XML)) { + result = NS_ERROR_XSLT_WRONG_MIME_TYPE; + } + } + + if (NS_FAILED(result)) { + nsCOMPtr channel = do_QueryInterface(aRequest); + nsAutoString spec; + getSpec(channel, spec); + mCompiler->cancel(result, nsnull, spec.get()); + } + + return mListener->OnStopRequest(aRequest, aContext, aStatusCode); +} + +NS_IMETHODIMP +txStylesheetSink::OnRedirect(nsIHttpChannel *aHttpChannel, + nsIChannel *aNewChannel) +{ + NS_ENSURE_ARG_POINTER(aNewChannel); + + nsresult rv; + nsCOMPtr secMan = + do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr oldURI; + rv = aHttpChannel->GetURI(getter_AddRefs(oldURI)); // The original URI + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr newURI; + rv = aNewChannel->GetURI(getter_AddRefs(newURI)); // The new URI + NS_ENSURE_SUCCESS(rv, rv); + + return secMan->CheckSameOriginURI(oldURI, newURI); +} + +NS_IMETHODIMP +txStylesheetSink::GetInterface(const nsIID& aIID, void** aResult) +{ + if (aIID.Equals(NS_GET_IID(nsIAuthPrompt))) { + NS_ENSURE_ARG(aResult); + *aResult = nsnull; + + nsresult rv; + nsCOMPtr wwatcher = + do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr prompt; + rv = wwatcher->GetNewAuthPrompter(nsnull, getter_AddRefs(prompt)); + NS_ENSURE_SUCCESS(rv, rv); + + nsIAuthPrompt* rawPtr = nsnull; + prompt.swap(rawPtr); + *aResult = rawPtr; + + return NS_OK; + } + + return QueryInterface(aIID, aResult); +} + class txCompileObserver : public txACompileObserver { public: @@ -200,7 +419,7 @@ public: TX_DECL_ACOMPILEOBSERVER; - nsresult startLoad(nsIURI* aUri, txStylesheetSink* aSink, + nsresult startLoad(nsIURI* aUri, txStylesheetCompiler* aCompiler, nsIURI* aReferrerUri); protected: @@ -251,25 +470,43 @@ txCompileObserver::loadURI(const nsAString& aUri, nsresult rv = NS_NewURI(getter_AddRefs(uri), aUri); NS_ENSURE_SUCCESS(rv, rv); - nsRefPtr sink = new txStylesheetSink(aCompiler); - NS_ENSURE_TRUE(sink, NS_ERROR_OUT_OF_MEMORY); - - return startLoad(uri, sink, nsnull); + return startLoad(uri, aCompiler, nsnull); } void txCompileObserver::onDoneCompiling(txStylesheetCompiler* aCompiler, - nsresult aResult) + nsresult aResult, + const PRUnichar *aErrorText, + const PRUnichar *aParam) { - mProcessor->setStylesheet(aCompiler->getStylesheet()); + if (NS_SUCCEEDED(aResult)) { + mProcessor->setStylesheet(aCompiler->getStylesheet()); + } + else { + mProcessor->reportError(aResult, aErrorText, aParam); + } } nsresult -txCompileObserver::startLoad(nsIURI* aUri, txStylesheetSink* aSink, +txCompileObserver::startLoad(nsIURI* aUri, txStylesheetCompiler* aCompiler, nsIURI* aReferrerUri) { + nsresult rv; + if (aReferrerUri) { + nsCOMPtr securityManager = + do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + rv = securityManager->CheckLoadURI(aReferrerUri, aUri, + nsIScriptSecurityManager::STANDARD); + NS_ENSURE_SUCCESS(rv, rv); + + rv = securityManager->CheckSameOriginURI(aReferrerUri, aUri); + NS_ENSURE_SUCCESS(rv, rv); + } + nsCOMPtr channel; - nsresult rv = NS_NewChannel(getter_AddRefs(channel), aUri); + rv = NS_NewChannel(getter_AddRefs(channel), aUri); NS_ENSURE_SUCCESS(rv, rv); channel->SetLoadGroup(mLoadGroup); @@ -285,41 +522,19 @@ txCompileObserver::startLoad(nsIURI* aUri, txStylesheetSink* aSink, } } - nsAutoString charset(NS_LITERAL_STRING("UTF-8")); - PRInt32 charsetSource = kCharsetFromDocTypeDefault; - - // check channel's charset... - nsCAutoString charsetVal; - rv = channel->GetContentCharset(charsetVal); - if (NS_SUCCEEDED(rv)) { - nsCOMPtr calias = - do_GetService(NS_CHARSETALIAS_CONTRACTID); - - if (calias) { - nsAutoString preferred; - rv = calias->GetPreferred(NS_ConvertASCIItoUCS2(charsetVal), - preferred); - if (NS_SUCCEEDED(rv)) { - charset = preferred; - charsetSource = kCharsetFromChannel; - } - } - } - - static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID); nsCOMPtr parser = do_CreateInstance(kCParserCID, &rv); NS_ENSURE_SUCCESS(rv, rv); - // Set the parser as the stream listener for the document loader... - nsCOMPtr listener = do_QueryInterface(parser, &rv); - NS_ENSURE_TRUE(listener, rv); + nsRefPtr sink = new txStylesheetSink(aCompiler, parser); + NS_ENSURE_TRUE(sink, NS_ERROR_OUT_OF_MEMORY); + + channel->SetNotificationCallbacks(sink); - parser->SetDocumentCharset(charset, charsetSource); parser->SetCommand(kLoadAsData); - parser->SetContentSink(aSink); + parser->SetContentSink(sink); parser->Parse(aUri); - return channel->AsyncOpen(listener, nsnull); + return channel->AsyncOpen(sink, parser); } nsresult @@ -338,10 +553,7 @@ TX_LoadSheet(nsIURI* aUri, txMozillaXSLTProcessor* aProcessor, new txStylesheetCompiler(NS_ConvertUTF8toUCS2(uri), observer); NS_ENSURE_TRUE(compiler, NS_ERROR_OUT_OF_MEMORY); - nsRefPtr sink = new txStylesheetSink(compiler); - NS_ENSURE_TRUE(sink, NS_ERROR_OUT_OF_MEMORY); - - return observer->startLoad(aUri, sink, aReferrerUri); + return observer->startLoad(aUri, compiler, aReferrerUri); } /** @@ -494,13 +706,16 @@ txSyncCompileObserver::loadURI(const nsAString& aUri, do_GetService("@mozilla.org/content/syncload-dom-service;1"); NS_ENSURE_TRUE(mLoadService, NS_ERROR_OUT_OF_MEMORY); } + nsCOMPtr uri; nsresult rv = NS_NewURI(getter_AddRefs(uri), aUri); NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr channel; rv = NS_NewChannel(getter_AddRefs(channel), uri); NS_ENSURE_SUCCESS(rv, rv); - // This is probably called by js, a loadGroup for the channeldoesn't + + // This is probably called by js, a loadGroup for the channel doesn't // make sense. nsCOMPtr httpChannel(do_QueryInterface(channel)); @@ -513,13 +728,16 @@ txSyncCompileObserver::loadURI(const nsAString& aUri, httpChannel->SetReferrer(mReferrer); } } + nsCOMPtr document; rv = mLoadService->LoadDocument(channel, mReferrer, getter_AddRefs(document)); NS_ENSURE_SUCCESS(rv, rv); rv = handleNode(document, aCompiler); if (NS_FAILED(rv)) { - aCompiler->cancel(rv); + nsCAutoString spec; + uri->GetSpec(spec); + aCompiler->cancel(rv, nsnull, NS_ConvertUTF8toUCS2(spec).get()); return rv; } @@ -528,7 +746,9 @@ txSyncCompileObserver::loadURI(const nsAString& aUri, } void txSyncCompileObserver::onDoneCompiling(txStylesheetCompiler* aCompiler, - nsresult aResult) + nsresult aResult, + const PRUnichar *aErrorText, + const PRUnichar *aParam) { } diff --git a/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp b/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp index 03120d4cc63..d4da3086d4f 100644 --- a/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp @@ -40,10 +40,17 @@ #include "txMozillaXSLTProcessor.h" #include "nsContentCID.h" #include "nsDOMError.h" +#include "nsIChannel.h" #include "nsIContent.h" +#include "nsIDOMText.h" #include "nsIDocument.h" #include "nsIDOMClassInfo.h" +#include "nsIIOService.h" +#include "nsILoadGroup.h" #include "nsIScriptLoader.h" +#include "nsIStringBundle.h" +#include "nsIURI.h" +#include "nsNetUtil.h" #include "txExecutionState.h" #include "txMozillaTextOutput.h" #include "txMozillaXMLOutput.h" @@ -53,6 +60,8 @@ #include "txUnknownHandler.h" #include "txXSLTProcessor.h" +static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID); + /** * Output Handler Factories */ @@ -238,7 +247,8 @@ NS_INTERFACE_MAP_BEGIN(txMozillaXSLTProcessor) NS_INTERFACE_MAP_ENTRY_EXTERNAL_DOM_CLASSINFO(XSLTProcessor) NS_INTERFACE_MAP_END -txMozillaXSLTProcessor::txMozillaXSLTProcessor() : mVariables(PR_TRUE) +txMozillaXSLTProcessor::txMozillaXSLTProcessor() : mTransformResult(NS_OK), + mVariables(PR_TRUE) { } @@ -307,10 +317,17 @@ txMozillaXSLTProcessor::SetTransformObserver(nsITransformObserver* aObserver) nsresult txMozillaXSLTProcessor::SetSourceContentModel(nsIDOMNode* aSourceDOM) { + if (NS_FAILED(mTransformResult)) { + notifyError(); + return NS_OK; + } + mSource = aSourceDOM; + if (mStylesheet) { return DoTransform(); } + return NS_OK; } @@ -363,10 +380,7 @@ txMozillaXSLTProcessor::ImportStylesheet(nsIDOMNode *aStyle) type == nsIDOMNode::DOCUMENT_NODE, NS_ERROR_INVALID_ARG); - nsresult rv = TX_CompileStylesheet(aStyle, getter_AddRefs(mStylesheet)); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; + return TX_CompileStylesheet(aStyle, getter_AddRefs(mStylesheet)); } NS_IMETHODIMP @@ -593,6 +607,148 @@ txMozillaXSLTProcessor::setStylesheet(txStylesheet* aStylesheet) return NS_OK; } +void +txMozillaXSLTProcessor::reportError(nsresult aResult, + const PRUnichar *aErrorText, + const PRUnichar *aSourceText) +{ + if (!mObserver) { + return; + } + + mTransformResult = aResult; + + if (aErrorText) { + mErrorText.Assign(aErrorText); + } + else { + nsCOMPtr sbs = + do_GetService(NS_STRINGBUNDLE_CONTRACTID); + if (sbs) { + nsXPIDLString errorText; + sbs->FormatStatusMessage(aResult, nsString().get(), + getter_Copies(errorText)); + + nsXPIDLString errorMessage; + nsCOMPtr bundle; + sbs->CreateBundle(XSLT_MSGS_URL, getter_AddRefs(bundle)); + + if (bundle) { + const PRUnichar* error[] = { errorText.get() }; + bundle->FormatStringFromName(NS_LITERAL_STRING("LoadingError").get(), + error, 1, + getter_Copies(errorMessage)); + } + mErrorText.Assign(errorMessage); + } + } + + if (aSourceText) { + mSourceText.Assign(aSourceText); + } + + if (mSource) { + notifyError(); + } +} + +void +txMozillaXSLTProcessor::notifyError() +{ + nsresult rv; + nsCOMPtr errorDocument = do_CreateInstance(kXMLDocumentCID, + &rv); + if (NS_FAILED(rv)) { + return; + } + + nsCOMPtr sourceDOMDocument; + mSource->GetOwnerDocument(getter_AddRefs(sourceDOMDocument)); + if (!sourceDOMDocument) { + sourceDOMDocument = do_QueryInterface(mSource); + } + nsCOMPtr sourceDoc = do_QueryInterface(sourceDOMDocument); + + // Set up the document + nsCOMPtr document = do_QueryInterface(errorDocument); + if (!document) { + return; + } + + nsCOMPtr loadGroup; + nsCOMPtr channel; + sourceDoc->GetDocumentLoadGroup(getter_AddRefs(loadGroup)); + nsCOMPtr serv = do_GetService(NS_IOSERVICE_CONTRACTID); + if (serv) { + // Create a temporary channel to get nsIDocument->Reset to + // do the right thing. We want the output document to get + // much of the input document's characteristics. + nsCOMPtr docURL; + sourceDoc->GetDocumentURL(getter_AddRefs(docURL)); + serv->NewChannelFromURI(docURL, getter_AddRefs(channel)); + } + document->Reset(channel, loadGroup); + nsCOMPtr baseURL; + sourceDoc->GetBaseURL(*getter_AddRefs(baseURL)); + document->SetBaseURL(baseURL); + + NS_NAMED_LITERAL_STRING(ns, "http://www.mozilla.org/newlayout/xml/parsererror.xml"); + + nsCOMPtr element; + rv = errorDocument->CreateElementNS(ns, NS_LITERAL_STRING("parsererror"), + getter_AddRefs(element)); + if (NS_FAILED(rv)) { + return; + } + + nsCOMPtr rootContent = do_QueryInterface(element); + if (!rootContent) { + return; + } + + rootContent->SetDocument(document, PR_FALSE, PR_TRUE); + document->SetRootContent(rootContent); + + nsCOMPtr text; + rv = errorDocument->CreateTextNode(mErrorText, getter_AddRefs(text)); + if (NS_FAILED(rv)) { + return; + } + + nsCOMPtr resultNode; + rv = element->AppendChild(text, getter_AddRefs(resultNode)); + if (NS_FAILED(rv)) { + return; + } + + if (!mSourceText.IsEmpty()) { + nsCOMPtr sourceElement; + rv = errorDocument->CreateElementNS(ns, + NS_LITERAL_STRING("sourcetext"), + getter_AddRefs(sourceElement)); + if (NS_FAILED(rv)) { + return; + } + + rv = element->AppendChild(sourceElement, getter_AddRefs(resultNode)); + if (NS_FAILED(rv)) { + return; + } + + rv = errorDocument->CreateTextNode(mSourceText, getter_AddRefs(text)); + if (NS_FAILED(rv)) { + return; + } + + rv = sourceElement->AppendChild(text, getter_AddRefs(resultNode)); + if (NS_FAILED(rv)) { + return; + } + } + + mObserver->OnTransformDone(mTransformResult, errorDocument); +} + /* static*/ nsresult txVariable::Convert(nsIVariant *aValue, ExprResult** aResult) diff --git a/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.h b/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.h index 2fb4337c950..6f7e333cc9b 100644 --- a/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.h +++ b/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.h @@ -66,6 +66,8 @@ class nsIXMLContentSink; #define TRANSFORMIIX_XSLT_PROCESSOR_CONTRACTID \ "@mozilla.org/document-transformer;1?type=xslt" +#define XSLT_MSGS_URL "chrome://communicator/locale/layout/xslt.properties" + class txVariable : public txIGlobalParameter { public: @@ -146,12 +148,17 @@ public: NS_IMETHOD CancelLoads() {return NS_OK;}; nsresult setStylesheet(txStylesheet* aStylesheet); + void reportError(nsresult aResult, const PRUnichar *aErrorText, + const PRUnichar *aSourceText); private: nsresult DoTransform(); + void notifyError(); nsRefPtr mStylesheet; nsCOMPtr mSource; + nsresult mTransformResult; + nsString mErrorText, mSourceText; nsCOMPtr mObserver; txExpandedNameMap mVariables; }; diff --git a/mozilla/extensions/transformiix/source/xslt/txStandaloneStylesheetCompiler.cpp b/mozilla/extensions/transformiix/source/xslt/txStandaloneStylesheetCompiler.cpp index 7178bc6935d..49747a6632c 100644 --- a/mozilla/extensions/transformiix/source/xslt/txStandaloneStylesheetCompiler.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txStandaloneStylesheetCompiler.cpp @@ -336,7 +336,8 @@ txDriver::Release() } void -txDriver::onDoneCompiling(txStylesheetCompiler* aCompiler, nsresult aResult) +txDriver::onDoneCompiling(txStylesheetCompiler* aCompiler, nsresult aResult, + const PRUnichar *aErrorText, const PRUnichar *aParam) { } diff --git a/mozilla/extensions/transformiix/source/xslt/txStylesheetCompileHandlers.cpp b/mozilla/extensions/transformiix/source/xslt/txStylesheetCompileHandlers.cpp index 4b1feaff313..34a67fa0f89 100644 --- a/mozilla/extensions/transformiix/source/xslt/txStylesheetCompileHandlers.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txStylesheetCompileHandlers.cpp @@ -460,7 +460,7 @@ txFnStartElementContinueTopLevel(PRInt32 aNamespaceID, { aState.mHandlerTable = gTxTopHandler; - return NS_ERROR_XSLT_GET_NEW_HANDLER; + return NS_XSLT_GET_NEW_HANDLER; } nsresult @@ -1158,7 +1158,7 @@ txFnStartElementStartTopVar(PRInt32 aNamespaceID, { aState.mHandlerTable = gTxTemplateHandler; - return NS_ERROR_XSLT_GET_NEW_HANDLER; + return NS_XSLT_GET_NEW_HANDLER; } nsresult @@ -1168,7 +1168,7 @@ txFnTextStartTopVar(const nsAString& aStr, txStylesheetCompilerState& aState) aState.mHandlerTable = gTxTemplateHandler; - return NS_ERROR_XSLT_GET_NEW_HANDLER; + return NS_XSLT_GET_NEW_HANDLER; } /** @@ -1844,7 +1844,7 @@ txFnStartElementContinueTemplate(PRInt32 aNamespaceID, { aState.mHandlerTable = gTxTemplateHandler; - return NS_ERROR_XSLT_GET_NEW_HANDLER; + return NS_XSLT_GET_NEW_HANDLER; } nsresult @@ -1855,7 +1855,7 @@ txFnTextContinueTemplate(const nsAString& aStr, aState.mHandlerTable = gTxTemplateHandler; - return NS_ERROR_XSLT_GET_NEW_HANDLER; + return NS_XSLT_GET_NEW_HANDLER; } /* @@ -2434,7 +2434,7 @@ txFnStartElementStartRTF(PRInt32 aNamespaceID, aState.mHandlerTable = gTxTemplateHandler; - return NS_ERROR_XSLT_GET_NEW_HANDLER; + return NS_XSLT_GET_NEW_HANDLER; } nsresult @@ -2450,7 +2450,7 @@ txFnTextStartRTF(const nsAString& aStr, txStylesheetCompilerState& aState) aState.mHandlerTable = gTxTemplateHandler; - return NS_ERROR_XSLT_GET_NEW_HANDLER; + return NS_XSLT_GET_NEW_HANDLER; } /* diff --git a/mozilla/extensions/transformiix/source/xslt/txStylesheetCompiler.cpp b/mozilla/extensions/transformiix/source/xslt/txStylesheetCompiler.cpp index d677d8bbb7b..798ca87c0b0 100644 --- a/mozilla/extensions/transformiix/source/xslt/txStylesheetCompiler.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txStylesheetCompiler.cpp @@ -336,7 +336,7 @@ txStylesheetCompiler::startElementInternal(PRInt32 aNamespaceID, rv = (handler->mStartFunction)(aNamespaceID, aLocalName, aPrefix, aAttributes, aAttrCount, *this); - } while (rv == NS_ERROR_XSLT_GET_NEW_HANDLER); + } while (rv == NS_XSLT_GET_NEW_HANDLER); NS_ENSURE_SUCCESS(rv, rv); @@ -413,7 +413,8 @@ txStylesheetCompiler::doneLoading() } void -txStylesheetCompiler::cancel(nsresult aError) +txStylesheetCompiler::cancel(nsresult aError, const PRUnichar *aErrorText, + const PRUnichar *aParam) { PR_LOG(txLog::xslt, PR_LOG_ALWAYS, ("Compiler::cancel: %s, module: %d, code %d\n", @@ -424,7 +425,7 @@ txStylesheetCompiler::cancel(nsresult aError) } if (mObserver) { - mObserver->onDoneCompiling(this, mStatus); + mObserver->onDoneCompiling(this, mStatus, aErrorText, aParam); // This will ensure that we don't call onDoneCompiling twice. Also // ensures that we don't keep the observer alive longer then necessary. mObserver = nsnull; @@ -449,10 +450,12 @@ txStylesheetCompiler::loadURI(const nsAString& aUri, void txStylesheetCompiler::onDoneCompiling(txStylesheetCompiler* aCompiler, - nsresult aResult) + nsresult aResult, + const PRUnichar *aErrorText, + const PRUnichar *aParam) { if (NS_FAILED(aResult)) { - cancel(aResult); + cancel(aResult, aErrorText, aParam); return; } @@ -474,7 +477,7 @@ txStylesheetCompiler::flushCharacters() do { rv = (mHandlerTable->mTextHandler)(mCharacters, *this); - } while (rv == NS_ERROR_XSLT_GET_NEW_HANDLER); + } while (rv == NS_XSLT_GET_NEW_HANDLER); NS_ENSURE_SUCCESS(rv, rv); diff --git a/mozilla/extensions/transformiix/source/xslt/txStylesheetCompiler.h b/mozilla/extensions/transformiix/source/xslt/txStylesheetCompiler.h index 4c04bb9ed45..2f1302e35f6 100644 --- a/mozilla/extensions/transformiix/source/xslt/txStylesheetCompiler.h +++ b/mozilla/extensions/transformiix/source/xslt/txStylesheetCompiler.h @@ -82,14 +82,18 @@ public: virtual nsresult loadURI(const nsAString& aUri, txStylesheetCompiler* aCompiler) = 0; virtual void onDoneCompiling(txStylesheetCompiler* aCompiler, - nsresult aResult) = 0; + nsresult aResult, + const PRUnichar *aErrorText = nsnull, + const PRUnichar *aParam = nsnull) = 0; }; #define TX_DECL_ACOMPILEOBSERVER \ nsrefcnt AddRef(); \ nsrefcnt Release(); \ nsresult loadURI(const nsAString& aUri, txStylesheetCompiler* aCompiler); \ - void onDoneCompiling(txStylesheetCompiler* aCompiler, nsresult aResult) + void onDoneCompiling(txStylesheetCompiler* aCompiler, nsresult aResult, \ + const PRUnichar *aErrorText = nsnull, \ + const PRUnichar *aParam = nsnull) class txStylesheetCompilerState : public txIParseContext { @@ -212,13 +216,16 @@ public: nsresult characters(const nsAString& aStr); nsresult doneLoading(); - void cancel(nsresult aError); + void cancel(nsresult aError, const PRUnichar *aErrorText = nsnull, + const PRUnichar *aParam = nsnull); txStylesheet* getStylesheet(); // txACompileObserver nsresult loadURI(const nsAString& aUri, txStylesheetCompiler* aCompiler); - void onDoneCompiling(txStylesheetCompiler* aCompiler, nsresult aResult); + void onDoneCompiling(txStylesheetCompiler* aCompiler, nsresult aResult, + const PRUnichar *aErrorText = nsnull, + const PRUnichar *aParam = nsnull); private: nsresult startElementInternal(PRInt32 aNamespaceID, nsIAtom* aLocalName,