Landing XSLT branch. Tracking bug is 155578, fixes bugs 46633, 54659, 73492, 70369, 85408, 90157, 130161, 109918, 150916 and 170097

* New scriptable interfaces to XSLT
* Make HTML-output create real html
* cleanup the XSLTProcessor class

Patch by sicking, pike and peterv

r=sicking/pike, sr=peterv, a=asa
This commit is contained in:
sicking%bigfoot.com 2002-10-21 21:35:23 +00:00
parent 34e4c5889b
commit e5c6aaae8b
47 changed files with 3709 additions and 2051 deletions

View File

@ -813,13 +813,6 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIDocumentTransformer.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIController.idl</PATH>
@ -899,14 +892,28 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsITransformObserver.idl</PATH>
<PATH>nsISyncLoadDOMService.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsISyncLoadDOMService.idl</PATH>
<PATH>nsIXSLTException.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIXSLTProcessor.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIXSLTProcessorObsolete.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
@ -958,11 +965,6 @@
<PATH>nsISelectionListener.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIDocumentTransformer.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIController.idl</PATH>
@ -1020,12 +1022,22 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsITransformObserver.idl</PATH>
<PATH>nsISyncLoadDOMService.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsISyncLoadDOMService.idl</PATH>
<PATH>nsIXSLTException.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIXSLTProcessor.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIXSLTProcessorObsolete.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
</LINKORDER>
@ -1790,13 +1802,6 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIDocumentTransformer.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIController.idl</PATH>
@ -1876,14 +1881,28 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsITransformObserver.idl</PATH>
<PATH>nsISyncLoadDOMService.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsISyncLoadDOMService.idl</PATH>
<PATH>nsIXSLTException.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIXSLTProcessor.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIXSLTProcessorObsolete.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
@ -1935,11 +1954,6 @@
<PATH>nsISelectionListener.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIDocumentTransformer.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIController.idl</PATH>
@ -1997,12 +2011,22 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsITransformObserver.idl</PATH>
<PATH>nsISyncLoadDOMService.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsISyncLoadDOMService.idl</PATH>
<PATH>nsIXSLTException.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIXSLTProcessor.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIXSLTProcessorObsolete.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
</LINKORDER>
@ -2069,12 +2093,6 @@
<PATH>nsISelectionListener.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>headers</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIDocumentTransformer.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>headers</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
@ -2144,13 +2162,25 @@
<FILEREF>
<TARGETNAME>headers</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsITransformObserver.idl</PATH>
<PATH>nsISyncLoadDOMService.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>headers</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsISyncLoadDOMService.idl</PATH>
<PATH>nsIXSLTException.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>headers</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIXSLTProcessor.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>headers</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIXSLTProcessorObsolete.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
</GROUPLIST>

View File

@ -52,7 +52,7 @@
<parameter name="aData"/>
<body>
if (aTopic == "prettyprint-dom-created")
document.getAnonymousNodes(this).item(0).appendChild(aSubject.documentElement);
document.getAnonymousNodes(this).item(0).appendChild(aSubject);
</body>
</method>
</implementation>

View File

@ -43,16 +43,14 @@
<xsl:output method="xml"/>
<xsl:template match="/">
<div>
<link href="chrome://communicator/content/xml/XMLPrettyPrint.css" type="text/css" rel="stylesheet"/>
<div id="header">
<p>
This XML file does not appear to have any style information
associated with it. The document tree is shown below.
</p>
</div>
<xsl:apply-templates/>
<link href="chrome://communicator/content/xml/XMLPrettyPrint.css" type="text/css" rel="stylesheet"/>
<div id="header">
<p>
This XML file does not appear to have any style information
associated with it. The document tree is shown below.
</p>
</div>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="*">

View File

@ -118,6 +118,7 @@
#include "nsIObserver.h"
#include "nsIDocumentTransformer.h"
#include "nsISyncLoadDOMService.h"
#include "nsIXSLTProcessor.h"
// XXX misnamed header file, but oh well
#include "nsHTMLTokens.h"
@ -442,18 +443,17 @@ nsXMLContentSink::MaybePrettyPrint()
NS_ENSURE_SUCCESS(rv, rv);
// Transform the document
nsCOMPtr<nsIDocumentTransformer> transformer =
nsCOMPtr<nsIXSLTProcessor> transformer =
do_CreateInstance("@mozilla.org/document-transformer;1?type=text/xsl", &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMDocument> resultDocument;
nsAutoString emptyStr;
rv = NS_NewDOMDocument(getter_AddRefs(resultDocument), emptyStr, emptyStr,
nsnull, mDocumentURL);
NS_ENSURE_SUCCESS(rv, rv);
rv = transformer->ImportStylesheet(xslDocument);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMDocumentFragment> resultFragment;
nsCOMPtr<nsIDOMDocument> sourceDocument = do_QueryInterface(mDocument);
rv = transformer->TransformDocument(sourceDocument, xslDocument,
resultDocument, nsnull);
rv = transformer->TransformToFragment(sourceDocument, xslDocument,
getter_AddRefs(resultFragment));
NS_ENSURE_SUCCESS(rv, rv);
// Add the binding
@ -478,7 +478,7 @@ nsXMLContentSink::MaybePrettyPrint()
NS_ASSERTION(binding, "Prettyprint binding doesn't implement nsIObserver");
NS_ENSURE_TRUE(binding, NS_ERROR_UNEXPECTED);
return binding->Observe(resultDocument, "prettyprint-dom-created", NS_LITERAL_STRING("").get());
return binding->Observe(resultFragment, "prettyprint-dom-created", NS_LITERAL_STRING("").get());
}
@ -558,6 +558,20 @@ nsXMLContentSink::DidBuildModel(PRInt32 aQualityLevel)
return NS_OK;
}
NS_IMETHODIMP
nsXMLContentSink::OnDocumentCreated(nsIDOMDocument* aResultDocument)
{
NS_ENSURE_ARG(aResultDocument);
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(mWebShell));
nsCOMPtr<nsIContentViewer> contentViewer;
docShell->GetContentViewer(getter_AddRefs(contentViewer));
if (contentViewer) {
contentViewer->SetDOMDocument(aResultDocument);
}
return NS_OK;
}
NS_IMETHODIMP
nsXMLContentSink::OnTransformDone(nsresult aResult,
nsIDOMDocument* aResultDocument)
@ -636,32 +650,11 @@ nsXMLContentSink::OnTransformDone(nsresult aResult,
nsresult
nsXMLContentSink::SetupTransformMediator()
{
nsresult rv = NS_OK;
nsCOMPtr<nsIDOMDocument> currentDOMDoc(do_QueryInterface(mDocument));
mXSLTransformMediator->SetSourceContentModel(currentDOMDoc);
// Create the result document
nsCOMPtr<nsIDOMDocument> resultDOMDoc;
nsCOMPtr<nsIURI> url;
mDocument->GetBaseURL(*getter_AddRefs(url));
nsAutoString emptyStr;
rv = NS_NewDOMDocument(getter_AddRefs(resultDOMDoc), emptyStr, emptyStr, nsnull, url);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(mWebShell));
nsCOMPtr<nsIContentViewer> contentViewer;
docShell->GetContentViewer(getter_AddRefs(contentViewer));
if (contentViewer) {
contentViewer->SetDOMDocument(resultDOMDoc);
}
mXSLTransformMediator->SetResultDocument(resultDOMDoc);
mXSLTransformMediator->SetTransformObserver(this);
return rv;
return NS_OK;
}
NS_IMETHODIMP
@ -840,7 +833,9 @@ nsXMLContentSink::LoadXSLStyleSheet(nsIURI* aUrl)
// httpChannel->SetReferrer(documentURI);
}
// XXX need to set a load group on this channel!
nsCOMPtr<nsILoadGroup> loadGroup;
mDocument->GetDocumentLoadGroup(getter_AddRefs(loadGroup));
channel->SetLoadGroup(loadGroup);
return channel->AsyncOpen(sl, nsnull);
}

View File

@ -57,7 +57,7 @@ class nsICSSStyleSheet;
#include "nsIScriptLoaderObserver.h"
#include "nsSupportsArray.h"
#include "nsIExpatSink.h"
#include "nsITransformObserver.h"
#include "nsIDocumentTransformer.h"
class nsIDocument;
class nsIURI;
@ -99,7 +99,6 @@ public:
// nsISupports
NS_DECL_ISUPPORTS
NS_DECL_NSISCRIPTLOADEROBSERVER
NS_DECL_NSITRANSFORMOBSERVER
NS_DECL_NSIEXPATSINK
// nsIContentSink
@ -114,6 +113,10 @@ public:
// nsICSSLoaderObserver
NS_IMETHOD StyleSheetLoaded(nsICSSStyleSheet*aSheet, PRBool aNotify);
// nsITransformObserver
NS_IMETHOD OnDocumentCreated(nsIDOMDocument *aResultDocument);
NS_IMETHOD OnTransformDone(nsresult aResult, nsIDOMDocument *aResultDocument);
protected:
void StartLayout();

View File

@ -21,7 +21,7 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = document
DIRS = public document
include $(topsrcdir)/config/config.mk

View File

@ -21,7 +21,7 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = public src
DIRS = src
include $(topsrcdir)/config/config.mk

View File

@ -98,13 +98,13 @@ void
nsTransformMediator::TryToTransform()
{
nsCOMPtr<nsITransformObserver> observer = do_QueryReferent(mObserver);
if (mSourceDOM && mStyleDOM && mResultDoc && observer)
if (mSourceDOM && mStyleDOM && observer)
{
if (mEnabled && mTransformer) {
mTransformer->TransformDocument(mSourceDOM,
mStyleDOM,
mResultDoc,
observer);
observer,
getter_AddRefs(mResultDoc));
}
else if (mStyleInvalid) {
// Avoid recursion.
@ -144,14 +144,6 @@ nsTransformMediator::SetStyleSheetContentModel(nsIDOMNode* aStyle)
return NS_OK;
}
NS_IMETHODIMP
nsTransformMediator::SetResultDocument(nsIDOMDocument* aDoc)
{
mResultDoc = aDoc;
TryToTransform();
return NS_OK;
}
NS_IMETHODIMP
nsTransformMediator::GetResultDocument(nsIDOMDocument** aDoc)
{

View File

@ -44,7 +44,6 @@
#include "nsIDocumentTransformer.h"
#include "nsIDOMNode.h"
#include "nsIDOMDocument.h"
#include "nsITransformObserver.h"
#include "nsWeakPtr.h"
class nsTransformMediator : public nsITransformMediator {
@ -61,7 +60,6 @@ public:
NS_IMETHOD SetEnabled(PRBool aValue);
NS_IMETHOD SetSourceContentModel(nsIDOMNode* aSource);
NS_IMETHOD SetStyleSheetContentModel(nsIDOMNode* aStyle);
NS_IMETHOD SetResultDocument(nsIDOMDocument* aDoc);
NS_IMETHOD GetResultDocument(nsIDOMDocument** aDoc);
NS_IMETHOD SetTransformObserver(nsITransformObserver* aObserver);
NS_IMETHOD SetStyleInvalid(PRBool aInvalid);

View File

@ -0,0 +1 @@
Makefile

View File

@ -0,0 +1,6 @@
#
# This is a list of local files which get copied to the mozilla:dist:content directory
#
nsITransformMediator.h
nsIDocumentTransformer.h

View File

@ -0,0 +1,8 @@
#
# This is a list of local files which get copied to the mozilla:dist:idl directory
#
nsIXSLTException.idl
nsIXSLTProcessor.idl
nsIXSLTProcessorObsolete.idl

View File

@ -0,0 +1,60 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
# Portions created by the Initial Developer are Copyright (C) 2002
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Peter Van der Beken <peterv@netscape.com> (original author)
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = content
XPIDL_MODULE = content_xslt
EXPORTS = \
nsIDocumentTransformer.h \
nsITransformMediator.h \
$(NULL)
XPIDLSRCS = \
nsIXSLTException.idl \
nsIXSLTProcessor.idl \
nsIXSLTProcessorObsolete.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,78 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jonas Sicking <sicking@bigfoot.com> (Original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsIDocumentTransformer_h__
#define nsIDocumentTransformer_h__
#include "nsISupports.h"
class nsIDOMDocument;
class nsIDOMNode;
#define NS_ITRANSFORMOBSERVER_IID \
{0xcce88481, 0x6eb3, 0x11d6, \
{ 0xa7, 0xf2, 0x8d, 0x82, 0xcd, 0x2a, 0xf3, 0x7c }}
class nsITransformObserver : public nsISupports
{
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ITRANSFORMOBSERVER_IID)
NS_IMETHOD OnDocumentCreated(nsIDOMDocument *aResultDocument) = 0;
NS_IMETHOD OnTransformDone(nsresult aResult, nsIDOMDocument *aResultDocument) = 0;
};
#define NS_IDOCUMENTTRANSFORMER_IID \
{0x43e5a6c6, 0xa53c, 0x4f97, \
{ 0x91, 0x79, 0x47, 0xf2, 0x46, 0xec, 0xd9, 0xd6 }}
class nsIDocumentTransformer : public nsISupports
{
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IDOCUMENTTRANSFORMER_IID)
NS_IMETHOD TransformDocument(nsIDOMNode *aSourceDOM,
nsIDOMNode *aStyleDOM,
nsITransformObserver *aObserver,
nsIDOMDocument **_retval) = 0;
};
#endif //nsIDocumentTransformer_h__

View File

@ -0,0 +1,81 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Nisheeth Ranjan <nisheeth@netscape.com> (original author)
* Peter Van der Beken <peterv@netscape.com>
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsITransformMediator_h___
#define nsITransformMediator_h___
#include "nsISupports.h"
#include "nsAString.h"
class nsIDOMNode;
class nsIDOMDocument;
class nsITransformObserver;
class nsIXMLContentSink;
/* 6f4c2d0e-2cdf-11d3-aef3-00108300ff91 */
#define NS_ITRANSFORM_MEDIATOR_IID \
{ 0x6f4c2d0e, 0x2cdf, 0x11d3, {0xae, 0xf3, 0x00, 0x10, 0x83, 0x00, 0xff, 0x91} }
/**
* This interface represents a mediator between Gecko and an external
* transformation engine. The following process of document transformation
* is assumed : a source document, a stylesheet specifying the transform,
* and an output document are passed to a transformation engine. All three
* documents expose nsIDOMDocument interfaces. The transformation engine
* uses the nsIDOMDocument interfaces to read the source document and
* stylesheet, and write the output document.
*/
class nsITransformMediator : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ITRANSFORM_MEDIATOR_IID);
NS_IMETHOD SetEnabled(PRBool aValue) = 0;
NS_IMETHOD SetSourceContentModel(nsIDOMNode* aSource) = 0;
NS_IMETHOD SetStyleSheetContentModel(nsIDOMNode* aStyle) = 0;
NS_IMETHOD GetResultDocument(nsIDOMDocument** aDoc) = 0;
NS_IMETHOD SetTransformObserver(nsITransformObserver* aObserver) = 0;
NS_IMETHOD SetStyleInvalid(PRBool aInvalid) = 0;
};
extern nsresult NS_NewTransformMediator(nsITransformMediator** aInstancePtrResult,
const nsACString& aMimeType);
#endif // nsITransformMediator_h___

View File

@ -0,0 +1,53 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is TransforMiiX XSLT Processor.
*
* The Initial Developer of the Original Code is
* Axel Hecht.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Axel Hecht, <axel@pike.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIException.idl"
#include "domstubs.idl"
[scriptable, uuid(e06dfaea-92d5-47f7-a800-c5f5404d8771)]
interface nsIXSLTException : nsIException {
/**
* The node in the stylesheet that triggered the exception.
*/
readonly attribute nsIDOMNode styleNode;
/**
* The context node, may be null
*/
readonly attribute nsIDOMNode sourceNode;
};

View File

@ -0,0 +1,131 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is TransforMiiX XSLT Processor.
*
* The Initial Developer of the Original Code is
* Axel Hecht.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Axel Hecht, <axel@pike.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "domstubs.idl"
interface nsIVariant;
[scriptable, uuid(4a91aeb3-4100-43ee-a21e-9866268757c5)]
interface nsIXSLTProcessor : nsISupports
{
/**
* Import the stylesheet into this XSLTProcessor for transformations.
*
* Note: Changing the DOM of the stylesheet document after it has been
* imported does not affect the processor. It will apply the
* stylesheet as it looked at the time of the call to
* importStylesheet
*
* @param style The root-node of a XSLT stylesheet. This can be either
* a document node or an element node. If a document node
* then the document can contain either a XSLT stylesheet
* or a LRE stylesheet.
* If the argument is an element node it must be the
* xsl:stylesheet (or xsl:transform) element of an XSLT
* stylesheet.
*
* @exception nsIXSLTException
*/
void importStylesheet(in nsIDOMNode style);
/**
* Transforms the node source applying the stylesheet given by
* the importStylesheet() function. The owner document of the output node
* owns the returned document fragment.
*
* @param source The node to be transformed
* @param output The owner document of this node is used to generate
* the output
* @return DocumentFragment The result of the transformation
*
* @exception nsIXSLTException
*/
nsIDOMDocumentFragment transformToFragment(in nsIDOMNode source,
in nsIDOMDocument output);
/**
* Transforms the node source applying the stylesheet given by the
* importStylesheet() function.
*
* @param source The node to be transformed
* @param output The owner document of this node is used to generate
* the output
* @return DocumentFragment The result of the transformation
*
* @exception nsIXSLTException
*/
nsIDOMDocument transformToDocument(in nsIDOMNode source);
/**
* Sets a parameter to be used in the following calls to transformNode.
*
* @param namespaceURI The namespaceURI of the XSLT parameter
* @param localName The local name of the XSLT parameter
* @param value The new value of the XSLT parameter
*
* @exception NS_ERROR_ILLEGAL_VALUE The datatype of value is
* not supported
*/
void setParameter(in DOMString namespaceURI,
in DOMString localName,
in nsIVariant value);
/**
* Gets a parameter, if set and return null otherwise.
*
* @param namespaceURI The namespaceURI of the XSLT parameter
* @param localName The local name of the XSLT parameter
* @return nsIVariant The value of the XSLT parameter
*/
nsIVariant getParameter(in DOMString namespaceURI,
in DOMString localName);
/**
* Removes a parameter, if set.
*
* @param namespaceURI The namespaceURI of the XSLT parameter
* @param localName The local name of the XSLT parameter
*/
void removeParameter(in DOMString namespaceURI,
in DOMString localName);
/**
* Removes all set parameters from this nsIXSLTProcessor
*/
void clearParameters();
};

View File

@ -0,0 +1,57 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Nisheeth Ranjan <nisheeth@netscape.com> (original author)
* Peter Van der Beken <peterv@netscape.com>
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface nsIDOMNode;
interface nsIDOMDocument;
/**
* DEPRECATED! Don't use this interface! Use nsIXSLTProcessor instead!!
*/
[scriptable, uuid(3fbff728-2d20-11d3-aef3-00108300ff91)]
interface nsIXSLTProcessorObsolete : nsISupports
{
void transformDocument(in nsIDOMNode aSourceDOM,
in nsIDOMNode aStyleDOM,
in nsIDOMDocument aOutputDOC,
in nsISupports aObserver);
};

View File

@ -46,6 +46,7 @@ REQUIRES = xpcom \
htmlparser \
webshell \
docshell \
layout \
$(NULL)
IS_COMPONENT = 1
MODULE_NAME = TransformiixModule
@ -116,9 +117,11 @@ LOBJS =../source/base/ArrayList.$(OBJ_SUFFIX) \
../source/xslt/Names.$(OBJ_SUFFIX) \
../source/xslt/ProcessorState.$(OBJ_SUFFIX) \
../source/xslt/txMozillaTextOutput.$(OBJ_SUFFIX) \
../source/xslt/txMozillaXSLTProcessor.$(OBJ_SUFFIX) \
../source/xslt/txMozillaXMLOutput.$(OBJ_SUFFIX) \
../source/xslt/txRtfHandler.$(OBJ_SUFFIX) \
../source/xslt/txTextHandler.$(OBJ_SUFFIX) \
../source/xslt/txUnknownHandler.$(OBJ_SUFFIX) \
../source/xslt/txXSLTNumber.$(OBJ_SUFFIX) \
../source/xslt/txXSLTNumberCounters.$(OBJ_SUFFIX) \
../source/xslt/txXSLTPatterns.$(OBJ_SUFFIX) \

View File

@ -1,4 +1,5 @@
/*
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
@ -36,7 +37,7 @@
#include "nsXPathResult.h"
#include "nsXPIDLString.h"
#include "txAtoms.h"
#include "XSLTProcessor.h"
#include "txMozillaXSLTProcessor.h"
#include "TxLog.h"
#include "nsCRT.h"
#include "nsIScriptSecurityManager.h"
@ -49,13 +50,13 @@
#define TRANSFORMIIX_DOMCI_EXTENSION_CONTRACTID \
"@mozilla.org/transformiix-domci-extender;1"
NS_DOMCI_EXTENSION(Transformiix)
static NS_DEFINE_CID(kXSLTProcessorCID, TRANSFORMIIX_XSLT_PROCESSOR_CID);
NS_DOMCI_EXTENSION_ENTRY_BEGIN(XSLTProcessor)
NS_DOMCI_EXTENSION_ENTRY_INTERFACE(nsIDocumentTransformer)
NS_DOMCI_EXTENSION_ENTRY_END(XSLTProcessor, nsIDocumentTransformer,
PR_FALSE, &kXSLTProcessorCID)
NS_DOMCI_EXTENSION_ENTRY_INTERFACE(nsIXSLTProcessor)
NS_DOMCI_EXTENSION_ENTRY_INTERFACE(nsIXSLTProcessorObsolete) // XXX DEPRECATED
NS_DOMCI_EXTENSION_ENTRY_END(XSLTProcessor, nsIXSLTProcessor, PR_TRUE,
&kXSLTProcessorCID)
static NS_DEFINE_CID(kXPathEvaluatorCID, TRANSFORMIIX_XPATH_EVALUATOR_CID);
NS_DOMCI_EXTENSION_ENTRY_BEGIN(XPathEvaluator)
@ -86,7 +87,7 @@ NS_DOMCI_EXTENSION(Transformiix)
NS_DOMCI_EXTENSION_END
// Factory Constructor
NS_GENERIC_FACTORY_CONSTRUCTOR(XSLTProcessor)
NS_GENERIC_FACTORY_CONSTRUCTOR(txMozillaXSLTProcessor)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPathEvaluator)
NS_DECL_DOM_CLASSINFO(XSLTProcessor)
@ -148,11 +149,21 @@ RegisterTransformiix(nsIComponentManager *aCompMgr,
PR_TRUE, PR_TRUE, getter_Copies(previous));
NS_ENSURE_SUCCESS(rv, rv);
char* iidString = NS_GET_IID(nsIDocumentTransformer).ToString();
char* iidString = NS_GET_IID(nsIXSLTProcessorObsolete).ToString();
if (!iidString)
return NS_ERROR_OUT_OF_MEMORY;
rv = catman->AddCategoryEntry(JAVASCRIPT_DOM_INTERFACE,
"nsIDocumentTransformer",
"nsIXSLTProcessorObsolete",
iidString,
PR_TRUE, PR_TRUE, getter_Copies(previous));
nsCRT::free(iidString);
NS_ENSURE_SUCCESS(rv, rv);
iidString = NS_GET_IID(nsIXSLTProcessor).ToString();
if (!iidString)
return NS_ERROR_OUT_OF_MEMORY;
rv = catman->AddCategoryEntry(JAVASCRIPT_DOM_INTERFACE,
"nsIXSLTProcessor",
iidString,
PR_TRUE, PR_TRUE, getter_Copies(previous));
nsCRT::free(iidString);
@ -169,7 +180,6 @@ PR_STATIC_CALLBACK(nsresult)
Initialize(nsIModule* aSelf)
{
NS_PRECONDITION(!gInitialized, "module already initialized");
nsresult rv = NS_OK;
if (gInitialized)
return NS_OK;
@ -185,16 +195,12 @@ Initialize(nsIModule* aSelf)
xs->RegisterExceptionProvider(sXPathExceptionProvider,
NS_ERROR_MODULE_DOM_XPATH);
if (!txXMLAtoms::init())
return NS_ERROR_OUT_OF_MEMORY;
if (!txXPathAtoms::init())
return NS_ERROR_OUT_OF_MEMORY;
if (!txXSLTAtoms::init())
return NS_ERROR_OUT_OF_MEMORY;
if (!txHTMLAtoms::init())
if (!txXSLTProcessor::txInit()) {
return NS_ERROR_OUT_OF_MEMORY;
}
rv = CallGetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &gTxSecurityManager);
nsresult rv = CallGetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID,
&gTxSecurityManager);
if (NS_FAILED(rv)) {
gTxSecurityManager = nsnull;
return rv;
@ -230,10 +236,7 @@ Shutdown(nsIModule* aSelf)
NS_IF_RELEASE(NS_CLASSINFO_NAME(XPathNSResolver));
NS_IF_RELEASE(NS_CLASSINFO_NAME(XPathResult));
txXMLAtoms::shutdown();
txXPathAtoms::shutdown();
txXSLTAtoms::shutdown();
txHTMLAtoms::shutdown();
txXSLTProcessor::txShutdown();
NS_IF_RELEASE(gTxSecurityManager);
@ -245,7 +248,7 @@ static const nsModuleComponentInfo gComponents[] = {
{ "XSLTProcessor",
TRANSFORMIIX_XSLT_PROCESSOR_CID,
TRANSFORMIIX_XSLT_PROCESSOR_CONTRACTID,
XSLTProcessorConstructor,
txMozillaXSLTProcessorConstructor,
RegisterTransformiix },
{ "XPathEvaluator",
TRANSFORMIIX_XPATH_EVALUATOR_CID,

View File

@ -1587,6 +1587,20 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>txMozillaXSLTProcessor.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>txUnknownHandler.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
</FILELIST>
<LINKORDER>
<FILEREF>
@ -2039,6 +2053,16 @@
<PATH>txXSLTPatterns.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>txMozillaXSLTProcessor.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>txUnknownHandler.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
</LINKORDER>
</TARGET>
<TARGET>
@ -3575,6 +3599,20 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>txMozillaXSLTProcessor.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>txUnknownHandler.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
</FILELIST>
<LINKORDER>
<FILEREF>
@ -4027,6 +4065,16 @@
<PATH>txXSLTPatterns.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>txMozillaXSLTProcessor.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>txUnknownHandler.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
</LINKORDER>
</TARGET>
</TARGETLIST>
@ -4433,6 +4481,12 @@
<PATH>txMozillaXMLOutput.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>txMozillaXSLTProcessor.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
@ -4457,6 +4511,12 @@
<PATH>txTextHandler.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>txUnknownHandler.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>

View File

@ -26,7 +26,14 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
PROGRAM = ../transformiix$(BIN_SUFFIX)
LIBRARY_NAME = tx
FORCE_STATIC_LIB = 1
SIMPLE_PROGRAMS = transformiix$(BIN_SUFFIX)
ifdef MARK_INC
SIMPLE_PROGRAMS += txXSLTMarkDriver$(BIN_SUFFIX)
endif
EXTRA_DEPS = $(LIBRARY)
REQUIRES = expat \
$(NULL)
@ -109,6 +116,7 @@ OBJS =../base/ArrayList.$(OBJ_SUFFIX) \
../xslt/txXSLTPatterns.$(OBJ_SUFFIX) \
../xslt/txPatternParser.$(OBJ_SUFFIX) \
../xslt/XSLTProcessor.$(OBJ_SUFFIX) \
../xslt/txStandaloneXSLTProcessor.$(OBJ_SUFFIX) \
../xslt/functions/CurrentFunctionCall.$(OBJ_SUFFIX) \
../xslt/functions/DocumentFunctionCall.$(OBJ_SUFFIX) \
../xslt/functions/ElementAvailableFnCall.$(OBJ_SUFFIX) \
@ -118,11 +126,13 @@ OBJS =../base/ArrayList.$(OBJ_SUFFIX) \
../xslt/functions/txFormatNumberFunctionCall.$(OBJ_SUFFIX) \
../xslt/functions/txKeyFunctionCall.$(OBJ_SUFFIX) \
../xslt/util/txNodeSorter.$(OBJ_SUFFIX) \
../xslt/util/txXPathResultComparator.$(OBJ_SUFFIX) \
transformiix.$(OBJ_SUFFIX)
../xslt/util/txXPathResultComparator.$(OBJ_SUFFIX)
CPP_PROG_LINK = 1
EXTRA_LIBS = \
$(LIB_PREFIX)tx.$(LIB_SUFFIX) \
$(NULL)
SHARED_LIBRARY_LIBS = \
$(DIST)/lib/$(LIB_PREFIX)expat_s.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)xmltok_s.$(LIB_SUFFIX) \
$(NULL)
@ -133,4 +143,4 @@ INCLUDES += -I$(srcdir)/../xslt -I$(srcdir)/../base -I$(srcdir)/../net \
-I$(srcdir)/../xml -I$(srcdir)/../xml/dom \
-I$(srcdir)/../xml/parser \
-I$(srcdir)/../xpath -I$(srcdir)/../xslt/util \
-I$(srcdir)/../xslt/functions
-I$(srcdir)/../xslt/functions $(MARK_INC)

View File

@ -29,14 +29,13 @@
*
* Olivier Gerardin, ogerardin@vo.lu
* -- redirect non-data output (banner, errors) to stderr
* -- read XML from stdin when -i is omitted
* -- accept '-' to specify stdin/stdout on command line
*
*/
#include "XSLTProcessor.h"
#include "txStandaloneXSLTProcessor.h"
#include "CommandLineUtils.h"
#include <fstream.h>
//--------------/
//- Prototypes -/
@ -57,13 +56,8 @@ void printUsage();
**/
int main(int argc, char** argv) {
if (!txInit())
if (!txXSLTProcessor::txInit())
return 1;
XSLTProcessor xsltProcessor;
//-- add ErrorObserver
SimpleErrorObserver seo;
xsltProcessor.addErrorObserver(seo);
//-- available flags
StringList flags;
@ -79,8 +73,8 @@ int main(int argc, char** argv) {
if (!options.get(String("q"))) {
String copyright("(C) 1999 The MITRE Corporation, Keith Visco, and contributors");
cerr << xsltProcessor.getAppName() << " ";
cerr << xsltProcessor.getAppVersion() << endl;
cerr << "TransforMiiX ";
cerr << "1.2b pre" << endl;
cerr << copyright << endl;
//-- print banner line
PRUint32 fillSize = copyright.length() + 1;
@ -98,63 +92,52 @@ int main(int argc, char** argv) {
String* xsltFilename = (String*)options.get(String("s"));
String* outFilename = (String*)options.get(String("o"));
//-- open XML file
istream* xmlInput = &cin;
if (xmlFilename && ! xmlFilename->isEqual("-")) {
xmlInput = new ifstream(NS_LossyConvertUCS2toASCII(*xmlFilename).get(),
ios::in);
}
//-- handle output stream
ostream* resultOutput = &cout;
ofstream resultFileStream;
if ( outFilename && ! outFilename->isEqual("-")) {
if (outFilename && !outFilename->isEqual("-")) {
resultFileStream.open(NS_LossyConvertUCS2toASCII(*outFilename).get(),
ios::out);
if ( !resultFileStream ) {
if (!resultFileStream) {
cerr << "error opening output file: " << *xmlFilename << endl;
return -1;
}
resultOutput = &resultFileStream;
}
SimpleErrorObserver obs;
txStandaloneXSLTProcessor proc;
nsresult rv = NS_OK;
//-- process
String documentBase;
if ( !xsltFilename ) {
if (!xmlFilename) {
cerr << "you must specify XSLT file with -s option if XML is read from standard input" << endl;
printUsage();
return -1;
}
xsltProcessor.process(*xmlInput, *xmlFilename, *resultOutput);
if (!xsltFilename) {
if (!xmlFilename) {
cerr << "you must specify at least a source XML path" << endl;
printUsage();
return -1;
}
rv = proc.transform(*xmlFilename, *resultOutput, obs);
}
else {
//-- open XSLT file
ifstream xsltInput(NS_LossyConvertUCS2toASCII(*xsltFilename).get(),
ios::in);
xsltProcessor.process(*xmlInput, *xmlFilename, xsltInput, *xsltFilename, *resultOutput);
rv = proc.transform(*xmlFilename, *xsltFilename, *resultOutput, obs);
}
resultFileStream.close();
if (xmlInput != &cin)
delete xmlInput;
txShutdown();
return 0;
txXSLTProcessor::txShutdown();
return NS_SUCCEEDED(rv);
} //-- main
void printHelp() {
cerr << "transfrmx [-h] [-i xml-file] [-s xslt-file] [-o output-file]" << endl << endl;
cerr << "Options:";
cerr << endl << endl;
cerr << "\t-i specify XML file to process (default: read from stdin)" << endl;
cerr << "\t-i specify XML file to process" << endl;
cerr << "\t-s specify XSLT file to use for processing (default: use stylesheet" << endl
<< "\t\tspecified in XML file)" << endl;
cerr << "\t-o specify output file (default: write to stdout)" << endl;
cerr << "\t-h this help screen" << endl;
cerr << endl;
cerr << "You may use '-' in place of xml-file or output-file to explicitly specify" << endl;
cerr << "respectively the standard input and standard output." << endl;
cerr << "If the XML is read from stdin, then the -s option is mandatory." << endl;
cerr << "You may use '-' in place of the output-file to explicitly specify" << endl;
cerr << "standard output." << endl;
cerr << endl;
}
void printUsage() {

View File

@ -0,0 +1,119 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Axel Hecht <axel@pike.org> (original author)
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* Driver for running XSLTMark on standalone
*
* See http://www.datapower.com/XSLTMark/
*/
#include "txStandaloneXSLTProcessor.h"
#include "xmExternalDriver.hpp"
class txDriverProcessor : public txStandaloneXSLTProcessor,
public xmExternalDriver
{
public:
txDriverProcessor() : mXSL(0), mXML(0), mOut(0)
{
}
int loadStylesheet (char * filename)
{
delete mXSL;
mXSL = parsePath(String(filename), mObserver);
return mXSL ? 0 : 1;
}
int setInputDocument (char * filename)
{
delete mXML;
mXML = parsePath(String(filename), mObserver);
return mXML ? 0 : 1;
}
int openOutput (char * outputFilename)
{
mOut = new ofstream(outputFilename);
return mXML ? 0 : 1;
}
int runTransform ()
{
nsresult rv = transform(mXML, mXSL, *mOut, mObserver);
return NS_FAILED(rv);
}
int closeOutput ()
{
if (mOut)
mOut->close();
delete mOut;
mOut = 0;
return 0;
}
int terminate()
{
delete mXSL;
mXSL = 0;
delete mXML;
mXML = 0;
if (mOut && mOut->is_open())
mOut->close();
delete mOut;
mOut = 0;
return 0;
}
~txDriverProcessor()
{
delete mXSL;
delete mXML;
delete mOut;
}
private:
Document *mXSL, *mXML;
SimpleErrorObserver mObserver;
ofstream* mOut;
};
int main (int argc, char ** argv)
{
txDriverProcessor driver;
if (!txDriverProcessor::txInit())
return 1;
driver.main (argc, argv);
txDriverProcessor::txShutdown();
return 0;
}

View File

@ -154,7 +154,7 @@ nsresult nsXPathEvaluator::ParseContextImpl::resolveNamespacePrefix
}
if (!mNSMan) {
mNSMan = do_CreateInstance(kNameSpaceManagerCID);
mNSMan = do_GetService(kNameSpaceManagerCID);
if (!mNSMan) {
return NS_ERROR_FAILURE;
}

View File

@ -42,6 +42,7 @@ REQUIRES = string \
htmlparser \
webshell \
docshell \
layout \
$(NULL)
endif
@ -54,16 +55,18 @@ CPPSRCS = Names.cpp \
txXSLTNumberCounters.cpp \
txXSLTPatterns.cpp \
txPatternParser.cpp \
txUnknownHandler.cpp \
XSLTProcessor.cpp
ifdef TX_EXE
CPPSRCS += txHTMLOutput.cpp \
txStandaloneXSLTProcessor.cpp \
txTextOutput.cpp \
txUnknownHandler.cpp \
txXMLOutput.cpp
else
CPPSRCS += txMozillaTextOutput.cpp \
txMozillaXMLOutput.cpp
txMozillaXMLOutput.cpp \
txMozillaXSLTProcessor.cpp
endif
include $(topsrcdir)/config/rules.mk

View File

@ -44,17 +44,15 @@
#include "XMLParser.h"
#include "TxLog.h"
#include "txAtoms.h"
#include "XSLTProcessor.h"
#include "txSingleNodeContext.h"
#include "txVariableMap.h"
#include "XSLTProcessor.h"
/**
* Creates a new ProcessorState for the given XSL document
* and resultDocument
**/
ProcessorState::ProcessorState(Document* aSourceDocument,
Document* aXslDocument,
Document* aResultDocument)
Document* aXslDocument)
: mXslKeys(MB_TRUE),
mDecimalFormats(MB_TRUE),
mEvalContext(0),
@ -62,11 +60,13 @@ ProcessorState::ProcessorState(Document* aSourceDocument,
mGlobalVariableValues(MB_TRUE),
mSourceDocument(aSourceDocument),
xslDocument(aXslDocument),
resultDocument(aResultDocument)
mRTFDocument(0),
mOutputHandler(0),
mResultHandler(0),
mOutputHandlerFactory(0)
{
NS_ASSERTION(aSourceDocument, "missing source document");
NS_ASSERTION(aXslDocument, "missing xslt document");
NS_ASSERTION(aResultDocument, "missing result document");
/* turn object deletion on for some of the Maps (NamedMap) */
mExprHashes[SelectAttr].setOwnership(Map::eOwnsItems);
@ -104,6 +104,10 @@ ProcessorState::~ProcessorState()
if (mSourceDocument)
loadedDocuments.remove(mSourceDocument->getBaseURI());
// in module the outputhandler is refcounted
#ifdef TX_EXE
delete mOutputHandler;
#endif
} //-- ~ProcessorState
@ -635,26 +639,48 @@ txOutputFormat* ProcessorState::getOutputFormat()
return &mOutputFormat;
}
Document* ProcessorState::getResultDocument()
Document* ProcessorState::getRTFDocument()
{
return resultDocument;
return mRTFDocument;
}
void ProcessorState::setRTFDocument(Document* aDoc)
{
mRTFDocument = aDoc;
}
Document* ProcessorState::getStylesheetDocument()
{
NS_ASSERTION(xslDocument, "missing stylesheet document");
return xslDocument;
}
/*
* Add a global variable
*/
nsresult ProcessorState::addGlobalVariable(Element* aVarElem,
ImportFrame* aImportFrame)
nsresult ProcessorState::addGlobalVariable(const txExpandedName& aVarName,
Element* aVarElem,
ImportFrame* aImportFrame,
ExprResult* aDefaultValue)
{
nsresult rv;
txExpandedName varName;
String qName;
aVarElem->getAttr(txXSLTAtoms::name, kNameSpaceID_None, qName);
rv = varName.init(qName, aVarElem, MB_FALSE);
if (NS_FAILED(rv))
return rv;
// If we don't know the value, it's a plain global var, add it
// to the import frame for late evaluation.
if (!aDefaultValue) {
return aImportFrame->mVariables.add(aVarName, aVarElem);
}
// Otherwise, add a GlobalVariableValue not owning the value.
GlobalVariableValue* var =
(GlobalVariableValue*)mGlobalVariableValues.get(aVarName);
if (var) {
// we set this parameter twice, we should set it to the same
// value;
NS_ENSURE_TRUE(var->mValue == aDefaultValue, NS_ERROR_UNEXPECTED);
return NS_OK;
}
var = new GlobalVariableValue(aDefaultValue);
NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
return aImportFrame->mVariables.add(varName, aVarElem);
return mGlobalVariableValues.add(aVarName, var);
}
/*
@ -950,7 +976,7 @@ nsresult ProcessorState::getVariable(PRInt32 aNamespace, txAtom* aLName,
GlobalVariableValue* globVar;
globVar = (GlobalVariableValue*)mGlobalVariableValues.get(varName);
if (globVar) {
if (globVar->mEvaluating) {
if (globVar->mFlags == GlobalVariableValue::evaluating) {
String err("Cyclic variable-value detected");
receiveError(err, NS_ERROR_FAILURE);
return NS_ERROR_FAILURE;
@ -975,7 +1001,6 @@ nsresult ProcessorState::getVariable(PRInt32 aNamespace, txAtom* aLName,
globVar = new GlobalVariableValue();
if (!globVar)
return NS_ERROR_OUT_OF_MEMORY;
globVar->mEvaluating = MB_TRUE;
rv = mGlobalVariableValues.add(varName, globVar);
if (NS_FAILED(rv)) {
delete globVar;
@ -987,12 +1012,14 @@ nsresult ProcessorState::getVariable(PRInt32 aNamespace, txAtom* aLName,
mLocalVariables = 0;
txSingleNodeContext evalContext(mSourceDocument, this);
txIEvalContext* priorEC = setEvalContext(&evalContext);
XSLTProcessor processor;
globVar->mValue = processor.processVariable(varElem, this);
// Compute the variable value
globVar->mFlags = GlobalVariableValue::evaluating;
globVar->mValue = txXSLTProcessor::processVariable(varElem, this);
setEvalContext(priorEC);
mLocalVariables = oldVars;
globVar->mEvaluating = MB_FALSE;
// evaluation is over, the gvv now owns the ExprResult
globVar->mFlags = GlobalVariableValue::owned;
aResult = globVar->mValue;
return NS_OK;
}
@ -1178,5 +1205,8 @@ void txPSParseContext::receiveError(const String& aMsg, nsresult aRes)
ProcessorState::GlobalVariableValue::~GlobalVariableValue()
{
delete mValue;
NS_ASSERTION(mFlags != evaluating, "deleted while evaluating");
if (mFlags == owned) {
delete mValue;
}
}

View File

@ -39,6 +39,7 @@
#include "Map.h"
#include "txIXPathContext.h"
#include "txExpandedNameMap.h"
#include "txXMLEventHandler.h"
#include "XSLTFunctions.h"
#include "txError.h"
@ -56,8 +57,7 @@ public:
* And result Document
*/
ProcessorState(Document* aSourceDocument,
Document* aXslDocument,
Document* aResultDocument);
Document* aXslDocument);
/**
* Destroys this ProcessorState
@ -134,11 +134,6 @@ public:
*/
NodeSet* getAttributeSet(const txExpandedName& aName);
/**
* Returns the source node currently being processed
*/
Node* getCurrentNode();
/**
* Returns the template associated with the given name, or
* null if not template is found
@ -154,8 +149,10 @@ public:
/**
* Add a global variable
*/
nsresult addGlobalVariable(Element* aVarElem,
ImportFrame* aImportFrame);
nsresult addGlobalVariable(const txExpandedName& aVarName,
Element* aVarElem,
ImportFrame* aImportFrame,
ExprResult* aDefaultValue);
/**
* Returns map on top of the stack of local variable-bindings
@ -184,11 +181,6 @@ public:
Expr* getExpr(Element* aElem, ExprAttr aAttr);
txPattern* getPattern(Element* aElem, PatternAttr aAttr);
/**
* Returns a pointer to the result document
*/
Document* getResultDocument();
/**
* Retrieve the document designated by the URI uri, using baseUri as base URI.
* Parses it as an XML document, and returns it. If a fragment identifier is
@ -303,6 +295,21 @@ public:
*/
txDecimalFormat* getDecimalFormat(const txExpandedName& name);
/**
* Returns a pointer to a document that can be used to create RTFs
*/
Document* getRTFDocument();
/**
* Sets a new document to be used for creating RTFs
*/
void setRTFDocument(Document* aDoc);
/**
* Returns the stylesheet document
*/
Document* getStylesheetDocument();
/**
* Virtual methods from txIEvalContext
*/
@ -343,6 +350,15 @@ public:
nsresult resolveFunctionCall(txAtom* aName, PRInt32 aID,
Element* aElem, FunctionCall*& aFunction);
#ifdef TX_EXE
txIOutputXMLEventHandler* mOutputHandler;
#else
nsCOMPtr<txIOutputXMLEventHandler> mOutputHandler;
#endif
txXMLEventHandler* mResultHandler;
txIOutputHandlerFactory* mOutputHandlerFactory;
private:
class MatchableTemplate {
@ -359,10 +375,20 @@ private:
class GlobalVariableValue : public TxObject {
public:
GlobalVariableValue(ExprResult* aValue = 0)
: mValue(aValue), mFlags(nonOwned)
{
}
virtual ~GlobalVariableValue();
ExprResult* mValue;
MBool mEvaluating;
char mFlags;
enum _flags
{
nonOwned = 0,
evaluating,
owned
};
};
/**
@ -440,7 +466,11 @@ private:
Document* mSourceDocument;
Document* xslDocument;
Document* resultDocument;
/**
* Document used to create RTFs
*/
Document* mRTFDocument;
};
/**

File diff suppressed because it is too large Load Diff

View File

@ -28,354 +28,247 @@
#ifndef TRANSFRMX_XSLTPROCESSOR_H
#define TRANSFRMX_XSLTPROCESSOR_H
#ifndef __BORLANDC__
#ifdef TX_EXE
#include <iostream.h>
#include <fstream.h>
#endif
#endif
#ifndef TX_EXE
#include "nsICSSStyleSheet.h"
#include "nsICSSLoaderObserver.h"
#include "nsIDocumentTransformer.h"
#include "nsIDOMHTMLScriptElement.h"
#include "nsIScriptLoader.h"
#include "nsIScriptLoaderObserver.h"
#include "nsITransformObserver.h"
#include "nsWeakPtr.h"
#include "txMozillaTextOutput.h"
#include "txMozillaXMLOutput.h"
#endif
#include "dom.h"
#include "ExprParser.h"
#include "TxObject.h"
#include "NamedMap.h"
#include "ProcessorState.h"
#include "TxString.h"
#include "ErrorObserver.h"
#include "List.h"
#include "txTextHandler.h"
#ifndef TX_EXE
/* bacd8ad0-552f-11d3-a9f7-000064657374 */
#define TRANSFORMIIX_XSLT_PROCESSOR_CID \
{ 0xbacd8ad0, 0x552f, 0x11d3, { 0xa9, 0xf7, 0x00, 0x00, 0x64, 0x65, 0x73, 0x74 } }
#define TRANSFORMIIX_XSLT_PROCESSOR_CONTRACTID \
"@mozilla.org/document-transformer;1?type=text/xsl"
#else
/*
* Initialisation and shutdown routines for standalone
* Allocate and free static atoms.
*/
MBool txInit();
MBool txShutdown();
#endif
class txIGlobalParameter : public TxObject
{
public:
virtual nsresult getValue(ExprResult** aValue) = 0;
};
/**
* A class for Processing XSL Stylesheets
**/
class XSLTProcessor
#ifndef TX_EXE
: public nsIDocumentTransformer,
public nsIScriptLoaderObserver
#endif
* A class for Processing XSLT Stylesheets
*/
class txXSLTProcessor
{
friend class ProcessorState;
public:
#ifndef TX_EXE
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIDocumentTransformer interface
NS_DECL_NSIDOCUMENTTRANSFORMER
NS_DECL_NSISCRIPTLOADEROBSERVER
#endif
/**
* Initialisation and shutdown routines
* Allocate and free static atoms.
*/
static MBool txInit();
static MBool txShutdown();
/**
* A warning message used by all templates that do not allow non character
* data to be generated
**/
static const String NON_TEXT_TEMPLATE_WARNING;
* Processes a stylesheet document.
*
* @param aStylesheet the stylesheet document to process
* @param aPs the current ProcessorState
*/
static nsresult processStylesheet(Document* aStylesheet,
txExpandedNameMap* aGlobalParams,
ProcessorState* aPs);
/**
* Creates a new XSLTProcessor
**/
XSLTProcessor();
* Processes a stylesheet element.
*
* @param aStylesheet the stylesheet element to process
* @param aPs the current ProcessorState
*/
static nsresult processTopLevel(Element* aStylesheet,
txExpandedNameMap* aGlobalParams,
ProcessorState* aPs);
/**
* Default destructor for XSLTProcessor
**/
virtual ~XSLTProcessor();
/**
* Registers the given ErrorObserver with this XSLTProcessor
**/
void addErrorObserver(ErrorObserver& errorObserver);
/**
* Returns the name of this XSLT processor
**/
String& getAppName();
/**
* Returns the version of this XSLT processor
**/
String& getAppVersion();
//--------------------------------------------/
//-- Methods that return the Result Document -/
//--------------------------------------------/
#ifdef TX_EXE
/**
* Parses all XML Stylesheet PIs associated with the
* given XML document. If any stylesheet PIs are found with
* type="text/xsl" the href psuedo attribute value will be
* added to the given href argument. If multiple text/xsl stylesheet PIs
* are found, the one closest to the end of the document is used.
**/
void getHrefFromStylesheetPI(Document& xmlDocument, String& href);
/**
* Processes the given XML Document, the XSL stylesheet
* will be retrieved from the XML Stylesheet Processing instruction,
* otherwise an empty document will be returned.
* @param xmlDocument the XML document to process
* @return the result tree.
**/
Document* process(Document& xmlDocument);
#endif
/**
* Processes the given XML Document using the given XSL document
* @return the result tree.
* @param documentBase the document base for resolving relative URIs.
**/
Document* process
(Document& xmlDocument, Document& xslDocument);
/**
* Reads an XML Document from the given XML input stream, and
* processes the document using the XSL document derived from
* the given XSL input stream.
* @param documentBase the document base for resolving relative URIs.
* @return the result tree.
**/
Document* process(istream& xmlInput, String& xmlFilename,
istream& xslInput, String& xslFilename);
#ifdef TX_EXE
/**
* Reads an XML document from the given XML input stream. The
* XML document is processed using the associated XSL document
* retrieved from the XML document's Stylesheet Processing Instruction,
* otherwise an empty document will be returned.
* @param xmlDocument the XML document to process
* @param documentBase the document base of the XML document, for
* resolving relative URIs
* @return the result tree.
**/
Document* process(istream& xmlInput, String& xmlFilename);
//----------------------------------------------/
//-- Methods that print the result to a stream -/
//----------------------------------------------/
/**
* Reads an XML Document from the given XML input stream.
* The XSL Stylesheet is obtained from the XML Documents stylesheet PI.
* If no Stylesheet is found, an empty document will be the result;
* otherwise the XML Document is processed using the stylesheet.
* The result tree is printed to the given ostream argument,
* will not close the ostream argument
**/
void process(istream& xmlInput, String& xmlFilename, ostream& out);
/**
* Processes the given XML Document using the given XSL document.
* The result tree is printed to the given ostream argument,
* will not close the ostream argument
* @param documentBase the document base for resolving relative URIs.
**/
void process(Document& aXMLDocument, Node& aStylesheet,
ostream& aOut);
/**
* Reads an XML Document from the given XML input stream, and
* processes the document using the XSL document derived from
* the given XSL input stream.
* The result tree is printed to the given ostream argument,
* will not close the ostream argument
* @param documentBase the document base for resolving relative URIs.
**/
void process(istream& xmlInput, String& xmlFilename,
istream& xslInput, String& xslFilename,
ostream& out);
#endif
* Transforms a node.
*
* @param aPs the current ProcessorState with the node
* as current node and the desired templates
*/
static void transform(ProcessorState* aPs);
private:
/**
* Application Name and version
**/
String appName;
String appVersion;
/**
* The list of ErrorObservers
**/
List errorObservers;
/**
* Fatal ErrorObserver
**/
SimpleErrorObserver fatalObserver;
/**
* The version of XSL which this Processes
**/
String xslVersion;
/*
* Used as default expression for some elements
*/
Expr* mNodeExpr;
#ifdef TX_EXE
/**
* Parses the contents of data, and returns the type and href psuedo attributes
**/
void parseStylesheetPI(String& data, String& type, String& href);
#endif
void process(Node* node,
const String& mode,
ProcessorState* ps);
/*
* Copy a node. For document nodes, copy the children.
*
* @param aSourceNode node to copy
* @param aPs the current ProcessorState
*/
void copyNode(Node* aNode, ProcessorState* aPs);
void processAction(Node* aAction, ProcessorState* aPs);
static void copyNode(Node* aSourceNode, ProcessorState* aPs);
/**
* Processes the attribute sets specified in the use-attribute-sets attribute
* of the element specified in aElement
**/
void processAttributeSets(Element* aElement, ProcessorState* aPs,
Stack* aRecursionStack = 0);
/**
* Processes the children of the specified element using the given context node
* and ProcessorState
* @param aElement template to be processed. Must be != NULL
* @param aPs current ProcessorState
**/
void processChildren(Element* aElement,
ProcessorState* aPs);
void processChildrenAsValue(Element* aElement,
ProcessorState* aPs,
MBool aOnlyText,
String& aValue);
/**
* Invokes the default template for the specified node
* @param aPs current ProcessorState
* @param aMode template mode
**/
void processDefaultTemplate(ProcessorState* aPs,
const txExpandedName& aMode);
/*
* Processes an include or import stylesheet
* @param aHref URI of stylesheet to process
* @param aImportFrame current importFrame iterator
* @param aPs current ProcessorState
* Create the document we will use to create result tree fragments.
*
* @param aMethod the output method indicating which type of
* document to create
* @returns a document to create RTF nodes
*/
void processInclude(String& aHref,
txListIterator* aImportFrame,
ProcessorState* aPs);
static Document* createRTFDocument(txOutputMethod aMethod);
void processMatchedTemplate(Node* aTemplate,
txVariableMap* aParams,
const txExpandedName& aMode,
ProcessorState::ImportFrame* aFrame,
/**
* Log a message.
*
* @param aMessage the message to log
*/
static void logMessage(const String& aMessage);
/**
* Instantiate aAction in the result tree.
* Either perform the action associated with the element in the
* XSLT namespace, or copy the element as literal result element.
*
* @param aAction literal result element or XSLT element
* @param aPs the current ProcessorState
*/
static void processAction(Node* aAction,
ProcessorState* aPs);
/**
* Processes the attribute sets specified in the use-attribute-sets
* attribute of the element specified in aElement.
*
* @param aElement Element specifying the attribute sets
* @param aPs the current ProcessorState
* @param aRecursionStack recursion stack to track attribute sets
* including themselves, even indirectly
*/
static void processAttributeSets(Element* aElement, ProcessorState* aPs,
Stack* aRecursionStack = 0);
/**
* Processes the children of the specified element using the given
* context node and ProcessorState.
*
* @param aElement the template to be processed. Must be != NULL
* @param aPs the current ProcessorState
*/
static void processChildren(Element* aElement,
ProcessorState* aPs);
/*
/**
* Processes the children of the specified element using the given
* context node and ProcessorState and append the text data to
* aValue.
*
* @param aElement the template to be processed. Must be != NULL
* @param aPs the current ProcessorState
* @param aOnlyText if true, don't allow for nested content
* @param aValue String reference to append the result to
*/
static void processChildrenAsValue(Element* aElement,
ProcessorState* aPs,
MBool aOnlyText,
String& aValue);
/**
* Invokes the default template for the specified node.
*
* @param aPs the current ProcessorState
* @param aMode template mode
*/
static void processDefaultTemplate(ProcessorState* aPs,
const txExpandedName& aMode);
/**
* Processes an include or import stylesheet.
*
* @param aHref URI of stylesheet to process
* @param aImportFrame current importFrame iterator
* @param aPs the current ProcessorState
*/
static void processInclude(String& aHref,
txListIterator* aImportFrame,
ProcessorState* aPs);
/**
* Instantiate the children of the template aTemplate with the
* parameters aParams and the mode aMode.
*
* @param aTemplate xsl:template to instantiate
* @param aParams txVariableMap holding the params, if given
* @param aMode mode of this template
* @param aFrame the current import frame, needed for apply-templates
* @param aPs the current ProcessorState
*/
static void processMatchedTemplate(Node* aTemplate,
txVariableMap* aParams,
const txExpandedName& aMode,
ProcessorState::ImportFrame* aFrame,
ProcessorState* aPs);
/**
* Processes the xsl:with-param child elements of the given xsl action.
*
* @param aAction the action node that takes parameters (xsl:call-template
* or xsl:apply-templates
* or xsl:apply-templates)
* @param aMap map to place parsed variables in
* @param aPs the current ProcessorState
* @return errorcode
*/
nsresult processParameters(Element* aAction, txVariableMap* aMap,
ProcessorState* aPs);
static nsresult processParameters(Element* aAction, txVariableMap* aMap,
ProcessorState* aPs);
void processStylesheet(Document* aStylesheet,
txListIterator* aImportFrame,
ProcessorState* aPs);
/**
* Add a stylesheet to the processorstate. If the document element
* is a LRE, just add one template with pattern "/". Otherwise,
* call processTopLevel with the document element.
*
* @param aStylesheet the document to be added to the ps
* @param aImportFrame the import frame to add the stylesheet to
* @param aPs the current ProcessorState
*/
static void processStylesheet(Document* aStylesheet,
txExpandedNameMap* aGlobalParams,
txListIterator* aImportFrame,
ProcessorState* aPs);
/*
/**
* Processes the specified template using the given context,
* ProcessorState, and parameters.
* @param aTemplate the node in the xslt document that contains the
* template
* @param aParams map with parameters to the template
* @param aPs the current ProcessorState
* ProcessorState, and parameters. Iterates through the
* |xsl:param|s and then calls processAction.
*
* @param aTemplate xsl:template to process
* @param aParams variable map with xsl:with-param values
* @param aPs the current ProcessorState
*/
void processTemplate(Node* aTemplate, txVariableMap* aParams,
ProcessorState* aPs);
static void processTemplate(Node* aTemplate, txVariableMap* aParams,
ProcessorState* aPs);
void processTopLevel(Element* aStylesheet,
txListIterator* importFrame,
ProcessorState* aPs);
ExprResult* processVariable(Element* aVariable, ProcessorState* aPs);
void startTransform(Node* aNode, ProcessorState* aPs);
MBool initializeHandlers(ProcessorState* aPs);
/*
* Performs the xsl:copy action as specified in the XSLT specification
/**
* Processes the top-level children of xsl:stylesheet.
*
* @param aStylesheet the stylesheet
* @param aImportFrame the import frame of the stylesheet
* @param aPs the current ProcessorState
*/
void xslCopy(Element* aAction, ProcessorState* aPs);
static void processTopLevel(Element* aStylesheet,
txExpandedNameMap* aGlobalParams,
txListIterator* aImportFrame,
ProcessorState* aPs);
/*
* Performs the xsl:copy-of action as specified in the XSLT specification
/**
* Processes the given xsl:variable.
*
* @param aVariable the variable element
* @param aPs the current ProcessorState
*/
void xslCopyOf(ExprResult* aExprResult, ProcessorState* aPs);
static ExprResult* processVariable(Element* aVariable,
ProcessorState* aPs);
void startElement(const String& aName, const PRInt32 aNsID, ProcessorState* aPs);
/**
* Performs the xsl:copy action as specified in the XSLT specification.
*
* @param aAction element to copy
* @param aPs the current ProcessorState
*/
static void xslCopy(Element* aAction,
ProcessorState* aPs);
#ifdef TX_EXE
txStreamXMLEventHandler* mOutputHandler;
#else
txMozillaXMLEventHandler* mOutputHandler;
#endif
txXMLEventHandler* mResultHandler;
MBool mHaveDocumentElement;
#ifndef TX_EXE
void SignalTransformEnd();
/**
* Performs the xsl:copy-of action as specified in the XSLT specification.
*
* @param aExprResult expression result to copy
* @param aPs the current ProcessorState
*/
static void xslCopyOf(ExprResult* aExprResult,
ProcessorState* aPs);
nsCOMPtr<nsIScriptLoader> mScriptLoader;
nsWeakPtr mObserver;
#endif
}; //-- XSLTProcessor
/**
* Used as default expression for some elements
*/
static Expr* gNodeExpr;
friend class ProcessorState;
};
#endif

View File

@ -41,7 +41,8 @@
#include "txOutputFormat.h"
#include "XMLUtils.h"
txHTMLOutput::txHTMLOutput()
txHTMLOutput::txHTMLOutput(txOutputFormat* aFormat, ostream* aOut)
: txXMLOutput(aFormat, aOut)
{
mUseEmptyElementShorthand = MB_FALSE;

View File

@ -46,7 +46,7 @@
class txHTMLOutput : public txXMLOutput
{
public:
txHTMLOutput();
txHTMLOutput(txOutputFormat* aFormat, ostream* aOut);
~txHTMLOutput();
/*

View File

@ -37,21 +37,58 @@
* ***** END LICENSE BLOCK ***** */
#include "txMozillaTextOutput.h"
#include "nsContentCID.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIDOMElement.h"
#include "nsIDOMHTMLElement.h"
#include "nsIDOMText.h"
#include "nsIDocumentTransformer.h"
#include "TxString.h"
#include "nsNetUtil.h"
#include "nsIDOMNSDocument.h"
txMozillaTextOutput::txMozillaTextOutput()
static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID);
txMozillaTextOutput::txMozillaTextOutput(nsIDOMDocument* aSourceDocument,
nsIDOMDocument* aResultDocument,
nsITransformObserver* aObserver)
{
NS_INIT_ISUPPORTS();
mObserver = do_GetWeakReference(aObserver);
createResultDocument(aSourceDocument, aResultDocument);
}
txMozillaTextOutput::txMozillaTextOutput(nsIDOMDocumentFragment* aDest)
{
NS_INIT_ISUPPORTS();
nsCOMPtr<nsIDOMDocument> doc;
aDest->GetOwnerDocument(getter_AddRefs(doc));
NS_ASSERTION(doc, "unable to get ownerdocument");
nsCOMPtr<nsIDOMText> textNode;
nsresult rv = doc->CreateTextNode(NS_LITERAL_STRING(""),
getter_AddRefs(textNode));
if (NS_FAILED(rv)) {
return;
}
nsCOMPtr<nsIDOMNode> dummy;
rv = aDest->AppendChild(textNode, getter_AddRefs(dummy));
if (NS_FAILED(rv)) {
return;
}
mTextNode = textNode;
return;
}
txMozillaTextOutput::~txMozillaTextOutput()
{
}
NS_IMPL_ISUPPORTS1(txMozillaTextOutput, txIOutputXMLEventHandler);
void txMozillaTextOutput::attribute(const String& aName,
const PRInt32 aNsID,
const String& aValue)
@ -68,12 +105,12 @@ void txMozillaTextOutput::comment(const String& aData)
{
}
void txMozillaTextOutput::disableStylesheetLoad()
{
}
void txMozillaTextOutput::endDocument()
{
nsCOMPtr<nsITransformObserver> observer = do_QueryReferent(mObserver);
if (observer) {
observer->OnTransformDone(NS_OK, mDocument);
}
}
void txMozillaTextOutput::endElement(const String& aName,
@ -81,36 +118,20 @@ void txMozillaTextOutput::endElement(const String& aName,
{
}
nsresult txMozillaTextOutput::getRootContent(nsIContent** aReturn)
{
NS_ASSERTION(aReturn, "NULL pointer passed to getRootContent");
*aReturn = mRootContent;
NS_IF_ADDREF(*aReturn);
return NS_OK;
}
PRBool txMozillaTextOutput::isDone()
{
return PR_TRUE;
}
void txMozillaTextOutput::processingInstruction(const String& aTarget,
const String& aData)
{
}
void txMozillaTextOutput::removeScriptElement(nsIDOMHTMLScriptElement *aElement)
void txMozillaTextOutput::startDocument()
{
NS_NOTREACHED("No script elements in text output, so this is weird!");
}
void txMozillaTextOutput::setOutputDocument(nsIDOMDocument* aDocument)
void txMozillaTextOutput::createResultDocument(nsIDOMDocument* aSourceDocument,
nsIDOMDocument* aResultDocument)
{
NS_ASSERTION(aDocument, "Document can't be NULL!");
if (!aDocument)
return;
nsresult rv = NS_OK;
/*
* Create an XHTML document to hold the text.
*
@ -120,92 +141,172 @@ void txMozillaTextOutput::setOutputDocument(nsIDOMDocument* aDocument)
* <pre> * The text comes here * </pre>
* <body>
* </html>
*
* Except if we are transforming into a non-displayed document we create
* the following DOM
*
* <transformiix:result> * The text comes here * </transformiix:result>
*/
nsCOMPtr<nsIDocument> doc;
if (!aResultDocument) {
// Create the document
doc = do_CreateInstance(kXMLDocumentCID, &rv);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't create document");
mDocument = do_QueryInterface(doc);
}
else {
mDocument = aResultDocument;
doc = do_QueryInterface(aResultDocument);
NS_ASSERTION(doc, "Couldn't QI to nsIDocument");
}
if (!doc) {
return;
}
NS_ASSERTION(mDocument, "Need document");
nsCOMPtr<nsIDOMNSDocument> nsDoc = do_QueryInterface(mDocument);
if (nsDoc) {
nsDoc->SetTitle(NS_LITERAL_STRING(""));
}
// Reset and set up document
nsCOMPtr<nsILoadGroup> loadGroup;
nsCOMPtr<nsIChannel> channel;
nsCOMPtr<nsIDocument> sourceDoc = do_QueryInterface(aSourceDocument);
sourceDoc->GetDocumentLoadGroup(getter_AddRefs(loadGroup));
nsCOMPtr<nsIIOService> 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<nsIURI> docURL;
sourceDoc->GetDocumentURL(getter_AddRefs(docURL));
serv->NewChannelFromURI(docURL, getter_AddRefs(channel));
}
doc->Reset(channel, loadGroup);
nsCOMPtr<nsIURI> baseURL;
sourceDoc->GetBaseURL(*getter_AddRefs(baseURL));
doc->SetBaseURL(baseURL);
// XXX We might want to call SetDefaultStylesheets here
// Notify the contentsink that the document is created
nsCOMPtr<nsITransformObserver> observer = do_QueryReferent(mObserver);
if (observer) {
observer->OnDocumentCreated(mDocument);
}
// Create the content
// When transforming into a non-displayed document (i.e. when there is no
// observer) we only create a transformiix:result root element.
// Don't do this when called through nsIXSLTProcessorObsolete (i.e. when
// aResultDocument is set) for compability reasons
nsCOMPtr<nsIDOMNode> textContainer;
if (!aResultDocument && !observer) {
nsCOMPtr<nsIDOMElement> docElement;
mDocument->CreateElementNS(NS_LITERAL_STRING(kTXNameSpaceURI),
NS_LITERAL_STRING(kTXWrapper),
getter_AddRefs(docElement));
NS_ASSERTION(docElement, "Failed to create wrapper element");
if (!docElement) {
return;
}
rv = mDocument->AppendChild(docElement, getter_AddRefs(textContainer));
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the wrapper element");
if (NS_FAILED(rv)) {
return;
}
}
else {
nsCOMPtr<nsIDOMElement> element, docElement;
nsCOMPtr<nsIDOMNode> parent, pre;
NS_NAMED_LITERAL_STRING(XHTML_NSURI, "http://www.w3.org/1999/xhtml");
mDocument->CreateElementNS(XHTML_NSURI,
NS_LITERAL_STRING("html"),
getter_AddRefs(docElement));
nsCOMPtr<nsIContent> rootContent = do_QueryInterface(docElement);
NS_ASSERTION(rootContent, "Need root element");
if (!rootContent) {
return;
}
rv = rootContent->SetDocument(doc, PR_FALSE, PR_TRUE);
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to set the document");
if (NS_FAILED(rv)) {
return;
}
rv = doc->SetRootContent(rootContent);
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to set the root content");
if (NS_FAILED(rv)) {
return;
}
mDocument->CreateElementNS(XHTML_NSURI,
NS_LITERAL_STRING("head"),
getter_AddRefs(element));
NS_ASSERTION(element, "Failed to create head element");
if (!element) {
return;
}
rv = docElement->AppendChild(element, getter_AddRefs(parent));
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the head element");
if (NS_FAILED(rv)) {
return;
}
mDocument->CreateElementNS(XHTML_NSURI,
NS_LITERAL_STRING("body"),
getter_AddRefs(element));
NS_ASSERTION(element, "Failed to create body element");
if (!element) {
return;
}
rv = docElement->AppendChild(element, getter_AddRefs(parent));
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the body element");
if (NS_FAILED(rv)) {
return;
}
mDocument->CreateElementNS(XHTML_NSURI,
NS_LITERAL_STRING("pre"),
getter_AddRefs(element));
NS_ASSERTION(element, "Failed to create pre element");
if (!element) {
return;
}
rv = parent->AppendChild(element, getter_AddRefs(pre));
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the pre element");
if (NS_FAILED(rv)) {
return;
}
nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(pre);
htmlElement->SetId(NS_LITERAL_STRING("transformiixResult"));
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the id");
textContainer = pre;
}
nsCOMPtr<nsIDOMElement> element, docElement;
nsCOMPtr<nsIDOMNode> parent, pre;
nsCOMPtr<nsIDOMText> textNode;
NS_NAMED_LITERAL_STRING(XHTML_NSURI, "http://www.w3.org/1999/xhtml");
aDocument->CreateElementNS(XHTML_NSURI,
NS_LITERAL_STRING("html"),
getter_AddRefs(docElement));
mRootContent = do_QueryInterface(docElement);
NS_ASSERTION(mRootContent, "Need root element");
if (!mRootContent) {
return;
}
nsCOMPtr<nsIDocument> document = do_QueryInterface(aDocument);
NS_ASSERTION(document, "Need document");
nsresult rv = mRootContent->SetDocument(document, PR_FALSE, PR_TRUE);
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to set the document");
if (NS_FAILED(rv)) {
return;
}
rv = document->SetRootContent(mRootContent);
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to set the root content");
if (NS_FAILED(rv)) {
return;
}
aDocument->CreateElementNS(XHTML_NSURI,
NS_LITERAL_STRING("head"),
getter_AddRefs(element));
NS_ASSERTION(element, "Failed to create head element");
if (!element) {
return;
}
rv = docElement->AppendChild(element, getter_AddRefs(parent));
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the head element");
if (NS_FAILED(rv)) {
return;
}
aDocument->CreateElementNS(XHTML_NSURI,
NS_LITERAL_STRING("body"),
getter_AddRefs(element));
NS_ASSERTION(element, "Failed to create body element");
if (!mRootContent) {
return;
}
rv = docElement->AppendChild(element, getter_AddRefs(parent));
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the body element");
if (NS_FAILED(rv)) {
return;
}
aDocument->CreateElementNS(XHTML_NSURI,
NS_LITERAL_STRING("pre"),
getter_AddRefs(element));
NS_ASSERTION(element, "Failed to create pre element");
if (!element) {
return;
}
rv = parent->AppendChild(element, getter_AddRefs(pre));
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the pre element");
if (NS_FAILED(rv)) {
return;
}
nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(pre);
htmlElement->SetId(NS_LITERAL_STRING("transformiixResult"));
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the id");
aDocument->CreateTextNode(NS_LITERAL_STRING(""),
mDocument->CreateTextNode(NS_LITERAL_STRING(""),
getter_AddRefs(textNode));
NS_ASSERTION(textNode, "Failed to create the text node");
if (!textNode) {
return;
}
rv = pre->AppendChild(textNode, getter_AddRefs(parent));
nsCOMPtr<nsIDOMNode> dummy;
rv = textContainer->AppendChild(textNode, getter_AddRefs(dummy));
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the text node");
if (NS_FAILED(rv)) {
return;
@ -214,18 +315,13 @@ void txMozillaTextOutput::setOutputDocument(nsIDOMDocument* aDocument)
mTextNode = textNode;
}
void txMozillaTextOutput::setOutputFormat(txOutputFormat* aOutputFormat)
{
mOutputFormat.reset();
mOutputFormat.merge(*aOutputFormat);
mOutputFormat.setFromDefaults();
}
void txMozillaTextOutput::startDocument()
{
}
void txMozillaTextOutput::startElement(const String& aName,
const PRInt32 aNsID)
{
}
void txMozillaTextOutput::getOutputDocument(nsIDOMDocument** aDocument)
{
*aDocument = mDocument;
NS_IF_ADDREF(*aDocument);
}

View File

@ -43,14 +43,24 @@
#include "nsIContent.h"
#include "nsIDOMCharacterData.h"
#include "nsCOMPtr.h"
#include "nsWeakPtr.h"
#include "txOutputFormat.h"
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentFragment.h"
class txMozillaTextOutput : public txMozillaXMLEventHandler
class nsITransformObserver;
class txMozillaTextOutput : public txIOutputXMLEventHandler
{
public:
txMozillaTextOutput();
txMozillaTextOutput(nsIDOMDocument* aSourceDocument,
nsIDOMDocument* aResultDocument,
nsITransformObserver* aObserver);
txMozillaTextOutput(nsIDOMDocumentFragment* aDest);
virtual ~txMozillaTextOutput();
NS_DECL_ISUPPORTS
/**
* Signals to receive the start of an attribute.
*
@ -69,6 +79,16 @@ public:
*/
void characters(const String& aData);
/**
* Signals to receive characters that don't need output escaping.
*
* @param aData the characters to receive
*/
void charactersNoOutputEscaping(const String& aData)
{
NS_ASSERTION(0, "Don't call this in module, we don't do d-o-e");
}
/**
* Signals to receive data that should be treated as a comment.
*
@ -91,6 +111,18 @@ public:
void endElement(const String& aName,
const PRInt32 aNsID);
/**
* Returns whether the output handler supports
* disable-output-escaping.
*
* @return MB_TRUE if this handler supports
* disable-output-escaping
*/
MBool hasDisableOutputEscaping()
{
return MB_FALSE;
}
/**
* Signals to receive a processing instruction.
*
@ -114,48 +146,19 @@ public:
const PRInt32 aNsID);
/**
* Sets the output format.
*
* @param aOutputFormat the output format
*/
void setOutputFormat(txOutputFormat* aOutputFormat);
/**
* Disables loading of stylesheets.
*/
void disableStylesheetLoad();
/**
* Returns the root content of the result.
*
* @param aReturn the root content
*/
nsresult getRootContent(nsIContent** aReturn);
/**
* Returns PR_TRUE if the event handler has finished anything
* extra that had to happen after the transform has finished.
*/
PRBool isDone();
/**
* Removes a script element from the array of elements that are
* still loading.
*
* @param aReturn the script element to remove
*/
void removeScriptElement(nsIDOMHTMLScriptElement *aElement);
/**
* Sets the Mozilla output document.
* Gets the Mozilla output document
*
* @param aDocument the Mozilla output document
*/
void setOutputDocument(nsIDOMDocument* aDocument);
void getOutputDocument(nsIDOMDocument** aDocument);
private:
void createResultDocument(nsIDOMDocument* aSourceDocument,
nsIDOMDocument* aResultDocument);
nsCOMPtr<nsIDOMCharacterData> mTextNode;
nsCOMPtr<nsIContent> mRootContent;
nsWeakPtr mObserver;
nsCOMPtr<nsIDOMDocument> mDocument;
txOutputFormat mOutputFormat;
};

View File

@ -39,6 +39,7 @@
#include "txMozillaXMLOutput.h"
#include "nsIDocument.h"
#include "nsIDocShell.h"
#include "nsIDOMComment.h"
#include "nsIDOMDocumentType.h"
#include "nsIDOMDOMImplementation.h"
@ -48,31 +49,80 @@
#include "nsIDOMHTMLTableSectionElem.h"
#include "nsIDOMHTMLScriptElement.h"
#include "nsIDOMNSDocument.h"
#include "nsIParser.h"
#include "nsIRefreshURI.h"
#include "nsIScriptGlobalObject.h"
#include "nsITextContent.h"
#include "nsIDocumentTransformer.h"
#include "nsIXMLContent.h"
#include "nsContentCID.h"
#include "nsNetUtil.h"
#include "nsUnicharUtils.h"
#include "txAtoms.h"
#include "nsIParser.h"
#include "nsNetUtil.h"
#include "nsIScriptGlobalObject.h"
#include "nsIRefreshURI.h"
#include "nsIDocShell.h"
#include "nsIDOMDocumentFragment.h"
static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID);
static NS_DEFINE_CID(kHTMLDocumentCID, NS_HTMLDOCUMENT_CID);
#define kXHTMLNameSpaceURI "http://www.w3.org/1999/xhtml"
#define kTXNameSpaceURI "http://www.mozilla.org/TransforMiix"
#define kTXWrapper "transformiix:result"
#define TX_ENSURE_CURRENTNODE \
NS_ASSERTION(mCurrentNode, "mCurrentNode is NULL"); \
if (!mCurrentNode) \
return
txMozillaXMLOutput::txMozillaXMLOutput() : mDisableStylesheetLoad(PR_FALSE)
txMozillaXMLOutput::txMozillaXMLOutput(const String& aRootName,
PRInt32 aRootNsID,
txOutputFormat* aFormat,
nsIDOMDocument* aSourceDocument,
nsIDOMDocument* aResultDocument,
nsITransformObserver* aObserver)
: mStyleSheetCount(0),
mDontAddCurrent(PR_FALSE),
mHaveTitleElement(PR_FALSE),
mHaveBaseElement(PR_FALSE),
mInTransform(PR_FALSE),
mCreatingNewDocument(PR_TRUE)
{
NS_INIT_ISUPPORTS();
mOutputFormat.merge(*aFormat);
mOutputFormat.setFromDefaults();
mObserver = do_GetWeakReference(aObserver);
createResultDocument(aRootName, aRootNsID, aSourceDocument, aResultDocument);
}
txMozillaXMLOutput::txMozillaXMLOutput(txOutputFormat* aFormat,
nsIDOMDocumentFragment* aFragment)
: mStyleSheetCount(0),
mDontAddCurrent(PR_FALSE),
mHaveTitleElement(PR_FALSE),
mHaveBaseElement(PR_FALSE),
mInTransform(PR_FALSE),
mCreatingNewDocument(PR_FALSE)
{
NS_INIT_ISUPPORTS();
mOutputFormat.merge(*aFormat);
mOutputFormat.setFromDefaults();
aFragment->GetOwnerDocument(getter_AddRefs(mDocument));
nsCOMPtr<nsIDocument> doc = do_QueryInterface(mDocument);
NS_ASSERTION(doc, "can't QI to nsIDocument");
doc->GetNameSpaceManager(*getter_AddRefs(mNameSpaceManager));
NS_ASSERTION(mNameSpaceManager, "Can't get namespace manager.");
mCurrentNode = aFragment;
}
txMozillaXMLOutput::~txMozillaXMLOutput()
{
}
NS_IMPL_ISUPPORTS2(txMozillaXMLOutput,
txIOutputXMLEventHandler,
nsIScriptLoaderObserver);
void txMozillaXMLOutput::attribute(const String& aName,
const PRInt32 aNsID,
const String& aValue)
@ -118,22 +168,16 @@ void txMozillaXMLOutput::comment(const String& aData)
nsresult rv = mDocument->CreateComment(aData,
getter_AddRefs(comment));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create comment");
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(comment);
nsCOMPtr<nsIDOMNode> resultNode;
rv = mCurrentNode->AppendChild(node, getter_AddRefs(resultNode));
rv = mCurrentNode->AppendChild(comment, getter_AddRefs(resultNode));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't append comment");
}
void txMozillaXMLOutput::disableStylesheetLoad()
{
mDisableStylesheetLoad = PR_TRUE;
}
void txMozillaXMLOutput::endDocument()
{
closePrevious(eCloseElement | eFlushText);
if (!mHaveTitleElement) {
// This should really be handled by nsIDocument::Reset
if (mCreatingNewDocument && !mHaveTitleElement) {
nsCOMPtr<nsIDOMNSDocument> domDoc = do_QueryInterface(mDocument);
if (domDoc) {
domDoc->SetTitle(NS_LITERAL_STRING(""));
@ -155,10 +199,15 @@ void txMozillaXMLOutput::endDocument()
}
}
}
mInTransform = PR_FALSE;
SignalTransformEnd();
}
void txMozillaXMLOutput::endElement(const String& aName, const PRInt32 aNsID)
{
TX_ENSURE_CURRENTNODE;
#ifdef DEBUG
nsAutoString nodeName;
mCurrentNode->GetNodeName(nodeName);
@ -204,21 +253,10 @@ void txMozillaXMLOutput::endElement(const String& aName, const PRInt32 aNsID)
}
}
nsresult txMozillaXMLOutput::getRootContent(nsIContent** aReturn)
void txMozillaXMLOutput::getOutputDocument(nsIDOMDocument** aDocument)
{
NS_ASSERTION(aReturn, "NULL pointer passed to getRootContent");
*aReturn = mRootContent;
NS_IF_ADDREF(*aReturn);
return NS_OK;
}
PRBool txMozillaXMLOutput::isDone()
{
PRUint32 scriptCount = 0;
if (mScriptElements)
mScriptElements->Count(&scriptCount);
return (scriptCount == 0);
*aDocument = mDocument;
NS_IF_ADDREF(*aDocument);
}
void txMozillaXMLOutput::processingInstruction(const String& aTarget, const String& aData)
@ -234,24 +272,30 @@ void txMozillaXMLOutput::processingInstruction(const String& aTarget, const Stri
nsresult rv = mDocument->CreateProcessingInstruction(aTarget, aData,
getter_AddRefs(pi));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create processing instruction");
if (NS_FAILED(rv))
return;
nsCOMPtr<nsIStyleSheetLinkingElement> ssle = do_QueryInterface(pi);
if (ssle) {
ssle->InitStyleLinkElement(nsnull, PR_FALSE);
ssle->SetEnableUpdates(PR_FALSE);
nsCOMPtr<nsIStyleSheetLinkingElement> ssle;
if (mCreatingNewDocument) {
ssle = do_QueryInterface(pi);
if (ssle) {
ssle->InitStyleLinkElement(nsnull, PR_FALSE);
ssle->SetEnableUpdates(PR_FALSE);
}
}
nsCOMPtr<nsIDOMNode> resultNode;
mCurrentNode->AppendChild(pi, getter_AddRefs(resultNode));
rv = mCurrentNode->AppendChild(pi, getter_AddRefs(resultNode));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't append processing instruction");
if (NS_FAILED(rv))
return;
if (ssle) {
ssle->SetEnableUpdates(PR_TRUE);
rv = ssle->UpdateStyleSheet(nsnull, mStyleSheetCount);
if (NS_SUCCEEDED(rv) || (rv == NS_ERROR_HTMLPARSER_BLOCK))
mStyleSheetCount++;
ssle->SetEnableUpdates(PR_TRUE);
rv = ssle->UpdateStyleSheet(nsnull, mStyleSheetCount);
if (NS_SUCCEEDED(rv) || (rv == NS_ERROR_HTMLPARSER_BLOCK)) {
mStyleSheetCount++;
}
}
}
@ -264,102 +308,54 @@ void txMozillaXMLOutput::removeScriptElement(nsIDOMHTMLScriptElement *aElement)
}
}
void txMozillaXMLOutput::setOutputDocument(nsIDOMDocument* aDocument)
{
NS_ASSERTION(aDocument, "Document can't be NULL!");
if (!aDocument)
return;
mDocument = aDocument;
mCurrentNode = mDocument;
mStyleSheetCount = 0;
mHaveTitleElement = PR_FALSE;
mHaveBaseElement = PR_FALSE;
mNonAddedParent = nsnull;
mNonAddedNode = nsnull;
mRefreshString.Truncate();
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDocument);
doc->GetNameSpaceManager(*getter_AddRefs(mNameSpaceManager));
NS_ASSERTION(mNameSpaceManager, "Can't get namespace manager.");
}
void txMozillaXMLOutput::setOutputFormat(txOutputFormat* aOutputFormat)
{
mOutputFormat.reset();
mOutputFormat.merge(*aOutputFormat);
mOutputFormat.setFromDefaults();
}
void txMozillaXMLOutput::startDocument()
{
NS_ASSERTION(mDocument, "Document can't be NULL!");
mInTransform = PR_TRUE;
}
void txMozillaXMLOutput::startElement(const String& aName,
const PRInt32 aNsID)
{
TX_ENSURE_CURRENTNODE;
closePrevious(eCloseElement | eFlushText);
nsresult rv;
if (!mRootContent && !mOutputFormat.mSystemId.isEmpty()) {
// No root element yet, so add the doctype if necesary.
nsCOMPtr<nsIDOMDOMImplementation> implementation;
rv = mDocument->GetImplementation(getter_AddRefs(implementation));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't get DOMImplementation");
if (NS_SUCCEEDED(rv)) {
nsAutoString qName;
nsCOMPtr<nsIDOMDocumentType> documentType;
nsCOMPtr<nsIDOMNode> firstNode, node;
if (mOutputFormat.mMethod == eHTMLOutput)
qName.Assign(NS_LITERAL_STRING("html"));
else
qName.Assign(aName);
rv = implementation->CreateDocumentType(qName,
mOutputFormat.mPublicId,
mOutputFormat.mSystemId,
getter_AddRefs(documentType));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create doctype");
mDocument->GetFirstChild(getter_AddRefs(firstNode));
rv = mDocument->InsertBefore(documentType, firstNode, getter_AddRefs(node));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't insert doctype");
}
}
nsCOMPtr<nsIDOMElement> element;
mDontAddCurrent = PR_FALSE;
if ((mOutputFormat.mMethod == eHTMLOutput) && (aNsID == kNameSpaceID_None)) {
// Outputting HTML as XHTML, lowercase element names
nsAutoString lowerName(aName);
ToLowerCase(lowerName);
rv = mDocument->CreateElementNS(NS_LITERAL_STRING(kXHTMLNameSpaceURI), lowerName,
getter_AddRefs(element));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create element");
rv = mDocument->CreateElement(aName,
getter_AddRefs(element));
if (NS_FAILED(rv)) {
return;
}
startHTMLElement(element);
}
else {
nsAutoString nsURI;
mNameSpaceManager->GetNameSpaceURI(aNsID, nsURI);
rv = mDocument->CreateElementNS(nsURI, aName, getter_AddRefs(element));
rv = mDocument->CreateElementNS(nsURI, aName,
getter_AddRefs(element));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create element");
if (NS_FAILED(rv)) {
return;
}
if (aNsID == kNameSpaceID_XHTML)
startHTMLElement(element);
}
if (element) {
if (mCreatingNewDocument) {
nsCOMPtr<nsIContent> cont = do_QueryInterface(element);
if (cont) {
nsCOMPtr<nsIDocument> doc = do_QueryInterface(mDocument);
cont->SetDocument(doc, PR_FALSE, PR_TRUE);
}
mParentNode = mCurrentNode;
mCurrentNode = do_QueryInterface(element);
NS_ASSERTION(cont, "element doesn't implement nsIContent");
nsCOMPtr<nsIDocument> doc = do_QueryInterface(mDocument);
cont->SetDocument(doc, PR_FALSE, PR_TRUE);
}
mParentNode = mCurrentNode;
mCurrentNode = do_QueryInterface(element);
}
void txMozillaXMLOutput::closePrevious(PRInt8 aAction)
@ -367,11 +363,6 @@ void txMozillaXMLOutput::closePrevious(PRInt8 aAction)
TX_ENSURE_CURRENTNODE;
nsresult rv;
PRInt32 namespaceID = kNameSpaceID_None;
nsCOMPtr<nsIContent> currentContent = do_QueryInterface(mCurrentNode);
if (currentContent)
currentContent->GetNameSpaceID(namespaceID);
if ((aAction & eCloseElement) && mParentNode) {
nsCOMPtr<nsIDocument> document = do_QueryInterface(mParentNode);
nsCOMPtr<nsIDOMElement> currentElement = do_QueryInterface(mCurrentNode);
@ -446,16 +437,18 @@ void txMozillaXMLOutput::startHTMLElement(nsIDOMElement* aElement)
mDontAddCurrent = (atom == txHTMLAtoms::script);
nsCOMPtr<nsIStyleSheetLinkingElement> ssle =
do_QueryInterface(aElement);
if (ssle) {
// XXX Trick nsCSSLoader into blocking/notifying us?
// We would need to implement nsIParser and
// pass ourselves as first parameter to
// InitStyleLinkElement. We would then be notified
// of stylesheet loads/load failures.
ssle->InitStyleLinkElement(nsnull, PR_FALSE);
ssle->SetEnableUpdates(PR_FALSE);
if (mCreatingNewDocument) {
nsCOMPtr<nsIStyleSheetLinkingElement> ssle =
do_QueryInterface(aElement);
if (ssle) {
// XXX Trick nsCSSLoader into blocking/notifying us?
// We would need to implement nsIParser and
// pass ourselves as first parameter to
// InitStyleLinkElement. We would then be notified
// of stylesheet loads/load failures.
ssle->InitStyleLinkElement(nsnull, PR_FALSE);
ssle->SetEnableUpdates(PR_FALSE);
}
}
}
@ -503,7 +496,8 @@ void txMozillaXMLOutput::endHTMLElement(nsIDOMElement* aElement,
}
}
// Load scripts
else if (atom == txHTMLAtoms::script) {
else if (mCreatingNewDocument &&
atom == txHTMLAtoms::script) {
// Add this script element to the array of loading script elements.
nsCOMPtr<nsIDOMHTMLScriptElement> scriptElement =
do_QueryInterface(mCurrentNode);
@ -515,7 +509,8 @@ void txMozillaXMLOutput::endHTMLElement(nsIDOMElement* aElement,
mScriptElements->AppendElement(scriptElement);
}
// Set document title
else if (atom == txHTMLAtoms::title && !mHaveTitleElement) {
else if (mCreatingNewDocument &&
atom == txHTMLAtoms::title && !mHaveTitleElement) {
// The first title wins
mHaveTitleElement = PR_TRUE;
nsCOMPtr<nsIDOMNSDocument> domDoc = do_QueryInterface(mDocument);
@ -528,7 +523,8 @@ void txMozillaXMLOutput::endHTMLElement(nsIDOMElement* aElement,
domDoc->SetTitle(text);
}
}
else if (atom == txHTMLAtoms::base && !mHaveBaseElement) {
else if (mCreatingNewDocument &&
atom == txHTMLAtoms::base && !mHaveBaseElement) {
// The first base wins
mHaveBaseElement = PR_TRUE;
@ -545,7 +541,8 @@ void txMozillaXMLOutput::endHTMLElement(nsIDOMElement* aElement,
return;
doc->SetBaseURL(baseURI); // The document checks if it is legal to set this base
}
else if (atom == txHTMLAtoms::meta) {
else if (mCreatingNewDocument &&
atom == txHTMLAtoms::meta) {
// handle HTTP-EQUIV data
nsAutoString httpEquiv;
content->GetAttr(kNameSpaceID_None, txHTMLAtoms::httpEquiv, httpEquiv);
@ -563,7 +560,7 @@ void txMozillaXMLOutput::endHTMLElement(nsIDOMElement* aElement,
}
// Handle all sorts of stylesheets
if (!mDisableStylesheetLoad) {
if (mCreatingNewDocument) {
nsCOMPtr<nsIStyleSheetLinkingElement> ssle =
do_QueryInterface(aElement);
if (ssle) {
@ -603,3 +600,168 @@ void txMozillaXMLOutput::wrapChildren(nsIDOMNode* aCurrentNode,
}
}
}
nsresult
txMozillaXMLOutput::createResultDocument(const String& aName, PRInt32 aNsID,
nsIDOMDocument* aSourceDocument,
nsIDOMDocument* aResultDocument)
{
nsresult rv;
nsCOMPtr<nsIDocument> doc;
if (!aResultDocument) {
// Create the document
if (mOutputFormat.mMethod == eHTMLOutput) {
doc = do_CreateInstance(kHTMLDocumentCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
}
else {
// We should check the root name/namespace here and create the
// appropriate document
doc = do_CreateInstance(kXMLDocumentCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
}
mDocument = do_QueryInterface(doc);
}
else {
mDocument = aResultDocument;
doc = do_QueryInterface(aResultDocument);
}
mCurrentNode = mDocument;
doc->GetNameSpaceManager(*getter_AddRefs(mNameSpaceManager));
NS_ASSERTION(mNameSpaceManager, "Can't get namespace manager.");
// Reset and set up the document
nsCOMPtr<nsILoadGroup> loadGroup;
nsCOMPtr<nsIChannel> channel;
nsCOMPtr<nsIDocument> sourceDoc = do_QueryInterface(aSourceDocument);
sourceDoc->GetDocumentLoadGroup(getter_AddRefs(loadGroup));
nsCOMPtr<nsIIOService> 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<nsIURI> docURL;
sourceDoc->GetDocumentURL(getter_AddRefs(docURL));
serv->NewChannelFromURI(docURL, getter_AddRefs(channel));
}
doc->Reset(channel, loadGroup);
nsCOMPtr<nsIURI> baseURL;
sourceDoc->GetBaseURL(*getter_AddRefs(baseURL));
doc->SetBaseURL(baseURL);
// XXX We might want to call SetDefaultStylesheets here
// Set up script loader of the result document.
nsCOMPtr<nsIScriptLoader> loader;
doc->GetScriptLoader(getter_AddRefs(loader));
nsCOMPtr<nsITransformObserver> observer = do_QueryReferent(mObserver);
if (loader) {
if (observer) {
loader->AddObserver(this);
}
else {
// Don't load scripts, we can't notify the caller when they're loaded.
loader->SetEnabled(PR_FALSE);
}
}
// Notify the contentsink that the document is created
if (observer) {
observer->OnDocumentCreated(mDocument);
}
// Add a doc-type if requested
if (!mOutputFormat.mSystemId.isEmpty()) {
nsCOMPtr<nsIDOMDOMImplementation> implementation;
rv = aSourceDocument->GetImplementation(getter_AddRefs(implementation));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString qName;
if (mOutputFormat.mMethod == eHTMLOutput) {
qName.Assign(NS_LITERAL_STRING("html"));
}
else {
qName.Assign(aName.getConstNSString());
}
nsCOMPtr<nsIDOMDocumentType> documentType;
rv = implementation->CreateDocumentType(qName,
mOutputFormat.mPublicId,
mOutputFormat.mSystemId,
getter_AddRefs(documentType));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create doctype");
nsCOMPtr<nsIDOMNode> tmp;
mDocument->AppendChild(documentType, getter_AddRefs(tmp));
}
return NS_OK;
}
NS_IMETHODIMP
txMozillaXMLOutput::ScriptAvailable(nsresult aResult,
nsIDOMHTMLScriptElement *aElement,
PRBool aIsInline,
PRBool aWasPending,
nsIURI *aURI,
PRInt32 aLineNo,
const nsAString& aScript)
{
if (NS_FAILED(aResult)) {
removeScriptElement(aElement);
SignalTransformEnd();
}
return NS_OK;
}
NS_IMETHODIMP
txMozillaXMLOutput::ScriptEvaluated(nsresult aResult,
nsIDOMHTMLScriptElement *aElement,
PRBool aIsInline,
PRBool aWasPending)
{
removeScriptElement(aElement);
SignalTransformEnd();
return NS_OK;
}
void
txMozillaXMLOutput::SignalTransformEnd()
{
if (mInTransform) {
return;
}
nsCOMPtr<nsITransformObserver> observer = do_QueryReferent(mObserver);
if (!observer) {
return;
}
if (mScriptElements) {
PRUint32 scriptCount = 0;
mScriptElements->Count(&scriptCount);
if (scriptCount != 0) {
return;
}
}
// Make sure that we don't get deleted while this function is executed and
// we remove ourselfs from the scriptloader
nsCOMPtr<nsIScriptLoaderObserver> kungFuDeathGrip(this);
mObserver = nsnull;
// XXX Need a better way to determine transform success/failure
if (mDocument) {
nsCOMPtr<nsIScriptLoader> loader;
nsCOMPtr<nsIDocument> doc = do_QueryInterface(mDocument);
doc->GetScriptLoader(getter_AddRefs(loader));
if (loader) {
loader->RemoveObserver(this);
}
observer->OnTransformDone(NS_OK, mDocument);
}
else {
// XXX Need better error message and code.
observer->OnTransformDone(NS_ERROR_FAILURE, nsnull);
}
}

View File

@ -44,17 +44,31 @@
#include "nsIDOMDocument.h"
#include "nsIDOMHTMLTextAreaElement.h"
#include "nsINameSpaceManager.h"
#include "nsIScriptLoader.h"
#include "nsIScriptLoaderObserver.h"
#include "nsIStyleSheetLinkingElement.h"
#include "nsString.h"
#include "nsSupportsArray.h"
#include "nsWeakPtr.h"
#include "txOutputFormat.h"
class txMozillaXMLOutput : public txMozillaXMLEventHandler
class txMozillaXMLOutput : public txIOutputXMLEventHandler,
public nsIScriptLoaderObserver
{
public:
txMozillaXMLOutput();
txMozillaXMLOutput(const String& aRootName,
PRInt32 aRootNsID,
txOutputFormat* aFormat,
nsIDOMDocument* aSourceDocument,
nsIDOMDocument* aResultDocument,
nsITransformObserver* aObserver);
txMozillaXMLOutput(txOutputFormat* aFormat,
nsIDOMDocumentFragment* aFragment);
virtual ~txMozillaXMLOutput();
NS_DECL_ISUPPORTS
NS_DECL_NSISCRIPTLOADEROBSERVER
/**
* Signals to receive the start of an attribute.
*
@ -73,6 +87,16 @@ public:
*/
void characters(const String& aData);
/**
* Signals to receive characters that don't need output escaping.
*
* @param aData the characters to receive
*/
void charactersNoOutputEscaping(const String& aData)
{
NS_ASSERTION(0, "Don't call this in module, we don't do d-o-e");
}
/**
* Signals to receive data that should be treated as a comment.
*
@ -95,6 +119,18 @@ public:
void endElement(const String& aName,
const PRInt32 aNsID);
/**
* Returns whether the output handler supports
* disable-output-escaping.
*
* @return MB_TRUE if this handler supports
* disable-output-escaping
*/
MBool hasDisableOutputEscaping()
{
return MB_FALSE;
}
/**
* Signals to receive a processing instruction.
*
@ -118,31 +154,6 @@ public:
void startElement(const String& aName,
const PRInt32 aNsID);
/**
* Sets the output format.
*
* @param aOutputFormat the output format
*/
void setOutputFormat(txOutputFormat* aOutputFormat);
/**
* Disables loading of stylesheets.
*/
void disableStylesheetLoad();
/**
* Returns the root content of the result.
*
* @param aReturn the root content
*/
nsresult getRootContent(nsIContent** aReturn);
/**
* Returns PR_TRUE if the event handler has finished anything
* extra that had to happen after the transform has finished.
*/
PRBool isDone();
/**
* Removes a script element from the array of elements that are
* still loading.
@ -152,11 +163,11 @@ public:
void removeScriptElement(nsIDOMHTMLScriptElement *aElement);
/**
* Sets the Mozilla output document.
* Gets the Mozilla output document
*
* @param aDocument the Mozilla output document
*/
void setOutputDocument(nsIDOMDocument* aDocument);
void getOutputDocument(nsIDOMDocument** aDocument);
private:
void closePrevious(PRInt8 aAction);
@ -164,11 +175,16 @@ private:
void endHTMLElement(nsIDOMElement* aElement, PRBool aXHTML);
void processHTTPEquiv(nsIAtom* aHeader, const nsAString& aValue);
void wrapChildren(nsIDOMNode* aCurrentNode, nsIDOMElement* aWrapper);
nsresult createResultDocument(const String& aName, PRInt32 aNsID,
nsIDOMDocument* aSourceDocument,
nsIDOMDocument* aResultDocument);
void SignalTransformEnd();
nsCOMPtr<nsIDOMDocument> mDocument;
nsCOMPtr<nsIDOMNode> mCurrentNode;
nsCOMPtr<nsIDOMNode> mParentNode;
nsCOMPtr<nsIContent> mRootContent;
nsWeakPtr mObserver;
nsCOMPtr<nsIDOMNode> mNonAddedParent;
nsCOMPtr<nsIDOMNode> mNonAddedNode;
@ -184,12 +200,14 @@ private:
txOutputFormat mOutputFormat;
PRPackedBool mDisableStylesheetLoad;
PRPackedBool mDontAddCurrent;
PRPackedBool mHaveTitleElement;
PRPackedBool mHaveBaseElement;
PRPackedBool mInTransform;
PRPackedBool mCreatingNewDocument;
enum txAction { eCloseElement = 1, eFlushText = 2 };
};

View File

@ -0,0 +1,768 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Peter Van der Beken <peterv@netscape.com> (original author)
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "txMozillaXSLTProcessor.h"
#include "nsContentCID.h"
#include "nsDOMError.h"
#include "nsIContent.h"
#include "nsIDocument.h"
#include "nsIDOMClassInfo.h"
#include "nsIScriptLoader.h"
#include "nsNetUtil.h"
#include "ProcessorState.h"
#include "txMozillaTextOutput.h"
#include "txMozillaXMLOutput.h"
#include "txSingleNodeContext.h"
#include "txURIUtils.h"
#include "XMLUtils.h"
#include "txUnknownHandler.h"
#include "nsIHTMLDocument.h"
/**
* Output Handler Factories
*/
class txToDocHandlerFactory : public txIOutputHandlerFactory
{
public:
txToDocHandlerFactory(ProcessorState* aPs,
nsIDOMDocument* aSourceDocument,
nsIDOMDocument* aResultDocument,
nsITransformObserver* aObserver)
: mPs(aPs), mSourceDocument(aSourceDocument),
mResultDocument(aResultDocument), mObserver(aObserver)
{
}
virtual ~txToDocHandlerFactory()
{
}
TX_DECL_TXIOUTPUTHANDLERFACTORY;
private:
ProcessorState* mPs;
nsCOMPtr<nsIDOMDocument> mSourceDocument;
nsCOMPtr<nsIDOMDocument> mResultDocument;
nsCOMPtr<nsITransformObserver> mObserver;
};
class txToFragmentHandlerFactory : public txIOutputHandlerFactory
{
public:
txToFragmentHandlerFactory(nsIDOMDocumentFragment* aFragment)
: mFragment(aFragment)
{
}
virtual ~txToFragmentHandlerFactory()
{
}
TX_DECL_TXIOUTPUTHANDLERFACTORY;
private:
nsCOMPtr<nsIDOMDocumentFragment> mFragment;
};
nsresult
txToDocHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
txIOutputXMLEventHandler** aHandler)
{
*aHandler = nsnull;
switch (aFormat->mMethod) {
case eMethodNotSet:
case eXMLOutput:
{
*aHandler = new txUnknownHandler(mPs);
break;
}
case eHTMLOutput:
{
*aHandler = new txMozillaXMLOutput(String(), kNameSpaceID_None,
aFormat, mSourceDocument,
mResultDocument, mObserver);
break;
}
case eTextOutput:
{
*aHandler = new txMozillaTextOutput(mSourceDocument,
mResultDocument,
mObserver);
break;
}
}
NS_ENSURE_TRUE(*aHandler, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
nsresult
txToDocHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
const String& aName,
PRInt32 aNsID,
txIOutputXMLEventHandler** aHandler)
{
*aHandler = nsnull;
switch (aFormat->mMethod) {
case eMethodNotSet:
{
NS_ERROR("How can method not be known when root element is?");
return NS_ERROR_UNEXPECTED;
}
case eXMLOutput:
case eHTMLOutput:
{
*aHandler = new txMozillaXMLOutput(aName, aNsID, aFormat,
mSourceDocument,
mResultDocument,
mObserver);
break;
}
case eTextOutput:
{
*aHandler = new txMozillaTextOutput(mSourceDocument,
mResultDocument,
mObserver);
break;
}
}
NS_ENSURE_TRUE(*aHandler, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
nsresult
txToFragmentHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
txIOutputXMLEventHandler** aHandler)
{
*aHandler = nsnull;
switch (aFormat->mMethod) {
case eMethodNotSet:
{
txOutputFormat format;
format.merge(*aFormat);
nsCOMPtr<nsIDOMDocument> doc;
mFragment->GetOwnerDocument(getter_AddRefs(doc));
NS_ASSERTION(doc, "unable to get ownerdocument");
// Need a way for testing xhtml vs. html. But this is the best
// we can do for now.
nsCOMPtr<nsIHTMLDocument> htmldoc = do_QueryInterface(doc);
format.mMethod = htmldoc ? eHTMLOutput : eXMLOutput;
*aHandler = new txMozillaXMLOutput(&format, mFragment);
break;
}
case eXMLOutput:
case eHTMLOutput:
{
*aHandler = new txMozillaXMLOutput(aFormat, mFragment);
break;
}
case eTextOutput:
{
*aHandler = new txMozillaTextOutput(mFragment);
break;
}
}
NS_ENSURE_TRUE(*aHandler, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
nsresult
txToFragmentHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
const String& aName,
PRInt32 aNsID,
txIOutputXMLEventHandler** aHandler)
{
*aHandler = nsnull;
NS_ASSERTION(aFormat->mMethod != eMethodNotSet,
"How can method not be known when root element is?");
NS_ENSURE_TRUE(aFormat->mMethod != eMethodNotSet, NS_ERROR_UNEXPECTED);
return createHandlerWith(aFormat, aHandler);
}
/**
* txMozillaXSLTProcessor
*/
NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
NS_IMPL_ADDREF(txMozillaXSLTProcessor)
NS_IMPL_RELEASE(txMozillaXSLTProcessor)
NS_INTERFACE_MAP_BEGIN(txMozillaXSLTProcessor)
NS_INTERFACE_MAP_ENTRY(nsIXSLTProcessor)
NS_INTERFACE_MAP_ENTRY(nsIXSLTProcessorObsolete)
NS_INTERFACE_MAP_ENTRY(nsIDocumentTransformer)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXSLTProcessor)
NS_INTERFACE_MAP_ENTRY_EXTERNAL_DOM_CLASSINFO(XSLTProcessor)
NS_INTERFACE_MAP_END
txMozillaXSLTProcessor::txMozillaXSLTProcessor() : mVariables(PR_TRUE)
{
NS_INIT_ISUPPORTS();
}
txMozillaXSLTProcessor::~txMozillaXSLTProcessor()
{
}
NS_IMETHODIMP
txMozillaXSLTProcessor::TransformDocument(nsIDOMNode* aSourceDOM,
nsIDOMNode* aStyleDOM,
nsIDOMDocument* aOutputDoc,
nsISupports* aObserver)
{
NS_ENSURE_ARG(aSourceDOM);
NS_ENSURE_ARG(aStyleDOM);
NS_ENSURE_ARG(aOutputDoc);
NS_ENSURE_FALSE(aObserver, NS_ERROR_NOT_IMPLEMENTED);
if (!URIUtils::CanCallerAccess(aSourceDOM) ||
!URIUtils::CanCallerAccess(aStyleDOM) ||
!URIUtils::CanCallerAccess(aOutputDoc)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
// Create wrapper for the source document.
nsCOMPtr<nsIDOMDocument> sourceDOMDocument;
aSourceDOM->GetOwnerDocument(getter_AddRefs(sourceDOMDocument));
if (!sourceDOMDocument) {
sourceDOMDocument = do_QueryInterface(aSourceDOM);
NS_ENSURE_TRUE(sourceDOMDocument, NS_ERROR_FAILURE);
}
Document sourceDocument(sourceDOMDocument);
Node* sourceNode = sourceDocument.createWrapper(aSourceDOM);
NS_ENSURE_TRUE(sourceNode, NS_ERROR_FAILURE);
// Create wrapper for the style document.
nsCOMPtr<nsIDOMDocument> styleDOMDocument;
aStyleDOM->GetOwnerDocument(getter_AddRefs(styleDOMDocument));
if (!styleDOMDocument) {
styleDOMDocument = do_QueryInterface(aStyleDOM);
}
Document xslDocument(styleDOMDocument);
// Create a new ProcessorState. Must be done after creating the documents
// so that C++ will ensure that it is destroyed before the documents.
ProcessorState ps(&sourceDocument, &xslDocument);
// XXX Need to add error observers
// Set current txIEvalContext
txSingleNodeContext evalContext(&sourceDocument, &ps);
ps.setEvalContext(&evalContext);
// Index templates and process top level xslt elements
nsCOMPtr<nsIDOMDocument> styleDoc = do_QueryInterface(aStyleDOM);
nsresult rv;
if (styleDoc) {
rv = txXSLTProcessor::processStylesheet(&xslDocument,
&mVariables, &ps);
}
else {
nsCOMPtr<nsIDOMElement> styleElem = do_QueryInterface(aStyleDOM);
NS_ENSURE_TRUE(styleElem, NS_ERROR_FAILURE);
Element* element = xslDocument.createElement(styleElem);
NS_ENSURE_TRUE(element, NS_ERROR_OUT_OF_MEMORY);
rv = txXSLTProcessor::processTopLevel(element, &mVariables,
&ps);
}
NS_ENSURE_SUCCESS(rv, rv);
txToDocHandlerFactory handlerFactory(&ps, sourceDOMDocument, aOutputDoc,
nsnull);
ps.mOutputHandlerFactory = &handlerFactory;
// Process root of XML source document
txXSLTProcessor::transform(&ps);
return NS_OK;
}
NS_IMETHODIMP
txMozillaXSLTProcessor::TransformDocument(nsIDOMNode* aSourceDOM,
nsIDOMNode* aStyleDOM,
nsITransformObserver* aObserver,
nsIDOMDocument** aOutputDoc)
{
NS_ENSURE_ARG(aSourceDOM);
NS_ENSURE_ARG(aStyleDOM);
NS_ASSERTION(aObserver, "no observer");
NS_ENSURE_ARG_POINTER(aOutputDoc);
// Create wrapper for the source document.
nsCOMPtr<nsIDOMDocument> sourceDOMDocument;
aSourceDOM->GetOwnerDocument(getter_AddRefs(sourceDOMDocument));
if (!sourceDOMDocument) {
sourceDOMDocument = do_QueryInterface(aSourceDOM);
}
NS_ENSURE_TRUE(sourceDOMDocument, NS_ERROR_FAILURE);
Document sourceDocument(sourceDOMDocument);
Node* sourceNode = sourceDocument.createWrapper(aSourceDOM);
NS_ENSURE_TRUE(sourceNode, NS_ERROR_FAILURE);
// Create wrapper for the style document.
nsCOMPtr<nsIDOMDocument> styleDOMDocument;
aStyleDOM->GetOwnerDocument(getter_AddRefs(styleDOMDocument));
if (!styleDOMDocument) {
styleDOMDocument = do_QueryInterface(aStyleDOM);
}
Document xslDocument(styleDOMDocument);
// Create a new ProcessorState. Must be done after creating the documents
// so that C++ will ensure that it is destroyed before the documents.
ProcessorState ps(&sourceDocument, &xslDocument);
// XXX Need to add error observers
// Set current txIEvalContext
txSingleNodeContext evalContext(&sourceDocument, &ps);
ps.setEvalContext(&evalContext);
// Index templates and process top level xslt elements
nsCOMPtr<nsIDOMDocument> styleDoc = do_QueryInterface(aStyleDOM);
nsresult rv;
if (styleDoc) {
rv = txXSLTProcessor::processStylesheet(&xslDocument,
&mVariables, &ps);
}
else {
nsCOMPtr<nsIDOMElement> styleElem = do_QueryInterface(aStyleDOM);
NS_ENSURE_TRUE(styleElem, NS_ERROR_FAILURE);
Element* element = xslDocument.createElement(styleElem);
NS_ENSURE_TRUE(element, NS_ERROR_OUT_OF_MEMORY);
rv = txXSLTProcessor::processTopLevel(element, &mVariables,
&ps);
}
NS_ENSURE_SUCCESS(rv, rv);
txToDocHandlerFactory handlerFactory(&ps, sourceDOMDocument, nsnull,
aObserver);
ps.mOutputHandlerFactory = &handlerFactory;
// Process root of XML source document
txXSLTProcessor::transform(&ps);
ps.mOutputHandler->getOutputDocument(aOutputDoc);
return NS_OK;
}
NS_IMETHODIMP
txMozillaXSLTProcessor::ImportStylesheet(nsIDOMNode *aStyle)
{
if (!URIUtils::CanCallerAccess(aStyle)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if (mStylesheet) {
return NS_ERROR_NOT_IMPLEMENTED;
}
PRUint16 type = 0;
aStyle->GetNodeType(&type);
NS_ENSURE_TRUE(type == nsIDOMNode::ELEMENT_NODE ||
type == nsIDOMNode::DOCUMENT_NODE,
NS_ERROR_INVALID_ARG);
mStylesheet = aStyle;
return NS_OK;
}
NS_IMETHODIMP
txMozillaXSLTProcessor::TransformToDocument(nsIDOMNode *aSource,
nsIDOMDocument **aResult)
{
NS_ENSURE_ARG(aSource);
NS_ENSURE_ARG_POINTER(aResult);
NS_ENSURE_TRUE(mStylesheet, NS_ERROR_NOT_INITIALIZED);
if (!URIUtils::CanCallerAccess(aSource)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
// Create wrapper for the source document.
nsCOMPtr<nsIDOMDocument> sourceDOMDocument;
aSource->GetOwnerDocument(getter_AddRefs(sourceDOMDocument));
if (!sourceDOMDocument) {
sourceDOMDocument = do_QueryInterface(aSource);
}
NS_ENSURE_TRUE(sourceDOMDocument, NS_ERROR_FAILURE);
Document sourceDocument(sourceDOMDocument);
Node* sourceNode = sourceDocument.createWrapper(aSource);
NS_ENSURE_TRUE(sourceNode, NS_ERROR_FAILURE);
// Create wrapper for the style document.
nsCOMPtr<nsIDOMDocument> styleDOMDocument;
mStylesheet->GetOwnerDocument(getter_AddRefs(styleDOMDocument));
if (!styleDOMDocument) {
styleDOMDocument = do_QueryInterface(mStylesheet);
}
Document xslDocument(styleDOMDocument);
// Create a new ProcessorState. Must be done after creating the documents
// so that C++ will ensure that it is destroyed before the documents.
ProcessorState ps(&sourceDocument, &xslDocument);
// XXX Need to add error observers
// Set current txIEvalContext
txSingleNodeContext evalContext(&sourceDocument, &ps);
ps.setEvalContext(&evalContext);
// Index templates and process top level xslt elements
nsCOMPtr<nsIDOMDocument> styleDoc = do_QueryInterface(mStylesheet);
nsresult rv;
if (styleDoc) {
rv = txXSLTProcessor::processStylesheet(&xslDocument,
&mVariables, &ps);
}
else {
nsCOMPtr<nsIDOMElement> styleElem = do_QueryInterface(mStylesheet);
NS_ENSURE_TRUE(styleElem, NS_ERROR_FAILURE);
Element* element = xslDocument.createElement(styleElem);
NS_ENSURE_TRUE(element, NS_ERROR_OUT_OF_MEMORY);
rv = txXSLTProcessor::processTopLevel(element, &mVariables,
&ps);
}
NS_ENSURE_SUCCESS(rv, rv);
txToDocHandlerFactory handlerFactory(&ps, sourceDOMDocument, nsnull,
nsnull);
ps.mOutputHandlerFactory = &handlerFactory;
// Process root of XML source document
txXSLTProcessor::transform(&ps);
ps.mOutputHandler->getOutputDocument(aResult);
return NS_OK;
}
NS_IMETHODIMP
txMozillaXSLTProcessor::TransformToFragment(nsIDOMNode *aSource,
nsIDOMDocument *aOutput,
nsIDOMDocumentFragment **aResult)
{
NS_ENSURE_ARG(aSource);
NS_ENSURE_ARG(aOutput);
NS_ENSURE_ARG_POINTER(aResult);
NS_ENSURE_TRUE(mStylesheet, NS_ERROR_NOT_INITIALIZED);
if (!URIUtils::CanCallerAccess(aSource) ||
!URIUtils::CanCallerAccess(aOutput)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
// Create wrapper for the source document.
nsCOMPtr<nsIDOMDocument> sourceDOMDocument;
aSource->GetOwnerDocument(getter_AddRefs(sourceDOMDocument));
if (!sourceDOMDocument) {
sourceDOMDocument = do_QueryInterface(aSource);
}
NS_ENSURE_TRUE(sourceDOMDocument, NS_ERROR_FAILURE);
Document sourceDocument(sourceDOMDocument);
Node* sourceNode = sourceDocument.createWrapper(aSource);
NS_ENSURE_TRUE(sourceNode, NS_ERROR_FAILURE);
// Create wrapper for the style document.
nsCOMPtr<nsIDOMDocument> styleDOMDocument;
mStylesheet->GetOwnerDocument(getter_AddRefs(styleDOMDocument));
if (!styleDOMDocument) {
styleDOMDocument = do_QueryInterface(mStylesheet);
}
Document xslDocument(styleDOMDocument);
// Create a new ProcessorState. Must be done after creating the documents
// so that C++ will ensure that it is destroyed before the documents.
ProcessorState ps(&sourceDocument, &xslDocument);
// XXX Need to add error observers
// Set current txIEvalContext
txSingleNodeContext evalContext(&sourceDocument, &ps);
ps.setEvalContext(&evalContext);
// Index templates and process top level xslt elements
nsCOMPtr<nsIDOMDocument> styleDoc = do_QueryInterface(mStylesheet);
nsresult rv;
if (styleDoc) {
rv = txXSLTProcessor::processStylesheet(&xslDocument,
&mVariables, &ps);
}
else {
nsCOMPtr<nsIDOMElement> styleElem = do_QueryInterface(mStylesheet);
NS_ENSURE_TRUE(styleElem, NS_ERROR_FAILURE);
Element* element = xslDocument.createElement(styleElem);
NS_ENSURE_TRUE(element, NS_ERROR_OUT_OF_MEMORY);
rv = txXSLTProcessor::processTopLevel(element, &mVariables,
&ps);
}
NS_ENSURE_SUCCESS(rv, rv);
rv = aOutput->CreateDocumentFragment(aResult);
NS_ENSURE_SUCCESS(rv, rv);
txToFragmentHandlerFactory handlerFactory(*aResult);
ps.mOutputHandlerFactory = &handlerFactory;
// Process root of XML source document
txXSLTProcessor::transform(&ps);
return NS_OK;
}
NS_IMETHODIMP
txMozillaXSLTProcessor::SetParameter(const nsAString & aNamespaceURI,
const nsAString & aLocalName,
nsIVariant *aValue)
{
NS_ENSURE_ARG(aValue);
PRUint16 dataType;
aValue->GetDataType(&dataType);
switch (dataType) {
// Number
case nsIDataType::VTYPE_INT8:
case nsIDataType::VTYPE_INT16:
case nsIDataType::VTYPE_INT32:
case nsIDataType::VTYPE_INT64:
case nsIDataType::VTYPE_UINT8:
case nsIDataType::VTYPE_UINT16:
case nsIDataType::VTYPE_UINT32:
case nsIDataType::VTYPE_UINT64:
case nsIDataType::VTYPE_FLOAT:
case nsIDataType::VTYPE_DOUBLE:
// Boolean
case nsIDataType::VTYPE_BOOL:
// String
case nsIDataType::VTYPE_CHAR:
case nsIDataType::VTYPE_WCHAR:
case nsIDataType::VTYPE_DOMSTRING:
case nsIDataType::VTYPE_CHAR_STR:
case nsIDataType::VTYPE_WCHAR_STR:
case nsIDataType::VTYPE_STRING_SIZE_IS:
case nsIDataType::VTYPE_WSTRING_SIZE_IS:
case nsIDataType::VTYPE_UTF8STRING:
case nsIDataType::VTYPE_CSTRING:
case nsIDataType::VTYPE_ASTRING:
// Nodeset
case nsIDataType::VTYPE_INTERFACE:
case nsIDataType::VTYPE_INTERFACE_IS:
case nsIDataType::VTYPE_ARRAY:
{
// This might still be an error, but we'll only
// find out later since we lazily evaluate.
break;
}
default:
{
return NS_ERROR_FAILURE;
}
}
nsresult rv;
nsCOMPtr<nsINameSpaceManager> namespaceManager =
do_GetService(kNameSpaceManagerCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 nsId = kNameSpaceID_Unknown;
rv = namespaceManager->RegisterNameSpace(aNamespaceURI, nsId);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIAtom> localName = do_GetAtom(aLocalName);
txExpandedName varName(nsId, localName);
txVariable* var = (txVariable*)mVariables.get(varName);
if (var) {
var->setValue(aValue);
return NS_OK;
}
var = new txVariable(aValue);
NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
return mVariables.add(varName, var);
}
NS_IMETHODIMP
txMozillaXSLTProcessor::GetParameter(const nsAString& aNamespaceURI,
const nsAString& aLocalName,
nsIVariant **aResult)
{
nsresult rv;
nsCOMPtr<nsINameSpaceManager> namespaceManager =
do_GetService(kNameSpaceManagerCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 nsId = kNameSpaceID_Unknown;
rv = namespaceManager->RegisterNameSpace(aNamespaceURI, nsId);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIAtom> localName = do_GetAtom(aLocalName);
txExpandedName varName(nsId, localName);
txVariable* var = (txVariable*)mVariables.get(varName);
if (var) {
return var->getValue(aResult);
}
return NS_OK;
}
NS_IMETHODIMP
txMozillaXSLTProcessor::RemoveParameter(const nsAString& aNamespaceURI,
const nsAString& aLocalName)
{
nsresult rv;
nsCOMPtr<nsINameSpaceManager> namespaceManager =
do_GetService(kNameSpaceManagerCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 nsId = kNameSpaceID_Unknown;
rv = namespaceManager->RegisterNameSpace(aNamespaceURI, nsId);
nsCOMPtr<nsIAtom> localName = do_GetAtom(aLocalName);
txExpandedName varName(nsId, localName);
mVariables.remove(varName);
return NS_OK;
}
NS_IMETHODIMP
txMozillaXSLTProcessor::ClearParameters()
{
mVariables.clear();
return NS_OK;
}
/* static*/
nsresult
txVariable::Convert(nsIVariant *aValue, ExprResult** aResult)
{
*aResult = nsnull;
PRUint16 dataType;
aValue->GetDataType(&dataType);
switch (dataType) {
// Number
case nsIDataType::VTYPE_INT8:
case nsIDataType::VTYPE_INT16:
case nsIDataType::VTYPE_INT32:
case nsIDataType::VTYPE_INT64:
case nsIDataType::VTYPE_UINT8:
case nsIDataType::VTYPE_UINT16:
case nsIDataType::VTYPE_UINT32:
case nsIDataType::VTYPE_UINT64:
case nsIDataType::VTYPE_FLOAT:
case nsIDataType::VTYPE_DOUBLE:
{
double value;
nsresult rv = aValue->GetAsDouble(&value);
NS_ENSURE_SUCCESS(rv, rv);
*aResult = new NumberResult(value);
NS_ENSURE_TRUE(aResult, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
// Boolean
case nsIDataType::VTYPE_BOOL:
{
PRBool value;
nsresult rv = aValue->GetAsBool(&value);
NS_ENSURE_SUCCESS(rv, rv);
*aResult = new BooleanResult(value);
NS_ENSURE_TRUE(aResult, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
// String
case nsIDataType::VTYPE_CHAR:
case nsIDataType::VTYPE_WCHAR:
case nsIDataType::VTYPE_DOMSTRING:
case nsIDataType::VTYPE_CHAR_STR:
case nsIDataType::VTYPE_WCHAR_STR:
case nsIDataType::VTYPE_STRING_SIZE_IS:
case nsIDataType::VTYPE_WSTRING_SIZE_IS:
case nsIDataType::VTYPE_UTF8STRING:
case nsIDataType::VTYPE_CSTRING:
case nsIDataType::VTYPE_ASTRING:
{
String value;
nsresult rv = aValue->GetAsAString(value);
NS_ENSURE_SUCCESS(rv, rv);
*aResult = new StringResult(value);
NS_ENSURE_TRUE(aResult, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
// Nodeset
case nsIDataType::VTYPE_INTERFACE:
case nsIDataType::VTYPE_INTERFACE_IS:
{
nsID *iid;
nsCOMPtr<nsISupports> supports;
nsresult rv = aValue->GetAsInterface(&iid, getter_AddRefs(supports));
NS_ENSURE_SUCCESS(rv, rv);
if (iid) {
// XXX Figure out what the user added and if we can do
// anything with it.
// nsIDOMNode, nsIDOMNodeList, nsIDOMXPathResult
nsMemory::Free(iid);
}
break;
}
case nsIDataType::VTYPE_ARRAY:
{
// XXX Figure out what the user added and if we can do
// anything with it. Array of Nodes.
break;
}
}
return NS_ERROR_ILLEGAL_VALUE;
}

View File

@ -0,0 +1,147 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Peter Van der Beken <peterv@netscape.com> (original author)
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef TRANSFRMX_TXMOZILLAXSLTPROCESSOR_H
#define TRANSFRMX_TXMOZILLAXSLTPROCESSOR_H
#include "ExprResult.h"
#include "nsIDocumentTransformer.h"
#include "nsIVariant.h"
#include "nsIXSLTProcessor.h"
#include "nsVoidArray.h"
#include "nsWeakPtr.h"
#include "txExpandedNameMap.h"
#include "XSLTProcessor.h"
#include "nsIDOMNode.h"
#include "txXMLEventHandler.h"
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentFragment.h"
#include "nsIXSLTProcessorObsolete.h"
/* bacd8ad0-552f-11d3-a9f7-000064657374 */
#define TRANSFORMIIX_XSLT_PROCESSOR_CID \
{ 0xbacd8ad0, 0x552f, 0x11d3, {0xa9, 0xf7, 0x00, 0x00, 0x64, 0x65, 0x73, 0x74} }
#define TRANSFORMIIX_XSLT_PROCESSOR_CONTRACTID \
"@mozilla.org/document-transformer;1?type=text/xsl"
class txVariable : public txIGlobalParameter
{
public:
txVariable(nsIVariant *aValue) : mValue(aValue),
mTxValue(nsnull)
{
}
~txVariable()
{
delete mTxValue;
}
nsresult getValue(ExprResult** aValue)
{
NS_ASSERTION(mValue, "variablevalue is null");
if (!mTxValue) {
nsresult rv = Convert(mValue, &mTxValue);
NS_ENSURE_SUCCESS(rv, rv);
}
*aValue = mTxValue;
return NS_OK;
}
nsresult getValue(nsIVariant** aValue)
{
*aValue = mValue;
NS_ADDREF(*aValue);
return NS_OK;
}
void setValue(nsIVariant* aValue)
{
NS_ASSERTION(aValue, "setting variablevalue to null");
mValue = aValue;
delete mTxValue;
mTxValue = nsnull;
}
private:
static nsresult Convert(nsIVariant *aValue, ExprResult** aResult);
nsCOMPtr<nsIVariant> mValue;
ExprResult* mTxValue;
};
/**
* txMozillaXSLTProcessor is a front-end to the XSLT Processor.
*/
class txMozillaXSLTProcessor : public nsIXSLTProcessor,
public nsIXSLTProcessorObsolete,
public nsIDocumentTransformer
{
public:
/**
* Creates a new txMozillaXSLTProcessor
*/
txMozillaXSLTProcessor();
/**
* Default destructor for txMozillaXSLTProcessor
*/
virtual ~txMozillaXSLTProcessor();
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIXSLTProcessor interface
NS_DECL_NSIXSLTPROCESSOR
// nsIXSLTProcessorObsolete interface
NS_DECL_NSIXSLTPROCESSOROBSOLETE
// nsIDocumentTransformer interface
NS_IMETHOD TransformDocument(nsIDOMNode *aSourceDOM,
nsIDOMNode *aStyleDOM,
nsITransformObserver *aObserver,
nsIDOMDocument **_retval);
protected:
nsCOMPtr<nsIDOMNode> mStylesheet;
txExpandedNameMap mVariables;
};
#endif

View File

@ -0,0 +1,359 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Peter Van der Beken <peterv@netscape.com> (original author)
* Axel Hecht <axel@pike.org>
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "txStandaloneXSLTProcessor.h"
#include "txURIUtils.h"
#include "XMLParser.h"
#include "txSingleNodeContext.h"
#include "Names.h"
#include "txUnknownHandler.h"
#include "txHTMLOutput.h"
#include "txTextOutput.h"
/**
* Output Handler Factory
*/
class txStandaloneHandlerFactory : public txIOutputHandlerFactory
{
public:
txStandaloneHandlerFactory(ProcessorState* aPs,
ostream* aStream)
: mPs(aPs), mStream(aStream)
{
}
virtual ~txStandaloneHandlerFactory()
{
};
TX_DECL_TXIOUTPUTHANDLERFACTORY;
private:
ProcessorState* mPs;
ostream* mStream;
};
nsresult
txStandaloneHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
txIOutputXMLEventHandler** aHandler)
{
*aHandler = 0;
switch (aFormat->mMethod) {
case eXMLOutput:
*aHandler = new txXMLOutput(aFormat, mStream);
break;
case eHTMLOutput:
*aHandler = new txHTMLOutput(aFormat, mStream);
break;
case eTextOutput:
*aHandler = new txTextOutput(mStream);
break;
case eMethodNotSet:
*aHandler = new txUnknownHandler(mPs);
break;
}
NS_ENSURE_TRUE(*aHandler, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
nsresult
txStandaloneHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
const String& aName,
PRInt32 aNsID,
txIOutputXMLEventHandler** aHandler)
{
*aHandler = 0;
NS_ASSERTION(aFormat->mMethod != eMethodNotSet,
"How can method not be known when root element is?");
NS_ENSURE_TRUE(aFormat->mMethod != eMethodNotSet, NS_ERROR_UNEXPECTED);
return createHandlerWith(aFormat, aHandler);
}
/**
* txStandaloneXSLTProcessor
*/
/**
* Transform a XML document given by path.
* The stylesheet is retrieved by a processing instruction,
* or an error is returned.
*/
nsresult
txStandaloneXSLTProcessor::transform(String& aXMLPath, ostream& aOut,
ErrorObserver& aErr)
{
Document* xmlDoc = parsePath(aXMLPath, aErr);
if (!xmlDoc) {
return NS_ERROR_FAILURE;
}
// transform
nsresult rv = transform(xmlDoc, aOut, aErr);
delete xmlDoc;
return rv;
}
/**
* Transform a XML document given by path with the given
* stylesheet.
*/
nsresult
txStandaloneXSLTProcessor::transform(String& aXMLPath, String& aXSLPath,
ostream& aOut, ErrorObserver& aErr)
{
Document* xmlDoc = parsePath(aXMLPath, aErr);
if (!xmlDoc) {
return NS_ERROR_FAILURE;
}
Document* xslDoc = parsePath(aXSLPath, aErr);
if (!xslDoc) {
delete xmlDoc;
return NS_ERROR_FAILURE;
}
// transform
nsresult rv = transform(xmlDoc, xslDoc, aOut, aErr);
delete xmlDoc;
delete xslDoc;
return rv;
}
/**
* Transform a XML document.
* The stylesheet is retrieved by a processing instruction,
* or an error is returned.
*/
nsresult
txStandaloneXSLTProcessor::transform(Document* aXMLDoc, ostream& aOut,
ErrorObserver& aErr)
{
if (!aXMLDoc) {
return NS_ERROR_INVALID_POINTER;
}
// get stylesheet path
String stylePath;
getHrefFromStylesheetPI(*aXMLDoc, stylePath);
Document* xslDoc = parsePath(stylePath, aErr);
if (!xslDoc) {
return NS_ERROR_FAILURE;
}
// transform
nsresult rv = transform(aXMLDoc, xslDoc, aOut, aErr);
delete xslDoc;
return rv;
}
/**
* Processes the given XML Document using the given XSL document
* and prints the results to the given ostream argument
*/
nsresult
txStandaloneXSLTProcessor::transform(Document* aSource, Node* aStylesheet,
ostream& aOut, ErrorObserver& aErr)
{
// Create a new ProcessorState
Document* stylesheetDoc = 0;
Element* stylesheetElem = 0;
if (aStylesheet->getNodeType() == Node::DOCUMENT_NODE) {
stylesheetDoc = (Document*)aStylesheet;
}
else {
stylesheetElem = (Element*)aStylesheet;
stylesheetDoc = aStylesheet->getOwnerDocument();
}
ProcessorState ps(aSource, stylesheetDoc);
ps.addErrorObserver(aErr);
txSingleNodeContext evalContext(aSource, &ps);
ps.setEvalContext(&evalContext);
// Index templates and process top level xsl elements
nsresult rv = NS_OK;
if (stylesheetElem) {
rv = processTopLevel(stylesheetElem, 0, &ps);
}
else {
rv = processStylesheet(stylesheetDoc, 0, &ps);
}
if (NS_FAILED(rv)) {
return rv;
}
txStandaloneHandlerFactory handlerFactory(&ps, &aOut);
ps.mOutputHandlerFactory = &handlerFactory;
#ifndef XP_WIN
bool sync = aOut.sync_with_stdio(false);
#endif
// Process root of XML source document
txXSLTProcessor::transform(&ps);
#ifndef XP_WIN
aOut.sync_with_stdio(sync);
#endif
return NS_OK;
}
/**
* Parses all XML Stylesheet PIs associated with the
* given XML document. If any stylesheet PIs are found with
* type="text/xsl" the href psuedo attribute value will be
* added to the given href argument. If multiple text/xsl stylesheet PIs
* are found, the one closest to the end of the document is used.
*/
void txStandaloneXSLTProcessor::getHrefFromStylesheetPI(Document& xmlDocument,
String& href)
{
Node* node = xmlDocument.getFirstChild();
String type;
String tmpHref;
while (node) {
if (node->getNodeType() == Node::PROCESSING_INSTRUCTION_NODE) {
String target = ((ProcessingInstruction*)node)->getTarget();
if (STYLESHEET_PI.isEqual(target) ||
STYLESHEET_PI_OLD.isEqual(target)) {
String data = ((ProcessingInstruction*)node)->getData();
type.clear();
tmpHref.clear();
parseStylesheetPI(data, type, tmpHref);
if (XSL_MIME_TYPE.isEqual(type)) {
href.clear();
URIUtils::resolveHref(tmpHref, node->getBaseURI(), href);
}
}
}
node = node->getNextSibling();
}
}
/**
* Parses the contents of data, and returns the type and href pseudo attributes
*/
void txStandaloneXSLTProcessor::parseStylesheetPI(String& data,
String& type,
String& href)
{
PRUint32 size = data.length();
NamedMap bufferMap;
bufferMap.put(String("type"), &type);
bufferMap.put(String("href"), &href);
PRUint32 ccount = 0;
MBool inLiteral = MB_FALSE;
char matchQuote = '"';
String sink;
String* buffer = &sink;
for (ccount = 0; ccount < size; ccount++) {
char ch = data.charAt(ccount);
switch ( ch ) {
case ' ':
if (inLiteral) {
buffer->append(ch);
}
break;
case '=':
if (inLiteral) {
buffer->append(ch);
}
else if (buffer->length() > 0) {
buffer = (String*)bufferMap.get(*buffer);
if (!buffer) {
sink.clear();
buffer = &sink;
}
}
break;
case '"':
case '\'':
if (inLiteral) {
if (matchQuote == ch) {
inLiteral = MB_FALSE;
sink.clear();
buffer = &sink;
}
else {
buffer->append(ch);
}
}
else {
inLiteral = MB_TRUE;
matchQuote = ch;
}
break;
default:
buffer->append(ch);
break;
}
}
}
Document*
txStandaloneXSLTProcessor::parsePath(const String& aPath, ErrorObserver& aErr)
{
ifstream xmlInput(NS_LossyConvertUCS2toASCII(aPath).get(), ios::in);
if (!xmlInput) {
String err("Couldn't open ");
err.append(aPath);
aErr.receiveError(err);
return 0;
}
// parse source
XMLParser xmlParser;
Document* xmlDoc = xmlParser.parse(xmlInput, aPath);
if (!xmlDoc) {
String err("Parsing error in ");
err.append(aPath);
aErr.receiveError(err);
}
return xmlDoc;
}

View File

@ -0,0 +1,162 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Peter Van der Beken <peterv@netscape.com> (original author)
* Axel Hecht <axel@pike.org>
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef TRANSFRMX_TXSTANDALONEXSLTPROCESSOR_H
#define TRANSFRMX_TXSTANDALONEXSLTPROCESSOR_H
#include "XSLTProcessor.h"
#ifndef __BORLANDC__
#include <iostream.h>
#include <fstream.h>
#endif
class txStreamXMLEventHandler;
/**
* txStandaloneXSLTProcessor
*
* Use of the standalone TransforMiiX API:
*
* The XSLT Processor need initialisation and shutdown
* by
* txStandaloneXSLTProcessor::Init();
* and
* txStandaloneXSLTProcessor::Shutdown();
* Be sure to always call these functions in pairs.
*
* The API to transform documents consists of entry points
* to transform either one or two documents.
* If you provide one document, the stylesheet location is
* computed from the processing instruction. If that cannot
* be found, an error is issued.
*
* The result is output to a stream.
*
* Documents can be provided either by path or by DOM Document.
*
* Stylesheet parameters
* XXX TODO
*
*/
class txStandaloneXSLTProcessor : public txXSLTProcessor
{
public:
/**
* Methods that print the result to a stream
*/
/**
* Transform a XML document given by path.
* The stylesheet is retrieved by a processing instruction,
* or an error is returned.
*
* @param aXMLPath path to the source document
* @param aOut stream to which the result is feeded
* @param aErr error observer
* @result NS_OK if transformation was successful
*/
nsresult transform(String& aXMLPath, ostream& aOut, ErrorObserver& aErr);
/**
* Transform a XML document given by path with the given
* stylesheet.
*
* @param aXMLPath path to the source document
* @param aXSLPath path to the style document
* @param aOut stream to which the result is feeded
* @param aErr error observer
* @result NS_OK if transformation was successful
*/
nsresult transform(String& aXMLPath, String& aXSLPath, ostream& aOut,
ErrorObserver& aErr);
/**
* Transform a XML document.
* The stylesheet is retrieved by a processing instruction,
* or an error is returned.
*
* @param aXMLDoc source document
* @param aOut stream to which the result is feeded
* @param aErr error observer
* @result NS_OK if transformation was successful
*/
nsresult transform(Document* aXMLDoc, ostream& aOut, ErrorObserver& aErr);
/**
* Transform a XML document with the given stylesheet.
*
* @param aXMLDoc source document
* @param aXSLNode style node
* @param aOut stream to which the result is feeded
* @param aErr error observer
* @result NS_OK if transformation was successful
*/
nsresult transform(Document* aXMLDoc, Node* aXSLNode,
ostream& aOut, ErrorObserver& aErr);
protected:
/**
* Parses all XML Stylesheet PIs associated with the
* given XML document. If any stylesheet PIs are found with
* type="text/xsl" the href psuedo attribute value will be
* added to the given href argument. If multiple text/xsl stylesheet PIs
* are found, the one closest to the end of the document is used.
*/
static void getHrefFromStylesheetPI(Document& xmlDocument, String& href);
/**
* Parses the contents of data, returns the type and href psuedo attributes
*/
static void parseStylesheetPI(String& data,
String& type,
String& href);
/**
* Create a Document from a path.
*
* @param aPath path to the xml file
* @param aErr ErrorObserver
* @result Document XML Document, or null on error
*/
static Document* parsePath(const String& aPath, ErrorObserver& aErr);
};
#endif

View File

@ -39,7 +39,8 @@
#include "txTextOutput.h"
#include "TxString.h"
txTextOutput::txTextOutput()
txTextOutput::txTextOutput(ostream* aOut)
: mOut(aOut)
{
}
@ -89,21 +90,3 @@ void txTextOutput::startElement(const String& aName,
const PRInt32 aNsID)
{
}
void txTextOutput::getOutputStream(ostream** aOutputStream)
{
if (aOutputStream)
*aOutputStream = mOut;
}
void txTextOutput::setOutputStream(ostream* aOutputStream)
{
mOut = aOutputStream;
}
void txTextOutput::setOutputFormat(txOutputFormat* aOutputFormat)
{
mOutputFormat.reset();
mOutputFormat.merge(*aOutputFormat);
mOutputFormat.setFromDefaults();
}

View File

@ -42,10 +42,10 @@
#include "txXMLEventHandler.h"
#include "txOutputFormat.h"
class txTextOutput : public txStreamXMLEventHandler
class txTextOutput : public txIOutputXMLEventHandler
{
public:
txTextOutput();
txTextOutput(ostream* aOut);
~txTextOutput();
/*
@ -95,6 +95,18 @@ public:
void endElement(const String& aName,
const PRInt32 aNsID);
/**
* Returns whether the output handler supports
* disable-output-escaping.
*
* @return MB_TRUE if this handler supports
* disable-output-escaping
*/
MBool hasDisableOutputEscaping()
{
return MB_TRUE;
}
/*
* Signals to receive a processing instruction.
*
@ -118,30 +130,8 @@ public:
void startElement(const String& aName,
const PRInt32 aNsID);
/*
* Sets the output format.
*
* @param aOutputFormat the output format
*/
void setOutputFormat(txOutputFormat* aOutputFormat);
/**
* Get the output stream.
*
* @param aOutputStream the current output stream
*/
void getOutputStream(ostream** aOutputStream);
/**
* Sets the output stream.
*
* @param aDocument the Mozilla output document
*/
void setOutputStream(ostream* aOutputStream);
private:
ostream* mOut;
txOutputFormat mOutputFormat;
};
#endif

View File

@ -38,12 +38,22 @@
#include "txUnknownHandler.h"
#include <string.h>
#include "ProcessorState.h"
#ifndef TX_EXE
NS_IMPL_ISUPPORTS1(txUnknownHandler, txIOutputXMLEventHandler);
#endif
PRUint32 txUnknownHandler::kReasonableTransactions = 8;
txUnknownHandler::txUnknownHandler() : mTotal(0),
mMax(kReasonableTransactions)
txUnknownHandler::txUnknownHandler(ProcessorState* aPs)
: mTotal(0), mMax(kReasonableTransactions),
mPs(aPs)
{
#ifndef TX_EXE
NS_INIT_ISUPPORTS();
#endif
mArray = new txOutputTransaction*[kReasonableTransactions];
}
@ -60,7 +70,9 @@ void txUnknownHandler::attribute(const String& aName,
const PRInt32 aNsID,
const String& aValue)
{
NS_ASSERTION(0, "This shouldn't be called")
// If this is called then the stylesheet is trying to add an attribute
// without adding an element first. So we'll just ignore it.
// XXX ErrorReport: Signal this?
}
void txUnknownHandler::characters(const String& aData)
@ -69,7 +81,7 @@ void txUnknownHandler::characters(const String& aData)
new txOneStringTransaction(txOutputTransaction::eCharacterTransaction,
aData);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!")
NS_ASSERTION(0, "Out of memory!");
return;
}
addTransaction(transaction);
@ -81,7 +93,7 @@ void txUnknownHandler::charactersNoOutputEscaping(const String& aData)
new txOneStringTransaction(txOutputTransaction::eCharacterNoOETransaction,
aData);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!")
NS_ASSERTION(0, "Out of memory!");
return;
}
addTransaction(transaction);
@ -93,7 +105,7 @@ void txUnknownHandler::comment(const String& aData)
new txOneStringTransaction(txOutputTransaction::eCommentTransaction,
aData);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!")
NS_ASSERTION(0, "Out of memory!");
return;
}
addTransaction(transaction);
@ -101,19 +113,32 @@ void txUnknownHandler::comment(const String& aData)
void txUnknownHandler::endDocument()
{
txOutputTransaction* transaction =
new txOutputTransaction(txOutputTransaction::eEndDocumentTransaction);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!")
// This is an unusual case, no output method has been set and we
// didn't create a document element. Switching to XML output mode
// anyway.
#ifndef TX_EXE
// Make sure that we don't get deleted while this function is executed and
// we set a new outputhandler
nsCOMPtr<txIOutputXMLEventHandler> kungFuDeathGrip(this);
#endif
nsresult rv = createHandlerAndFlush(eXMLOutput, String(),
kNameSpaceID_None);
if (NS_FAILED(rv))
return;
}
addTransaction(transaction);
mPs->mResultHandler->endDocument();
// in module the outputhandler is refcounted
#ifdef TX_EXE
delete this;
#endif
}
void txUnknownHandler::endElement(const String& aName,
const PRInt32 aNsID)
{
NS_ASSERTION(0, "This shouldn't be called")
NS_ASSERTION(0, "This shouldn't be called");
}
void txUnknownHandler::processingInstruction(const String& aTarget,
@ -123,7 +148,7 @@ void txUnknownHandler::processingInstruction(const String& aTarget,
new txTwoStringTransaction(txOutputTransaction::ePITransaction,
aTarget, aData);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!")
NS_ASSERTION(0, "Out of memory!");
return;
}
addTransaction(transaction);
@ -134,7 +159,7 @@ void txUnknownHandler::startDocument()
txOutputTransaction* transaction =
new txOutputTransaction(txOutputTransaction::eStartDocumentTransaction);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!")
NS_ASSERTION(0, "Out of memory!");
return;
}
addTransaction(transaction);
@ -143,74 +168,108 @@ void txUnknownHandler::startDocument()
void txUnknownHandler::startElement(const String& aName,
const PRInt32 aNsID)
{
NS_ASSERTION(0, "This shouldn't be called")
}
#ifndef TX_EXE
// Make sure that we don't get deleted while this function is executed and
// we set a new outputhandler
nsCOMPtr<txIOutputXMLEventHandler> kungFuDeathGrip(this);
#endif
void txUnknownHandler::setOutputFormat(txOutputFormat* aOutputFormat)
{
}
void txUnknownHandler::getOutputStream(ostream** aOutputStream)
{
if (aOutputStream) {
*aOutputStream = mOut;
nsresult rv = NS_OK;
txOutputFormat* format = mPs->getOutputFormat();
if (format->mMethod != eMethodNotSet) {
rv = createHandlerAndFlush(format->mMethod, aName, aNsID);
}
else if (aNsID == kNameSpaceID_None &&
aName.isEqualIgnoreCase(String("html"))) {
rv = createHandlerAndFlush(eHTMLOutput, aName, aNsID);
}
else {
rv = createHandlerAndFlush(eXMLOutput, aName, aNsID);
}
if (NS_FAILED(rv))
return;
mPs->mResultHandler->startElement(aName, aNsID);
// in module the outputhandler is refcounted
#ifdef TX_EXE
delete this;
#endif
}
void txUnknownHandler::setOutputStream(ostream* aOutputStream)
#ifndef TX_EXE
void txUnknownHandler::getOutputDocument(nsIDOMDocument** aDocument)
{
mOut = aOutputStream;
*aDocument = nsnull;
}
#endif
void txUnknownHandler::flush(txStreamXMLEventHandler* aHandler)
nsresult txUnknownHandler::createHandlerAndFlush(txOutputMethod aMethod,
const String& aName,
const PRInt32 aNsID)
{
nsresult rv = NS_OK;
txOutputFormat* format = mPs->getOutputFormat();
format->mMethod = aMethod;
txIOutputXMLEventHandler* handler = 0;
rv = mPs->mOutputHandlerFactory->createHandlerWith(format, aName, aNsID,
&handler);
NS_ENSURE_SUCCESS(rv, rv);
mPs->mOutputHandler = handler;
mPs->mResultHandler = handler;
MBool hasDOE = handler->hasDisableOutputEscaping();
PRUint32 counter;
for (counter = 0; counter < mTotal; ++counter) {
switch (mArray[counter]->mType) {
case txOutputTransaction::eCharacterTransaction:
{
txOneStringTransaction* transaction = (txOneStringTransaction*)mArray[counter];
aHandler->characters(transaction->mString);
handler->characters(transaction->mString);
delete transaction;
break;
}
case txOutputTransaction::eCharacterNoOETransaction:
{
txOneStringTransaction* transaction = (txOneStringTransaction*)mArray[counter];
aHandler->charactersNoOutputEscaping(transaction->mString);
if (hasDOE) {
handler->charactersNoOutputEscaping(transaction->mString);
}
else {
handler->characters(transaction->mString);
}
delete transaction;
break;
}
case txOutputTransaction::eCommentTransaction:
{
txOneStringTransaction* transaction = (txOneStringTransaction*)mArray[counter];
aHandler->comment(transaction->mString);
handler->comment(transaction->mString);
delete transaction;
break;
}
case txOutputTransaction::eEndDocumentTransaction:
{
aHandler->endDocument();
delete mArray[counter];
break;
}
case txOutputTransaction::ePITransaction:
{
txTwoStringTransaction* transaction = (txTwoStringTransaction*)mArray[counter];
aHandler->processingInstruction(transaction->mStringOne,
handler->processingInstruction(transaction->mStringOne,
transaction->mStringTwo);
delete transaction;
break;
}
case txOutputTransaction::eStartDocumentTransaction:
{
aHandler->startDocument();
handler->startDocument();
delete mArray[counter];
break;
}
}
}
mTotal = 0;
return NS_OK;
}
void txUnknownHandler::addTransaction(txOutputTransaction* aTransaction)
@ -219,7 +278,7 @@ void txUnknownHandler::addTransaction(txOutputTransaction* aTransaction)
PRUint32 newMax = mMax * 2;
txOutputTransaction** newArray = new txOutputTransaction*[newMax];
if (!newArray) {
NS_ASSERTION(0, "Out of memory!")
NS_ASSERTION(0, "Out of memory!");
return;
}
mMax = newMax;

View File

@ -41,6 +41,9 @@
#include "txXMLEventHandler.h"
#include "TxString.h"
#include "txOutputFormat.h"
class ProcessorState;
class txOutputTransaction
{
@ -49,7 +52,6 @@ public:
eCharacterTransaction,
eCharacterNoOETransaction,
eCommentTransaction,
eEndDocumentTransaction,
ePITransaction,
eStartDocumentTransaction
};
@ -90,12 +92,16 @@ public:
String mStringTwo;
};
class txUnknownHandler : public txStreamXMLEventHandler
class txUnknownHandler : public txIOutputXMLEventHandler
{
public:
txUnknownHandler();
txUnknownHandler(ProcessorState* aPs);
virtual ~txUnknownHandler();
#ifndef TX_EXE
NS_DECL_ISUPPORTS
#endif
/*
* Signals to receive the start of an attribute.
*
@ -143,6 +149,18 @@ public:
void endElement(const String& aName,
const PRInt32 aNsID);
/**
* Returns whether the output handler supports
* disable-output-escaping.
*
* @return MB_TRUE if this handler supports
* disable-output-escaping
*/
MBool hasDisableOutputEscaping()
{
return MB_TRUE;
}
/*
* Signals to receive a processing instruction.
*
@ -165,34 +183,29 @@ public:
*/
void startElement(const String& aName,
const PRInt32 aNsID);
/*
* Sets the output format.
*
* @param aOutputFormat the output format
*/
void setOutputFormat(txOutputFormat* aOutputFormat);
#ifndef TX_EXE
/**
* Get the output stream.
* Gets the Mozilla output document
*
* @param aOutputStream the current output stream
* @param aDocument the Mozilla output document
*/
void getOutputStream(ostream** aOutputStream);
/*
* Sets the output stream.
*
* @param aOutputStream the output stream
*/
void setOutputStream(ostream* aOutputStream);
void flush(txStreamXMLEventHandler* aHandler);
void getOutputDocument(nsIDOMDocument** aDocument);
#endif
private:
nsresult createHandlerAndFlush(txOutputMethod aMethod,
const String& aName,
const PRInt32 aNsID);
void addTransaction(txOutputTransaction* aTransaction);
PRUint32 mTotal, mMax;
ostream* mOut;
/*
* XXX we shouldn't hold to the ProcessorState, as we're supposed
* to live without it. But as a standalone handler, we don't.
* The right fix may need a txOutputFormat here.
*/
ProcessorState* mPs;
txOutputTransaction** mArray;
static PRUint32 kReasonableTransactions;

View File

@ -25,14 +25,20 @@
#define TRANSFRMX_XML_EVENT_HANDLER_H
#include "baseutils.h"
#include "txError.h"
class String;
class txOutputFormat;
#ifdef TX_EXE
#include <iostream.h>
#else
#include "nsISupports.h"
#define kTXNameSpaceURI "http://www.mozilla.org/TransforMiix"
#define kTXWrapper "transformiix:result"
class nsIContent;
class nsIDOMDocument;
class nsIDOMHTMLScriptElement;
class nsITransformObserver;
#endif
/**
@ -109,79 +115,84 @@ public:
const PRInt32 aNsID) = 0;
};
class txOutputXMLEventHandler : public txXMLEventHandler
{
public:
/**
* Sets the output format.
*
* @param aOutputFormat the output format
*/
virtual void setOutputFormat(txOutputFormat* aOutputFormat) = 0;
};
#ifdef TX_EXE
class txStreamXMLEventHandler : public txOutputXMLEventHandler
class txIOutputXMLEventHandler : public txXMLEventHandler
#else
#define TX_IOUTPUTXMLEVENTHANDLER_IID \
{ 0x80e5e802, 0x8c88, 0x11d6, \
{ 0xa7, 0xf2, 0xc5, 0xc3, 0x85, 0x6b, 0xbb, 0xbc }}
class txIOutputXMLEventHandler : public nsISupports,
public txXMLEventHandler
#endif
{
public:
/**
* Get the output stream.
*
* @param aOutputStream the current output stream
*/
virtual void getOutputStream(ostream** aOutputStream) = 0;
/**
* Sets the output stream.
*
* @param aOutputStream the output stream
*/
virtual void setOutputStream(ostream* aOutputStream) = 0;
/**
* Signals to receive characters that don't need output escaping.
*
* @param aData the characters to receive
*/
virtual void charactersNoOutputEscaping(const String& aData) = 0;
};
#else
class txMozillaXMLEventHandler : public txOutputXMLEventHandler
{
public:
/**
* Disables loading of stylesheets.
*/
virtual void disableStylesheetLoad() = 0;
/**
* Returns the root content of the result.
* Returns whether the output handler supports
* disable-output-escaping.
*
* @param aReturn the root content
* @return MB_TRUE if this handler supports
* disable-output-escaping
*/
virtual nsresult getRootContent(nsIContent** aReturn) = 0;
virtual MBool hasDisableOutputEscaping() = 0;
#ifndef TX_EXE
NS_DEFINE_STATIC_IID_ACCESSOR(TX_IOUTPUTXMLEVENTHANDLER_IID)
/**
* Returns PR_TRUE if the event handler has finished anything
* extra that had to happen after the transform has finished.
*/
virtual PRBool isDone() = 0;
/**
* Removes a script element from the array of elements that are
* still loading.
*
* @param aReturn the script element to remove
*/
virtual void removeScriptElement(nsIDOMHTMLScriptElement *aElement) = 0;
/**
* Sets the Mozilla output document.
* Gets the Mozilla output document
*
* @param aDocument the Mozilla output document
*/
virtual void setOutputDocument(nsIDOMDocument* aDocument) = 0;
};
virtual void getOutputDocument(nsIDOMDocument** aDocument) = 0;
#endif
};
/**
* Interface used to create the appropriate outputhandler
*/
class txIOutputHandlerFactory
{
public:
virtual ~txIOutputHandlerFactory() {};
/**
* Creates an outputhandler for the specified format.
* @param aFromat format to get handler for
* @param aHandler outparam. The created handler
*/
virtual nsresult
createHandlerWith(txOutputFormat* aFormat,
txIOutputXMLEventHandler** aHandler) = 0;
/**
* Creates an outputhandler for the specified format, with the specified
* name and namespace for the root element.
* @param aFromat format to get handler for
* @param aName name of the root element
* @param aNsID namespace-id of the root element
* @param aHandler outparam. The created handler
*/
virtual nsresult
createHandlerWith(txOutputFormat* aFormat,
const String& aName,
PRInt32 aNsID,
txIOutputXMLEventHandler** aHandler) = 0;
};
#define TX_DECL_TXIOUTPUTHANDLERFACTORY \
nsresult createHandlerWith(txOutputFormat* aFormat, \
txIOutputXMLEventHandler** aHandler); \
nsresult createHandlerWith(txOutputFormat* aFormat, \
const String& aName, \
PRInt32 aNsID, \
txIOutputXMLEventHandler** aHandler) \
#endif

View File

@ -47,13 +47,17 @@ txAttribute::txAttribute(PRInt32 aNsID, txAtom* aLocalName, const String& aValue
{
}
txXMLOutput::txXMLOutput() : mUseEmptyElementShorthand(MB_TRUE),
mHaveDocumentElement(MB_FALSE),
mStartTagOpen(MB_FALSE),
mAfterEndTag(MB_FALSE),
mInCDATASection(MB_FALSE),
mIndentLevel(0)
txXMLOutput::txXMLOutput(txOutputFormat* aFormat, ostream* aOut)
: mOut(aOut),
mUseEmptyElementShorthand(MB_TRUE),
mHaveDocumentElement(MB_FALSE),
mStartTagOpen(MB_FALSE),
mAfterEndTag(MB_FALSE),
mInCDATASection(MB_FALSE),
mIndentLevel(0)
{
mOutputFormat.merge(*aFormat);
mOutputFormat.setFromDefaults();
}
txXMLOutput::~txXMLOutput()
@ -251,24 +255,6 @@ void txXMLOutput::startElement(const String& aName,
}
}
void txXMLOutput::getOutputStream(ostream** aOutputStream)
{
if (aOutputStream)
*aOutputStream = mOut;
}
void txXMLOutput::setOutputStream(ostream* aOutputStream)
{
mOut = aOutputStream;
}
void txXMLOutput::setOutputFormat(txOutputFormat* aOutputFormat)
{
mOutputFormat.reset();
mOutputFormat.merge(*aOutputFormat);
mOutputFormat.setFromDefaults();
}
void txXMLOutput::closeStartTag(MBool aUseEmptyElementShorthand)
{
mAfterEndTag = aUseEmptyElementShorthand;

View File

@ -91,10 +91,10 @@ public:
MBool mShorthand;
};
class txXMLOutput : public txStreamXMLEventHandler
class txXMLOutput : public txIOutputXMLEventHandler
{
public:
txXMLOutput();
txXMLOutput(txOutputFormat* aFormat, ostream* aOut);
virtual ~txXMLOutput();
static const int DEFAULT_INDENT;
@ -146,6 +146,18 @@ public:
virtual void endElement(const String& aName,
const PRInt32 aNsID);
/**
* Returns whether the output handler supports
* disable-output-escaping.
*
* @return MB_TRUE if this handler supports
* disable-output-escaping
*/
MBool hasDisableOutputEscaping()
{
return MB_TRUE;
}
/*
* Signals to receive a processing instruction.
*
@ -169,27 +181,6 @@ public:
virtual void startElement(const String& aName,
const PRInt32 aNsID);
/*
* Sets the output format.
*
* @param aOutputFormat the output format
*/
void setOutputFormat(txOutputFormat* aOutputFormat);
/**
* Get the output stream.
*
* @param aOutputStream the current output stream
*/
void getOutputStream(ostream** aOutputStream);
/**
* Sets the output stream.
*
* @param aOutputStream the new output stream
*/
void setOutputStream(ostream* aOutputStream);
protected:
virtual void closeStartTag(MBool aUseEmptyElementShorthand);
void printUTF8Char(DOM_CHAR& ch);