Compiled XSLT stylesheets. Improves speed, implements forwards-compatible-parsing and handling of unknown extension-elements. Also fixes some random edgecasebugs such as recursive merged named-attribute-sets and empty strings in copy-of.
Patch mainly by sicking, but large parts also by Pike and peterv. Tracker is bug 185797. r=Pike/sicking rs=peterv. git-svn-id: svn://10.0.0.236/trunk@140310 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
325f6d6a00
commit
64ce860e2a
@ -1808,20 +1808,6 @@
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>nsTransformMediator.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>nsXSLContentSink.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>nsElementMap.cpp</PATH>
|
||||
@ -3071,16 +3057,6 @@
|
||||
<PATH>nsStyleContext.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>nsTransformMediator.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>nsXSLContentSink.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>nsElementMap.cpp</PATH>
|
||||
@ -5168,20 +5144,6 @@
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>nsTransformMediator.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>nsXSLContentSink.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>nsElementMap.cpp</PATH>
|
||||
@ -6431,16 +6393,6 @@
|
||||
<PATH>nsStyleContext.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>nsTransformMediator.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>nsXSLContentSink.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>nsElementMap.cpp</PATH>
|
||||
@ -7871,20 +7823,6 @@
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
</GROUP>
|
||||
<GROUP><NAME>xsl</NAME>
|
||||
<FILEREF>
|
||||
<TARGETNAME>content.o</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>nsTransformMediator.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>content.o</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>nsXSLContentSink.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
</GROUP>
|
||||
<GROUP><NAME>xul/content</NAME>
|
||||
<FILEREF>
|
||||
<TARGETNAME>content.o</TARGETNAME>
|
||||
|
||||
@ -95,16 +95,6 @@
|
||||
<SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING>
|
||||
<SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING>
|
||||
</SETTING>
|
||||
<SETTING>
|
||||
<SETTING><NAME>SearchPath</NAME>
|
||||
<SETTING><NAME>Path</NAME><VALUE>::xsl:document:src:</VALUE></SETTING>
|
||||
<SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING>
|
||||
<SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING>
|
||||
</SETTING>
|
||||
<SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING>
|
||||
<SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING>
|
||||
<SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING>
|
||||
</SETTING>
|
||||
<SETTING>
|
||||
<SETTING><NAME>SearchPath</NAME>
|
||||
<SETTING><NAME>Path</NAME><VALUE>::xul:document:public:</VALUE></SETTING>
|
||||
@ -1154,16 +1144,6 @@
|
||||
<SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING>
|
||||
<SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING>
|
||||
</SETTING>
|
||||
<SETTING>
|
||||
<SETTING><NAME>SearchPath</NAME>
|
||||
<SETTING><NAME>Path</NAME><VALUE>::xsl:document:src:</VALUE></SETTING>
|
||||
<SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING>
|
||||
<SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING>
|
||||
</SETTING>
|
||||
<SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING>
|
||||
<SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING>
|
||||
<SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING>
|
||||
</SETTING>
|
||||
<SETTING>
|
||||
<SETTING><NAME>SearchPath</NAME>
|
||||
<SETTING><NAME>Path</NAME><VALUE>::xul:document:public:</VALUE></SETTING>
|
||||
|
||||
@ -85,7 +85,6 @@
|
||||
#include "prtime.h"
|
||||
#include "prlog.h"
|
||||
#include "prmem.h"
|
||||
#include "nsXSLContentSink.h"
|
||||
#include "nsParserCIID.h"
|
||||
#include "nsParserUtils.h"
|
||||
#include "nsIScrollable.h"
|
||||
@ -438,13 +437,12 @@ nsXMLContentSink::DidBuildModel(PRInt32 aQualityLevel)
|
||||
// Check if we want to prettyprint
|
||||
MaybePrettyPrint();
|
||||
|
||||
if (mXSLTransformMediator) {
|
||||
if (mXSLTProcessor) {
|
||||
nsCOMPtr<nsIDOMDocument> currentDOMDoc(do_QueryInterface(mDocument));
|
||||
mXSLTransformMediator->SetSourceContentModel(currentDOMDoc);
|
||||
mXSLTransformMediator->SetTransformObserver(this);
|
||||
// Since the mediator now holds a reference to us we drop our reference
|
||||
mXSLTProcessor->SetSourceContentModel(currentDOMDoc);
|
||||
// Since the processor now holds a reference to us we drop our reference
|
||||
// to it to avoid owning cycles
|
||||
mXSLTransformMediator = nsnull;
|
||||
mXSLTProcessor = nsnull;
|
||||
}
|
||||
else {
|
||||
// Kick off layout for non-XSLT transformed documents.
|
||||
@ -785,59 +783,23 @@ nsXMLContentSink::AddContentAsLeaf(nsIContent *aContent)
|
||||
nsresult
|
||||
nsXMLContentSink::LoadXSLStyleSheet(nsIURI* aUrl)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Create a transform mediator
|
||||
rv = NS_NewTransformMediator(getter_AddRefs(mXSLTransformMediator),
|
||||
NS_LITERAL_CSTRING(kXSLType));
|
||||
if (NS_FAILED(rv)) {
|
||||
mXSLTProcessor =
|
||||
do_CreateInstance("@mozilla.org/document-transformer;1?type=text/xslt");
|
||||
if (!mXSLTProcessor) {
|
||||
// No XSLT processor available, continue normal document loading
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Enable the transform mediator. It will start the transform
|
||||
// as soon as it has enough state to do so. The state needed is
|
||||
// the source content model, the style content model, the current
|
||||
// document, and an observer. The XML and XSL content sinks provide
|
||||
// this state by calling the various setters on nsITransformMediator.
|
||||
mXSLTransformMediator->SetEnabled(PR_TRUE);
|
||||
mXSLTProcessor->SetTransformObserver(this);
|
||||
|
||||
// Create and set up the channel
|
||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
rv = mDocument->GetDocumentLoadGroup(getter_AddRefs(loadGroup));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
rv = NS_NewChannel(getter_AddRefs(channel), aUrl);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
channel->SetLoadGroup(loadGroup);
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
||||
if (httpChannel) {
|
||||
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING("text/xml,application/xml,application/xhtml+xml,*/*;q=0.1"),
|
||||
PR_FALSE);
|
||||
|
||||
httpChannel->SetReferrer(mDocumentURL);
|
||||
nsresult rv = mDocument->GetDocumentLoadGroup(getter_AddRefs(loadGroup));
|
||||
if (NS_FAILED(rv)) {
|
||||
mXSLTProcessor = nsnull;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
// Create the XSL stylesheet document
|
||||
nsCOMPtr<nsIDocument> styleDoc = do_CreateInstance(kXMLDocumentCID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Create the XSL content sink
|
||||
nsCOMPtr<nsIXMLContentSink> sink;
|
||||
rv = NS_NewXSLContentSink(getter_AddRefs(sink), mXSLTransformMediator, styleDoc, aUrl, mWebShell);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIStreamListener> sl;
|
||||
rv = styleDoc->StartDocumentLoad(kLoadAsData, channel, loadGroup, nsnull,
|
||||
getter_AddRefs(sl), PR_TRUE, sink);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return channel->AsyncOpen(sl, nsnull);
|
||||
return mXSLTProcessor->LoadStyleSheet(aUrl, loadGroup, mDocumentURL);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -871,7 +833,7 @@ nsXMLContentSink::ProcessStyleLink(nsIContent* aElement,
|
||||
rv = NS_NewURI(getter_AddRefs(url), aHref, nsnull, mDocumentBaseURL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIScriptSecurityManager> secMan =
|
||||
nsCOMPtr<nsIScriptSecurityManager> secMan =
|
||||
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, NS_OK);
|
||||
|
||||
@ -1817,7 +1779,7 @@ nsXMLContentSink::HandleStartElement(const PRUnichar *aName,
|
||||
|
||||
// For XSLT, we need to wait till after the transform
|
||||
// to set the root content object.
|
||||
if (!mXSLTransformMediator) {
|
||||
if (!mXSLTProcessor) {
|
||||
mDocument->SetRootContent(mDocElement);
|
||||
}
|
||||
}
|
||||
@ -2101,10 +2063,10 @@ nsXMLContentSink::ReportError(const PRUnichar* aErrorText,
|
||||
}
|
||||
NS_IF_RELEASE(mDocElement);
|
||||
|
||||
if (mXSLTransformMediator) {
|
||||
// Get rid of the transform mediator.
|
||||
mXSLTransformMediator->SetEnabled(PR_FALSE);
|
||||
mXSLTransformMediator = nsnull;
|
||||
if (mXSLTProcessor) {
|
||||
// Get rid of the XSLT processor.
|
||||
mXSLTProcessor->CancelLoads();
|
||||
mXSLTProcessor = nsnull;
|
||||
}
|
||||
|
||||
NS_NAMED_LITERAL_STRING(name, "xmlns");
|
||||
|
||||
@ -43,13 +43,11 @@
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsITransformMediator.h"
|
||||
#include "nsIUnicharInputStream.h"
|
||||
#include "nsIStreamLoader.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsINodeInfo.h"
|
||||
#include "nsIDOMHTMLTextAreaElement.h"
|
||||
class nsICSSStyleSheet;
|
||||
#include "nsICSSLoaderObserver.h"
|
||||
#include "nsIHTMLContent.h"
|
||||
#include "nsIDOMHTMLScriptElement.h"
|
||||
@ -59,6 +57,7 @@ class nsICSSStyleSheet;
|
||||
#include "nsIExpatSink.h"
|
||||
#include "nsIDocumentTransformer.h"
|
||||
|
||||
class nsICSSStyleSheet;
|
||||
class nsIDocument;
|
||||
class nsIURI;
|
||||
class nsIWebShell;
|
||||
@ -204,7 +203,7 @@ protected:
|
||||
|
||||
nsCOMPtr<nsISupportsArray> mContentStack;
|
||||
nsCOMPtr<nsINodeInfoManager> mNodeInfoManager;
|
||||
nsCOMPtr<nsITransformMediator> mXSLTransformMediator;
|
||||
nsCOMPtr<nsIDocumentTransformer> mXSLTProcessor;
|
||||
};
|
||||
|
||||
#endif // nsXMLContentSink_h__
|
||||
|
||||
@ -21,7 +21,7 @@ VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = public document
|
||||
DIRS = public
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = src
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
@ -1,54 +0,0 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH=../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = content
|
||||
LIBRARY_NAME = gkconxsldoc_s
|
||||
REQUIRES = xpcom \
|
||||
string \
|
||||
htmlparser \
|
||||
view \
|
||||
widget \
|
||||
dom \
|
||||
necko \
|
||||
gfx \
|
||||
layout \
|
||||
content \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
CPPSRCS = \
|
||||
nsXSLContentSink.cpp \
|
||||
nsTransformMediator.cpp \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../../../xml/document/src \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
@ -1,166 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*
|
||||
* 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsTransformMediator.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsString.h"
|
||||
|
||||
nsresult
|
||||
NS_NewTransformMediator(nsITransformMediator** aInstancePtrResult,
|
||||
const nsACString& aMimeType)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aInstancePtrResult);
|
||||
|
||||
nsTransformMediator* it;
|
||||
NS_NEWXPCOM(it, nsTransformMediator);
|
||||
if (!it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
nsresult rv = it->Init(aMimeType);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete it;
|
||||
return rv;
|
||||
}
|
||||
return CallQueryInterface(it, aInstancePtrResult);
|
||||
}
|
||||
|
||||
nsTransformMediator::nsTransformMediator() : mEnabled(PR_FALSE),
|
||||
mStyleInvalid(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
nsTransformMediator::~nsTransformMediator()
|
||||
{
|
||||
}
|
||||
|
||||
static
|
||||
nsresult ConstructContractID(nsACString& aContractID,
|
||||
const nsACString& aMimeType)
|
||||
{
|
||||
aContractID.Assign(NS_LITERAL_CSTRING("@mozilla.org/document-transformer;1?type="));
|
||||
aContractID.Append(aMimeType);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTransformMediator::Init(const nsACString& aMimeType)
|
||||
{
|
||||
// Construct prog ID for the document tranformer component
|
||||
nsCAutoString contractID;
|
||||
nsresult rv = ConstructContractID(contractID, aMimeType);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Try to find a component that implements the nsIDocumentTransformer interface
|
||||
mTransformer = do_CreateInstance(contractID.get(), &rv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// nsISupports
|
||||
NS_IMPL_ISUPPORTS1(nsTransformMediator, nsITransformMediator)
|
||||
|
||||
void
|
||||
nsTransformMediator::TryToTransform()
|
||||
{
|
||||
if (mSourceDOM && mStyleDOM && mObserver)
|
||||
{
|
||||
if (mEnabled && mTransformer) {
|
||||
mTransformer->TransformDocument(mSourceDOM,
|
||||
mStyleDOM,
|
||||
mObserver,
|
||||
getter_AddRefs(mResultDoc));
|
||||
}
|
||||
else if (mStyleInvalid) {
|
||||
// Avoid recursion.
|
||||
mStyleInvalid = PR_FALSE;
|
||||
|
||||
// Notify the observer with the stylesheet which contains
|
||||
// the error message.
|
||||
nsCOMPtr<nsIDOMDocument> errorDoc;
|
||||
mStyleDOM->GetOwnerDocument(getter_AddRefs(errorDoc));
|
||||
mObserver->OnTransformDone(NS_ERROR_FAILURE, errorDoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// nsITransformMediator
|
||||
NS_IMETHODIMP
|
||||
nsTransformMediator::SetEnabled(PRBool aValue)
|
||||
{
|
||||
mEnabled = aValue;
|
||||
TryToTransform();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTransformMediator::SetSourceContentModel(nsIDOMNode* aSource)
|
||||
{
|
||||
mSourceDOM = aSource;
|
||||
TryToTransform();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTransformMediator::SetStyleSheetContentModel(nsIDOMNode* aStyle)
|
||||
{
|
||||
mStyleDOM = aStyle;
|
||||
TryToTransform();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTransformMediator::GetResultDocument(nsIDOMDocument** aDoc)
|
||||
{
|
||||
*aDoc = mResultDoc;
|
||||
NS_IF_ADDREF(*aDoc);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTransformMediator::SetTransformObserver(nsITransformObserver* aObserver)
|
||||
{
|
||||
mObserver = aObserver;
|
||||
TryToTransform();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTransformMediator::SetStyleInvalid(PRBool aInvalid)
|
||||
{
|
||||
mStyleInvalid = aInvalid;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1,78 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*
|
||||
* 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsTransformMediator_h__
|
||||
#define nsTransformMediator_h__
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsITransformMediator.h"
|
||||
#include "nsIDocumentTransformer.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
|
||||
class nsTransformMediator : public nsITransformMediator {
|
||||
public:
|
||||
nsTransformMediator();
|
||||
virtual ~nsTransformMediator();
|
||||
|
||||
nsresult Init(const nsACString& aMimeType);
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsITransformMediator
|
||||
NS_IMETHOD SetEnabled(PRBool aValue);
|
||||
NS_IMETHOD SetSourceContentModel(nsIDOMNode* aSource);
|
||||
NS_IMETHOD SetStyleSheetContentModel(nsIDOMNode* aStyle);
|
||||
NS_IMETHOD GetResultDocument(nsIDOMDocument** aDoc);
|
||||
NS_IMETHOD SetTransformObserver(nsITransformObserver* aObserver);
|
||||
NS_IMETHOD SetStyleInvalid(PRBool aInvalid);
|
||||
|
||||
protected:
|
||||
void TryToTransform();
|
||||
|
||||
PRBool mEnabled;
|
||||
PRBool mStyleInvalid;
|
||||
nsCOMPtr<nsIDocumentTransformer> mTransformer;
|
||||
nsCOMPtr<nsIDOMNode> mSourceDOM;
|
||||
nsCOMPtr<nsIDOMNode> mStyleDOM;
|
||||
nsCOMPtr<nsIDOMDocument> mResultDoc;
|
||||
nsCOMPtr<nsITransformObserver> mObserver;
|
||||
};
|
||||
|
||||
#endif // nsTransformMediator_h__
|
||||
@ -1,193 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*
|
||||
* 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsXSLContentSink.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIParser.h"
|
||||
#include "nsIStyleSheetLinkingElement.h"
|
||||
#include "nsITransformMediator.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsString.h"
|
||||
#include "nsEscape.h"
|
||||
|
||||
nsresult
|
||||
NS_NewXSLContentSink(nsIXMLContentSink** aResult,
|
||||
nsITransformMediator* aTM,
|
||||
nsIDocument* aDoc,
|
||||
nsIURI* aURL,
|
||||
nsIWebShell* aWebShell)
|
||||
{
|
||||
NS_ENSURE_ARG(aResult);
|
||||
|
||||
nsXSLContentSink* it;
|
||||
NS_NEWXPCOM(it, nsXSLContentSink);
|
||||
NS_ENSURE_TRUE(it, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsCOMPtr<nsIXMLContentSink> sink = it;
|
||||
nsresult rv = it->Init(aTM, aDoc, aURL, aWebShell);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return CallQueryInterface(it, aResult);
|
||||
}
|
||||
|
||||
nsXSLContentSink::nsXSLContentSink()
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
nsXSLContentSink::~nsXSLContentSink()
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXSLContentSink::Init(nsITransformMediator* aTM,
|
||||
nsIDocument* aDoc,
|
||||
nsIURI* aURL,
|
||||
nsIWebShell* aContainer)
|
||||
{
|
||||
nsresult rv = nsXMLContentSink::Init(aDoc, aURL, aContainer, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mXSLTransformMediator = aTM;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// nsIContentSink
|
||||
NS_IMETHODIMP
|
||||
nsXSLContentSink::WillBuildModel(void)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXSLContentSink::DidBuildModel(PRInt32 aQualityLevel)
|
||||
{
|
||||
mDocument->SetRootContent(mDocElement);
|
||||
mDocument->EndLoad();
|
||||
|
||||
nsCOMPtr<nsIDOMNode> styleNode;
|
||||
nsCOMPtr<nsIURL> url = do_QueryInterface(mDocumentURL);
|
||||
if (url) {
|
||||
nsCAutoString ref;
|
||||
url->GetRef(ref);
|
||||
if (!ref.IsEmpty()) {
|
||||
NS_UnescapeURL(ref); // XXX this may result in non-ASCII octets
|
||||
nsCOMPtr<nsIDOMDocument> styleDoc = do_QueryInterface(mDocument);
|
||||
NS_ENSURE_TRUE(styleDoc, NS_ERROR_NO_INTERFACE);
|
||||
nsCOMPtr<nsIDOMElement> elem;
|
||||
styleDoc->GetElementById(NS_ConvertUTF8toUCS2(ref),
|
||||
getter_AddRefs(elem));
|
||||
styleNode = elem;
|
||||
}
|
||||
else {
|
||||
styleNode = do_QueryInterface(mDocument);
|
||||
}
|
||||
}
|
||||
else {
|
||||
styleNode = do_QueryInterface(mDocument);
|
||||
}
|
||||
|
||||
if (mXSLTransformMediator) {
|
||||
// Pass the style content model to the tranform mediator.
|
||||
mXSLTransformMediator->SetStyleSheetContentModel(styleNode);
|
||||
mXSLTransformMediator = nsnull;
|
||||
}
|
||||
|
||||
// Drop our reference to the parser to get rid of a circular
|
||||
// reference.
|
||||
NS_IF_RELEASE(mParser);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// To stop infinite recursive processing of <?xml-stylesheet?>
|
||||
NS_IMETHODIMP
|
||||
nsXSLContentSink::ProcessStyleLink(nsIContent* aElement,
|
||||
const nsString& aHref,
|
||||
PRBool aAlternate,
|
||||
const nsString& aTitle,
|
||||
const nsString& aType,
|
||||
const nsString& aMedia)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXSLContentSink::ReportError(const PRUnichar* aErrorText,
|
||||
const PRUnichar* aSourceText)
|
||||
{
|
||||
// nsXMLContentSink::ReportError sets mXSLTransformMediator to nsnull
|
||||
nsCOMPtr<nsITransformMediator> mediator = mXSLTransformMediator;
|
||||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
mParser->GetChannel(getter_AddRefs(channel));
|
||||
mDocument->GetDocumentLoadGroup(getter_AddRefs(loadGroup));
|
||||
mDocument->Reset(channel, loadGroup);
|
||||
|
||||
nsXMLContentSink::ReportError(aErrorText, aSourceText);
|
||||
|
||||
if (mediator) {
|
||||
nsCOMPtr<nsIDOMNode> styleNode = do_QueryInterface(mDocElement);
|
||||
mediator->SetStyleInvalid(PR_TRUE);
|
||||
mediator->SetStyleSheetContentModel(styleNode);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXSLContentSink::CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
|
||||
nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
|
||||
nsIContent** aResult, PRBool* aAppendContent)
|
||||
{
|
||||
*aAppendContent = PR_TRUE;
|
||||
return NS_NewXMLElement(aResult, aNodeInfo);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXSLContentSink::CloseElement(nsIContent* aContent, PRBool* aAppendContent)
|
||||
{
|
||||
*aAppendContent = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1,89 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*
|
||||
* 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsXSLContentSink_h__
|
||||
#define nsXSLContentSink_h__
|
||||
|
||||
#include "nsXMLContentSink.h"
|
||||
|
||||
// The XSL content sink accepts a parsed XML document
|
||||
// from the parser and creates a XSL rule data model
|
||||
// and an XSL stylesheet content model.
|
||||
|
||||
class nsXSLContentSink : public nsXMLContentSink {
|
||||
public:
|
||||
nsXSLContentSink();
|
||||
~nsXSLContentSink();
|
||||
|
||||
nsresult Init(nsITransformMediator* aTM,
|
||||
nsIDocument* aDoc,
|
||||
nsIURI* aURL,
|
||||
nsIWebShell* aContainer);
|
||||
|
||||
// nsIContentSink
|
||||
NS_IMETHOD WillBuildModel(void);
|
||||
NS_IMETHOD DidBuildModel(PRInt32 aQualityLevel);
|
||||
|
||||
// nsIExpatSink
|
||||
NS_IMETHOD ReportError(const PRUnichar *aErrorText,
|
||||
const PRUnichar *aSourceText);
|
||||
|
||||
protected:
|
||||
// override nsXMLContentSink hooks
|
||||
nsresult CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
|
||||
nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
|
||||
nsIContent** aResult, PRBool* aAppendContent);
|
||||
|
||||
nsresult CloseElement(nsIContent* aContent, PRBool* aAppendContent);
|
||||
|
||||
NS_IMETHOD ProcessStyleLink(nsIContent* aElement,
|
||||
const nsString& aHref,
|
||||
PRBool aAlternate,
|
||||
const nsString& aTitle,
|
||||
const nsString& aType,
|
||||
const nsString& aMedia);
|
||||
};
|
||||
|
||||
|
||||
nsresult
|
||||
NS_NewXSLContentSink(nsIXMLContentSink** aResult,
|
||||
nsITransformMediator* aTM,
|
||||
nsIDocument* aDoc,
|
||||
nsIURI* aURL,
|
||||
nsIWebShell* aWebShell);
|
||||
#endif // nsXSLContentSink_h__
|
||||
@ -2,5 +2,4 @@
|
||||
# This is a list of local files which get copied to the mozilla:dist:content directory
|
||||
#
|
||||
|
||||
nsITransformMediator.h
|
||||
nsIDocumentTransformer.h
|
||||
|
||||
@ -47,7 +47,6 @@ XPIDL_MODULE = content_xslt
|
||||
|
||||
EXPORTS = \
|
||||
nsIDocumentTransformer.h \
|
||||
nsITransformMediator.h \
|
||||
$(NULL)
|
||||
|
||||
XPIDLSRCS = \
|
||||
|
||||
@ -42,6 +42,8 @@
|
||||
|
||||
class nsIDOMDocument;
|
||||
class nsIDOMNode;
|
||||
class nsILoadGroup;
|
||||
class nsIURI;
|
||||
|
||||
#define NS_ITRANSFORMOBSERVER_IID \
|
||||
{0xcce88481, 0x6eb3, 0x11d6, \
|
||||
@ -55,7 +57,8 @@ public:
|
||||
|
||||
NS_IMETHOD OnDocumentCreated(nsIDOMDocument *aResultDocument) = 0;
|
||||
|
||||
NS_IMETHOD OnTransformDone(nsresult aResult, nsIDOMDocument *aResultDocument) = 0;
|
||||
NS_IMETHOD OnTransformDone(nsresult aResult,
|
||||
nsIDOMDocument *aResultDocument) = 0;
|
||||
|
||||
};
|
||||
|
||||
@ -69,10 +72,11 @@ public:
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IDOCUMENTTRANSFORMER_IID)
|
||||
|
||||
NS_IMETHOD TransformDocument(nsIDOMNode *aSourceDOM,
|
||||
nsIDOMNode *aStyleDOM,
|
||||
nsITransformObserver *aObserver,
|
||||
nsIDOMDocument **_retval) = 0;
|
||||
NS_IMETHOD SetTransformObserver(nsITransformObserver* aObserver) = 0;
|
||||
NS_IMETHOD LoadStyleSheet(nsIURI* aUri, nsILoadGroup* aLoadGroup,
|
||||
nsIURI* aReferrerUri) = 0;
|
||||
NS_IMETHOD SetSourceContentModel(nsIDOMNode* aSource) = 0;
|
||||
NS_IMETHOD CancelLoads() = 0;
|
||||
};
|
||||
|
||||
#endif //nsIDocumentTransformer_h__
|
||||
|
||||
@ -47,6 +47,7 @@ REQUIRES = xpcom \
|
||||
webshell \
|
||||
docshell \
|
||||
layout \
|
||||
uconv \
|
||||
$(NULL)
|
||||
IS_COMPONENT = 1
|
||||
MODULE_NAME = TransformiixModule
|
||||
@ -55,10 +56,10 @@ MODULE_NAME = TransformiixModule
|
||||
CPPSRCS = XSLTProcessorModule.cpp
|
||||
LOBJS = ../source/base/Double.$(OBJ_SUFFIX) \
|
||||
../source/base/List.$(OBJ_SUFFIX) \
|
||||
../source/base/Map.$(OBJ_SUFFIX) \
|
||||
../source/base/SimpleErrorObserver.$(OBJ_SUFFIX) \
|
||||
../source/base/txAtoms.$(OBJ_SUFFIX) \
|
||||
../source/base/txExpandedNameMap.$(OBJ_SUFFIX) \
|
||||
../source/base/txNamespaceMap.$(OBJ_SUFFIX) \
|
||||
../source/base/txURIUtils.$(OBJ_SUFFIX) \
|
||||
../source/xml/dom/mozImpl/MozillaAttr.$(OBJ_SUFFIX) \
|
||||
../source/xml/dom/mozImpl/MozillaDocument.$(OBJ_SUFFIX) \
|
||||
@ -107,18 +108,24 @@ LOBJS = ../source/base/Double.$(OBJ_SUFFIX) \
|
||||
../source/xml/parser/txXMLParser.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txBufferingHandler.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txOutputFormat.$(OBJ_SUFFIX) \
|
||||
../source/xslt/ProcessorState.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txExecutionState.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txInstructions.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txMozillaStylesheetCompiler.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txMozillaTextOutput.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txMozillaXSLTProcessor.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txMozillaXMLOutput.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txRtfHandler.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txStylesheet.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txStylesheetCompileHandlers.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txStylesheetCompiler.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txTextHandler.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txToplevelItems.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txUnknownHandler.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txXSLTNumber.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txXSLTNumberCounters.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txXSLTPatterns.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txXSLTProcessor.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txPatternParser.$(OBJ_SUFFIX) \
|
||||
../source/xslt/XSLTProcessor.$(OBJ_SUFFIX) \
|
||||
../source/xslt/functions/CurrentFunctionCall.$(OBJ_SUFFIX) \
|
||||
../source/xslt/functions/DocumentFunctionCall.$(OBJ_SUFFIX) \
|
||||
../source/xslt/functions/ElementAvailableFnCall.$(OBJ_SUFFIX) \
|
||||
|
||||
@ -42,6 +42,7 @@
|
||||
#include "nsCRT.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "txURIUtils.h"
|
||||
#include "txXSLTProcessor.h"
|
||||
#include "nsXPath1Scheme.h"
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPath1SchemeProcessor)
|
||||
@ -202,7 +203,7 @@ Initialize(nsIModule* aSelf)
|
||||
xs->RegisterExceptionProvider(gXPathExceptionProvider,
|
||||
NS_ERROR_MODULE_DOM_XPATH);
|
||||
|
||||
if (!txXSLTProcessor::txInit()) {
|
||||
if (!txXSLTProcessor::init()) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@ -219,8 +220,6 @@ Initialize(nsIModule* aSelf)
|
||||
return rv;
|
||||
}
|
||||
|
||||
TX_LG_CREATE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -249,12 +248,10 @@ Shutdown(nsIModule* aSelf)
|
||||
NS_IF_RELEASE(NS_CLASSINFO_NAME(XPathNSResolver));
|
||||
NS_IF_RELEASE(NS_CLASSINFO_NAME(XPathResult));
|
||||
|
||||
txXSLTProcessor::txShutdown();
|
||||
txXSLTProcessor::shutdown();
|
||||
|
||||
NS_IF_RELEASE(gTxSecurityManager);
|
||||
NS_IF_RELEASE(gTxNameSpaceManager);
|
||||
|
||||
TX_LG_DELETE;
|
||||
}
|
||||
|
||||
// Component Table
|
||||
|
||||
@ -1069,13 +1069,6 @@
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ProcessorState.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ExprLexer.cpp</PATH>
|
||||
@ -1307,13 +1300,6 @@
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>XSLTProcessor.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txXMLParser.cpp</PATH>
|
||||
@ -1363,13 +1349,6 @@
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>Map.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>XSLTProcessorModule.cpp</PATH>
|
||||
@ -1531,6 +1510,69 @@
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNamespaceMap.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txExecutionState.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txInstructions.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txStylesheet.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txStylesheetCompileHandlers.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txStylesheetCompiler.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txToplevelItems.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txXSLTProcessor.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txMozillaStylesheetCompiler.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
</FILELIST>
|
||||
<LINKORDER>
|
||||
<FILEREF>
|
||||
@ -1603,11 +1645,6 @@
|
||||
<PATH>NodeSet.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ProcessorState.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ExprLexer.cpp</PATH>
|
||||
@ -1763,11 +1800,6 @@
|
||||
<PATH>MozillaAttr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>XSLTProcessor.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>MozillaDocument.cpp</PATH>
|
||||
@ -1828,11 +1860,6 @@
|
||||
<PATH>FunctionAvailableFnCall.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>Map.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>XSLTProcessorModule.cpp</PATH>
|
||||
@ -1943,6 +1970,51 @@
|
||||
<PATH>txUnknownHandler.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNamespaceMap.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txExecutionState.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txInstructions.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txStylesheet.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txStylesheetCompileHandlers.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txStylesheetCompiler.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txToplevelItems.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txXSLTProcessor.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txMozillaStylesheetCompiler.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
</LINKORDER>
|
||||
</TARGET>
|
||||
<TARGET>
|
||||
@ -2905,13 +2977,6 @@
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ProcessorState.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ExprLexer.cpp</PATH>
|
||||
@ -3143,13 +3208,6 @@
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>XSLTProcessor.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>NSPR20.shlb</PATH>
|
||||
@ -3227,13 +3285,6 @@
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>Map.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>XSLTProcessorModule.cpp</PATH>
|
||||
@ -3423,6 +3474,69 @@
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNamespaceMap.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txExecutionState.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txInstructions.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txStylesheet.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txStylesheetCompileHandlers.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txStylesheetCompiler.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txToplevelItems.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txXSLTProcessor.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txMozillaStylesheetCompiler.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
</FILELIST>
|
||||
<LINKORDER>
|
||||
<FILEREF>
|
||||
@ -3455,11 +3569,6 @@
|
||||
<PATH>NodeSet.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ProcessorState.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ExprLexer.cpp</PATH>
|
||||
@ -3615,11 +3724,6 @@
|
||||
<PATH>MozillaAttr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>XSLTProcessor.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>MozillaDocument.cpp</PATH>
|
||||
@ -3700,11 +3804,6 @@
|
||||
<PATH>FunctionAvailableFnCall.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>Map.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>XSLTProcessorModule.cpp</PATH>
|
||||
@ -3835,6 +3934,51 @@
|
||||
<PATH>txUnknownHandler.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNamespaceMap.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txExecutionState.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txInstructions.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txStylesheet.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txStylesheetCompileHandlers.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txStylesheetCompiler.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txToplevelItems.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txXSLTProcessor.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txMozillaStylesheetCompiler.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
</LINKORDER>
|
||||
</TARGET>
|
||||
</TARGETLIST>
|
||||
@ -3859,12 +4003,6 @@
|
||||
<PATH>List.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>Map.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
@ -3883,6 +4021,12 @@
|
||||
<PATH>txExpandedNameMap.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNamespaceMap.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
@ -4166,7 +4310,19 @@
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ProcessorState.cpp</PATH>
|
||||
<PATH>txExecutionState.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txInstructions.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txMozillaStylesheetCompiler.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
@ -4205,12 +4361,36 @@
|
||||
<PATH>txRtfHandler.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txStylesheet.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txStylesheetCompileHandlers.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txStylesheetCompiler.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txTextHandler.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txToplevelItems.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
@ -4238,7 +4418,7 @@
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>XSLTProcessor.cpp</PATH>
|
||||
<PATH>txXSLTProcessor.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<GROUP><NAME>functions</NAME>
|
||||
|
||||
@ -105,6 +105,7 @@ protected:
|
||||
ListItem* remove(ListItem* sItem);
|
||||
|
||||
private:
|
||||
txList(const txList& aOther); // not implemented
|
||||
|
||||
ListItem* firstItem;
|
||||
ListItem* lastItem;
|
||||
|
||||
@ -44,10 +44,10 @@ endif
|
||||
|
||||
CPPSRCS = Double.cpp \
|
||||
List.cpp \
|
||||
Map.cpp \
|
||||
SimpleErrorObserver.cpp \
|
||||
txAtoms.cpp \
|
||||
txExpandedNameMap.cpp \
|
||||
txNamespaceMap.cpp \
|
||||
txURIUtils.cpp
|
||||
|
||||
ifdef TX_EXE
|
||||
|
||||
@ -1,270 +0,0 @@
|
||||
/*
|
||||
* 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 XSL:P XSLT processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Keith Visco.
|
||||
*
|
||||
* Portions created by Keith Visco (C) 1999-2000 Keith Visco.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* A Hashtable for TxObjects
|
||||
*/
|
||||
|
||||
|
||||
#include "Map.h"
|
||||
#include "List.h"
|
||||
|
||||
//-------------/
|
||||
//- Constants -/
|
||||
//-------------/
|
||||
|
||||
const int Map::DEFAULT_SIZE = 13;
|
||||
|
||||
//----------------/
|
||||
//- Constructors -/
|
||||
//----------------/
|
||||
|
||||
/**
|
||||
* Creates a new Map with the default Size
|
||||
**/
|
||||
Map::Map() {
|
||||
initialize(DEFAULT_SIZE);
|
||||
} //-- Map
|
||||
|
||||
/**
|
||||
* Creates a new Map with the specified number of buckets
|
||||
**/
|
||||
Map::Map(int size) {
|
||||
initialize(size);
|
||||
} //-- Map
|
||||
|
||||
/**
|
||||
* Helper method for Constructors
|
||||
**/
|
||||
void Map::initialize(PRInt32 size) {
|
||||
|
||||
//-- by default the Map will not delete it's
|
||||
//-- object references
|
||||
mOwnership = eOwnsNone;
|
||||
|
||||
//-- create a new array of bucket pointers
|
||||
elements = new BucketItem*[size];
|
||||
|
||||
//-- initialize all elements to 0;
|
||||
for ( PRInt32 i = 0; i < size; i++ ) elements[i] = 0;
|
||||
|
||||
numberOfBuckets = size;
|
||||
numberOfElements = 0;
|
||||
} //-- initialize
|
||||
|
||||
/**
|
||||
* Destructor for Map
|
||||
**/
|
||||
Map::~Map() {
|
||||
clear();
|
||||
delete [] elements;
|
||||
} //-- ~Map
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Removes all elements from the Map. Deletes objects according
|
||||
* to the mOwnership attribute
|
||||
**/
|
||||
void Map::clear() {
|
||||
|
||||
for (int i = 0; i < numberOfBuckets; i++) {
|
||||
|
||||
BucketItem* bktItem = elements[i];
|
||||
while (bktItem) {
|
||||
BucketItem* tItem = bktItem;
|
||||
bktItem = bktItem->next;
|
||||
if (mOwnership & eOwnsItems)
|
||||
delete tItem->item;
|
||||
if (mOwnership & eOwnsKeys)
|
||||
delete tItem->key;
|
||||
//--delete tItem;
|
||||
delete tItem;
|
||||
}
|
||||
}
|
||||
numberOfElements = 0;
|
||||
} //-- clear
|
||||
|
||||
/**
|
||||
* Returns the object reference in this Map associated with the given key
|
||||
* @return the object reference in this Map associated with the given key
|
||||
**/
|
||||
TxObject* Map::get(TxObject* key) {
|
||||
BucketItem* item = getBucketItem(key);
|
||||
if ( item ) return item->item;
|
||||
return 0;
|
||||
} //-- get
|
||||
|
||||
/**
|
||||
* Returns true if there are no objects in this map.
|
||||
* @return true if there are no objects in this map.
|
||||
**/
|
||||
MBool Map::isEmpty() {
|
||||
return (numberOfElements == 0) ? MB_TRUE : MB_FALSE;
|
||||
} //-- isEmpty
|
||||
|
||||
|
||||
/**
|
||||
* Returns a List of all the keys in this Map.
|
||||
* Please delete this List when you are done with it
|
||||
**/
|
||||
List* Map::keys() {
|
||||
List* list = new List();
|
||||
for (int i = 0; i < numberOfBuckets; i++) {
|
||||
BucketItem* item = elements[i];
|
||||
while (item) {
|
||||
list->add(item->key);
|
||||
item = item->next;
|
||||
}
|
||||
}
|
||||
return list;
|
||||
} //-- keys
|
||||
|
||||
/**
|
||||
* Adds the TxObject reference to the map and associates it with the given
|
||||
* key
|
||||
**/
|
||||
void Map::put(TxObject* key, TxObject* obj) {
|
||||
|
||||
if ((!key) || (!obj)) return;
|
||||
|
||||
//-- compute hash for key
|
||||
PRUint32 hashCode = key->hashCode();
|
||||
|
||||
//-- calculate index
|
||||
int idx = hashCode % numberOfBuckets;
|
||||
|
||||
//-- fetch first item in bucket
|
||||
BucketItem* bktItem = elements[idx];
|
||||
|
||||
//-- if bktItem is 0 then there are no items is this Bucket,
|
||||
//-- add to front of list
|
||||
if ( !bktItem ) {
|
||||
elements[idx] = createBucketItem(key, obj);
|
||||
++numberOfElements;
|
||||
}
|
||||
//-- find current item, or add to end of list
|
||||
else {
|
||||
BucketItem* prevItem = bktItem;
|
||||
//-- advance to next spot
|
||||
while ( bktItem ) {
|
||||
//-- if current key equals desired key, break
|
||||
if ( bktItem->key->equals(key) ) {
|
||||
break;
|
||||
}
|
||||
prevItem = bktItem;
|
||||
bktItem = bktItem->next;
|
||||
}
|
||||
//-- if we did not find a bucket Item create a new one
|
||||
if ( !bktItem) {
|
||||
bktItem = createBucketItem(key, obj);
|
||||
prevItem->next = bktItem;
|
||||
bktItem->prev = prevItem;
|
||||
++numberOfElements;
|
||||
}
|
||||
//-- we found bucket item, just set value
|
||||
else bktItem->item = obj;
|
||||
}
|
||||
} //-- put
|
||||
/**
|
||||
* Removes the the specified TxObject from the Map
|
||||
* @param key the TxObject which is used to calculate the hashCode of
|
||||
* the TxObject to remove from the Map
|
||||
* @return the TxObject removed from the Map
|
||||
**/
|
||||
TxObject* Map::remove(TxObject* key) {
|
||||
|
||||
if (!key) return 0;
|
||||
|
||||
// compute hash for key
|
||||
PRUint32 hashCode = key->hashCode();
|
||||
|
||||
int idx = hashCode % numberOfBuckets;
|
||||
|
||||
BucketItem* bktItem = elements[idx];
|
||||
|
||||
while ( bktItem ) {
|
||||
if ( bktItem->key->equals(key) ) break;
|
||||
bktItem = bktItem->next;
|
||||
}
|
||||
|
||||
if ( bktItem ) {
|
||||
if (bktItem == elements[idx]) elements[idx] = bktItem->next;
|
||||
else bktItem->prev->next = bktItem->next;
|
||||
numberOfElements--;
|
||||
TxObject* txObject = bktItem->item;
|
||||
bktItem->item = 0;
|
||||
delete bktItem;
|
||||
return txObject;
|
||||
}
|
||||
return 0;
|
||||
|
||||
} //-- remove
|
||||
|
||||
/**
|
||||
* Sets the ownership flag.
|
||||
**/
|
||||
void Map::setOwnership(txMapOwnership aOwnership) {
|
||||
mOwnership = aOwnership;
|
||||
} //-- setOwnership
|
||||
|
||||
/**
|
||||
* Returns the number of key-object pairs in the Map
|
||||
* @return the number of key-object pairs in the Map
|
||||
**/
|
||||
int Map::size() {
|
||||
return numberOfElements;
|
||||
} //-- size
|
||||
|
||||
//-------------------/
|
||||
//- Private Methods -/
|
||||
//-------------------/
|
||||
|
||||
Map::BucketItem* Map::createBucketItem(TxObject* key, TxObject* obj)
|
||||
{
|
||||
BucketItem* bktItem = new BucketItem;
|
||||
bktItem->next = 0;
|
||||
bktItem->prev = 0;
|
||||
bktItem->key = key;
|
||||
bktItem->item = obj;
|
||||
return bktItem;
|
||||
} //-- createBucketItem
|
||||
|
||||
Map::BucketItem* Map::getBucketItem(TxObject* key) {
|
||||
|
||||
// compute hash for key
|
||||
PRUint32 hashCode = key->hashCode();
|
||||
|
||||
int idx = hashCode % numberOfBuckets;
|
||||
|
||||
BucketItem* bktItem = elements[idx];
|
||||
|
||||
while ( bktItem ) {
|
||||
if ( bktItem->key->equals(key) ) return bktItem;
|
||||
bktItem = bktItem->next;
|
||||
}
|
||||
|
||||
return bktItem;
|
||||
|
||||
} //-- getBucketItem
|
||||
@ -1,168 +0,0 @@
|
||||
/*
|
||||
* 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 XSL:P XSLT processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Keith Visco.
|
||||
*
|
||||
* Portions created by Keith Visco (C) 1999-2000 Keith Visco.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* A Hashtable for TxObjects
|
||||
*/
|
||||
|
||||
#ifndef TRANSFRMX_MAP_H
|
||||
#define TRANSFRMX_MAP_H
|
||||
|
||||
#include "baseutils.h"
|
||||
#include "TxObject.h"
|
||||
|
||||
class txList;
|
||||
|
||||
class Map : public TxObject {
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//----------------/
|
||||
//- Constructors -/
|
||||
//----------------/
|
||||
|
||||
/**
|
||||
* Creates a new Map with the default Size
|
||||
**/
|
||||
Map();
|
||||
|
||||
/**
|
||||
* Creates a new Map with the specified number of buckets
|
||||
**/
|
||||
Map(int size);
|
||||
|
||||
/**
|
||||
* Destructor for a Map table, will not delete references unless
|
||||
* The setObjectDeletion flag has been set to MB_TRUE
|
||||
**/
|
||||
virtual ~Map();
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of all the keys of this Map.
|
||||
*
|
||||
* You will need to delete this List when you are done with it.
|
||||
**/
|
||||
txList* keys();
|
||||
|
||||
/**
|
||||
* Returns the object reference in this Map associated with the given name
|
||||
* @return the object reference in this Map associated with the given name
|
||||
**/
|
||||
TxObject* get(TxObject* key);
|
||||
|
||||
/**
|
||||
* Adds the TxObject reference to the map and associates it with the given
|
||||
* key
|
||||
**/
|
||||
void put(TxObject* key, TxObject* obj);
|
||||
|
||||
/**
|
||||
* enum used when setting ownership
|
||||
**/
|
||||
enum txMapOwnership
|
||||
{
|
||||
eOwnsNone = 0x00,
|
||||
eOwnsItems = 0x01,
|
||||
eOwnsKeys = 0x02,
|
||||
eOwnsKeysAndItems = eOwnsItems | eOwnsKeys
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes all elements from the Map. Deletes objects according
|
||||
* to the mOwnership attribute
|
||||
**/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Returns true if there are no elements in this Map
|
||||
* @return true if there are no elements in this Map.
|
||||
**/
|
||||
MBool isEmpty();
|
||||
|
||||
// THIS IS DEPRECATED
|
||||
TxObject* remove(TxObject* key);
|
||||
|
||||
// THIS IS DEPRECATED, use setOwnership
|
||||
void setObjectDeletion(MBool deleteObjects)
|
||||
{
|
||||
setOwnership(deleteObjects ? eOwnsKeysAndItems : eOwnsNone );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ownership attribute.
|
||||
**/
|
||||
void setOwnership(txMapOwnership aOwnership);
|
||||
|
||||
/**
|
||||
* Returns the number of key-element pairs in the Map
|
||||
* @return the number of key-element in the Map
|
||||
**/
|
||||
int size();
|
||||
|
||||
//-------------------/
|
||||
//- Private Members -/
|
||||
//-------------------/
|
||||
|
||||
|
||||
private:
|
||||
|
||||
struct BucketItem {
|
||||
TxObject* key;
|
||||
TxObject* item;
|
||||
BucketItem* next;
|
||||
BucketItem* prev;
|
||||
};
|
||||
|
||||
static const int DEFAULT_SIZE;
|
||||
|
||||
// map table
|
||||
BucketItem** elements;
|
||||
|
||||
PRInt32 numberOfBuckets;
|
||||
PRInt32 numberOfElements;
|
||||
|
||||
/**
|
||||
* The ownership flag. Used to decide which objects are
|
||||
* owned by the map and thus should be deleted when released
|
||||
**/
|
||||
txMapOwnership mOwnership;
|
||||
|
||||
//-------------------/
|
||||
//- Private Methods -/
|
||||
//-------------------/
|
||||
|
||||
BucketItem* createBucketItem(TxObject* key, TxObject* objPtr);
|
||||
|
||||
BucketItem* getBucketItem(TxObject* key);
|
||||
|
||||
/**
|
||||
* Helper method for constructors
|
||||
**/
|
||||
void initialize(int size);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -51,4 +51,34 @@
|
||||
#define NS_ERROR_XPATH_INVALID_ARG NS_ERROR_INVALID_ARG
|
||||
#define NS_ERROR_XSLT_INVALID_URL NS_ERROR_INVALID_ARG
|
||||
|
||||
#define NS_ERROR_XSLT_PARSE_FAILURE \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 1)
|
||||
|
||||
#define NS_ERROR_XPATH_PARSE_FAILURE \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 2)
|
||||
|
||||
#define NS_ERROR_XSLT_GET_NEW_HANDLER \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 3)
|
||||
|
||||
#define NS_ERROR_XSLT_ALREADY_SET \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 4)
|
||||
|
||||
#define NS_ERROR_XSLT_EXECUTION_FAILURE \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 5)
|
||||
|
||||
#define NS_ERROR_XPATH_UNKNOWN_FUNCTION \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 6)
|
||||
|
||||
#define NS_ERROR_XSLT_BAD_RECURSION \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 7)
|
||||
|
||||
#define NS_ERROR_XSLT_BAD_VALUE \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 8)
|
||||
|
||||
#define NS_ERROR_XSLT_NODESET_EXPECTED \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 9)
|
||||
|
||||
#define NS_ERROR_XSLT_ABORTED \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 10)
|
||||
|
||||
#endif // __TX_ERROR
|
||||
|
||||
@ -65,7 +65,7 @@ nsresult txExpandedNameMap::add(const txExpandedName& aKey, TxObject* aValue)
|
||||
for (i = 0; i < mItemCount; ++i) {
|
||||
if (mItems[i].mLocalName == aKey.mLocalName &&
|
||||
mItems[i].mNamespaceID == aKey.mNamespaceID) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return NS_ERROR_XSLT_ALREADY_SET;
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ nsresult txExpandedNameMap::set(const txExpandedName& aKey, TxObject* aValue)
|
||||
* @param aKey key for item to get
|
||||
* @return item with specified key, or null if no such item exists
|
||||
*/
|
||||
TxObject* txExpandedNameMap::get(const txExpandedName& aKey)
|
||||
TxObject* txExpandedNameMap::get(const txExpandedName& aKey) const
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < mItemCount; ++i) {
|
||||
|
||||
@ -73,7 +73,7 @@ public:
|
||||
* @param aKey key for item to get
|
||||
* @return item with specified key, or null if no such item exists
|
||||
*/
|
||||
TxObject* get(const txExpandedName& aKey);
|
||||
TxObject* get(const txExpandedName& aKey) const;
|
||||
|
||||
/**
|
||||
* Removes an item, deleting it if the map owns the values
|
||||
|
||||
131
mozilla/extensions/transformiix/source/base/txNamespaceMap.cpp
Normal file
131
mozilla/extensions/transformiix/source/base/txNamespaceMap.cpp
Normal 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
|
||||
* Jonas Sicking.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* Jonas Sicking. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking <jonas@sicking.cc>
|
||||
*
|
||||
* 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 "txNamespaceMap.h"
|
||||
#include "dom.h"
|
||||
#include "txAtoms.h"
|
||||
|
||||
txNamespaceMap::txNamespaceMap()
|
||||
{
|
||||
}
|
||||
|
||||
txNamespaceMap::txNamespaceMap(const txNamespaceMap& aOther)
|
||||
: mPrefixes(aOther.mPrefixes)
|
||||
{
|
||||
mNamespaces = aOther.mNamespaces; //bah! I want a copy-constructor!
|
||||
}
|
||||
|
||||
nsresult
|
||||
txNamespaceMap::addNamespace(nsIAtom* aPrefix, const nsAString& aNamespaceURI)
|
||||
{
|
||||
nsIAtom* prefix = aPrefix == txXMLAtoms::_empty ? 0 : aPrefix;
|
||||
|
||||
PRInt32 nsId;
|
||||
if (!prefix && aNamespaceURI.IsEmpty()) {
|
||||
nsId = kNameSpaceID_None;
|
||||
}
|
||||
else {
|
||||
#ifdef TX_EXE
|
||||
nsId = txNamespaceManager::getNamespaceID(aNamespaceURI);
|
||||
#else
|
||||
NS_ASSERTION(gTxNameSpaceManager, "No namespace manager");
|
||||
gTxNameSpaceManager->RegisterNameSpace(aNamespaceURI, nsId);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Check if the mapping already exists
|
||||
PRInt32 index = mPrefixes.IndexOf(prefix);
|
||||
if (index >= 0) {
|
||||
mNamespaces.ReplaceElementAt(NS_INT32_TO_PTR(nsId), index);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// New mapping
|
||||
if (!mPrefixes.AppendObject(prefix)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (!mNamespaces.AppendElement(NS_INT32_TO_PTR(nsId))) {
|
||||
mPrefixes.RemoveObjectAt(mPrefixes.Count() - 1);
|
||||
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
txNamespaceMap::lookupNamespace(nsIAtom* aPrefix)
|
||||
{
|
||||
if (aPrefix == txXMLAtoms::xml) {
|
||||
return kNameSpaceID_XML;
|
||||
}
|
||||
|
||||
nsIAtom* prefix = aPrefix == txXMLAtoms::_empty ? 0 : aPrefix;
|
||||
|
||||
PRInt32 index = mPrefixes.IndexOf(prefix);
|
||||
if (index >= 0) {
|
||||
return NS_PTR_TO_INT32(mNamespaces.SafeElementAt(index));
|
||||
}
|
||||
|
||||
if (!prefix) {
|
||||
return kNameSpaceID_None;
|
||||
}
|
||||
|
||||
return kNameSpaceID_Unknown;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
txNamespaceMap::lookupNamespace(const nsAString& aPrefix)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> prefix = do_GetAtom(aPrefix);
|
||||
|
||||
return lookupNamespace(prefix);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
txNamespaceMap::lookupNamespaceWithDefault(const nsAString& aPrefix)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> prefix = do_GetAtom(aPrefix);
|
||||
if (prefix != txXSLTAtoms::_poundDefault) {
|
||||
return lookupNamespace(prefix);
|
||||
}
|
||||
|
||||
return lookupNamespace(nsnull);
|
||||
}
|
||||
78
mozilla/extensions/transformiix/source/base/txNamespaceMap.h
Normal file
78
mozilla/extensions/transformiix/source/base/txNamespaceMap.h
Normal file
@ -0,0 +1,78 @@
|
||||
/* -*- 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
|
||||
* Jonas Sicking.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* Jonas Sicking. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking <sicking@bigfoot.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 TRANSFRMX_TXNAMESPACEMAP_H
|
||||
#define TRANSFRMX_TXNAMESPACEMAP_H
|
||||
|
||||
#include "txError.h"
|
||||
#include "baseutils.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsCOMArray.h"
|
||||
|
||||
class txNamespaceMap
|
||||
{
|
||||
public:
|
||||
txNamespaceMap();
|
||||
txNamespaceMap(const txNamespaceMap& aOther);
|
||||
|
||||
nsrefcnt AddRef()
|
||||
{
|
||||
return ++mRefCnt;
|
||||
}
|
||||
nsrefcnt Release()
|
||||
{
|
||||
if (--mRefCnt == 0) {
|
||||
mRefCnt = 1; //stabilize
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
nsresult addNamespace(nsIAtom* aPrefix, const nsAString& aNamespaceURI);
|
||||
PRInt32 lookupNamespace(nsIAtom* aPrefix);
|
||||
PRInt32 lookupNamespace(const nsAString& aPrefix);
|
||||
PRInt32 lookupNamespaceWithDefault(const nsAString& aPrefix);
|
||||
|
||||
private:
|
||||
nsAutoRefCnt mRefCnt;
|
||||
nsCOMArray<nsIAtom> mPrefixes;
|
||||
nsVoidArray mNamespaces;
|
||||
};
|
||||
|
||||
#endif //TRANSFRMX_TXNAMESPACEMAP_H
|
||||
@ -36,10 +36,10 @@ REQUIRES = string \
|
||||
|
||||
OBJS = ../base/Double.$(OBJ_SUFFIX) \
|
||||
../base/List.$(OBJ_SUFFIX) \
|
||||
../base/Map.$(OBJ_SUFFIX) \
|
||||
../base/SimpleErrorObserver.$(OBJ_SUFFIX) \
|
||||
../base/txAtoms.$(OBJ_SUFFIX) \
|
||||
../base/txExpandedNameMap.$(OBJ_SUFFIX) \
|
||||
../base/txNamespaceMap.$(OBJ_SUFFIX) \
|
||||
../base/txStringUtils.$(OBJ_SUFFIX) \
|
||||
../base/txURIUtils.$(OBJ_SUFFIX) \
|
||||
../xml/dom/standalone/Attr.$(OBJ_SUFFIX) \
|
||||
@ -82,21 +82,27 @@ OBJS = ../base/Double.$(OBJ_SUFFIX) \
|
||||
../xml/XMLUtils.$(OBJ_SUFFIX) \
|
||||
../xml/XMLDOMUtils.$(OBJ_SUFFIX) \
|
||||
../xml/parser/txXMLParser.$(OBJ_SUFFIX) \
|
||||
../xslt/txOutputFormat.$(OBJ_SUFFIX) \
|
||||
../xslt/ProcessorState.$(OBJ_SUFFIX) \
|
||||
../xslt/txBufferingHandler.$(OBJ_SUFFIX) \
|
||||
../xslt/txExecutionState.$(OBJ_SUFFIX) \
|
||||
../xslt/txHTMLOutput.$(OBJ_SUFFIX) \
|
||||
../xslt/txInstructions.$(OBJ_SUFFIX) \
|
||||
../xslt/txOutputFormat.$(OBJ_SUFFIX) \
|
||||
../xslt/txRtfHandler.$(OBJ_SUFFIX) \
|
||||
../xslt/txStandaloneXSLTProcessor.$(OBJ_SUFFIX) \
|
||||
../xslt/txStandaloneStylesheetCompiler.$(OBJ_SUFFIX) \
|
||||
../xslt/txStylesheet.$(OBJ_SUFFIX) \
|
||||
../xslt/txStylesheetCompileHandlers.$(OBJ_SUFFIX) \
|
||||
../xslt/txStylesheetCompiler.$(OBJ_SUFFIX) \
|
||||
../xslt/txTextHandler.$(OBJ_SUFFIX) \
|
||||
../xslt/txTextOutput.$(OBJ_SUFFIX) \
|
||||
../xslt/txToplevelItems.$(OBJ_SUFFIX) \
|
||||
../xslt/txUnknownHandler.$(OBJ_SUFFIX) \
|
||||
../xslt/txXMLOutput.$(OBJ_SUFFIX) \
|
||||
../xslt/txXSLTNumber.$(OBJ_SUFFIX) \
|
||||
../xslt/txXSLTNumberCounters.$(OBJ_SUFFIX) \
|
||||
../xslt/txXSLTPatterns.$(OBJ_SUFFIX) \
|
||||
../xslt/txPatternParser.$(OBJ_SUFFIX) \
|
||||
../xslt/XSLTProcessor.$(OBJ_SUFFIX) \
|
||||
../xslt/txStandaloneXSLTProcessor.$(OBJ_SUFFIX) \
|
||||
../xslt/txXSLTProcessor.$(OBJ_SUFFIX) \
|
||||
../xslt/functions/CurrentFunctionCall.$(OBJ_SUFFIX) \
|
||||
../xslt/functions/DocumentFunctionCall.$(OBJ_SUFFIX) \
|
||||
../xslt/functions/ElementAvailableFnCall.$(OBJ_SUFFIX) \
|
||||
@ -121,3 +127,4 @@ INCLUDES += -I$(srcdir)/../xslt -I$(srcdir)/../base -I$(srcdir)/../net \
|
||||
-I$(srcdir)/../xml/parser \
|
||||
-I$(srcdir)/../xpath -I$(srcdir)/../xslt/util \
|
||||
-I$(srcdir)/../xslt/functions $(MARK_INC)
|
||||
DEFINES += -DXML_DTD -DXML_UNICODE
|
||||
|
||||
@ -259,7 +259,7 @@ void runCategory(nsIFile* aConfCat, nsIFile* aGoldCat, nsIFile* aRefTmp,
|
||||
aRefTmp->GetFileSize(&resultSize);
|
||||
reference->GetFileSize(&refSize);
|
||||
result.seekg(0);
|
||||
int read, toread = (int)resultSize;
|
||||
int toread = (int)resultSize;
|
||||
nsCString resContent, refContent;
|
||||
resContent.SetCapacity(toread);
|
||||
readToString(result, resContent);
|
||||
@ -344,7 +344,7 @@ int main(int argc, char** argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (!txXSLTProcessor::txInit()) {
|
||||
if (!txXSLTProcessor::init()) {
|
||||
PRBool exists;
|
||||
if (NS_SUCCEEDED(resFile->Exists(&exists)) && exists)
|
||||
resFile->Remove(PR_FALSE);
|
||||
@ -408,7 +408,7 @@ int main(int argc, char** argv)
|
||||
if (NS_SUCCEEDED(resFile->Exists(&exists)) && exists)
|
||||
resFile->Remove(PR_FALSE);
|
||||
resultFileStream.close();
|
||||
txXSLTProcessor::txShutdown();
|
||||
txXSLTProcessor::shutdown();
|
||||
rv = NS_ShutdownXPCOM(nsnull);
|
||||
#ifdef NS_TRACE_MALLOC
|
||||
NS_TraceMallocShutdown();
|
||||
|
||||
@ -124,7 +124,7 @@ int main(int argc, char** argv)
|
||||
rv = NS_InitXPCOM2(nsnull, nsnull, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!txXSLTProcessor::txInit())
|
||||
if (!txXSLTProcessor::init())
|
||||
return 1;
|
||||
|
||||
txOptions options;
|
||||
@ -189,7 +189,7 @@ int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
resultFileStream.close();
|
||||
txXSLTProcessor::txShutdown();
|
||||
txXSLTProcessor::shutdown();
|
||||
rv = NS_ShutdownXPCOM(nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return 0;
|
||||
|
||||
@ -43,6 +43,7 @@
|
||||
* See http://www.datapower.com/XSLTMark/
|
||||
*/
|
||||
|
||||
#include "txStandaloneStylesheetCompiler.h"
|
||||
#include "txStandaloneXSLTProcessor.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "xmExternalDriver.hpp"
|
||||
@ -51,15 +52,16 @@ class txDriverProcessor : public txStandaloneXSLTProcessor,
|
||||
public xmExternalDriver
|
||||
{
|
||||
public:
|
||||
txDriverProcessor() : mXSL(0), mXML(0), mOut(0)
|
||||
txDriverProcessor() : mXML(0), mOut(0)
|
||||
{
|
||||
}
|
||||
|
||||
int loadStylesheet (char * filename)
|
||||
{
|
||||
delete mXSL;
|
||||
mXSL = parsePath(nsDependentCString(filename), mObserver);
|
||||
return mXSL ? 0 : 1;
|
||||
NS_ConvertASCIItoUCS2 path(filename);
|
||||
nsresult rv =
|
||||
TX_CompileStylesheetPath(path, getter_AddRefs(mStylesheet));
|
||||
return NS_SUCCEEDED(rv) ? 0 : 1;
|
||||
}
|
||||
int setInputDocument (char * filename)
|
||||
{
|
||||
@ -74,7 +76,9 @@ public:
|
||||
}
|
||||
int runTransform ()
|
||||
{
|
||||
nsresult rv = transform(mXML, mXSL, *mOut, mObserver);
|
||||
if (!mXML || !mStylesheet || !mOut)
|
||||
return 1;
|
||||
nsresult rv = transform(mXML, mStylesheet, *mOut, mObserver);
|
||||
return NS_FAILED(rv);
|
||||
}
|
||||
int closeOutput ()
|
||||
@ -87,8 +91,6 @@ public:
|
||||
}
|
||||
int terminate()
|
||||
{
|
||||
delete mXSL;
|
||||
mXSL = 0;
|
||||
delete mXML;
|
||||
mXML = 0;
|
||||
if (mOut && mOut->is_open())
|
||||
@ -99,12 +101,12 @@ public:
|
||||
}
|
||||
~txDriverProcessor()
|
||||
{
|
||||
delete mXSL;
|
||||
delete mXML;
|
||||
delete mOut;
|
||||
}
|
||||
private:
|
||||
Document *mXSL, *mXML;
|
||||
Document *mXML;
|
||||
nsRefPtr<txStylesheet> mStylesheet;
|
||||
SimpleErrorObserver mObserver;
|
||||
ofstream* mOut;
|
||||
};
|
||||
@ -113,10 +115,10 @@ int main (int argc, char ** argv)
|
||||
{
|
||||
txDriverProcessor driver;
|
||||
NS_InitXPCOM2(nsnull, nsnull, nsnull);
|
||||
if (!txDriverProcessor::txInit())
|
||||
if (!txDriverProcessor::init())
|
||||
return 1;
|
||||
driver.main (argc, argv);
|
||||
txDriverProcessor::txShutdown();
|
||||
txDriverProcessor::shutdown();
|
||||
NS_ShutdownXPCOM(nsnull);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
#include "nsReadableUtils.h"
|
||||
#include "txAtoms.h"
|
||||
#include "txStringUtils.h"
|
||||
#include "txNamespaceMap.h"
|
||||
|
||||
/**
|
||||
* Helper class for checking and partioning of QNames
|
||||
@ -113,11 +114,10 @@ txQNameParser::parse(const nsAString::const_iterator& aStart,
|
||||
return eBrokenName;
|
||||
}
|
||||
|
||||
nsresult txExpandedName::init(const nsAString& aQName,
|
||||
Node* aResolver,
|
||||
MBool aUseDefault)
|
||||
nsresult
|
||||
txExpandedName::init(const nsAString& aQName, txNamespaceMap* aResolver,
|
||||
MBool aUseDefault)
|
||||
{
|
||||
NS_ASSERTION(aResolver, "missing resolve node");
|
||||
nsAString::const_iterator start, end;
|
||||
aQName.BeginReading(start);
|
||||
aQName.EndReading(end);
|
||||
@ -131,7 +131,7 @@ nsresult txExpandedName::init(const nsAString& aQName,
|
||||
if (qr == txQNameParser::eTwoNames) {
|
||||
nsCOMPtr<nsIAtom> prefix =
|
||||
do_GetAtom(Substring(start, p.mColon));
|
||||
PRInt32 namespaceID = aResolver->lookupNamespaceID(prefix);
|
||||
PRInt32 namespaceID = aResolver->lookupNamespace(prefix);
|
||||
if (namespaceID == kNameSpaceID_Unknown)
|
||||
return NS_ERROR_FAILURE;
|
||||
mNamespaceID = namespaceID;
|
||||
@ -141,7 +141,7 @@ nsresult txExpandedName::init(const nsAString& aQName,
|
||||
else {
|
||||
mLocalName = do_GetAtom(aQName);
|
||||
if (aUseDefault)
|
||||
mNamespaceID = aResolver->lookupNamespaceID(0);
|
||||
mNamespaceID = aResolver->lookupNamespace(0);
|
||||
else
|
||||
mNamespaceID = kNameSpaceID_None;
|
||||
}
|
||||
@ -152,6 +152,30 @@ nsresult txExpandedName::init(const nsAString& aQName,
|
||||
//- Implementation of XMLUtils -/
|
||||
//------------------------------/
|
||||
|
||||
nsresult
|
||||
XMLUtils::splitXMLName(const nsAString& aName, nsIAtom** aPrefix,
|
||||
nsIAtom** aLocalName)
|
||||
{
|
||||
nsAString::const_iterator start, end;
|
||||
aName.BeginReading(start);
|
||||
aName.EndReading(end);
|
||||
txQNameParser p;
|
||||
txQNameParser::QResult qr = p.parse(start, end);
|
||||
|
||||
if (qr == txQNameParser::eBrokenName) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (qr == txQNameParser::eTwoNames) {
|
||||
*aPrefix = NS_NewAtom(Substring(start, p.mColon));
|
||||
*aLocalName = NS_NewAtom(Substring(++p.mColon, end));
|
||||
}
|
||||
else {
|
||||
*aPrefix = nsnull;
|
||||
*aLocalName = NS_NewAtom(aName);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void XMLUtils::getPrefix(const nsAString& src, nsIAtom** dest)
|
||||
{
|
||||
// Anything preceding ':' is the namespace part of the name
|
||||
|
||||
@ -36,6 +36,8 @@
|
||||
#include "nsIAtom.h"
|
||||
#include "txError.h"
|
||||
|
||||
class txNamespaceMap;
|
||||
|
||||
class txExpandedName {
|
||||
public:
|
||||
txExpandedName() : mNamespaceID(kNameSpaceID_None)
|
||||
@ -58,7 +60,19 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
nsresult init(const nsAString& aQName, Node* aResolver, MBool aUseDefault);
|
||||
nsresult init(const nsAString& aQName, txNamespaceMap* aResolver,
|
||||
MBool aUseDefault);
|
||||
|
||||
void reset()
|
||||
{
|
||||
mNamespaceID = kNameSpaceID_None;
|
||||
mLocalName = nsnull;
|
||||
}
|
||||
|
||||
PRBool isNull()
|
||||
{
|
||||
return mNamespaceID == kNameSpaceID_None && !mLocalName;
|
||||
}
|
||||
|
||||
txExpandedName& operator = (const txExpandedName& rhs)
|
||||
{
|
||||
@ -86,7 +100,8 @@ public:
|
||||
class XMLUtils {
|
||||
|
||||
public:
|
||||
|
||||
static nsresult splitXMLName(const nsAString& aName, nsIAtom** aPrefix,
|
||||
nsIAtom** aLocalName);
|
||||
static void getPrefix(const nsAString& src, nsIAtom** dest);
|
||||
static const nsDependentSubstring getLocalPart(const nsAString& src);
|
||||
static void getLocalPart(const nsAString& src, nsIAtom** dest);
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
#include "nsString.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "TxObject.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
/*
|
||||
XPath class definitions.
|
||||
@ -343,18 +344,13 @@ public:
|
||||
* @param nodeExpr the NodeExpr to use when matching Nodes
|
||||
* @param axisIdentifier the Axis Identifier in which to search for nodes
|
||||
**/
|
||||
LocationStep(txNodeTest* aNodeTest, LocationStepType aAxisIdentifier);
|
||||
|
||||
/**
|
||||
* Destructor, will delete all predicates and the given NodeExpr
|
||||
**/
|
||||
virtual ~LocationStep();
|
||||
LocationStep(nsAutoPtr<txNodeTest> aNodeTest, LocationStepType aAxisIdentifier);
|
||||
|
||||
TX_DECL_EXPR;
|
||||
|
||||
private:
|
||||
|
||||
txNodeTest* mNodeTest;
|
||||
nsAutoPtr<txNodeTest> mNodeTest;
|
||||
LocationStepType mAxisIdentifier;
|
||||
|
||||
void fromDescendants(Node* node, txIMatchContext* aContext,
|
||||
|
||||
@ -499,11 +499,10 @@ Expr* ExprParser::createFunctionCall(ExprLexer& lexer,
|
||||
}
|
||||
rv = aContext->resolveFunctionCall(lName, namespaceID, fnCall);
|
||||
|
||||
// XXX this should be removed once we don't return
|
||||
// NS_ERROR_NOT_IMPLEMENTED for unparsed-entity-uri(). As should the
|
||||
// code in parseParameters that deals with fnCall = 0.
|
||||
// Bug 65981
|
||||
if (rv == NS_ERROR_NOT_IMPLEMENTED) {
|
||||
// XXX We should have an errorfunction that always fails
|
||||
// and use that here
|
||||
if (rv == NS_ERROR_NOT_IMPLEMENTED ||
|
||||
rv == NS_ERROR_XPATH_UNKNOWN_FUNCTION) {
|
||||
NS_ASSERTION(!fnCall, "Now is it implemented or not?");
|
||||
if (!parseParameters(0, lexer, aContext)) {
|
||||
return 0;
|
||||
@ -537,7 +536,7 @@ LocationStep* ExprParser::createLocationStep(ExprLexer& lexer,
|
||||
{
|
||||
//-- child axis is default
|
||||
LocationStep::LocationStepType axisIdentifier = LocationStep::CHILD_AXIS;
|
||||
txNodeTest* nodeTest = 0;
|
||||
nsAutoPtr<txNodeTest> nodeTest;
|
||||
|
||||
//-- get Axis Identifier or AbbreviatedStep, if present
|
||||
Token* tok = lexer.peek();
|
||||
@ -677,7 +676,6 @@ LocationStep* ExprParser::createLocationStep(ExprLexer& lexer,
|
||||
LocationStep* lstep = new LocationStep(nodeTest, axisIdentifier);
|
||||
if (!lstep) {
|
||||
//XXX out of memory
|
||||
delete nodeTest;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -126,7 +126,7 @@ NodeSet* FunctionCall::evaluateToNodeSet(Expr* aExpr, txIEvalContext* aContext)
|
||||
return 0;
|
||||
|
||||
if (exprResult->getResultType() != ExprResult::NODESET) {
|
||||
aContext->receiveError(NS_LITERAL_STRING("NodeSet expected as argument"), NS_ERROR_XPATH_INVALID_ARG);
|
||||
aContext->receiveError(NS_LITERAL_STRING("NodeSet expected as argument"), NS_ERROR_XSLT_NODESET_EXPECTED);
|
||||
delete exprResult;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -36,21 +36,12 @@
|
||||
* @param nodeExpr the NodeExpr to use when matching Nodes
|
||||
* @param axisIdentifier the Axis Identifier in which to search for nodes
|
||||
**/
|
||||
LocationStep::LocationStep(txNodeTest* aNodeTest,
|
||||
LocationStep::LocationStep(nsAutoPtr<txNodeTest> aNodeTest,
|
||||
LocationStepType aAxisIdentifier)
|
||||
: mNodeTest(aNodeTest), mAxisIdentifier(aAxisIdentifier)
|
||||
{
|
||||
} //-- LocationStep
|
||||
|
||||
/**
|
||||
* Destroys this LocationStep
|
||||
* All predicates will be deleted
|
||||
* The NodeExpr will be deleted
|
||||
**/
|
||||
LocationStep::~LocationStep() {
|
||||
delete mNodeTest;
|
||||
} //-- ~LocationStep
|
||||
|
||||
//-----------------------------/
|
||||
//- Virtual methods from Expr -/
|
||||
//-----------------------------/
|
||||
|
||||
@ -178,6 +178,12 @@ MBool nsXPathExpression::EvalContextImpl::isStripSpaceAllowed(Node* aNode)
|
||||
return MB_FALSE;
|
||||
}
|
||||
|
||||
void* nsXPathExpression::EvalContextImpl::getPrivateContext()
|
||||
{
|
||||
// we don't have a private context here.
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void nsXPathExpression::EvalContextImpl::receiveError(const nsAString& aMsg,
|
||||
nsresult aRes)
|
||||
{
|
||||
|
||||
@ -69,6 +69,12 @@ MBool txForwardContext::isStripSpaceAllowed(Node* aNode)
|
||||
return mInner->isStripSpaceAllowed(aNode);
|
||||
}
|
||||
|
||||
void* txForwardContext::getPrivateContext()
|
||||
{
|
||||
NS_ASSERTION(mInner, "mInner is null!!!");
|
||||
return mInner->getPrivateContext();
|
||||
}
|
||||
|
||||
void txForwardContext::receiveError(const nsAString& aMsg, nsresult aRes)
|
||||
{
|
||||
NS_ASSERTION(mInner, "mInner is null!!!");
|
||||
|
||||
@ -115,6 +115,11 @@ public:
|
||||
*/
|
||||
virtual MBool isStripSpaceAllowed(Node* aNode) = 0;
|
||||
|
||||
/**
|
||||
* Returns a pointer to the private context
|
||||
*/
|
||||
virtual void* getPrivateContext() = 0;
|
||||
|
||||
/*
|
||||
* Callback to be used by the expression/pattern if errors are detected.
|
||||
*/
|
||||
@ -125,6 +130,7 @@ public:
|
||||
nsresult getVariable(PRInt32 aNamespace, nsIAtom* aLName, \
|
||||
ExprResult*& aResult); \
|
||||
MBool isStripSpaceAllowed(Node* aNode); \
|
||||
void* getPrivateContext(); \
|
||||
void receiveError(const nsAString& aMsg, nsresult aRes)
|
||||
|
||||
class txIEvalContext : public txIMatchContext
|
||||
|
||||
@ -68,6 +68,12 @@ MBool txNodeSetContext::isStripSpaceAllowed(Node* aNode)
|
||||
return mInner->isStripSpaceAllowed(aNode);
|
||||
}
|
||||
|
||||
void* txNodeSetContext::getPrivateContext()
|
||||
{
|
||||
NS_ASSERTION(mInner, "mInner is null!!!");
|
||||
return mInner->getPrivateContext();
|
||||
}
|
||||
|
||||
void txNodeSetContext::receiveError(const nsAString& aMsg, nsresult aRes)
|
||||
{
|
||||
NS_ASSERTION(mInner, "mInner is null!!!");
|
||||
|
||||
@ -40,8 +40,7 @@
|
||||
#define __TX_XPATH_SET_CONTEXT
|
||||
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
class NodeSet;
|
||||
#include "NodeSet.h"
|
||||
|
||||
class txNodeSetContext : public txIEvalContext
|
||||
{
|
||||
@ -50,7 +49,7 @@ public:
|
||||
: mContextSet(aContextNodeSet), mPosition(0), mInner(aContext)
|
||||
{
|
||||
}
|
||||
~txNodeSetContext()
|
||||
virtual ~txNodeSetContext()
|
||||
{
|
||||
}
|
||||
|
||||
@ -67,10 +66,23 @@ public:
|
||||
|
||||
TX_DECL_EVAL_CONTEXT;
|
||||
|
||||
private:
|
||||
protected:
|
||||
NodeSet* mContextSet;
|
||||
PRUint32 mPosition;
|
||||
txIMatchContext* mInner;
|
||||
};
|
||||
|
||||
class txOwningNodeSetContext : public txNodeSetContext
|
||||
{
|
||||
public:
|
||||
txOwningNodeSetContext(NodeSet* aContextNodeSet, txIMatchContext* aContext)
|
||||
: txNodeSetContext(aContextNodeSet, aContext)
|
||||
{
|
||||
}
|
||||
virtual ~txOwningNodeSetContext()
|
||||
{
|
||||
delete mContextSet;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __TX_XPATH_SET_CONTEXT
|
||||
|
||||
@ -66,6 +66,12 @@ public:
|
||||
return mInner->isStripSpaceAllowed(aNode);
|
||||
}
|
||||
|
||||
void* getPrivateContext()
|
||||
{
|
||||
NS_ASSERTION(mInner, "mInner is null!!!");
|
||||
return mInner->getPrivateContext();
|
||||
}
|
||||
|
||||
void receiveError(const nsAString& aMsg, nsresult aRes)
|
||||
{
|
||||
NS_ASSERTION(mInner, "mInner is null!!!");
|
||||
|
||||
@ -44,28 +44,40 @@ REQUIRES += dom \
|
||||
webshell \
|
||||
docshell \
|
||||
layout \
|
||||
uconv \
|
||||
$(NULL)
|
||||
else
|
||||
REQUIRES += expat \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
CPPSRCS = txOutputFormat.cpp \
|
||||
ProcessorState.cpp \
|
||||
CPPSRCS = \
|
||||
txBufferingHandler.cpp \
|
||||
txExecutionState.cpp \
|
||||
txInstructions.cpp \
|
||||
txOutputFormat.cpp \
|
||||
txRtfHandler.cpp \
|
||||
txStylesheet.cpp \
|
||||
txStylesheetCompileHandlers.cpp \
|
||||
txStylesheetCompiler.cpp \
|
||||
txTextHandler.cpp \
|
||||
txToplevelItems.cpp \
|
||||
txXSLTNumber.cpp \
|
||||
txXSLTNumberCounters.cpp \
|
||||
txXSLTPatterns.cpp \
|
||||
txXSLTProcessor.cpp \
|
||||
txPatternParser.cpp \
|
||||
txUnknownHandler.cpp \
|
||||
XSLTProcessor.cpp
|
||||
txUnknownHandler.cpp
|
||||
|
||||
ifdef TX_EXE
|
||||
CPPSRCS += txHTMLOutput.cpp \
|
||||
txStandaloneXSLTProcessor.cpp \
|
||||
txStandaloneStylesheetCompiler.cpp \
|
||||
txTextOutput.cpp \
|
||||
txXMLOutput.cpp
|
||||
else
|
||||
CPPSRCS += txMozillaTextOutput.cpp \
|
||||
CPPSRCS += txMozillaStylesheetCompiler.cpp \
|
||||
txMozillaTextOutput.cpp \
|
||||
txMozillaXMLOutput.cpp \
|
||||
txMozillaXSLTProcessor.cpp
|
||||
endif
|
||||
@ -76,5 +88,8 @@ INCLUDES += -I$(srcdir) -I$(srcdir)/../base \
|
||||
-I$(srcdir)/../xml -I$(srcdir)/../xml/dom \
|
||||
-I$(srcdir)/../xml/parser \
|
||||
-I$(srcdir)/../xpath -I$(srcdir)/util -I$(srcdir)/functions
|
||||
ifdef TX_EXE
|
||||
DEFINES += -DXML_DTD -DXML_UNICODE
|
||||
endif
|
||||
|
||||
libs:: $(OBJS)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,574 +0,0 @@
|
||||
/* -*- 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
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef TRANSFRMX_PROCESSORSTATE_H
|
||||
#define TRANSFRMX_PROCESSORSTATE_H
|
||||
|
||||
#include "NodeSet.h"
|
||||
#include "ErrorObserver.h"
|
||||
#include "txPatternParser.h"
|
||||
#include "Expr.h"
|
||||
#include "txOutputFormat.h"
|
||||
#include "Map.h"
|
||||
#include "txIXPathContext.h"
|
||||
#include "txExpandedNameMap.h"
|
||||
#include "txXMLEventHandler.h"
|
||||
#include "XSLTFunctions.h"
|
||||
#include "txError.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsDoubleHashtable.h"
|
||||
#include "txKey.h"
|
||||
|
||||
class txVariableMap;
|
||||
class txXSLKey;
|
||||
|
||||
class txLoadedDocumentEntry : public PLDHashStringEntry {
|
||||
public:
|
||||
txLoadedDocumentEntry(const void* aKey) : PLDHashStringEntry(aKey)
|
||||
{
|
||||
}
|
||||
~txLoadedDocumentEntry()
|
||||
{
|
||||
delete mDocument;
|
||||
}
|
||||
Document* mDocument;
|
||||
};
|
||||
|
||||
DECL_DHASH_WRAPPER(txLoadedDocumentsBase, txLoadedDocumentEntry, nsAString&)
|
||||
|
||||
class txLoadedDocumentsHash : public txLoadedDocumentsBase
|
||||
{
|
||||
public:
|
||||
~txLoadedDocumentsHash();
|
||||
nsresult init(Document* aSourceDocument, Document* aStyleDocument);
|
||||
void Add(Document* aDocument);
|
||||
Document* Get(const nsAString& aURI);
|
||||
|
||||
private:
|
||||
friend class ProcessorState;
|
||||
Document* mSourceDocument;
|
||||
Document* mStyleDocument;
|
||||
};
|
||||
|
||||
/**
|
||||
* Class used for keeping the current state of the XSL Processor
|
||||
*/
|
||||
class ProcessorState : public txIMatchContext {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new ProcessorState for the given XSL document
|
||||
* And result Document
|
||||
*/
|
||||
ProcessorState(Node* aSourceNode, Document* aXslDocument);
|
||||
|
||||
/**
|
||||
* Destroys this ProcessorState
|
||||
*/
|
||||
~ProcessorState();
|
||||
|
||||
/**
|
||||
* Contain information that is import precedence dependant.
|
||||
*/
|
||||
class ImportFrame {
|
||||
public:
|
||||
ImportFrame(ImportFrame* aFirstNotImported);
|
||||
~ImportFrame();
|
||||
|
||||
// Map of named templates
|
||||
txExpandedNameMap mNamedTemplates;
|
||||
|
||||
// Map of template modes, each item in the map is a list
|
||||
// of templates
|
||||
txExpandedNameMap mMatchableTemplates;
|
||||
|
||||
// List of whitespace preserving and stripping nametests
|
||||
txList mWhiteNameTests;
|
||||
|
||||
// Map of named attribute sets
|
||||
txExpandedNameMap mNamedAttributeSets;
|
||||
|
||||
// Output format, as specified by the xsl:output elements
|
||||
txOutputFormat mOutputFormat;
|
||||
|
||||
// ImportFrame which is the first one *not* imported by this frame
|
||||
ImportFrame* mFirstNotImported;
|
||||
|
||||
// Map of top-level variables/parameters
|
||||
txExpandedNameMap mVariables;
|
||||
|
||||
// The following stuff is missing here:
|
||||
|
||||
// Namespace aliases (xsl:namespace-alias)
|
||||
};
|
||||
// To be able to do some cleaning up in destructor
|
||||
friend class ImportFrame;
|
||||
|
||||
/**
|
||||
* Adds the given attribute set to the list of available named attribute
|
||||
* sets
|
||||
* @param aAttributeSet the Element to add as a named attribute set
|
||||
* @param aImportFrame ImportFrame to add the attributeset to
|
||||
*/
|
||||
void addAttributeSet(Element* aAttributeSet, ImportFrame* aImportFrame);
|
||||
|
||||
/**
|
||||
* Registers the given ErrorObserver with this ProcessorState
|
||||
*/
|
||||
void addErrorObserver(ErrorObserver& errorObserver);
|
||||
|
||||
/**
|
||||
* Adds the given template to the list of templates to process
|
||||
* @param aXslTemplate The Element to add as a template
|
||||
* @param aImportFrame ImportFrame to add the template to
|
||||
*/
|
||||
void addTemplate(Element* aXslTemplate, ImportFrame* aImportFrame);
|
||||
|
||||
/**
|
||||
* Adds the given LRE Stylesheet to the list of templates to process
|
||||
* @param aStylesheet The Stylesheet to add as a template
|
||||
* @param importFrame ImportFrame to add the template to
|
||||
*/
|
||||
void addLREStylesheet(Document* aStylesheet, ImportFrame* aImportFrame);
|
||||
|
||||
/**
|
||||
* Returns the AttributeSet associated with the given name
|
||||
* or null if no AttributeSet is found
|
||||
*/
|
||||
NodeSet* getAttributeSet(const txExpandedName& aName);
|
||||
|
||||
/**
|
||||
* Returns the template associated with the given name, or
|
||||
* null if not template is found
|
||||
*/
|
||||
Element* getNamedTemplate(const txExpandedName& aName);
|
||||
|
||||
/**
|
||||
* Returns the OutputFormat which contains information on how
|
||||
* to serialize the output.
|
||||
*/
|
||||
txOutputFormat* getOutputFormat();
|
||||
|
||||
/**
|
||||
* Add a global variable
|
||||
*/
|
||||
nsresult addGlobalVariable(const txExpandedName& aVarName,
|
||||
Element* aVarElem,
|
||||
ImportFrame* aImportFrame,
|
||||
ExprResult* aDefaultValue);
|
||||
|
||||
/**
|
||||
* Returns map on top of the stack of local variable-bindings
|
||||
*/
|
||||
txVariableMap* getLocalVariables();
|
||||
|
||||
/**
|
||||
* Sets top map of the local variable-bindings stack
|
||||
*/
|
||||
void setLocalVariables(txVariableMap* aMap);
|
||||
|
||||
/**
|
||||
* Enums for the getExpr and getPattern functions
|
||||
*/
|
||||
enum ExprAttr {
|
||||
SelectAttr = 0,
|
||||
TestAttr,
|
||||
ValueAttr
|
||||
};
|
||||
|
||||
enum PatternAttr {
|
||||
CountAttr = 0,
|
||||
FromAttr
|
||||
};
|
||||
|
||||
Expr* getExpr(Element* aElem, ExprAttr aAttr);
|
||||
txPattern* getPattern(Element* aElem, PatternAttr aAttr);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* supplied, the element with seleced id is returned.
|
||||
* The returned document is owned by the ProcessorState
|
||||
*
|
||||
* @param uri the URI of the document to retrieve
|
||||
* @param baseUri the base URI used to resolve the URI if uri is relative
|
||||
* @return loaded document or element pointed to by fragment identifier. If
|
||||
* loading or parsing fails NULL will be returned.
|
||||
*/
|
||||
Node* retrieveDocument(const nsAString& uri, const nsAString& baseUri);
|
||||
|
||||
/**
|
||||
* Return stack of urls of currently entered stylesheets
|
||||
*/
|
||||
nsStringArray& getEnteredStylesheets()
|
||||
{
|
||||
return mEnteredStylesheets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return list of import containers
|
||||
*/
|
||||
List* getImportFrames();
|
||||
|
||||
/**
|
||||
* Find template in specified mode matching the supplied node
|
||||
* @param aNode node to find matching template for
|
||||
* @param aMode mode of the template
|
||||
* @param aImportFrame out-param, is set to the ImportFrame containing
|
||||
* the found template
|
||||
* @return root-node of found template, null if none is found
|
||||
*/
|
||||
Node* findTemplate(Node* aNode,
|
||||
const txExpandedName& aMode,
|
||||
ImportFrame** aImportFrame)
|
||||
{
|
||||
return findTemplate(aNode, aMode, 0, aImportFrame);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find template in specified mode matching the supplied node. Only search
|
||||
* templates imported by a specific ImportFrame
|
||||
* @param aNode node to find matching template for
|
||||
* @param aMode mode of the template
|
||||
* @param aImportedBy seach only templates imported by this ImportFrame,
|
||||
* or null to search all templates
|
||||
* @param aImportFrame out-param, is set to the ImportFrame containing
|
||||
* the found template
|
||||
* @return root-node of found template, null if none is found
|
||||
*/
|
||||
Node* findTemplate(Node* aNode,
|
||||
const txExpandedName& aMode,
|
||||
ImportFrame* aImportedBy,
|
||||
ImportFrame** aImportFrame);
|
||||
|
||||
/**
|
||||
* Struct holding information about a current template rule
|
||||
*/
|
||||
struct TemplateRule {
|
||||
ImportFrame* mFrame;
|
||||
const txExpandedName* mMode;
|
||||
txVariableMap* mParams;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets current template rule
|
||||
*/
|
||||
TemplateRule* getCurrentTemplateRule();
|
||||
|
||||
/**
|
||||
* Sets current template rule
|
||||
*/
|
||||
void setCurrentTemplateRule(TemplateRule* aTemplateRule);
|
||||
|
||||
/**
|
||||
* Adds the set of names to the Whitespace preserving element set
|
||||
*/
|
||||
void preserveSpace(nsAString& names);
|
||||
|
||||
void processAttrValueTemplate(const nsAFlatString& aAttValue,
|
||||
Element* aContext,
|
||||
nsAString& aResult);
|
||||
|
||||
/**
|
||||
* Adds the set of names to the Whitespace stripping handling list.
|
||||
* xsl:strip-space calls this with MB_TRUE, xsl:preserve-space
|
||||
* with MB_FALSE
|
||||
* aElement is used to resolve QNames
|
||||
*/
|
||||
void shouldStripSpace(const nsAString& aNames, Element* aElement,
|
||||
MBool aShouldStrip,
|
||||
ImportFrame* aImportFrame);
|
||||
|
||||
/**
|
||||
* Adds the supplied xsl:key to the set of keys
|
||||
*/
|
||||
MBool addKey(Element* aKeyElem);
|
||||
|
||||
/**
|
||||
* Get the nodeset for a key+document+value. Note that the result can
|
||||
* only be used until the next call to this function.
|
||||
* @param aKeyName Name of key.
|
||||
* @param aDocument Context-document to get key-nodes in.
|
||||
* @param aKeyValue Key-value to get the nodes for.
|
||||
* @param aIndexIfNotFound Check if the requested key is index in the
|
||||
* requested document and if it isn't index it.
|
||||
* This should only be false if it's known that
|
||||
* the key is already indexed in that document.
|
||||
* @param aResult Out-param returning the result. This pointer
|
||||
* can only be used until the next call to
|
||||
* getKeyNodes.
|
||||
*/
|
||||
nsresult getKeyNodes(const txExpandedName& aKeyName, Document* aDocument,
|
||||
const nsAString& aKeyValue, PRBool aIndexIfNotFound,
|
||||
const NodeSet** aResult)
|
||||
{
|
||||
return mKeyHash.getKeyNodes(aKeyName, aDocument, aKeyValue,
|
||||
aIndexIfNotFound, this, aResult);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a decimal format. Returns false if the format already exists
|
||||
* but dosn't contain the exact same parametervalues
|
||||
*/
|
||||
MBool addDecimalFormat(Element* element);
|
||||
|
||||
/**
|
||||
* Returns a decimal format or NULL if no such format exists.
|
||||
*/
|
||||
txDecimalFormat* getDecimalFormat(const txExpandedName& name);
|
||||
|
||||
/**
|
||||
* Returns the stylesheet document
|
||||
*/
|
||||
Document* getStylesheetDocument();
|
||||
|
||||
/**
|
||||
* Virtual methods from txIEvalContext
|
||||
*/
|
||||
|
||||
TX_DECL_MATCH_CONTEXT;
|
||||
|
||||
/**
|
||||
* Set the current txIEvalContext and get the prior one
|
||||
*/
|
||||
txIEvalContext* setEvalContext(txIEvalContext* aEContext)
|
||||
{
|
||||
txIEvalContext* tmp = mEvalContext;
|
||||
mEvalContext = aEContext;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current txIEvalContext
|
||||
*/
|
||||
txIEvalContext* getEvalContext()
|
||||
{
|
||||
return mEvalContext;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* More other functions
|
||||
*/
|
||||
void receiveError(const nsAString& errorMessage)
|
||||
{
|
||||
receiveError(errorMessage, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a FunctionCall which has the given name.
|
||||
* @return the FunctionCall for the function with the given name.
|
||||
*/
|
||||
nsresult resolveFunctionCall(nsIAtom* aName, PRInt32 aID,
|
||||
Element* aElem, FunctionCall*& aFunction);
|
||||
|
||||
txAXMLEventHandler* mOutputHandler;
|
||||
txAXMLEventHandler* mResultHandler;
|
||||
|
||||
txAOutputHandlerFactory* mOutputHandlerFactory;
|
||||
|
||||
private:
|
||||
|
||||
class MatchableTemplate {
|
||||
public:
|
||||
MatchableTemplate(Node* aTemplate, txPattern* aPattern,
|
||||
double aPriority)
|
||||
: mTemplate(aTemplate), mMatch(aPattern), mPriority(aPriority)
|
||||
{
|
||||
}
|
||||
Node* mTemplate;
|
||||
txPattern* mMatch;
|
||||
double mPriority;
|
||||
};
|
||||
|
||||
class GlobalVariableValue : public TxObject {
|
||||
public:
|
||||
GlobalVariableValue(ExprResult* aValue = 0)
|
||||
: mValue(aValue), mFlags(nonOwned)
|
||||
{
|
||||
}
|
||||
virtual ~GlobalVariableValue();
|
||||
|
||||
ExprResult* mValue;
|
||||
char mFlags;
|
||||
enum _flags
|
||||
{
|
||||
nonOwned = 0,
|
||||
evaluating,
|
||||
owned
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* The list of ErrorObservers registered with this ProcessorState
|
||||
*/
|
||||
List errorObservers;
|
||||
|
||||
/**
|
||||
* Stack of URIs for currently entered stylesheets
|
||||
*/
|
||||
nsStringArray mEnteredStylesheets;
|
||||
|
||||
/**
|
||||
* List of import containers. Sorted by ascending import precedence
|
||||
*/
|
||||
txList mImportFrames;
|
||||
|
||||
/**
|
||||
* The output format used when serializing the result
|
||||
*/
|
||||
txOutputFormat mOutputFormat;
|
||||
|
||||
/**
|
||||
* The set of loaded documents. This includes both document() loaded
|
||||
* documents and xsl:include/xsl:import'ed documents.
|
||||
*/
|
||||
txLoadedDocumentsHash mLoadedDocuments;
|
||||
|
||||
/**
|
||||
* The set of all available keys
|
||||
*/
|
||||
txExpandedNameMap mXslKeys;
|
||||
|
||||
/**
|
||||
* Hash of all key-values
|
||||
*/
|
||||
txKeyHash mKeyHash;
|
||||
|
||||
/**
|
||||
* The set of all avalible decimalformats
|
||||
*/
|
||||
txExpandedNameMap mDecimalFormats;
|
||||
|
||||
/**
|
||||
* Default decimal-format
|
||||
*/
|
||||
txDecimalFormat mDefaultDecimalFormat;
|
||||
|
||||
/**
|
||||
* List of hashes with parsed expression. Every listitem holds the
|
||||
* expressions for an attribute name
|
||||
*/
|
||||
Map mExprHashes[3];
|
||||
|
||||
/**
|
||||
* List of hashes with parsed patterns. Every listitem holds the
|
||||
* patterns for an attribute name
|
||||
*/
|
||||
Map mPatternHashes[2];
|
||||
|
||||
/**
|
||||
* Current txIEvalContext*
|
||||
*/
|
||||
txIEvalContext* mEvalContext;
|
||||
|
||||
/**
|
||||
* Current template rule
|
||||
*/
|
||||
TemplateRule* mCurrentTemplateRule;
|
||||
|
||||
/**
|
||||
* Top of stack of local variable-bindings
|
||||
*/
|
||||
txVariableMap* mLocalVariables;
|
||||
|
||||
/**
|
||||
* Map of values of global variables
|
||||
*/
|
||||
txExpandedNameMap mGlobalVariableValues;
|
||||
|
||||
/**
|
||||
* Document used to create RTFs
|
||||
*/
|
||||
Document* mRTFDocument;
|
||||
|
||||
/**
|
||||
* Source-node where processing started
|
||||
*/
|
||||
Node* mSourceNode;
|
||||
};
|
||||
|
||||
/**
|
||||
* txNameTestItem holds both an ElementExpr and a bool for use in
|
||||
* whitespace stripping.
|
||||
*/
|
||||
class txNameTestItem {
|
||||
public:
|
||||
txNameTestItem(nsIAtom* aPrefix, nsIAtom* aLocalName, PRInt32 aNSID,
|
||||
MBool stripSpace)
|
||||
: mNameTest(aPrefix, aLocalName, aNSID, Node::ELEMENT_NODE),
|
||||
mStrips(stripSpace)
|
||||
{
|
||||
}
|
||||
|
||||
MBool matches(Node* aNode, txIMatchContext* aContext) {
|
||||
return mNameTest.matches(aNode, aContext);
|
||||
}
|
||||
|
||||
MBool stripsSpace() {
|
||||
return mStrips;
|
||||
}
|
||||
|
||||
double getDefaultPriority() {
|
||||
return mNameTest.getDefaultPriority();
|
||||
}
|
||||
|
||||
protected:
|
||||
txNameTest mNameTest;
|
||||
MBool mStrips;
|
||||
};
|
||||
|
||||
/**
|
||||
* txPSParseContext
|
||||
* a txIParseContext forwarding all but resolveNamespacePrefix
|
||||
* to a ProcessorState
|
||||
*/
|
||||
class txPSParseContext : public txIParseContext {
|
||||
public:
|
||||
txPSParseContext(ProcessorState* aPS, Element* aStyleNode)
|
||||
: mPS(aPS), mStyle(aStyleNode)
|
||||
{
|
||||
}
|
||||
|
||||
~txPSParseContext()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult resolveNamespacePrefix(nsIAtom* aPrefix, PRInt32& aID);
|
||||
nsresult resolveFunctionCall(nsIAtom* aName, PRInt32 aID,
|
||||
FunctionCall*& aFunction);
|
||||
PRBool caseInsensitiveNameTests();
|
||||
void receiveError(const nsAString& aMsg, nsresult aRes);
|
||||
|
||||
protected:
|
||||
ProcessorState* mPS;
|
||||
Element* mStyle;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,267 +0,0 @@
|
||||
/* -*- 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
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TRANSFRMX_XSLTPROCESSOR_H
|
||||
#define TRANSFRMX_XSLTPROCESSOR_H
|
||||
|
||||
#include "ProcessorState.h"
|
||||
|
||||
class txStack;
|
||||
|
||||
class txIGlobalParameter : public TxObject
|
||||
{
|
||||
public:
|
||||
virtual nsresult getValue(ExprResult** aValue) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* A class for Processing XSLT Stylesheets
|
||||
*/
|
||||
class txXSLTProcessor
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initialisation and shutdown routines
|
||||
* Allocate and free static atoms.
|
||||
*/
|
||||
static MBool txInit();
|
||||
static MBool txShutdown();
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Transforms a node.
|
||||
*
|
||||
* @param aPs the current ProcessorState with the node
|
||||
* as current node and the desired templates
|
||||
*/
|
||||
static void transform(ProcessorState* aPs);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Copy a node. For document nodes, copy the children.
|
||||
*
|
||||
* @param aSourceNode node to copy
|
||||
* @param aPs the current ProcessorState
|
||||
*/
|
||||
static void copyNode(Node* aSourceNode, ProcessorState* aPs);
|
||||
|
||||
/**
|
||||
* Log a message.
|
||||
*
|
||||
* @param aMessage the message to log
|
||||
*/
|
||||
static void logMessage(const nsAString& 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,
|
||||
txStack* 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,
|
||||
nsAString& 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(const nsAString& 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)
|
||||
* @param aMap map to place parsed variables in
|
||||
* @param aPs the current ProcessorState
|
||||
* @return errorcode
|
||||
*/
|
||||
static nsresult processParameters(Element* aAction, txVariableMap* aMap,
|
||||
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. 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
|
||||
*/
|
||||
static void processTemplate(Node* aTemplate, txVariableMap* aParams,
|
||||
ProcessorState* aPs);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
static void processTopLevel(Element* aStylesheet,
|
||||
txExpandedNameMap* aGlobalParams,
|
||||
txListIterator* aImportFrame,
|
||||
ProcessorState* aPs);
|
||||
|
||||
/**
|
||||
* Processes the given xsl:variable.
|
||||
*
|
||||
* @param aVariable the variable element
|
||||
* @param aPs the current ProcessorState
|
||||
*/
|
||||
static ExprResult* processVariable(Element* aVariable,
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Used as default expression for some elements
|
||||
*/
|
||||
static Expr* gNodeExpr;
|
||||
|
||||
friend class ProcessorState;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,6 +1,6 @@
|
||||
#include "ProcessorState.h"
|
||||
#include "txAtoms.h"
|
||||
#include "XSLTFunctions.h"
|
||||
#include "txExecutionState.h"
|
||||
|
||||
/*
|
||||
Implementation of XSLT 1.0 extension function: current
|
||||
@ -9,8 +9,7 @@
|
||||
/**
|
||||
* Creates a new current function call
|
||||
**/
|
||||
CurrentFunctionCall::CurrentFunctionCall(ProcessorState* aPs)
|
||||
: mPs(aPs)
|
||||
CurrentFunctionCall::CurrentFunctionCall()
|
||||
{
|
||||
}
|
||||
|
||||
@ -22,7 +21,16 @@ CurrentFunctionCall::CurrentFunctionCall(ProcessorState* aPs)
|
||||
*/
|
||||
ExprResult* CurrentFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
return new NodeSet(mPs->getEvalContext()->getContextNode());
|
||||
txExecutionState* es =
|
||||
NS_STATIC_CAST(txExecutionState*, aContext->getPrivateContext());
|
||||
if (!es) {
|
||||
NS_ASSERTION(0,
|
||||
"called xslt extension function \"current\" with wrong context");
|
||||
// Just return an empty nodeset, this at least has the right
|
||||
// result type.
|
||||
return new NodeSet();
|
||||
}
|
||||
return new NodeSet(es->getEvalContext()->getContextNode());
|
||||
}
|
||||
|
||||
nsresult CurrentFunctionCall::getNameAtom(nsIAtom** aAtom)
|
||||
|
||||
@ -36,19 +36,17 @@
|
||||
* A representation of the XSLT additional function: document()
|
||||
*/
|
||||
|
||||
#include "ProcessorState.h"
|
||||
#include "txAtoms.h"
|
||||
#include "txIXPathContext.h"
|
||||
#include "XMLDOMUtils.h"
|
||||
#include "XSLTFunctions.h"
|
||||
#include "txExecutionState.h"
|
||||
|
||||
/*
|
||||
* Creates a new DocumentFunctionCall.
|
||||
*/
|
||||
DocumentFunctionCall::DocumentFunctionCall(ProcessorState* aPs,
|
||||
Node* aDefResolveNode)
|
||||
: mProcessorState(aPs),
|
||||
mDefResolveNode(aDefResolveNode)
|
||||
DocumentFunctionCall::DocumentFunctionCall(const nsAString& aBaseURI)
|
||||
: mBaseURI(aBaseURI)
|
||||
{
|
||||
}
|
||||
|
||||
@ -61,7 +59,11 @@ DocumentFunctionCall::DocumentFunctionCall(ProcessorState* aPs,
|
||||
*/
|
||||
ExprResult* DocumentFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
txExecutionState* es =
|
||||
NS_STATIC_CAST(txExecutionState*, aContext->getPrivateContext());
|
||||
|
||||
NodeSet* nodeSet = new NodeSet();
|
||||
NS_ENSURE_TRUE(nodeSet, nsnull);
|
||||
|
||||
// document(object, node-set?)
|
||||
if (requireParams(1, 2, aContext)) {
|
||||
@ -110,17 +112,21 @@ ExprResult* DocumentFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
// the baseUri of node itself
|
||||
node->getBaseURI(baseURI);
|
||||
}
|
||||
nodeSet->add(mProcessorState->retrieveDocument(uriStr, baseURI));
|
||||
Node* loadNode = es->retrieveDocument(uriStr, baseURI);
|
||||
if (loadNode) {
|
||||
nodeSet->add(loadNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// The first argument is not a NodeSet
|
||||
nsAutoString uriStr;
|
||||
exprResult1->stringValue(uriStr);
|
||||
if (!baseURISet) {
|
||||
mDefResolveNode->getBaseURI(baseURI);
|
||||
Node* loadNode =
|
||||
es->retrieveDocument(uriStr, baseURISet ? baseURI : mBaseURI);
|
||||
if (loadNode) {
|
||||
nodeSet->add(loadNode);
|
||||
}
|
||||
nodeSet->add(mProcessorState->retrieveDocument(uriStr, baseURI));
|
||||
}
|
||||
delete exprResult1;
|
||||
}
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
#include "txAtoms.h"
|
||||
#include "XMLUtils.h"
|
||||
#include "XSLTFunctions.h"
|
||||
#include "ExprResult.h"
|
||||
|
||||
/*
|
||||
Implementation of XSLT 1.0 extension function: element-available
|
||||
@ -51,8 +52,8 @@
|
||||
* aNode is the Element in the stylesheet containing the
|
||||
* Expr and is used for namespaceID resolution
|
||||
**/
|
||||
ElementAvailableFunctionCall::ElementAvailableFunctionCall(Node* aQNameResolveNode)
|
||||
: mQNameResolveNode(aQNameResolveNode)
|
||||
ElementAvailableFunctionCall::ElementAvailableFunctionCall(txNamespaceMap* aMappings)
|
||||
: mMappings(aMappings)
|
||||
{
|
||||
}
|
||||
|
||||
@ -77,7 +78,7 @@ ExprResult* ElementAvailableFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
nsAutoString property;
|
||||
exprResult->stringValue(property);
|
||||
txExpandedName qname;
|
||||
nsresult rv = qname.init(property, mQNameResolveNode, MB_TRUE);
|
||||
nsresult rv = qname.init(property, mMappings, MB_TRUE);
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
qname.mNamespaceID == kNameSpaceID_XSLT &&
|
||||
(qname.mLocalName == txXSLTAtoms::applyImports ||
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
#include "txAtoms.h"
|
||||
#include "XMLUtils.h"
|
||||
#include "XSLTFunctions.h"
|
||||
#include "ExprResult.h"
|
||||
|
||||
/*
|
||||
Implementation of XSLT 1.0 extension function: function-available
|
||||
@ -49,8 +50,8 @@
|
||||
/**
|
||||
* Creates a new function-available function call
|
||||
**/
|
||||
FunctionAvailableFunctionCall::FunctionAvailableFunctionCall(Node* aQNameResolveNode)
|
||||
: mQNameResolveNode(aQNameResolveNode)
|
||||
FunctionAvailableFunctionCall::FunctionAvailableFunctionCall(txNamespaceMap* aMappings)
|
||||
: mMappings(aMappings)
|
||||
{
|
||||
}
|
||||
|
||||
@ -75,7 +76,7 @@ ExprResult* FunctionAvailableFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
nsAutoString property;
|
||||
exprResult->stringValue(property);
|
||||
txExpandedName qname;
|
||||
nsresult rv = qname.init(property, mQNameResolveNode, MB_FALSE);
|
||||
nsresult rv = qname.init(property, mMappings, MB_FALSE);
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
qname.mNamespaceID == kNameSpaceID_None &&
|
||||
(qname.mLocalName == txXPathAtoms::boolean ||
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include "txIXPathContext.h"
|
||||
#include "XSLTFunctions.h"
|
||||
#include "prprf.h"
|
||||
#include "NodeSet.h"
|
||||
|
||||
/*
|
||||
Implementation of XSLT 1.0 extension function: generate-id
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include "txAtoms.h"
|
||||
#include "XMLUtils.h"
|
||||
#include "XSLTFunctions.h"
|
||||
#include "ExprResult.h"
|
||||
|
||||
/*
|
||||
Implementation of XSLT 1.0 extension function: system-property
|
||||
@ -12,8 +13,8 @@
|
||||
* aNode is the Element in the stylesheet containing the
|
||||
* Expr and is used for namespaceID resolution
|
||||
**/
|
||||
SystemPropertyFunctionCall::SystemPropertyFunctionCall(Node* aQNameResolveNode)
|
||||
: mQNameResolveNode(aQNameResolveNode)
|
||||
SystemPropertyFunctionCall::SystemPropertyFunctionCall(txNamespaceMap* aMappings)
|
||||
: mMappings(aMappings)
|
||||
{
|
||||
}
|
||||
|
||||
@ -37,7 +38,7 @@ ExprResult* SystemPropertyFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
nsAutoString property;
|
||||
exprResult->stringValue(property);
|
||||
txExpandedName qname;
|
||||
nsresult rv = qname.init(property, mQNameResolveNode, MB_TRUE);
|
||||
nsresult rv = qname.init(property, mMappings, MB_TRUE);
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
qname.mNamespaceID == kNameSpaceID_XSLT) {
|
||||
if (qname.mLocalName == txXSLTAtoms::version) {
|
||||
|
||||
@ -32,10 +32,14 @@
|
||||
#define TRANSFRMX_XSLT_FUNCTIONS_H
|
||||
|
||||
#include "Expr.h"
|
||||
#include "Map.h"
|
||||
#include "NodeSet.h"
|
||||
#include "txNamespaceMap.h"
|
||||
#include "XMLUtils.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
class ProcessorState;
|
||||
class txPattern;
|
||||
class txStylesheet;
|
||||
class txKeyValueHashKey;
|
||||
class txExecutionState;
|
||||
|
||||
/**
|
||||
* The definition for the XSLT document() function
|
||||
@ -47,13 +51,12 @@ public:
|
||||
/**
|
||||
* Creates a new document() function call
|
||||
**/
|
||||
DocumentFunctionCall(ProcessorState* aPs, Node* aDefResolveNode);
|
||||
DocumentFunctionCall(const nsAString& aBaseURI);
|
||||
|
||||
TX_DECL_FUNCTION;
|
||||
|
||||
private:
|
||||
ProcessorState* mProcessorState;
|
||||
Node* mDefResolveNode;
|
||||
nsString mBaseURI;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -66,13 +69,12 @@ public:
|
||||
/*
|
||||
* Creates a new key() function call
|
||||
*/
|
||||
txKeyFunctionCall(ProcessorState* aPs, Node* aQNameResolveNode);
|
||||
txKeyFunctionCall(txNamespaceMap* aMappings);
|
||||
|
||||
TX_DECL_FUNCTION;
|
||||
|
||||
private:
|
||||
ProcessorState* mProcessorState;
|
||||
Node* mQNameResolveNode;
|
||||
nsRefPtr<txNamespaceMap> mMappings;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -85,7 +87,7 @@ public:
|
||||
/**
|
||||
* Creates a new format-number() function call
|
||||
**/
|
||||
txFormatNumberFunctionCall(ProcessorState* aPs, Node* aQNameResolveNode);
|
||||
txFormatNumberFunctionCall(txStylesheet* aStylesheet, txNamespaceMap* aMappings);
|
||||
|
||||
TX_DECL_FUNCTION;
|
||||
|
||||
@ -102,8 +104,8 @@ private:
|
||||
Finished
|
||||
};
|
||||
|
||||
ProcessorState* mPs;
|
||||
Node* mQNameResolveNode;
|
||||
txStylesheet* mStylesheet;
|
||||
nsRefPtr<txNamespaceMap> mMappings;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -142,12 +144,9 @@ public:
|
||||
/**
|
||||
* Creates a new current() function call
|
||||
**/
|
||||
CurrentFunctionCall(ProcessorState* ps);
|
||||
CurrentFunctionCall();
|
||||
|
||||
TX_DECL_FUNCTION;
|
||||
|
||||
private:
|
||||
ProcessorState* mPs;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -197,7 +196,7 @@ public:
|
||||
* aNode is the Element in the stylesheet containing the
|
||||
* Expr and is used for namespaceID resolution
|
||||
**/
|
||||
SystemPropertyFunctionCall(Node* aQNameResolveNode);
|
||||
SystemPropertyFunctionCall(txNamespaceMap* aMappings);
|
||||
|
||||
TX_DECL_FUNCTION;
|
||||
|
||||
@ -205,7 +204,7 @@ private:
|
||||
/*
|
||||
* resolve namespaceIDs with this node
|
||||
*/
|
||||
Node* mQNameResolveNode;
|
||||
nsRefPtr<txNamespaceMap> mMappings;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -220,7 +219,7 @@ public:
|
||||
* aNode is the Element in the stylesheet containing the
|
||||
* Expr and is used for namespaceID resolution
|
||||
**/
|
||||
ElementAvailableFunctionCall(Node* aQNameResolveNode);
|
||||
ElementAvailableFunctionCall(txNamespaceMap* aMappings);
|
||||
|
||||
TX_DECL_FUNCTION;
|
||||
|
||||
@ -228,7 +227,7 @@ private:
|
||||
/*
|
||||
* resolve namespaceIDs with this node
|
||||
*/
|
||||
Node* mQNameResolveNode;
|
||||
nsRefPtr<txNamespaceMap> mMappings;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -241,7 +240,7 @@ public:
|
||||
/**
|
||||
* Creates a new function-available() function call
|
||||
**/
|
||||
FunctionAvailableFunctionCall(Node* aQNameResolveNode);
|
||||
FunctionAvailableFunctionCall(txNamespaceMap* aMappings);
|
||||
|
||||
TX_DECL_FUNCTION;
|
||||
|
||||
@ -249,7 +248,7 @@ private:
|
||||
/*
|
||||
* resolve namespaceIDs with this node
|
||||
*/
|
||||
Node* mQNameResolveNode;
|
||||
nsRefPtr<txNamespaceMap> mMappings;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -37,11 +37,12 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "XSLTFunctions.h"
|
||||
#include "ProcessorState.h"
|
||||
#include "primitives.h"
|
||||
#include "txAtoms.h"
|
||||
#include "txIXPathContext.h"
|
||||
#include "txStylesheet.h"
|
||||
#include <math.h>
|
||||
#include "ExprResult.h"
|
||||
|
||||
#include "prdtoa.h"
|
||||
|
||||
@ -55,10 +56,10 @@ const PRUnichar txFormatNumberFunctionCall::FORMAT_QUOTE = '\'';
|
||||
/*
|
||||
* Creates a new format-number function call
|
||||
*/
|
||||
txFormatNumberFunctionCall::txFormatNumberFunctionCall(ProcessorState* aPs,
|
||||
Node* aQNameResolveNode)
|
||||
: mPs(aPs),
|
||||
mQNameResolveNode(aQNameResolveNode)
|
||||
txFormatNumberFunctionCall::txFormatNumberFunctionCall(txStylesheet* aStylesheet,
|
||||
txNamespaceMap* aMappings)
|
||||
: mStylesheet(aStylesheet),
|
||||
mMappings(aMappings)
|
||||
{
|
||||
}
|
||||
|
||||
@ -87,12 +88,12 @@ ExprResult* txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
if (iter.hasNext()) {
|
||||
nsAutoString formatQName;
|
||||
evaluateToString((Expr*)iter.next(), aContext, formatQName);
|
||||
rv = formatName.init(formatQName, mQNameResolveNode, MB_FALSE);
|
||||
rv = formatName.init(formatQName, mMappings, MB_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
formatName.mNamespaceID = kNameSpaceID_Unknown;
|
||||
}
|
||||
|
||||
txDecimalFormat* format = mPs->getDecimalFormat(formatName);
|
||||
txDecimalFormat* format = mStylesheet->getDecimalFormat(formatName);
|
||||
if (!format) {
|
||||
nsAutoString err(NS_LITERAL_STRING("unknown decimal format for: "));
|
||||
toString(err);
|
||||
|
||||
@ -41,6 +41,13 @@
|
||||
|
||||
#include "nsDoubleHashtable.h"
|
||||
#include "XMLUtils.h"
|
||||
#include "NodeSet.h"
|
||||
#include "List.h"
|
||||
#include "txXSLTPatterns.h"
|
||||
|
||||
class txPattern;
|
||||
class Expr;
|
||||
class txExecutionState;
|
||||
|
||||
class txKeyValueHashKey
|
||||
{
|
||||
@ -129,17 +136,17 @@ public:
|
||||
* @param aUse use-expression
|
||||
* @return PR_FALSE if an error occured, PR_TRUE otherwise
|
||||
*/
|
||||
PRBool addKey(txPattern* aMatch, Expr* aUse);
|
||||
PRBool addKey(nsAutoPtr<txPattern> aMatch, nsAutoPtr<Expr> aUse);
|
||||
|
||||
/**
|
||||
* Indexes a document and adds it to the hash of key values
|
||||
* @param aDocument Document to index and add
|
||||
* @param aKeyValueHash Hash to add values to
|
||||
* @param aPs ProcessorState to use for XPath evaluation
|
||||
* @param aEs txExecutionState to use for XPath evaluation
|
||||
*/
|
||||
nsresult indexDocument(Document* aDocument,
|
||||
txKeyValueHash& aKeyValueHash,
|
||||
ProcessorState* aPs);
|
||||
txExecutionState& aEs);
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -148,10 +155,10 @@ private:
|
||||
* @param aNode Node to search
|
||||
* @param aKey Key to use when adding into the hash
|
||||
* @param aKeyValueHash Hash to add values to
|
||||
* @param aPs ProcessorState to use for XPath evaluation
|
||||
* @param aEs txExecutionState to use for XPath evaluation
|
||||
*/
|
||||
nsresult indexTree(Node* aNode, txKeyValueHashKey& aKey,
|
||||
txKeyValueHash& aKeyValueHash, ProcessorState* aPs);
|
||||
txKeyValueHash& aKeyValueHash, txExecutionState& aEs);
|
||||
|
||||
/**
|
||||
* Tests one node if it matches any of the keys match-patterns. If
|
||||
@ -159,17 +166,17 @@ private:
|
||||
* @param aNode Node to test
|
||||
* @param aKey Key to use when adding into the hash
|
||||
* @param aKeyValueHash Hash to add values to
|
||||
* @param aPs ProcessorState to use for XPath evaluation
|
||||
* @param aEs txExecutionState to use for XPath evaluation
|
||||
*/
|
||||
nsresult testNode(Node* aNode, txKeyValueHashKey& aKey,
|
||||
txKeyValueHash& aKeyValueHash, ProcessorState* aPs);
|
||||
txKeyValueHash& aKeyValueHash, txExecutionState& aEs);
|
||||
|
||||
/**
|
||||
* represents one match/use pair
|
||||
*/
|
||||
struct Key {
|
||||
txPattern* matchPattern;
|
||||
Expr* useExpr;
|
||||
nsAutoPtr<txPattern> matchPattern;
|
||||
nsAutoPtr<Expr> useExpr;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -187,7 +194,7 @@ private:
|
||||
class txKeyHash
|
||||
{
|
||||
public:
|
||||
txKeyHash(txExpandedNameMap& aKeys)
|
||||
txKeyHash(const txExpandedNameMap& aKeys)
|
||||
: mKeys(aKeys)
|
||||
{
|
||||
}
|
||||
@ -198,7 +205,7 @@ public:
|
||||
Document* aDocument,
|
||||
const nsAString& aKeyValue,
|
||||
PRBool aIndexIfNotFound,
|
||||
ProcessorState* aPs,
|
||||
txExecutionState& aEs,
|
||||
const NodeSet** aResult);
|
||||
|
||||
private:
|
||||
@ -209,7 +216,7 @@ private:
|
||||
txIndexedKeyHash mIndexedKeys;
|
||||
|
||||
// Map of txXSLKeys
|
||||
txExpandedNameMap& mKeys;
|
||||
const txExpandedNameMap& mKeys;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -18,13 +18,14 @@
|
||||
* -- original author.
|
||||
*/
|
||||
|
||||
#include "ProcessorState.h"
|
||||
#include "txExecutionState.h"
|
||||
#include "txAtoms.h"
|
||||
#include "txSingleNodeContext.h"
|
||||
#include "XMLDOMUtils.h"
|
||||
#include "XSLTFunctions.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "txKey.h"
|
||||
#include "txXSLTPatterns.h"
|
||||
|
||||
/*
|
||||
* txKeyFunctionCall
|
||||
@ -34,10 +35,8 @@
|
||||
/*
|
||||
* Creates a new key function call
|
||||
*/
|
||||
txKeyFunctionCall::txKeyFunctionCall(ProcessorState* aPs,
|
||||
Node* aQNameResolveNode)
|
||||
: mProcessorState(aPs),
|
||||
mQNameResolveNode(aQNameResolveNode)
|
||||
txKeyFunctionCall::txKeyFunctionCall(txNamespaceMap* aMappings)
|
||||
: mMappings(aMappings)
|
||||
{
|
||||
}
|
||||
|
||||
@ -54,6 +53,9 @@ ExprResult* txKeyFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
if (!aContext || !requireParams(2, 2, aContext))
|
||||
return new StringResult(NS_LITERAL_STRING("error"));
|
||||
|
||||
txExecutionState* es =
|
||||
NS_STATIC_CAST(txExecutionState*, aContext->getPrivateContext());
|
||||
|
||||
NodeSet* res = new NodeSet;
|
||||
if (!res) {
|
||||
// ErrorReport: out of memory
|
||||
@ -65,7 +67,7 @@ ExprResult* txKeyFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
evaluateToString((Expr*)iter.next(), aContext, keyQName);
|
||||
|
||||
txExpandedName keyName;
|
||||
nsresult rv = keyName.init(keyQName, mQNameResolveNode, PR_FALSE);
|
||||
nsresult rv = keyName.init(keyQName, mMappings, PR_FALSE);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete res;
|
||||
return new StringResult(NS_LITERAL_STRING("error"));
|
||||
@ -89,8 +91,7 @@ ExprResult* txKeyFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
nsAutoString val;
|
||||
XMLDOMUtils::getNodeValue(nodeSet->get(i), val);
|
||||
const NodeSet* nodes = 0;
|
||||
rv = mProcessorState->getKeyNodes(keyName, contextDoc, val,
|
||||
i == 0, &nodes);
|
||||
rv = es->getKeyNodes(keyName, contextDoc, val, i == 0, &nodes);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete res;
|
||||
delete exprResult;
|
||||
@ -105,8 +106,7 @@ ExprResult* txKeyFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
nsAutoString val;
|
||||
exprResult->stringValue(val);
|
||||
const NodeSet* nodes = 0;
|
||||
rv = mProcessorState->getKeyNodes(keyName, contextDoc, val,
|
||||
PR_TRUE, &nodes);
|
||||
rv = es->getKeyNodes(keyName, contextDoc, val, PR_TRUE, &nodes);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete res;
|
||||
delete exprResult;
|
||||
@ -199,7 +199,7 @@ txKeyHash::getKeyNodes(const txExpandedName& aKeyName,
|
||||
Document* aDocument,
|
||||
const nsAString& aKeyValue,
|
||||
PRBool aIndexIfNotFound,
|
||||
ProcessorState* aPs,
|
||||
txExecutionState& aEs,
|
||||
const NodeSet** aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(mKeyValues.mHashTable.ops && mIndexedKeys.mHashTable.ops,
|
||||
@ -241,7 +241,7 @@ txKeyHash::getKeyNodes(const txExpandedName& aKeyName,
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsresult rv = xslKey->indexDocument(aDocument, mKeyValues, aPs);
|
||||
nsresult rv = xslKey->indexDocument(aDocument, mKeyValues, aEs);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
indexEntry->mIndexed = PR_TRUE;
|
||||
@ -273,8 +273,6 @@ txXSLKey::~txXSLKey()
|
||||
txListIterator iter(&mKeys);
|
||||
Key* key;
|
||||
while ((key = (Key*)iter.next())) {
|
||||
delete key->matchPattern;
|
||||
delete key->useExpr;
|
||||
delete key;
|
||||
}
|
||||
}
|
||||
@ -285,18 +283,22 @@ txXSLKey::~txXSLKey()
|
||||
* @param aUse use-expression
|
||||
* @return PR_FALSE if an error occured, PR_TRUE otherwise
|
||||
*/
|
||||
PRBool txXSLKey::addKey(txPattern* aMatch, Expr* aUse)
|
||||
PRBool txXSLKey::addKey(nsAutoPtr<txPattern> aMatch, nsAutoPtr<Expr> aUse)
|
||||
{
|
||||
if (!aMatch || !aUse)
|
||||
return PR_FALSE;
|
||||
|
||||
Key* key = new Key;
|
||||
nsAutoPtr<Key> key(new Key);
|
||||
if (!key)
|
||||
return PR_FALSE;
|
||||
|
||||
key->matchPattern = aMatch;
|
||||
key->useExpr = aUse;
|
||||
mKeys.add(key);
|
||||
nsresult rv = mKeys.add(key);
|
||||
NS_ENSURE_SUCCESS(rv, PR_FALSE);
|
||||
|
||||
key.forget();
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
@ -304,14 +306,14 @@ PRBool txXSLKey::addKey(txPattern* aMatch, Expr* aUse)
|
||||
* Indexes a document and adds it to the hash of key values
|
||||
* @param aDocument Document to index and add
|
||||
* @param aKeyValueHash Hash to add values to
|
||||
* @param aPs ProcessorState to use for XPath evaluation
|
||||
* @param aEs txExecutionState to use for XPath evaluation
|
||||
*/
|
||||
nsresult txXSLKey::indexDocument(Document* aDocument,
|
||||
txKeyValueHash& aKeyValueHash,
|
||||
ProcessorState* aPs)
|
||||
txExecutionState& aEs)
|
||||
{
|
||||
txKeyValueHashKey key(mName, aDocument, NS_LITERAL_STRING(""));
|
||||
return indexTree(aDocument, key, aKeyValueHash, aPs);
|
||||
return indexTree(aDocument, key, aKeyValueHash, aEs);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -320,27 +322,27 @@ nsresult txXSLKey::indexDocument(Document* aDocument,
|
||||
* @param aNode Node to search
|
||||
* @param aKey Key to use when adding into the hash
|
||||
* @param aKeyValueHash Hash to add values to
|
||||
* @param aPs ProcessorState to use for XPath evaluation
|
||||
* @param aEs txExecutionState to use for XPath evaluation
|
||||
*/
|
||||
nsresult txXSLKey::indexTree(Node* aNode, txKeyValueHashKey& aKey,
|
||||
txKeyValueHash& aKeyValueHash,
|
||||
ProcessorState* aPs)
|
||||
txExecutionState& aEs)
|
||||
{
|
||||
nsresult rv = testNode(aNode, aKey, aKeyValueHash, aPs);
|
||||
nsresult rv = testNode(aNode, aKey, aKeyValueHash, aEs);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// check if the nodes attributes matches
|
||||
NamedNodeMap* attrs = aNode->getAttributes();
|
||||
if (attrs) {
|
||||
for (PRUint32 i=0; i<attrs->getLength(); i++) {
|
||||
rv = testNode(attrs->item(i), aKey, aKeyValueHash, aPs);
|
||||
rv = testNode(attrs->item(i), aKey, aKeyValueHash, aEs);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
Node* child = aNode->getFirstChild();
|
||||
while (child) {
|
||||
rv = indexTree(child, aKey, aKeyValueHash, aPs);
|
||||
rv = indexTree(child, aKey, aKeyValueHash, aEs);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
child = child->getNextSibling();
|
||||
@ -355,22 +357,25 @@ nsresult txXSLKey::indexTree(Node* aNode, txKeyValueHashKey& aKey,
|
||||
* @param aNode Node to test
|
||||
* @param aKey Key to use when adding into the hash
|
||||
* @param aKeyValueHash Hash to add values to
|
||||
* @param aPs ProcessorState to use for XPath evaluation
|
||||
* @param aEs txExecutionState to use for XPath evaluation
|
||||
*/
|
||||
nsresult txXSLKey::testNode(Node* aNode, txKeyValueHashKey& aKey,
|
||||
txKeyValueHash& aKeyValueHash, ProcessorState* aPs)
|
||||
txKeyValueHash& aKeyValueHash, txExecutionState& aEs)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsAutoString val;
|
||||
txListIterator iter(&mKeys);
|
||||
while (iter.hasNext())
|
||||
{
|
||||
Key* key=(Key*)iter.next();
|
||||
if (key->matchPattern->matches(aNode, aPs)) {
|
||||
txSingleNodeContext evalContext(aNode, aPs);
|
||||
txIEvalContext* prevCon =
|
||||
aPs->setEvalContext(&evalContext);
|
||||
if (key->matchPattern->matches(aNode, &aEs)) {
|
||||
txSingleNodeContext evalContext(aNode, &aEs);
|
||||
rv = aEs.pushEvalContext(&evalContext);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
ExprResult* exprResult = key->useExpr->evaluate(&evalContext);
|
||||
aPs->setEvalContext(prevCon);
|
||||
aEs.popEvalContext();
|
||||
|
||||
if (exprResult->getResultType() == ExprResult::NODESET) {
|
||||
NodeSet* res = (NodeSet*)exprResult;
|
||||
for (int i=0; i<res->size(); i++) {
|
||||
|
||||
635
mozilla/extensions/transformiix/source/xslt/txExecutionState.cpp
Normal file
635
mozilla/extensions/transformiix/source/xslt/txExecutionState.cpp
Normal file
@ -0,0 +1,635 @@
|
||||
/* -*- 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
|
||||
* Jonas Sicking.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* Jonas Sicking. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking <jonas@sicking.cc>
|
||||
*
|
||||
* 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 "txExecutionState.h"
|
||||
#include "txSingleNodeContext.h"
|
||||
#include "txInstructions.h"
|
||||
#include "txStylesheet.h"
|
||||
#include "txVariableMap.h"
|
||||
#include "txRtfHandler.h"
|
||||
#include "txXSLTProcessor.h"
|
||||
#include "TxLog.h"
|
||||
#include "txURIUtils.h"
|
||||
#include "txXMLParser.h"
|
||||
|
||||
#ifndef TX_EXE
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsContentCID.h"
|
||||
static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID);
|
||||
#endif
|
||||
|
||||
const PRInt32 txExecutionState::kMaxRecursionDepth = 20000;
|
||||
|
||||
DHASH_WRAPPER(txLoadedDocumentsBase, txLoadedDocumentEntry, nsAString&)
|
||||
|
||||
nsresult txLoadedDocumentsHash::init(Document* aSourceDocument)
|
||||
{
|
||||
nsresult rv = Init(8);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mSourceDocument = aSourceDocument;
|
||||
Add(mSourceDocument);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
txLoadedDocumentsHash::~txLoadedDocumentsHash()
|
||||
{
|
||||
if (!mHashTable.ops) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString baseURI;
|
||||
mSourceDocument->getBaseURI(baseURI);
|
||||
txLoadedDocumentEntry* entry = GetEntry(baseURI);
|
||||
if (entry) {
|
||||
entry->mDocument = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
void txLoadedDocumentsHash::Add(Document* aDocument)
|
||||
{
|
||||
nsAutoString baseURI;
|
||||
aDocument->getBaseURI(baseURI);
|
||||
txLoadedDocumentEntry* entry = AddEntry(baseURI);
|
||||
if (entry) {
|
||||
entry->mDocument = aDocument;
|
||||
}
|
||||
}
|
||||
|
||||
Document* txLoadedDocumentsHash::Get(const nsAString& aURI)
|
||||
{
|
||||
txLoadedDocumentEntry* entry = GetEntry(aURI);
|
||||
if (entry) {
|
||||
return entry->mDocument;
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
txExecutionState::txExecutionState(txStylesheet* aStylesheet)
|
||||
: mTemplateParams(nsnull),
|
||||
mStylesheet(aStylesheet),
|
||||
mNextInstruction(nsnull),
|
||||
mLocalVariables(nsnull),
|
||||
mRecursionDepth(0),
|
||||
mTemplateRules(nsnull),
|
||||
mTemplateRulesBufferSize(0),
|
||||
mTemplateRuleCount(0),
|
||||
mEvalContext(nsnull),
|
||||
mInitialEvalContext(nsnull),
|
||||
mRTFDocument(nsnull),
|
||||
mGlobalParams(nsnull),
|
||||
mKeyHash(aStylesheet->getKeyMap())
|
||||
{
|
||||
}
|
||||
|
||||
txExecutionState::~txExecutionState()
|
||||
{
|
||||
delete mResultHandler;
|
||||
delete mLocalVariables;
|
||||
delete mEvalContext;
|
||||
delete mRTFDocument;
|
||||
delete mTemplateParams;
|
||||
|
||||
PRInt32 i;
|
||||
for (i = 0; i < mTemplateRuleCount; ++i) {
|
||||
NS_IF_RELEASE(mTemplateRules[i].mModeLocalName);
|
||||
}
|
||||
delete [] mTemplateRules;
|
||||
|
||||
txStackIterator varsIter(&mLocalVarsStack);
|
||||
while (varsIter.hasNext()) {
|
||||
delete (txVariableMap*)varsIter.next();
|
||||
}
|
||||
|
||||
txStackIterator contextIter(&mEvalContextStack);
|
||||
while (contextIter.hasNext()) {
|
||||
txIEvalContext* context = (txIEvalContext*)contextIter.next();
|
||||
if (context != mInitialEvalContext) {
|
||||
delete context;
|
||||
}
|
||||
}
|
||||
|
||||
txStackIterator handlerIter(&mResultHandlerStack);
|
||||
while (handlerIter.hasNext()) {
|
||||
delete (txAXMLEventHandler*)handlerIter.next();
|
||||
}
|
||||
|
||||
txStackIterator paramIter(&mParamStack);
|
||||
while (paramIter.hasNext()) {
|
||||
delete (txExpandedNameMap*)paramIter.next();
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
txExecutionState::init(Node* aNode,
|
||||
txExpandedNameMap* aGlobalParams)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
mGlobalParams = aGlobalParams;
|
||||
|
||||
// Set up initial context
|
||||
mEvalContext = new txSingleNodeContext(aNode, this);
|
||||
NS_ENSURE_TRUE(mEvalContext, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
mInitialEvalContext = mEvalContext;
|
||||
|
||||
// Set up output and result-handler
|
||||
txAXMLEventHandler* handler = 0;
|
||||
rv = mOutputHandlerFactory->
|
||||
createHandlerWith(mStylesheet->getOutputFormat(), &handler);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mOutputHandler = handler;
|
||||
mResultHandler = handler;
|
||||
mOutputHandler->startDocument();
|
||||
|
||||
// Initiate first instruction
|
||||
txStylesheet::ImportFrame* frame = 0;
|
||||
txExpandedName nullName;
|
||||
txInstruction* templ = mStylesheet->findTemplate(aNode, nullName,
|
||||
this, nsnull, &frame);
|
||||
pushTemplateRule(frame, nullName, nsnull);
|
||||
rv = runTemplate(templ);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Set up loaded-documents-hash
|
||||
Document* sourceDoc;
|
||||
if (aNode->getNodeType() == Node::DOCUMENT_NODE) {
|
||||
sourceDoc = (Document*)aNode;
|
||||
}
|
||||
else {
|
||||
sourceDoc = aNode->getOwnerDocument();
|
||||
}
|
||||
rv = mLoadedDocuments.init(sourceDoc);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Init members
|
||||
rv = mKeyHash.init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// The actual value here doesn't really matter since noone should use this
|
||||
// value. But lets put something errorlike in just in case
|
||||
mGlobalVarPlaceholderValue = new StringResult(NS_LITERAL_STRING("Error"));
|
||||
NS_ENSURE_TRUE(mGlobalVarPlaceholderValue, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txExecutionState::end()
|
||||
{
|
||||
popTemplateRule();
|
||||
mOutputHandler->endDocument();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
txExecutionState::getVariable(PRInt32 aNamespace, nsIAtom* aLName,
|
||||
ExprResult*& aResult)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
txExpandedName name(aNamespace, aLName);
|
||||
|
||||
// look for a local variable
|
||||
if (mLocalVariables) {
|
||||
aResult = mLocalVariables->getVariable(name);
|
||||
if (aResult) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// look for an evaluated global variable
|
||||
aResult = mGlobalVariableValues.getVariable(name);
|
||||
if (aResult) {
|
||||
if (aResult == mGlobalVarPlaceholderValue) {
|
||||
// XXX ErrorReport: cyclic variable-value
|
||||
aResult = nsnull;
|
||||
return NS_ERROR_XSLT_BAD_RECURSION;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Is there perchance a global variable not evaluated yet?
|
||||
txStylesheet::GlobalVariable* var = mStylesheet->getGlobalVariable(name);
|
||||
if (!var) {
|
||||
// XXX ErrorReport: variable doesn't exist in this scope
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_ASSERTION(var->mExpr && !var->mFirstInstruction ||
|
||||
!var->mExpr && var->mFirstInstruction,
|
||||
"global variable should have either instruction or expression");
|
||||
|
||||
// Is this a stylesheet parameter that has a value?
|
||||
if (var->mIsParam && mGlobalParams) {
|
||||
txIGlobalParameter* param =
|
||||
(txIGlobalParameter*)mGlobalParams->get(name);
|
||||
if (param) {
|
||||
rv = param->getValue(&aResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mGlobalVariableValues.bindVariable(name, aResult, PR_FALSE);
|
||||
if (NS_FAILED(rv)) {
|
||||
aResult = nsnull;
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Insert a placeholdervalue to protect against recursion
|
||||
rv = mGlobalVariableValues.bindVariable(name, mGlobalVarPlaceholderValue,
|
||||
PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// evaluate the global variable
|
||||
pushEvalContext(mInitialEvalContext);
|
||||
if (var->mExpr) {
|
||||
txVariableMap* oldVars = mLocalVariables;
|
||||
mLocalVariables = nsnull;
|
||||
aResult = var->mExpr->evaluate(getEvalContext());
|
||||
NS_ENSURE_TRUE(aResult, NS_ERROR_FAILURE);
|
||||
|
||||
mLocalVariables = oldVars;
|
||||
}
|
||||
else {
|
||||
nsAutoPtr<txRtfHandler> rtfHandler(new txRtfHandler);
|
||||
NS_ENSURE_TRUE(rtfHandler, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = pushResultHandler(rtfHandler);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rtfHandler.forget();
|
||||
|
||||
txInstruction* prevInstr = mNextInstruction;
|
||||
// set return to nsnull to stop execution
|
||||
mNextInstruction = nsnull;
|
||||
rv = runTemplate(var->mFirstInstruction);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = pushTemplateRule(nsnull, txExpandedName(), nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = txXSLTProcessor::execute(*this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
popTemplateRule();
|
||||
|
||||
mNextInstruction = prevInstr;
|
||||
rtfHandler = (txRtfHandler*)popResultHandler();
|
||||
aResult = rtfHandler->createRTF();
|
||||
NS_ENSURE_TRUE(aResult, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
popEvalContext();
|
||||
|
||||
// Remove the placeholder and insert the calculated value
|
||||
mGlobalVariableValues.removeVariable(name);
|
||||
rv = mGlobalVariableValues.bindVariable(name, aResult, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete aResult;
|
||||
aResult = nsnull;
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
txExecutionState::isStripSpaceAllowed(Node* aNode)
|
||||
{
|
||||
return mStylesheet->isStripSpaceAllowed(aNode, this);
|
||||
}
|
||||
|
||||
void*
|
||||
txExecutionState::getPrivateContext()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
txExecutionState::receiveError(const nsAString& aMsg, nsresult aRes)
|
||||
{
|
||||
// XXX implement me
|
||||
}
|
||||
|
||||
nsresult
|
||||
txExecutionState::pushEvalContext(txIEvalContext* aContext)
|
||||
{
|
||||
nsresult rv = mEvalContextStack.push(mEvalContext);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mEvalContext = aContext;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
txIEvalContext*
|
||||
txExecutionState::popEvalContext()
|
||||
{
|
||||
txIEvalContext* prev = mEvalContext;
|
||||
mEvalContext = (txIEvalContext*)mEvalContextStack.pop();
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txExecutionState::pushString(const nsAString& aStr)
|
||||
{
|
||||
if (!mStringStack.AppendString(aStr)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
txExecutionState::popString(nsAString& aStr)
|
||||
{
|
||||
PRInt32 count = mStringStack.Count() - 1;
|
||||
NS_ASSERTION(count >= 0, "stack is empty");
|
||||
mStringStack.StringAt(count, aStr);
|
||||
mStringStack.RemoveStringAt(count);
|
||||
}
|
||||
|
||||
nsresult
|
||||
txExecutionState::pushInt(PRInt32 aInt)
|
||||
{
|
||||
return mIntStack.push(NS_INT32_TO_PTR(aInt));
|
||||
}
|
||||
|
||||
PRInt32
|
||||
txExecutionState::popInt()
|
||||
{
|
||||
return NS_PTR_TO_INT32(mIntStack.pop());
|
||||
}
|
||||
|
||||
nsresult
|
||||
txExecutionState::pushResultHandler(txAXMLEventHandler* aHandler)
|
||||
{
|
||||
nsresult rv = mResultHandlerStack.push(mResultHandler);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mResultHandler = aHandler;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
txAXMLEventHandler*
|
||||
txExecutionState::popResultHandler()
|
||||
{
|
||||
txAXMLEventHandler* oldHandler = mResultHandler;
|
||||
mResultHandler = (txAXMLEventHandler*)mResultHandlerStack.pop();
|
||||
|
||||
return oldHandler;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txExecutionState::pushTemplateRule(txStylesheet::ImportFrame* aFrame,
|
||||
const txExpandedName& aMode,
|
||||
txExpandedNameMap* aParams)
|
||||
{
|
||||
if (mTemplateRuleCount == mTemplateRulesBufferSize) {
|
||||
PRInt32 newSize =
|
||||
mTemplateRulesBufferSize ? mTemplateRulesBufferSize * 2 : 10;
|
||||
TemplateRule* newRules = new TemplateRule[newSize];
|
||||
NS_ENSURE_TRUE(newRules, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
memcpy(newRules, mTemplateRules,
|
||||
mTemplateRuleCount * sizeof(TemplateRule));
|
||||
delete [] mTemplateRules;
|
||||
mTemplateRules = newRules;
|
||||
mTemplateRulesBufferSize = newSize;
|
||||
}
|
||||
|
||||
mTemplateRules[mTemplateRuleCount].mFrame = aFrame;
|
||||
mTemplateRules[mTemplateRuleCount].mModeNsId = aMode.mNamespaceID;
|
||||
mTemplateRules[mTemplateRuleCount].mModeLocalName = aMode.mLocalName;
|
||||
mTemplateRules[mTemplateRuleCount].mParams = aParams;
|
||||
NS_IF_ADDREF(mTemplateRules[mTemplateRuleCount].mModeLocalName);
|
||||
++mTemplateRuleCount;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
txExecutionState::popTemplateRule()
|
||||
{
|
||||
// decrement outside of RELEASE, that would decrement twice
|
||||
--mTemplateRuleCount;
|
||||
NS_IF_RELEASE(mTemplateRules[mTemplateRuleCount].mModeLocalName);
|
||||
}
|
||||
|
||||
txIEvalContext*
|
||||
txExecutionState::getEvalContext()
|
||||
{
|
||||
return mEvalContext;
|
||||
}
|
||||
|
||||
txExpandedNameMap*
|
||||
txExecutionState::getParamMap()
|
||||
{
|
||||
return mTemplateParams;
|
||||
}
|
||||
|
||||
Node*
|
||||
txExecutionState::retrieveDocument(const nsAString& uri,
|
||||
const nsAString& baseUri)
|
||||
{
|
||||
nsAutoString absUrl;
|
||||
URIUtils::resolveHref(uri, baseUri, absUrl);
|
||||
|
||||
PRInt32 hash = absUrl.RFindChar(PRUnichar('#'));
|
||||
PRUint32 urlEnd, fragStart, fragEnd;
|
||||
if (hash == kNotFound) {
|
||||
urlEnd = absUrl.Length();
|
||||
fragStart = 0;
|
||||
fragEnd = 0;
|
||||
}
|
||||
else {
|
||||
urlEnd = hash;
|
||||
fragStart = hash + 1;
|
||||
fragEnd = absUrl.Length();
|
||||
}
|
||||
|
||||
nsDependentSubstring docUrl(absUrl, 0, urlEnd);
|
||||
nsDependentSubstring frag(absUrl, fragStart, fragEnd);
|
||||
|
||||
PR_LOG(txLog::xslt, PR_LOG_DEBUG,
|
||||
("Retrieve Document %s, uri %s, baseUri %s, fragment %s\n",
|
||||
NS_LossyConvertUCS2toASCII(docUrl).get(),
|
||||
NS_LossyConvertUCS2toASCII(uri).get(),
|
||||
NS_LossyConvertUCS2toASCII(baseUri).get(),
|
||||
NS_LossyConvertUCS2toASCII(frag).get()));
|
||||
|
||||
// try to get already loaded document
|
||||
Document* xmlDoc = mLoadedDocuments.Get(docUrl);
|
||||
|
||||
if (!xmlDoc) {
|
||||
// open URI
|
||||
nsAutoString errMsg, refUri;
|
||||
// XXX we should get the referrer from the actual node
|
||||
// triggering the load, but this will do for the time being
|
||||
mLoadedDocuments.mSourceDocument->getBaseURI(refUri);
|
||||
nsresult rv;
|
||||
rv = txParseDocumentFromURI(docUrl, refUri,
|
||||
mLoadedDocuments.mSourceDocument, errMsg,
|
||||
&xmlDoc);
|
||||
|
||||
if (NS_FAILED(rv) || !xmlDoc) {
|
||||
receiveError(NS_LITERAL_STRING("Couldn't load document '") +
|
||||
docUrl + NS_LITERAL_STRING("': ") + errMsg,
|
||||
NS_ERROR_XSLT_INVALID_URL);
|
||||
return NULL;
|
||||
}
|
||||
// add to list of documents
|
||||
mLoadedDocuments.Add(xmlDoc);
|
||||
}
|
||||
|
||||
// return element with supplied id if supplied
|
||||
if (!frag.IsEmpty())
|
||||
return xmlDoc->getElementById(frag);
|
||||
|
||||
return xmlDoc;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txExecutionState::getKeyNodes(const txExpandedName& aKeyName,
|
||||
Document* aDocument,
|
||||
const nsAString& aKeyValue,
|
||||
PRBool aIndexIfNotFound,
|
||||
const NodeSet** aResult)
|
||||
{
|
||||
return mKeyHash.getKeyNodes(aKeyName, aDocument, aKeyValue,
|
||||
aIndexIfNotFound, *this, aResult);
|
||||
}
|
||||
|
||||
txExecutionState::TemplateRule*
|
||||
txExecutionState::getCurrentTemplateRule()
|
||||
{
|
||||
return mTemplateRules + mTemplateRuleCount - 1;
|
||||
}
|
||||
|
||||
txInstruction*
|
||||
txExecutionState::getNextInstruction()
|
||||
{
|
||||
txInstruction* instr = mNextInstruction;
|
||||
if (instr) {
|
||||
mNextInstruction = instr->mNext;
|
||||
}
|
||||
|
||||
return instr;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txExecutionState::runTemplate(txInstruction* aTemplate)
|
||||
{
|
||||
NS_ENSURE_TRUE(++mRecursionDepth < kMaxRecursionDepth,
|
||||
NS_ERROR_XSLT_BAD_RECURSION);
|
||||
|
||||
nsresult rv = mLocalVarsStack.push(mLocalVariables);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mReturnStack.push(mNextInstruction);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mLocalVariables = nsnull;
|
||||
mNextInstruction = aTemplate;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
txExecutionState::gotoInstruction(txInstruction* aNext)
|
||||
{
|
||||
mNextInstruction = aNext;
|
||||
}
|
||||
|
||||
void
|
||||
txExecutionState::returnFromTemplate()
|
||||
{
|
||||
--mRecursionDepth;
|
||||
NS_ASSERTION(!mReturnStack.isEmpty() && !mLocalVarsStack.isEmpty(),
|
||||
"return or variable stack is empty");
|
||||
delete mLocalVariables;
|
||||
mNextInstruction = (txInstruction*)mReturnStack.pop();
|
||||
mLocalVariables = (txVariableMap*)mLocalVarsStack.pop();
|
||||
}
|
||||
|
||||
nsresult
|
||||
txExecutionState::bindVariable(const txExpandedName& aName,
|
||||
ExprResult* aValue, MBool aOwned)
|
||||
{
|
||||
if (!mLocalVariables) {
|
||||
mLocalVariables = new txVariableMap;
|
||||
NS_ENSURE_TRUE(mLocalVariables, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
return mLocalVariables->bindVariable(aName, aValue, aOwned);
|
||||
}
|
||||
|
||||
void
|
||||
txExecutionState::removeVariable(const txExpandedName& aName)
|
||||
{
|
||||
mLocalVariables->removeVariable(aName);
|
||||
}
|
||||
|
||||
nsresult
|
||||
txExecutionState::pushParamMap(txExpandedNameMap* aParams)
|
||||
{
|
||||
nsresult rv = mParamStack.push(mTemplateParams);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mTemplateParams = aParams;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
txExpandedNameMap*
|
||||
txExecutionState::popParamMap()
|
||||
{
|
||||
txExpandedNameMap* oldParams = mTemplateParams;
|
||||
mTemplateParams = (txExpandedNameMap*)mParamStack.pop();
|
||||
|
||||
return oldParams;
|
||||
}
|
||||
182
mozilla/extensions/transformiix/source/xslt/txExecutionState.h
Normal file
182
mozilla/extensions/transformiix/source/xslt/txExecutionState.h
Normal file
@ -0,0 +1,182 @@
|
||||
/* -*- 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
|
||||
* Jonas Sicking.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* Jonas Sicking. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking <jonas@sicking.cc>
|
||||
*
|
||||
* 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_TXEXECUTIONSTATE_H
|
||||
#define TRANSFRMX_TXEXECUTIONSTATE_H
|
||||
|
||||
#include "txError.h"
|
||||
#include "baseutils.h"
|
||||
#include "txXMLEventHandler.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "txStack.h"
|
||||
#include "XMLUtils.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "txIXPathContext.h"
|
||||
#include "txVariableMap.h"
|
||||
#include "nsDoubleHashtable.h"
|
||||
#include "txKey.h"
|
||||
#include "txStylesheet.h"
|
||||
#include "ExprResult.h"
|
||||
|
||||
class txInstruction;
|
||||
class txIOutputHandlerFactory;
|
||||
class txExpandedNameMap;
|
||||
|
||||
|
||||
class txLoadedDocumentEntry : public PLDHashStringEntry {
|
||||
public:
|
||||
txLoadedDocumentEntry(const void* aKey) : PLDHashStringEntry(aKey)
|
||||
{
|
||||
}
|
||||
~txLoadedDocumentEntry()
|
||||
{
|
||||
delete mDocument;
|
||||
}
|
||||
Document* mDocument;
|
||||
};
|
||||
|
||||
DECL_DHASH_WRAPPER(txLoadedDocumentsBase, txLoadedDocumentEntry, nsAString&)
|
||||
|
||||
class txLoadedDocumentsHash : public txLoadedDocumentsBase
|
||||
{
|
||||
public:
|
||||
~txLoadedDocumentsHash();
|
||||
nsresult init(Document* aSourceDocument);
|
||||
void Add(Document* aDocument);
|
||||
Document* Get(const nsAString& aURI);
|
||||
|
||||
private:
|
||||
friend class txExecutionState;
|
||||
Document* mSourceDocument;
|
||||
};
|
||||
|
||||
|
||||
class txExecutionState : public txIMatchContext
|
||||
{
|
||||
public:
|
||||
txExecutionState(txStylesheet* aStylesheet);
|
||||
~txExecutionState();
|
||||
nsresult init(Node* aNode, txExpandedNameMap* aGlobalParams);
|
||||
nsresult end();
|
||||
|
||||
TX_DECL_MATCH_CONTEXT;
|
||||
|
||||
/**
|
||||
* Struct holding information about a current template rule
|
||||
*/
|
||||
struct TemplateRule {
|
||||
txStylesheet::ImportFrame* mFrame;
|
||||
PRInt32 mModeNsId;
|
||||
nsIAtom* mModeLocalName;
|
||||
txExpandedNameMap* mParams;
|
||||
};
|
||||
|
||||
// Stack functions
|
||||
nsresult pushEvalContext(txIEvalContext* aContext);
|
||||
txIEvalContext* popEvalContext();
|
||||
nsresult pushString(const nsAString& aStr);
|
||||
void popString(nsAString& aStr);
|
||||
nsresult pushInt(PRInt32 aInt);
|
||||
PRInt32 popInt();
|
||||
nsresult pushResultHandler(txAXMLEventHandler* aHandler);
|
||||
txAXMLEventHandler* popResultHandler();
|
||||
nsresult pushTemplateRule(txStylesheet::ImportFrame* aFrame,
|
||||
const txExpandedName& aMode,
|
||||
txExpandedNameMap* aParams);
|
||||
void popTemplateRule();
|
||||
nsresult pushParamMap(txExpandedNameMap* aParams);
|
||||
txExpandedNameMap* popParamMap();
|
||||
|
||||
// state-getting functions
|
||||
txIEvalContext* getEvalContext();
|
||||
txExpandedNameMap* getParamMap();
|
||||
Node* retrieveDocument(const nsAString& uri, const nsAString& baseUri);
|
||||
nsresult getKeyNodes(const txExpandedName& aKeyName, Document* aDocument,
|
||||
const nsAString& aKeyValue, PRBool aIndexIfNotFound,
|
||||
const NodeSet** aResult);
|
||||
TemplateRule* getCurrentTemplateRule();
|
||||
|
||||
// state-modification functions
|
||||
txInstruction* getNextInstruction();
|
||||
nsresult runTemplate(txInstruction* aInstruction);
|
||||
nsresult runTemplate(txInstruction* aInstruction,
|
||||
txInstruction* aReturnTo);
|
||||
void gotoInstruction(txInstruction* aNext);
|
||||
void returnFromTemplate();
|
||||
nsresult bindVariable(const txExpandedName& aName,
|
||||
ExprResult* aValue, MBool aOwned);
|
||||
void removeVariable(const txExpandedName& aName);
|
||||
|
||||
txAXMLEventHandler* mOutputHandler;
|
||||
txAXMLEventHandler* mResultHandler;
|
||||
txAOutputHandlerFactory* mOutputHandlerFactory;
|
||||
|
||||
txExpandedNameMap* mTemplateParams;
|
||||
|
||||
nsRefPtr<txStylesheet> mStylesheet;
|
||||
|
||||
private:
|
||||
txStack mReturnStack;
|
||||
txStack mLocalVarsStack;
|
||||
txStack mEvalContextStack;
|
||||
txStack mIntStack;
|
||||
txStack mResultHandlerStack;
|
||||
txStack mParamStack;
|
||||
nsStringArray mStringStack;
|
||||
txInstruction* mNextInstruction;
|
||||
txVariableMap* mLocalVariables;
|
||||
txVariableMap mGlobalVariableValues;
|
||||
nsAutoPtr<ExprResult> mGlobalVarPlaceholderValue;
|
||||
PRInt32 mRecursionDepth;
|
||||
|
||||
TemplateRule* mTemplateRules;
|
||||
PRInt32 mTemplateRulesBufferSize;
|
||||
PRInt32 mTemplateRuleCount;
|
||||
|
||||
txIEvalContext* mEvalContext;
|
||||
txIEvalContext* mInitialEvalContext;
|
||||
Document* mRTFDocument;
|
||||
txExpandedNameMap* mGlobalParams;
|
||||
|
||||
txLoadedDocumentsHash mLoadedDocuments;
|
||||
txKeyHash mKeyHash;
|
||||
|
||||
static const PRInt32 kMaxRecursionDepth;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -215,17 +215,17 @@ void txHTMLOutput::attribute(const nsAString& aName,
|
||||
if (shortHand &&
|
||||
localPart.Equals(aValue, txCaseInsensitiveStringComparator())) {
|
||||
txListIterator iter(&mAttributes);
|
||||
txAttribute* setAtt = 0;
|
||||
txOutAttr* setAtt = 0;
|
||||
nsCOMPtr<nsIAtom> localName = do_GetAtom(localPart);
|
||||
txExpandedName att(aNsID, localName);
|
||||
while ((setAtt = (txAttribute*)iter.next())) {
|
||||
while ((setAtt = (txOutAttr*)iter.next())) {
|
||||
if (setAtt->mName == att) {
|
||||
setAtt->mShorthand = MB_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!setAtt) {
|
||||
setAtt = new txAttribute(aNsID, localName, nsString());
|
||||
setAtt = new txOutAttr(aNsID, localName, nsString());
|
||||
setAtt->mShorthand = MB_TRUE;
|
||||
mAttributes.add(setAtt);
|
||||
}
|
||||
|
||||
1054
mozilla/extensions/transformiix/source/xslt/txInstructions.cpp
Normal file
1054
mozilla/extensions/transformiix/source/xslt/txInstructions.cpp
Normal file
File diff suppressed because it is too large
Load Diff
427
mozilla/extensions/transformiix/source/xslt/txInstructions.h
Normal file
427
mozilla/extensions/transformiix/source/xslt/txInstructions.h
Normal file
@ -0,0 +1,427 @@
|
||||
/* -*- 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
|
||||
* Jonas Sicking.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* Jonas Sicking. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking <jonas@sicking.cc>
|
||||
*
|
||||
* 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_TXINSTRUCTIONS_H
|
||||
#define TRANSFRMX_TXINSTRUCTIONS_H
|
||||
|
||||
#include "txError.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "TxObject.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsString.h"
|
||||
#include "XMLUtils.h"
|
||||
#include "txNamespaceMap.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "Expr.h"
|
||||
#include "txXSLTNumber.h"
|
||||
#include "txXSLTPatterns.h"
|
||||
|
||||
class txExecutionState;
|
||||
|
||||
class txInstruction : public TxObject
|
||||
{
|
||||
public:
|
||||
txInstruction() : mNext(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~txInstruction()
|
||||
{
|
||||
delete mNext;
|
||||
}
|
||||
|
||||
virtual nsresult execute(txExecutionState& aEs) = 0;
|
||||
|
||||
txInstruction* mNext;
|
||||
};
|
||||
|
||||
#define TX_DECL_TXINSTRUCTION \
|
||||
virtual nsresult execute(txExecutionState& aEs);
|
||||
|
||||
|
||||
class txApplyDefaultElementTemplate : public txInstruction
|
||||
{
|
||||
public:
|
||||
TX_DECL_TXINSTRUCTION
|
||||
};
|
||||
|
||||
class txApplyImportsEnd : public txInstruction
|
||||
{
|
||||
public:
|
||||
TX_DECL_TXINSTRUCTION
|
||||
};
|
||||
|
||||
class txApplyImportsStart : public txInstruction
|
||||
{
|
||||
public:
|
||||
TX_DECL_TXINSTRUCTION
|
||||
};
|
||||
|
||||
class txApplyTemplates : public txInstruction
|
||||
{
|
||||
public:
|
||||
txApplyTemplates(const txExpandedName& aMode);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
txExpandedName mMode;
|
||||
};
|
||||
|
||||
class txAttribute : public txInstruction
|
||||
{
|
||||
public:
|
||||
txAttribute(nsAutoPtr<Expr> aName, nsAutoPtr<Expr> aNamespace,
|
||||
txNamespaceMap* aMappings);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
nsAutoPtr<Expr> mName;
|
||||
nsAutoPtr<Expr> mNamespace;
|
||||
nsRefPtr<txNamespaceMap> mMappings;
|
||||
};
|
||||
|
||||
class txCallTemplate : public txInstruction
|
||||
{
|
||||
public:
|
||||
txCallTemplate(const txExpandedName& aName);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
txExpandedName mName;
|
||||
};
|
||||
|
||||
class txCheckParam : public txInstruction
|
||||
{
|
||||
public:
|
||||
txCheckParam(const txExpandedName& aName);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
txExpandedName mName;
|
||||
txInstruction* mBailTarget;
|
||||
};
|
||||
|
||||
class txConditionalGoto : public txInstruction
|
||||
{
|
||||
public:
|
||||
txConditionalGoto(nsAutoPtr<Expr> aCondition, txInstruction* aTarget);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
nsAutoPtr<Expr> mCondition;
|
||||
txInstruction* mTarget;
|
||||
};
|
||||
|
||||
class txComment : public txInstruction
|
||||
{
|
||||
public:
|
||||
TX_DECL_TXINSTRUCTION
|
||||
};
|
||||
|
||||
class txCopyBase : public txInstruction
|
||||
{
|
||||
protected:
|
||||
nsresult copyNode(Node* aNode, txExecutionState& aEs);
|
||||
};
|
||||
|
||||
class txCopy : public txCopyBase
|
||||
{
|
||||
public:
|
||||
txCopy();
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
txInstruction* mBailTarget;
|
||||
};
|
||||
|
||||
class txCopyOf : public txCopyBase
|
||||
{
|
||||
public:
|
||||
txCopyOf(nsAutoPtr<Expr> aSelect);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
nsAutoPtr<Expr> mSelect;
|
||||
};
|
||||
|
||||
class txEndElement : public txInstruction
|
||||
{
|
||||
public:
|
||||
TX_DECL_TXINSTRUCTION
|
||||
};
|
||||
|
||||
class txErrorInstruction : public txInstruction
|
||||
{
|
||||
public:
|
||||
TX_DECL_TXINSTRUCTION
|
||||
};
|
||||
|
||||
class txGoTo : public txInstruction
|
||||
{
|
||||
public:
|
||||
txGoTo(txInstruction* aTarget);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
txInstruction* mTarget;
|
||||
};
|
||||
|
||||
class txInsertAttrSet : public txInstruction
|
||||
{
|
||||
public:
|
||||
txInsertAttrSet(const txExpandedName& aName);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
txExpandedName mName;
|
||||
};
|
||||
|
||||
class txLoopNodeSet : public txInstruction
|
||||
{
|
||||
public:
|
||||
txLoopNodeSet(txInstruction* aTarget);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
txInstruction* mTarget;
|
||||
};
|
||||
|
||||
class txLREAttribute : public txInstruction
|
||||
{
|
||||
public:
|
||||
txLREAttribute(PRInt32 aNamespaceID, nsIAtom* aLocalName,
|
||||
nsIAtom* aPrefix, nsAutoPtr<Expr> aValue);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
PRInt32 mNamespaceID;
|
||||
nsCOMPtr<nsIAtom> mLocalName;
|
||||
nsCOMPtr<nsIAtom> mPrefix;
|
||||
nsAutoPtr<Expr> mValue;
|
||||
};
|
||||
|
||||
class txMessage : public txInstruction
|
||||
{
|
||||
public:
|
||||
txMessage(PRBool aTerminate);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
PRBool mTerminate;
|
||||
};
|
||||
|
||||
class txNumber : public txInstruction
|
||||
{
|
||||
public:
|
||||
txNumber(txXSLTNumber::LevelType aLevel, nsAutoPtr<txPattern> aCount,
|
||||
nsAutoPtr<txPattern> aFrom, nsAutoPtr<Expr> aValue,
|
||||
nsAutoPtr<Expr> aFormat, nsAutoPtr<Expr> aGroupingSeparator,
|
||||
nsAutoPtr<Expr> aGroupingSize);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
txXSLTNumber::LevelType mLevel;
|
||||
nsAutoPtr<txPattern> mCount;
|
||||
nsAutoPtr<txPattern> mFrom;
|
||||
nsAutoPtr<Expr> mValue;
|
||||
nsAutoPtr<Expr> mFormat;
|
||||
nsAutoPtr<Expr> mGroupingSeparator;
|
||||
nsAutoPtr<Expr> mGroupingSize;
|
||||
};
|
||||
|
||||
class txPopParams : public txInstruction
|
||||
{
|
||||
public:
|
||||
TX_DECL_TXINSTRUCTION
|
||||
};
|
||||
|
||||
class txProcessingInstruction : public txInstruction
|
||||
{
|
||||
public:
|
||||
txProcessingInstruction(nsAutoPtr<Expr> aName);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
nsAutoPtr<Expr> mName;
|
||||
};
|
||||
|
||||
class txPushNewContext : public txInstruction
|
||||
{
|
||||
public:
|
||||
txPushNewContext(nsAutoPtr<Expr> aSelect);
|
||||
~txPushNewContext();
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
|
||||
nsresult addSort(nsAutoPtr<Expr> aSelectExpr, nsAutoPtr<Expr> aLangExpr,
|
||||
nsAutoPtr<Expr> aDataTypeExpr, nsAutoPtr<Expr> aOrderExpr,
|
||||
nsAutoPtr<Expr> aCaseOrderExpr);
|
||||
|
||||
struct SortKey {
|
||||
SortKey(nsAutoPtr<Expr> aSelectExpr, nsAutoPtr<Expr> aLangExpr,
|
||||
nsAutoPtr<Expr> aDataTypeExpr, nsAutoPtr<Expr> aOrderExpr,
|
||||
nsAutoPtr<Expr> aCaseOrderExpr);
|
||||
|
||||
nsAutoPtr<Expr> mSelectExpr;
|
||||
nsAutoPtr<Expr> mLangExpr;
|
||||
nsAutoPtr<Expr> mDataTypeExpr;
|
||||
nsAutoPtr<Expr> mOrderExpr;
|
||||
nsAutoPtr<Expr> mCaseOrderExpr;
|
||||
};
|
||||
|
||||
nsVoidArray mSortKeys;
|
||||
nsAutoPtr<Expr> mSelect;
|
||||
txInstruction* mBailTarget;
|
||||
};
|
||||
|
||||
class txPushNullTemplateRule : public txInstruction
|
||||
{
|
||||
public:
|
||||
TX_DECL_TXINSTRUCTION
|
||||
};
|
||||
|
||||
class txPushParams : public txInstruction
|
||||
{
|
||||
public:
|
||||
TX_DECL_TXINSTRUCTION
|
||||
};
|
||||
|
||||
class txPushRTFHandler : public txInstruction
|
||||
{
|
||||
public:
|
||||
TX_DECL_TXINSTRUCTION
|
||||
};
|
||||
|
||||
class txPushStringHandler : public txInstruction
|
||||
{
|
||||
public:
|
||||
txPushStringHandler(PRBool aOnlyText);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
PRBool mOnlyText;
|
||||
};
|
||||
|
||||
class txRemoveVariable : public txInstruction
|
||||
{
|
||||
public:
|
||||
txRemoveVariable(const txExpandedName& aName);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
txExpandedName mName;
|
||||
};
|
||||
|
||||
class txReturn : public txInstruction
|
||||
{
|
||||
public:
|
||||
TX_DECL_TXINSTRUCTION
|
||||
};
|
||||
|
||||
class txSetParam : public txInstruction
|
||||
{
|
||||
public:
|
||||
txSetParam(const txExpandedName& aName, nsAutoPtr<Expr> aValue);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
txExpandedName mName;
|
||||
nsAutoPtr<Expr> mValue;
|
||||
};
|
||||
|
||||
class txSetVariable : public txInstruction
|
||||
{
|
||||
public:
|
||||
txSetVariable(const txExpandedName& aName, nsAutoPtr<Expr> aValue);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
txExpandedName mName;
|
||||
nsAutoPtr<Expr> mValue;
|
||||
};
|
||||
|
||||
class txStartElement : public txInstruction
|
||||
{
|
||||
public:
|
||||
txStartElement(nsAutoPtr<Expr> aName, nsAutoPtr<Expr> aNamespace,
|
||||
txNamespaceMap* aMappings);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
nsAutoPtr<Expr> mName;
|
||||
nsAutoPtr<Expr> mNamespace;
|
||||
nsRefPtr<txNamespaceMap> mMappings;
|
||||
};
|
||||
|
||||
class txStartLREElement : public txInstruction
|
||||
{
|
||||
public:
|
||||
txStartLREElement(PRInt32 aNamespaceID, nsIAtom* aLocalName,
|
||||
nsIAtom* aPrefix);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
PRInt32 mNamespaceID;
|
||||
nsCOMPtr<nsIAtom> mLocalName;
|
||||
nsCOMPtr<nsIAtom> mPrefix;
|
||||
};
|
||||
|
||||
class txText : public txInstruction
|
||||
{
|
||||
public:
|
||||
txText(const nsAString& aStr, PRBool aDOE);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
nsString mStr;
|
||||
PRBool mDOE;
|
||||
};
|
||||
|
||||
class txValueOf : public txInstruction
|
||||
{
|
||||
public:
|
||||
txValueOf(nsAutoPtr<Expr> aExpr, PRBool aDOE);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
nsAutoPtr<Expr> mExpr;
|
||||
PRBool mDOE;
|
||||
};
|
||||
|
||||
#endif //TRANSFRMX_TXINSTRUCTIONS_H
|
||||
@ -0,0 +1,566 @@
|
||||
/* -*- 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 "nsCOMArray.h"
|
||||
#include "nsICharsetAlias.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIExpatSink.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsINameSpace.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsINodeInfo.h"
|
||||
#include "nsIParser.h"
|
||||
#include "nsISyncLoadDOMService.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIXMLContentSink.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsParserCIID.h"
|
||||
#include "txAtoms.h"
|
||||
#include "txMozillaXSLTProcessor.h"
|
||||
#include "txStylesheetCompiler.h"
|
||||
#include "XMLUtils.h"
|
||||
|
||||
static const char kLoadAsData[] = "loadAsData";
|
||||
|
||||
class txStylesheetSink : public nsIXMLContentSink,
|
||||
public nsIExpatSink
|
||||
{
|
||||
public:
|
||||
txStylesheetSink(txStylesheetCompiler* aCompiler);
|
||||
virtual ~txStylesheetSink();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIEXPATSINK
|
||||
|
||||
// nsIContentSink
|
||||
NS_IMETHOD WillBuildModel(void) { return NS_OK; }
|
||||
NS_IMETHOD DidBuildModel(PRInt32 aQualityLevel);
|
||||
NS_IMETHOD WillInterrupt(void) { return NS_OK; }
|
||||
NS_IMETHOD WillResume(void) { return NS_OK; }
|
||||
NS_IMETHOD SetParser(nsIParser* aParser) { return NS_OK; }
|
||||
NS_IMETHOD FlushPendingNotifications() { return NS_OK; }
|
||||
NS_IMETHOD SetDocumentCharset(nsAString& aCharset) { return NS_OK; }
|
||||
|
||||
private:
|
||||
nsRefPtr<txStylesheetCompiler> mCompiler;
|
||||
|
||||
protected:
|
||||
// This exists soly to supress a warning from nsDerivedSafe
|
||||
txStylesheetSink();
|
||||
};
|
||||
|
||||
txStylesheetSink::txStylesheetSink(txStylesheetCompiler* aCompiler)
|
||||
: mCompiler(aCompiler)
|
||||
{
|
||||
}
|
||||
|
||||
txStylesheetSink::~txStylesheetSink()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS2(txStylesheetSink, nsIXMLContentSink, nsIExpatSink)
|
||||
|
||||
NS_IMETHODIMP
|
||||
txStylesheetSink::HandleStartElement(const PRUnichar *aName,
|
||||
const PRUnichar **aAtts,
|
||||
PRUint32 aAttsCount,
|
||||
PRUint32 aIndex,
|
||||
PRUint32 aLineNumber)
|
||||
{
|
||||
nsresult rv = mCompiler->startElement(aName, aAtts, aAttsCount);
|
||||
if (NS_FAILED(rv)) {
|
||||
mCompiler->cancel(rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
txStylesheetSink::HandleEndElement(const PRUnichar *aName)
|
||||
{
|
||||
nsresult rv = mCompiler->endElement();
|
||||
if (NS_FAILED(rv)) {
|
||||
mCompiler->cancel(rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
txStylesheetSink::HandleComment(const PRUnichar *aName)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
txStylesheetSink::HandleCDataSection(const PRUnichar *aData,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
return HandleCharacterData(aData, aLength);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
txStylesheetSink::HandleDoctypeDecl(const nsAString & aSubset,
|
||||
const nsAString & aName,
|
||||
const nsAString & aSystemId,
|
||||
const nsAString & aPublicId,
|
||||
nsISupports *aCatalogData)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
txStylesheetSink::HandleCharacterData(const PRUnichar *aData,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
nsresult rv = mCompiler->characters(Substring(aData, aData + aLength));
|
||||
if (NS_FAILED(rv)) {
|
||||
mCompiler->cancel(rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
txStylesheetSink::HandleProcessingInstruction(const PRUnichar *aTarget,
|
||||
const PRUnichar *aData)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
txStylesheetSink::HandleXMLDeclaration(const PRUnichar *aData,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
txStylesheetSink::ReportError(const PRUnichar *aErrorText,
|
||||
const PRUnichar *aSourceText)
|
||||
{
|
||||
mCompiler->cancel(NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
txStylesheetSink::DidBuildModel(PRInt32 aQualityLevel)
|
||||
{
|
||||
return mCompiler->doneLoading();
|
||||
}
|
||||
|
||||
class txCompileObserver : public txACompileObserver
|
||||
{
|
||||
public:
|
||||
txCompileObserver(txMozillaXSLTProcessor* aProcessor,
|
||||
nsILoadGroup* aLoadGroup);
|
||||
virtual ~txCompileObserver();
|
||||
|
||||
TX_DECL_ACOMPILEOBSERVER;
|
||||
|
||||
nsresult startLoad(nsIURI* aUri, txStylesheetSink* aSink,
|
||||
nsIURI* aReferrerUri);
|
||||
|
||||
protected:
|
||||
nsAutoRefCnt mRefCnt;
|
||||
|
||||
private:
|
||||
nsRefPtr<txMozillaXSLTProcessor> mProcessor;
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
|
||||
protected:
|
||||
// This exists soly to supress a warning from nsDerivedSafe
|
||||
txCompileObserver();
|
||||
};
|
||||
|
||||
txCompileObserver::txCompileObserver(txMozillaXSLTProcessor* aProcessor,
|
||||
nsILoadGroup* aLoadGroup)
|
||||
: mProcessor(aProcessor),
|
||||
mLoadGroup(aLoadGroup)
|
||||
{
|
||||
}
|
||||
|
||||
txCompileObserver::~txCompileObserver()
|
||||
{
|
||||
}
|
||||
|
||||
nsrefcnt
|
||||
txCompileObserver::AddRef()
|
||||
{
|
||||
return ++mRefCnt;
|
||||
}
|
||||
|
||||
nsrefcnt
|
||||
txCompileObserver::Release()
|
||||
{
|
||||
if (--mRefCnt == 0) {
|
||||
mRefCnt = 1; //stabilize
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txCompileObserver::loadURI(const nsAString& aUri,
|
||||
txStylesheetCompiler* aCompiler)
|
||||
{
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), aUri);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsRefPtr<txStylesheetSink> sink = new txStylesheetSink(aCompiler);
|
||||
NS_ENSURE_TRUE(sink, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return startLoad(uri, sink, nsnull);
|
||||
}
|
||||
|
||||
void
|
||||
txCompileObserver::onDoneCompiling(txStylesheetCompiler* aCompiler,
|
||||
nsresult aResult)
|
||||
{
|
||||
mProcessor->setStylesheet(aCompiler->getStylesheet());
|
||||
}
|
||||
|
||||
nsresult
|
||||
txCompileObserver::startLoad(nsIURI* aUri, txStylesheetSink* aSink,
|
||||
nsIURI* aReferrerUri)
|
||||
{
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
nsresult rv = NS_NewChannel(getter_AddRefs(channel), aUri);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
channel->SetLoadGroup(mLoadGroup);
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
||||
if (httpChannel) {
|
||||
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING("text/xml,application/xml,application/xhtml+xml,*/*;q=0.1"),
|
||||
PR_FALSE);
|
||||
|
||||
if (aReferrerUri) {
|
||||
httpChannel->SetReferrer(aReferrerUri);
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString charset(NS_LITERAL_STRING("UTF-8"));
|
||||
PRInt32 charsetSource = kCharsetFromDocTypeDefault;
|
||||
|
||||
// check channel's charset...
|
||||
nsCAutoString charsetVal;
|
||||
rv = channel->GetContentCharset(charsetVal);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsICharsetAlias> calias =
|
||||
do_GetService(NS_CHARSETALIAS_CONTRACTID);
|
||||
|
||||
if (calias) {
|
||||
nsAutoString preferred;
|
||||
rv = calias->GetPreferred(NS_ConvertASCIItoUCS2(charsetVal),
|
||||
preferred);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
charset = preferred;
|
||||
charsetSource = kCharsetFromChannel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
|
||||
nsCOMPtr<nsIParser> parser = do_CreateInstance(kCParserCID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Set the parser as the stream listener for the document loader...
|
||||
nsCOMPtr<nsIStreamListener> listener = do_QueryInterface(parser, &rv);
|
||||
NS_ENSURE_TRUE(listener, rv);
|
||||
|
||||
parser->SetDocumentCharset(charset, charsetSource);
|
||||
parser->SetCommand(kLoadAsData);
|
||||
parser->SetContentSink(aSink);
|
||||
parser->Parse(aUri);
|
||||
|
||||
return channel->AsyncOpen(listener, nsnull);
|
||||
}
|
||||
|
||||
nsresult
|
||||
TX_LoadSheet(nsIURI* aUri, txMozillaXSLTProcessor* aProcessor,
|
||||
nsILoadGroup* aLoadGroup, nsIURI* aReferrerUri)
|
||||
{
|
||||
nsCAutoString uri;
|
||||
aUri->GetSpec(uri);
|
||||
|
||||
nsRefPtr<txCompileObserver> observer =
|
||||
new txCompileObserver(aProcessor, aLoadGroup);
|
||||
NS_ENSURE_TRUE(observer, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsRefPtr<txStylesheetCompiler> compiler =
|
||||
new txStylesheetCompiler(NS_ConvertUTF8toUCS2(uri), observer);
|
||||
NS_ENSURE_TRUE(compiler, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsRefPtr<txStylesheetSink> sink = new txStylesheetSink(compiler);
|
||||
NS_ENSURE_TRUE(sink, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return observer->startLoad(aUri, sink, aReferrerUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* handling DOM->txStylesheet
|
||||
* Observer needs to do synchronous loads.
|
||||
*/
|
||||
static nsresult
|
||||
handleNode(nsIDOMNode* aNode, txStylesheetCompiler* aCompiler)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
PRUint16 nodetype;
|
||||
aNode->GetNodeType(&nodetype);
|
||||
switch (nodetype) {
|
||||
case nsIDOMNode::ELEMENT_NODE:
|
||||
{
|
||||
nsCOMPtr<nsIContent> element = do_QueryInterface(aNode);
|
||||
|
||||
nsCOMPtr<nsINodeInfo> ni;
|
||||
element->GetNodeInfo(*getter_AddRefs(ni));
|
||||
|
||||
PRInt32 namespaceID;
|
||||
nsCOMPtr<nsIAtom> prefix, localname;
|
||||
ni->GetNamespaceID(namespaceID);
|
||||
ni->GetNameAtom(*getter_AddRefs(localname));
|
||||
ni->GetPrefixAtom(*getter_AddRefs(prefix));
|
||||
|
||||
PRInt32 attsCount;
|
||||
element->GetAttrCount(attsCount);
|
||||
nsAutoArrayPtr<txStylesheetAttr> atts;
|
||||
if (attsCount > 0) {
|
||||
atts = new txStylesheetAttr[attsCount];
|
||||
NS_ENSURE_TRUE(atts, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
PRInt32 counter;
|
||||
for (counter = 0; counter < attsCount; ++counter) {
|
||||
txStylesheetAttr& att = atts[counter];
|
||||
element->GetAttrNameAt(counter, att.mNamespaceID,
|
||||
*getter_AddRefs(att.mLocalName),
|
||||
*getter_AddRefs(att.mPrefix));
|
||||
element->GetAttr(att.mNamespaceID, att.mLocalName, att.mValue);
|
||||
}
|
||||
}
|
||||
|
||||
rv = aCompiler->startElement(namespaceID, localname, prefix, atts,
|
||||
attsCount);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// explicitly destroy the attrs here since we no longer need it
|
||||
atts = nsnull;
|
||||
|
||||
PRInt32 childCount;
|
||||
element->ChildCount(childCount);
|
||||
if (childCount > 0) {
|
||||
PRInt32 counter = 0;
|
||||
nsCOMPtr<nsIContent> child;
|
||||
while (NS_SUCCEEDED(element->ChildAt(counter++, *getter_AddRefs(child))) && child) {
|
||||
nsCOMPtr<nsIDOMNode> childNode = do_QueryInterface(child);
|
||||
rv = handleNode(childNode, aCompiler);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
rv = aCompiler->endElement();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
break;
|
||||
}
|
||||
case nsIDOMNode::CDATA_SECTION_NODE:
|
||||
case nsIDOMNode::TEXT_NODE:
|
||||
{
|
||||
nsAutoString chars;
|
||||
aNode->GetNodeValue(chars);
|
||||
rv = aCompiler->characters(chars);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
break;
|
||||
}
|
||||
case nsIDOMNode::DOCUMENT_NODE:
|
||||
{
|
||||
nsCOMPtr<nsIDocument> document = do_QueryInterface(aNode);
|
||||
PRInt32 childCount;
|
||||
document->GetChildCount(childCount);
|
||||
if (childCount > 0) {
|
||||
PRInt32 counter = 0;
|
||||
nsCOMPtr<nsIContent> child;
|
||||
while (NS_SUCCEEDED(document->ChildAt(counter++, *getter_AddRefs(child))) && child) {
|
||||
nsCOMPtr<nsIDOMNode> childNode = do_QueryInterface(child);
|
||||
rv = handleNode(childNode, aCompiler);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class txSyncCompileObserver : public txACompileObserver
|
||||
{
|
||||
public:
|
||||
txSyncCompileObserver(nsIURI* aReferrerURI);
|
||||
virtual ~txSyncCompileObserver();
|
||||
|
||||
TX_DECL_ACOMPILEOBSERVER;
|
||||
|
||||
protected:
|
||||
nsAutoRefCnt mRefCnt;
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsISyncLoadDOMService> mLoadService;
|
||||
nsCOMPtr<nsIURI> mReferrer;
|
||||
|
||||
protected:
|
||||
// This exists soly to supress a warning from nsDerivedSafe
|
||||
txSyncCompileObserver();
|
||||
};
|
||||
|
||||
txSyncCompileObserver::txSyncCompileObserver(nsIURI* aReferrer)
|
||||
: mReferrer(aReferrer)
|
||||
{
|
||||
}
|
||||
|
||||
txSyncCompileObserver::~txSyncCompileObserver()
|
||||
{
|
||||
}
|
||||
|
||||
nsrefcnt
|
||||
txSyncCompileObserver::AddRef()
|
||||
{
|
||||
return ++mRefCnt;
|
||||
}
|
||||
|
||||
nsrefcnt
|
||||
txSyncCompileObserver::Release()
|
||||
{
|
||||
if (--mRefCnt == 0) {
|
||||
mRefCnt = 1; //stabilize
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txSyncCompileObserver::loadURI(const nsAString& aUri,
|
||||
txStylesheetCompiler* aCompiler)
|
||||
{
|
||||
if (!mLoadService) {
|
||||
mLoadService =
|
||||
do_GetService("@mozilla.org/content/syncload-dom-service;1");
|
||||
NS_ENSURE_TRUE(mLoadService, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), aUri);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
rv = NS_NewChannel(getter_AddRefs(channel), uri);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// This is probably called by js, a loadGroup for the channeldoesn't
|
||||
// make sense.
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
||||
if (httpChannel) {
|
||||
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING("text/xml,application/xml,application/xhtml+xml,*/*;q=0.1"),
|
||||
PR_FALSE);
|
||||
|
||||
if (mReferrer) {
|
||||
httpChannel->SetReferrer(mReferrer);
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIDOMDocument> document;
|
||||
rv = mLoadService->LoadDocument(channel, mReferrer,
|
||||
getter_AddRefs(document));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = handleNode(document, aCompiler);
|
||||
if (NS_FAILED(rv)) {
|
||||
aCompiler->cancel(rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = aCompiler->doneLoading();
|
||||
return rv;
|
||||
}
|
||||
|
||||
void txSyncCompileObserver::onDoneCompiling(txStylesheetCompiler* aCompiler,
|
||||
nsresult aResult)
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
TX_CompileStylesheet(nsIDOMNode* aNode, txStylesheet** aStylesheet)
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocument> document;
|
||||
aNode->GetOwnerDocument(getter_AddRefs(document));
|
||||
if (!document) {
|
||||
document = do_QueryInterface(aNode);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(document);
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
doc->GetBaseURL(*getter_AddRefs(uri));
|
||||
nsCAutoString baseURI;
|
||||
uri->GetSpec(baseURI);
|
||||
|
||||
nsRefPtr<txSyncCompileObserver> obs = new txSyncCompileObserver(uri);
|
||||
NS_ENSURE_TRUE(obs, NS_ERROR_OUT_OF_MEMORY);
|
||||
NS_ConvertUTF8toUCS2 base(baseURI);
|
||||
nsRefPtr<txStylesheetCompiler> compiler =
|
||||
new txStylesheetCompiler(base, obs);
|
||||
NS_ENSURE_TRUE(compiler, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = handleNode(document, compiler);
|
||||
if (NS_FAILED(rv)) {
|
||||
compiler->cancel(rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = compiler->doneLoading();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aStylesheet = compiler->getStylesheet();
|
||||
NS_ADDREF(*aStylesheet);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -44,14 +44,14 @@
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMClassInfo.h"
|
||||
#include "nsIScriptLoader.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "ProcessorState.h"
|
||||
#include "txExecutionState.h"
|
||||
#include "txMozillaTextOutput.h"
|
||||
#include "txMozillaXMLOutput.h"
|
||||
#include "txSingleNodeContext.h"
|
||||
#include "txURIUtils.h"
|
||||
#include "XMLUtils.h"
|
||||
#include "txUnknownHandler.h"
|
||||
#include "txXSLTProcessor.h"
|
||||
#include "nsIHTMLDocument.h"
|
||||
|
||||
/**
|
||||
@ -60,11 +60,11 @@
|
||||
class txToDocHandlerFactory : public txAOutputHandlerFactory
|
||||
{
|
||||
public:
|
||||
txToDocHandlerFactory(ProcessorState* aPs,
|
||||
txToDocHandlerFactory(txExecutionState* aEs,
|
||||
nsIDOMDocument* aSourceDocument,
|
||||
nsIDOMDocument* aResultDocument,
|
||||
nsITransformObserver* aObserver)
|
||||
: mPs(aPs), mSourceDocument(aSourceDocument),
|
||||
: mEs(aEs), mSourceDocument(aSourceDocument),
|
||||
mResultDocument(aResultDocument), mObserver(aObserver)
|
||||
{
|
||||
}
|
||||
@ -76,7 +76,7 @@ public:
|
||||
TX_DECL_TXAOUTPUTHANDLERFACTORY
|
||||
|
||||
private:
|
||||
ProcessorState* mPs;
|
||||
txExecutionState* mEs;
|
||||
nsCOMPtr<nsIDOMDocument> mSourceDocument;
|
||||
nsCOMPtr<nsIDOMDocument> mResultDocument;
|
||||
nsCOMPtr<nsITransformObserver> mObserver;
|
||||
@ -109,7 +109,7 @@ txToDocHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
|
||||
case eMethodNotSet:
|
||||
case eXMLOutput:
|
||||
{
|
||||
*aHandler = new txUnknownHandler(mPs);
|
||||
*aHandler = new txUnknownHandler(mEs);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -260,129 +260,89 @@ txMozillaXSLTProcessor::TransformDocument(nsIDOMNode* aSourceDOM,
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
PRUint16 type = 0;
|
||||
aStyleDOM->GetNodeType(&type);
|
||||
NS_ENSURE_TRUE(type == nsIDOMNode::ELEMENT_NODE ||
|
||||
type == nsIDOMNode::DOCUMENT_NODE,
|
||||
NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsresult rv = TX_CompileStylesheet(aStyleDOM, getter_AddRefs(mStylesheet));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// Create wrapper for the source document.
|
||||
mSource = aSourceDOM;
|
||||
nsCOMPtr<nsIDOMDocument> sourceDOMDocument;
|
||||
aSourceDOM->GetOwnerDocument(getter_AddRefs(sourceDOMDocument));
|
||||
mSource->GetOwnerDocument(getter_AddRefs(sourceDOMDocument));
|
||||
if (!sourceDOMDocument) {
|
||||
sourceDOMDocument = do_QueryInterface(aSourceDOM);
|
||||
NS_ENSURE_TRUE(sourceDOMDocument, NS_ERROR_FAILURE);
|
||||
sourceDOMDocument = do_QueryInterface(mSource);
|
||||
}
|
||||
NS_ENSURE_TRUE(sourceDOMDocument, NS_ERROR_FAILURE);
|
||||
Document sourceDocument(sourceDOMDocument);
|
||||
Node* sourceNode = sourceDocument.createWrapper(aSourceDOM);
|
||||
Node* sourceNode = sourceDocument.createWrapper(mSource);
|
||||
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(sourceNode, &xslDocument);
|
||||
|
||||
// XXX Need to add error observers
|
||||
|
||||
// Set current txIEvalContext
|
||||
txSingleNodeContext evalContext(sourceNode, &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,
|
||||
txExecutionState es(mStylesheet);
|
||||
txToDocHandlerFactory handlerFactory(&es, sourceDOMDocument, aOutputDoc,
|
||||
nsnull);
|
||||
ps.mOutputHandlerFactory = &handlerFactory;
|
||||
es.mOutputHandlerFactory = &handlerFactory;
|
||||
|
||||
es.init(sourceNode, &mVariables);
|
||||
|
||||
// Process root of XML source document
|
||||
txXSLTProcessor::transform(&ps);
|
||||
txXSLTProcessor::execute(es);
|
||||
es.end();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
txMozillaXSLTProcessor::TransformDocument(nsIDOMNode* aSourceDOM,
|
||||
nsIDOMNode* aStyleDOM,
|
||||
nsITransformObserver* aObserver,
|
||||
nsIDOMDocument** aOutputDoc)
|
||||
txMozillaXSLTProcessor::SetTransformObserver(nsITransformObserver* aObserver)
|
||||
{
|
||||
NS_ENSURE_ARG(aSourceDOM);
|
||||
NS_ENSURE_ARG(aStyleDOM);
|
||||
NS_ASSERTION(aObserver, "no observer");
|
||||
NS_ENSURE_ARG_POINTER(aOutputDoc);
|
||||
mObserver = aObserver;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txMozillaXSLTProcessor::SetSourceContentModel(nsIDOMNode* aSourceDOM)
|
||||
{
|
||||
mSource = aSourceDOM;
|
||||
if (mStylesheet) {
|
||||
return DoTransform();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txMozillaXSLTProcessor::DoTransform()
|
||||
{
|
||||
NS_ENSURE_TRUE(mSource, NS_ERROR_UNEXPECTED);
|
||||
NS_ENSURE_TRUE(mStylesheet, NS_ERROR_UNEXPECTED);
|
||||
NS_ASSERTION(mObserver, "no observer");
|
||||
|
||||
// Create wrapper for the source document.
|
||||
nsCOMPtr<nsIDOMDocument> sourceDOMDocument;
|
||||
aSourceDOM->GetOwnerDocument(getter_AddRefs(sourceDOMDocument));
|
||||
mSource->GetOwnerDocument(getter_AddRefs(sourceDOMDocument));
|
||||
if (!sourceDOMDocument) {
|
||||
sourceDOMDocument = do_QueryInterface(aSourceDOM);
|
||||
sourceDOMDocument = do_QueryInterface(mSource);
|
||||
}
|
||||
NS_ENSURE_TRUE(sourceDOMDocument, NS_ERROR_FAILURE);
|
||||
Document sourceDocument(sourceDOMDocument);
|
||||
Node* sourceNode = sourceDocument.createWrapper(aSourceDOM);
|
||||
Node* sourceNode = sourceDocument.createWrapper(mSource);
|
||||
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(sourceNode, &xslDocument);
|
||||
txExecutionState es(mStylesheet);
|
||||
|
||||
// XXX Need to add error observers
|
||||
|
||||
// Set current txIEvalContext
|
||||
txSingleNodeContext evalContext(sourceNode, &ps);
|
||||
ps.setEvalContext(&evalContext);
|
||||
txToDocHandlerFactory handlerFactory(&es, sourceDOMDocument, nsnull,
|
||||
mObserver);
|
||||
es.mOutputHandlerFactory = &handlerFactory;
|
||||
|
||||
// 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;
|
||||
es.init(sourceNode, &mVariables);
|
||||
|
||||
// Process root of XML source document
|
||||
txXSLTProcessor::transform(&ps);
|
||||
txXSLTProcessor::execute(es);
|
||||
es.end();
|
||||
|
||||
txAOutputXMLEventHandler* handler =
|
||||
NS_STATIC_CAST(txAOutputXMLEventHandler*, ps.mOutputHandler);
|
||||
handler->getOutputDocument(aOutputDoc);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -394,27 +354,15 @@ txMozillaXSLTProcessor::ImportStylesheet(nsIDOMNode *aStyle)
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
if (mStylesheet) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
PRUint16 type = 0;
|
||||
aStyle->GetNodeType(&type);
|
||||
switch (type) {
|
||||
case nsIDOMNode::ELEMENT_NODE:
|
||||
aStyle->GetOwnerDocument(getter_AddRefs(mStylesheetDocument));
|
||||
break;
|
||||
NS_ENSURE_TRUE(type == nsIDOMNode::ELEMENT_NODE ||
|
||||
type == nsIDOMNode::DOCUMENT_NODE,
|
||||
NS_ERROR_INVALID_ARG);
|
||||
|
||||
case nsIDOMNode::DOCUMENT_NODE:
|
||||
mStylesheetDocument = do_QueryInterface(aStyle);
|
||||
break;
|
||||
nsresult rv = TX_CompileStylesheet(aStyle, getter_AddRefs(mStylesheet));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
default:
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
mStylesheet = aStyle;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -441,45 +389,22 @@ txMozillaXSLTProcessor::TransformToDocument(nsIDOMNode *aSource,
|
||||
Node* sourceNode = sourceDocument.createWrapper(aSource);
|
||||
NS_ENSURE_TRUE(sourceNode, NS_ERROR_FAILURE);
|
||||
|
||||
// Create wrapper for the style document.
|
||||
Document xslDocument(mStylesheetDocument);
|
||||
|
||||
// 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(sourceNode, &xslDocument);
|
||||
txExecutionState es(mStylesheet);
|
||||
|
||||
// XXX Need to add error observers
|
||||
|
||||
// Set current txIEvalContext
|
||||
txSingleNodeContext evalContext(sourceNode, &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,
|
||||
txToDocHandlerFactory handlerFactory(&es, sourceDOMDocument, nsnull,
|
||||
nsnull);
|
||||
ps.mOutputHandlerFactory = &handlerFactory;
|
||||
es.mOutputHandlerFactory = &handlerFactory;
|
||||
|
||||
es.init(sourceNode, &mVariables);
|
||||
|
||||
// Process root of XML source document
|
||||
txXSLTProcessor::transform(&ps);
|
||||
txXSLTProcessor::execute(es);
|
||||
es.end();
|
||||
|
||||
txAOutputXMLEventHandler* handler =
|
||||
NS_STATIC_CAST(txAOutputXMLEventHandler*, ps.mOutputHandler);
|
||||
NS_STATIC_CAST(txAOutputXMLEventHandler*, es.mOutputHandler);
|
||||
handler->getOutputDocument(aResult);
|
||||
|
||||
return NS_OK;
|
||||
@ -511,43 +436,20 @@ txMozillaXSLTProcessor::TransformToFragment(nsIDOMNode *aSource,
|
||||
Node* sourceNode = sourceDocument.createWrapper(aSource);
|
||||
NS_ENSURE_TRUE(sourceNode, NS_ERROR_FAILURE);
|
||||
|
||||
// Create wrapper for the style document.
|
||||
Document xslDocument(mStylesheetDocument);
|
||||
|
||||
// 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(sourceNode, &xslDocument);
|
||||
txExecutionState es(mStylesheet);
|
||||
|
||||
// XXX Need to add error observers
|
||||
|
||||
// Set current txIEvalContext
|
||||
txSingleNodeContext evalContext(sourceNode, &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);
|
||||
nsresult rv = aOutput->CreateDocumentFragment(aResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
txToFragmentHandlerFactory handlerFactory(*aResult);
|
||||
ps.mOutputHandlerFactory = &handlerFactory;
|
||||
es.mOutputHandlerFactory = &handlerFactory;
|
||||
|
||||
es.init(sourceNode, &mVariables);
|
||||
|
||||
// Process root of XML source document
|
||||
txXSLTProcessor::transform(&ps);
|
||||
txXSLTProcessor::execute(es);
|
||||
es.end();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -671,6 +573,23 @@ txMozillaXSLTProcessor::Reset()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
txMozillaXSLTProcessor::LoadStyleSheet(nsIURI* aUri, nsILoadGroup* aLoadGroup,
|
||||
nsIURI* aReferrerUri)
|
||||
{
|
||||
return TX_LoadSheet(aUri, this, aLoadGroup, aReferrerUri);
|
||||
}
|
||||
|
||||
nsresult
|
||||
txMozillaXSLTProcessor::setStylesheet(txStylesheet* aStylesheet)
|
||||
{
|
||||
mStylesheet = aStylesheet;
|
||||
if (mSource) {
|
||||
return DoTransform();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static*/
|
||||
nsresult
|
||||
txVariable::Convert(nsIVariant *aValue, ExprResult** aResult)
|
||||
|
||||
@ -47,18 +47,24 @@
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsWeakPtr.h"
|
||||
#include "txExpandedNameMap.h"
|
||||
#include "XSLTProcessor.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "txXMLEventHandler.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIXSLTProcessorObsolete.h"
|
||||
#include "txXSLTProcessor.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "txStylesheet.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
class nsIURI;
|
||||
class nsIXMLContentSink;
|
||||
|
||||
/* 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"
|
||||
"@mozilla.org/document-transformer;1?type=text/xslt"
|
||||
|
||||
class txVariable : public txIGlobalParameter
|
||||
{
|
||||
@ -133,15 +139,27 @@ public:
|
||||
NS_DECL_NSIXSLTPROCESSOROBSOLETE
|
||||
|
||||
// nsIDocumentTransformer interface
|
||||
NS_IMETHOD TransformDocument(nsIDOMNode *aSourceDOM,
|
||||
nsIDOMNode *aStyleDOM,
|
||||
nsITransformObserver *aObserver,
|
||||
nsIDOMDocument **_retval);
|
||||
NS_IMETHOD SetTransformObserver(nsITransformObserver* aObserver);
|
||||
NS_IMETHOD LoadStyleSheet(nsIURI* aUri, nsILoadGroup* aLoadGroup,
|
||||
nsIURI* aReferrerUri);
|
||||
NS_IMETHOD SetSourceContentModel(nsIDOMNode* aSource);
|
||||
NS_IMETHOD CancelLoads() {return NS_OK;};
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIDOMNode> mStylesheet;
|
||||
nsCOMPtr<nsIDOMDocument> mStylesheetDocument;
|
||||
nsresult setStylesheet(txStylesheet* aStylesheet);
|
||||
|
||||
private:
|
||||
nsresult DoTransform();
|
||||
|
||||
nsRefPtr<txStylesheet> mStylesheet;
|
||||
nsCOMPtr<nsIDOMNode> mSource;
|
||||
nsCOMPtr<nsITransformObserver> mObserver;
|
||||
txExpandedNameMap mVariables;
|
||||
};
|
||||
|
||||
extern nsresult TX_LoadSheet(nsIURI* aUri, txMozillaXSLTProcessor* aProcessor,
|
||||
nsILoadGroup* aLoadGroup, nsIURI* aReferrerUri);
|
||||
|
||||
extern nsresult TX_CompileStylesheet(nsIDOMNode* aNode,
|
||||
txStylesheet** aStylesheet);
|
||||
|
||||
#endif
|
||||
|
||||
@ -44,12 +44,11 @@
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
txPattern* txPatternParser::createPattern(const nsAFlatString& aPattern,
|
||||
txIParseContext* aContext,
|
||||
ProcessorState* aPs)
|
||||
txIParseContext* aContext)
|
||||
{
|
||||
txPattern* pattern = 0;
|
||||
ExprLexer lexer(aPattern);
|
||||
nsresult rv = createUnionPattern(lexer, aContext, aPs, pattern);
|
||||
nsresult rv = createUnionPattern(lexer, aContext, pattern);
|
||||
if (NS_FAILED(rv)) {
|
||||
// XXX error report parsing error
|
||||
return 0;
|
||||
@ -59,13 +58,12 @@ txPattern* txPatternParser::createPattern(const nsAFlatString& aPattern,
|
||||
|
||||
nsresult txPatternParser::createUnionPattern(ExprLexer& aLexer,
|
||||
txIParseContext* aContext,
|
||||
ProcessorState* aPs,
|
||||
txPattern*& aPattern)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
txPattern* locPath = 0;
|
||||
|
||||
rv = createLocPathPattern(aLexer, aContext, aPs, locPath);
|
||||
rv = createLocPathPattern(aLexer, aContext, locPath);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
@ -96,7 +94,7 @@ nsresult txPatternParser::createUnionPattern(ExprLexer& aLexer,
|
||||
|
||||
aLexer.nextToken();
|
||||
do {
|
||||
rv = createLocPathPattern(aLexer, aContext, aPs, locPath);
|
||||
rv = createLocPathPattern(aLexer, aContext, locPath);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete unionPattern;
|
||||
return rv;
|
||||
@ -123,7 +121,6 @@ nsresult txPatternParser::createUnionPattern(ExprLexer& aLexer,
|
||||
|
||||
nsresult txPatternParser::createLocPathPattern(ExprLexer& aLexer,
|
||||
txIParseContext* aContext,
|
||||
ProcessorState* aPs,
|
||||
txPattern*& aPattern)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
@ -157,7 +154,7 @@ nsresult txPatternParser::createLocPathPattern(ExprLexer& aLexer,
|
||||
rv = createIdPattern(aLexer, stepPattern);
|
||||
}
|
||||
else if (nameAtom == txXSLTAtoms::key) {
|
||||
rv = createKeyPattern(aLexer, aContext, aPs, stepPattern);
|
||||
rv = createKeyPattern(aLexer, aContext, stepPattern);
|
||||
}
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
@ -246,7 +243,6 @@ nsresult txPatternParser::createIdPattern(ExprLexer& aLexer,
|
||||
|
||||
nsresult txPatternParser::createKeyPattern(ExprLexer& aLexer,
|
||||
txIParseContext* aContext,
|
||||
ProcessorState* aPs,
|
||||
txPattern*& aPattern)
|
||||
{
|
||||
// check for '(' Literal, Literal ')'
|
||||
@ -270,7 +266,7 @@ nsresult txPatternParser::createKeyPattern(ExprLexer& aLexer,
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
aPattern = new txKeyPattern(aPs, prefix, localName, namespaceID, value);
|
||||
aPattern = new txKeyPattern(prefix, localName, namespaceID, value);
|
||||
|
||||
return aPattern ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@ -46,22 +46,18 @@ class txPatternParser : public ExprParser
|
||||
{
|
||||
public:
|
||||
static txPattern* createPattern(const nsAFlatString& aPattern,
|
||||
txIParseContext* aContext,
|
||||
ProcessorState* aPs);
|
||||
txIParseContext* aContext);
|
||||
protected:
|
||||
static nsresult createUnionPattern(ExprLexer& aLexer,
|
||||
txIParseContext* aContext,
|
||||
ProcessorState* aPs,
|
||||
txPattern*& aPattern);
|
||||
static nsresult createLocPathPattern(ExprLexer& aLexer,
|
||||
txIParseContext* aContext,
|
||||
ProcessorState* aPs,
|
||||
txPattern*& aPattern);
|
||||
static nsresult createIdPattern(ExprLexer& aLexer,
|
||||
txPattern*& aPattern);
|
||||
static nsresult createKeyPattern(ExprLexer& aLexer,
|
||||
txIParseContext* aContext,
|
||||
ProcessorState* aPs,
|
||||
txPattern*& aPattern);
|
||||
static nsresult createStepPattern(ExprLexer& aLexer,
|
||||
txIParseContext* aContext,
|
||||
|
||||
@ -0,0 +1,346 @@
|
||||
/* -*- 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) 2003
|
||||
* 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 "txStandaloneStylesheetCompiler.h"
|
||||
#include "txStylesheetCompiler.h"
|
||||
#include "txURIUtils.h"
|
||||
#include "xmlparse.h"
|
||||
|
||||
/**
|
||||
* Implementation of an In-Memory DOM based XML parser. The actual XML
|
||||
* parsing is provided by EXPAT.
|
||||
*/
|
||||
class txDriver : public txACompileObserver
|
||||
{
|
||||
public:
|
||||
nsresult parse(istream& aInputStream, const nsAString& aUri);
|
||||
const nsAString& getErrorString();
|
||||
|
||||
/**
|
||||
* Expat handlers
|
||||
*/
|
||||
int StartElement(const XML_Char *aName, const XML_Char **aAtts);
|
||||
int EndElement(const XML_Char* aName);
|
||||
void CharacterData(const XML_Char* aChars, int aLength);
|
||||
int ExternalEntityRef(const XML_Char *aContext, const XML_Char *aBase,
|
||||
const XML_Char *aSystemId,
|
||||
const XML_Char *aPublicId);
|
||||
|
||||
TX_DECL_ACOMPILEOBSERVER;
|
||||
|
||||
nsRefPtr<txStylesheetCompiler> mCompiler;
|
||||
protected:
|
||||
void createErrorString();
|
||||
nsString mErrorString;
|
||||
XML_Parser mExpatParser;
|
||||
nsAutoRefCnt mRefCnt;
|
||||
};
|
||||
|
||||
nsresult
|
||||
TX_CompileStylesheetPath(const nsAString& aHref, txStylesheet** aResult)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
nsAutoString errMsg;
|
||||
istream* xslInput = URIUtils::getInputStream(aHref, errMsg);
|
||||
if (!xslInput) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsRefPtr<txDriver> driver = new txDriver();
|
||||
if (!driver) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
driver->mCompiler = new txStylesheetCompiler(aHref, driver);
|
||||
if (!driver->mCompiler) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
nsresult rv = driver->parse(*xslInput, aHref);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
};
|
||||
*aResult = driver->mCompiler->getStylesheet();
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* expat C stub handlers
|
||||
*/
|
||||
|
||||
// shortcut macro for redirection into txDriver method calls
|
||||
#define TX_DRIVER(_userData) NS_STATIC_CAST(txDriver*, _userData)
|
||||
|
||||
PR_STATIC_CALLBACK(int)
|
||||
startElement(void *aUserData, const XML_Char *aName, const XML_Char **aAtts)
|
||||
{
|
||||
NS_ENSURE_TRUE(aUserData, XML_ERROR_NONE);
|
||||
return TX_DRIVER(aUserData)->StartElement(aName, aAtts);
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(int)
|
||||
endElement(void *aUserData, const XML_Char* aName)
|
||||
{
|
||||
NS_ENSURE_TRUE(aUserData, XML_ERROR_NONE);
|
||||
return TX_DRIVER(aUserData)->EndElement(aName);
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(void)
|
||||
charData(void* aUserData, const XML_Char* aChars, int aLength)
|
||||
{
|
||||
if (!aUserData) {
|
||||
NS_WARNING("no userData in charData handler");
|
||||
return;
|
||||
}
|
||||
TX_DRIVER(aUserData)->CharacterData(aChars, aLength);
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(int)
|
||||
externalEntityRefHandler(XML_Parser aParser,
|
||||
const XML_Char *aContext,
|
||||
const XML_Char *aBase,
|
||||
const XML_Char *aSystemId,
|
||||
const XML_Char *aPublicId)
|
||||
{
|
||||
// aParser is aUserData is the txDriver,
|
||||
// we set that in txDriver::parse
|
||||
NS_ENSURE_TRUE(aParser, XML_ERROR_NONE);
|
||||
return TX_DRIVER(aParser)->ExternalEntityRef(aContext, aBase,
|
||||
aSystemId, aPublicId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses the given input stream and returns a DOM Document.
|
||||
* A NULL pointer will be returned if errors occurred
|
||||
*/
|
||||
nsresult
|
||||
txDriver::parse(istream& aInputStream, const nsAString& aUri)
|
||||
{
|
||||
mErrorString.Truncate();
|
||||
if (!aInputStream) {
|
||||
mErrorString.Append(NS_LITERAL_STRING("unable to parse xml: invalid or unopen stream encountered."));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mExpatParser = XML_ParserCreate(nsnull);
|
||||
if (!mExpatParser) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
XML_SetUserData(mExpatParser, this);
|
||||
XML_SetElementHandler(mExpatParser, startElement, endElement);
|
||||
XML_SetCharacterDataHandler(mExpatParser, charData);
|
||||
#ifdef XML_DTD
|
||||
XML_SetParamEntityParsing(mExpatParser, XML_PARAM_ENTITY_PARSING_ALWAYS);
|
||||
#endif
|
||||
XML_SetExternalEntityRefHandler(mExpatParser, externalEntityRefHandler);
|
||||
XML_SetExternalEntityRefHandlerArg(mExpatParser, this);
|
||||
XML_SetBase(mExpatParser,
|
||||
(const XML_Char*)(PromiseFlatString(aUri).get()));
|
||||
|
||||
const int bufferSize = 1024;
|
||||
char buf[bufferSize];
|
||||
PRBool done;
|
||||
int success;
|
||||
do {
|
||||
aInputStream.read(buf, bufferSize);
|
||||
done = aInputStream.eof();
|
||||
success = XML_Parse(mExpatParser, buf, aInputStream.gcount(), done);
|
||||
if (!success) {
|
||||
createErrorString();
|
||||
done = MB_TRUE;
|
||||
}
|
||||
} while (!done);
|
||||
aInputStream.clear();
|
||||
|
||||
// clean up
|
||||
XML_ParserFree(mExpatParser);
|
||||
mCompiler->doneLoading();
|
||||
if (!success) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
const nsAString&
|
||||
txDriver::getErrorString()
|
||||
{
|
||||
return mErrorString;
|
||||
}
|
||||
|
||||
int
|
||||
txDriver::StartElement(const XML_Char *aName, const XML_Char **aAtts)
|
||||
{
|
||||
PRInt32 attcount = 0;
|
||||
const XML_Char** atts = aAtts;
|
||||
while (*atts) {
|
||||
++atts;
|
||||
++attcount;
|
||||
}
|
||||
nsresult rv =
|
||||
mCompiler->startElement(NS_STATIC_CAST(const PRUnichar*, aName),
|
||||
NS_STATIC_CAST(const PRUnichar**, aAtts),
|
||||
attcount/2);
|
||||
if (NS_FAILED(rv)) {
|
||||
mCompiler->cancel(rv);
|
||||
return XML_ERROR_SYNTAX;
|
||||
}
|
||||
return XML_ERROR_NONE;
|
||||
}
|
||||
|
||||
int
|
||||
txDriver::EndElement(const XML_Char* aName)
|
||||
{
|
||||
nsresult rv = mCompiler->endElement();
|
||||
if (NS_FAILED(rv)) {
|
||||
mCompiler->cancel(rv);
|
||||
return XML_ERROR_SYNTAX;
|
||||
}
|
||||
return XML_ERROR_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
txDriver::CharacterData(const XML_Char* aChars, int aLength)
|
||||
{
|
||||
const PRUnichar* pChars = NS_STATIC_CAST(const PRUnichar*, aChars);
|
||||
// ignore rv, as this expat handler returns void
|
||||
nsresult rv = mCompiler->characters(Substring(pChars, pChars + aLength));
|
||||
if (NS_FAILED(rv)) {
|
||||
mCompiler->cancel(rv);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
txDriver::ExternalEntityRef(const XML_Char *aContext, const XML_Char *aBase,
|
||||
const XML_Char *aSystemId,
|
||||
const XML_Char *aPublicId)
|
||||
{
|
||||
if (aPublicId) {
|
||||
// not supported, this is "http://some.site.net/foo.dtd" stuff
|
||||
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
|
||||
}
|
||||
nsAutoString absUrl;
|
||||
URIUtils::resolveHref(nsDependentString((PRUnichar*)aSystemId),
|
||||
nsDependentString((PRUnichar*)aBase), absUrl);
|
||||
istream* extInput = URIUtils::getInputStream(absUrl, mErrorString);
|
||||
if (!extInput) {
|
||||
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
|
||||
}
|
||||
XML_Parser parent = mExpatParser;
|
||||
mExpatParser =
|
||||
XML_ExternalEntityParserCreate(mExpatParser, aContext, nsnull);
|
||||
if (!mExpatParser) {
|
||||
mExpatParser = parent;
|
||||
delete extInput;
|
||||
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
|
||||
}
|
||||
XML_SetBase(mExpatParser, absUrl.get());
|
||||
|
||||
const int bufSize = 1024;
|
||||
char buffer[bufSize];
|
||||
int result;
|
||||
PRBool done;
|
||||
do {
|
||||
extInput->read(buffer, bufSize);
|
||||
done = extInput->eof();
|
||||
if (!(result =
|
||||
XML_Parse(mExpatParser, buffer, extInput->gcount(), done))) {
|
||||
createErrorString();
|
||||
mErrorString.Append(PRUnichar('\n'));
|
||||
done = MB_TRUE;
|
||||
}
|
||||
} while (!done);
|
||||
|
||||
delete extInput;
|
||||
XML_ParserFree(mExpatParser);
|
||||
|
||||
mExpatParser = parent;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
txDriver::createErrorString()
|
||||
{
|
||||
XML_Error errCode = XML_GetErrorCode(mExpatParser);
|
||||
mErrorString.AppendWithConversion(XML_ErrorString(errCode));
|
||||
mErrorString.Append(NS_LITERAL_STRING(" at line "));
|
||||
mErrorString.AppendInt(XML_GetCurrentLineNumber(mExpatParser));
|
||||
mErrorString.Append(NS_LITERAL_STRING(" in "));
|
||||
mErrorString.Append((const PRUnichar*)XML_GetBase(mExpatParser));
|
||||
}
|
||||
|
||||
/**
|
||||
* txACompileObserver implementation
|
||||
*/
|
||||
|
||||
nsrefcnt
|
||||
txDriver::AddRef()
|
||||
{
|
||||
return ++mRefCnt;
|
||||
}
|
||||
|
||||
nsrefcnt
|
||||
txDriver::Release()
|
||||
{
|
||||
if (--mRefCnt == 0) {
|
||||
mRefCnt = 1; //stabilize
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
void
|
||||
txDriver::onDoneCompiling(txStylesheetCompiler* aCompiler, nsresult aResult)
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
txDriver::loadURI(const nsAString& aUri, txStylesheetCompiler* aCompiler)
|
||||
{
|
||||
nsAutoString errMsg;
|
||||
istream* xslInput = URIUtils::getInputStream(aUri, errMsg);
|
||||
if (!xslInput) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsRefPtr<txDriver> driver = new txDriver();
|
||||
if (!driver) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
driver->mCompiler = aCompiler;
|
||||
return driver->parse(*xslInput, aUri);
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
/* -*- 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) 2003
|
||||
* 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 ***** */
|
||||
|
||||
#ifndef __TX_STANDALONE_STYLESHEET_COMPILER_H__
|
||||
#define __TX_STANDALONE_STYLESHEET_COMPILER_H__
|
||||
|
||||
#include "txStylesheet.h"
|
||||
|
||||
/**
|
||||
* API to load XML files into compiled stylesheets.
|
||||
* Parsing is done by expat.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Parse a stylesheet from the aPath.
|
||||
*/
|
||||
nsresult
|
||||
TX_CompileStylesheetPath(const nsAString& aHref, txStylesheet** aResult);
|
||||
|
||||
#endif // __TX_STANDALONE_STYLESHEET_COMPILER_H__
|
||||
@ -39,6 +39,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "txStandaloneXSLTProcessor.h"
|
||||
#include "txStandaloneStylesheetCompiler.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "txHTMLOutput.h"
|
||||
@ -48,15 +49,17 @@
|
||||
#include "txURIUtils.h"
|
||||
#include "txXMLParser.h"
|
||||
|
||||
TX_IMPL_DOM_STATICS;
|
||||
|
||||
/**
|
||||
* Output Handler Factory
|
||||
*/
|
||||
class txStandaloneHandlerFactory : public txAOutputHandlerFactory
|
||||
{
|
||||
public:
|
||||
txStandaloneHandlerFactory(ProcessorState* aPs,
|
||||
txStandaloneHandlerFactory(txExecutionState* aEs,
|
||||
ostream* aStream)
|
||||
: mPs(aPs), mStream(aStream)
|
||||
: mEs(aEs), mStream(aStream)
|
||||
{
|
||||
}
|
||||
|
||||
@ -67,7 +70,7 @@ public:
|
||||
TX_DECL_TXAOUTPUTHANDLERFACTORY;
|
||||
|
||||
private:
|
||||
ProcessorState* mPs;
|
||||
txExecutionState* mEs;
|
||||
ostream* mStream;
|
||||
};
|
||||
|
||||
@ -90,7 +93,7 @@ txStandaloneHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
|
||||
break;
|
||||
|
||||
case eMethodNotSet:
|
||||
*aHandler = new txUnknownHandler(mPs);
|
||||
*aHandler = new txUnknownHandler(mEs);
|
||||
break;
|
||||
}
|
||||
NS_ENSURE_TRUE(*aHandler, NS_ERROR_OUT_OF_MEMORY);
|
||||
@ -150,16 +153,17 @@ txStandaloneXSLTProcessor::transform(nsACString& aXMLPath,
|
||||
if (!xmlDoc) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
Document* xslDoc = parsePath(aXSLPath, aErr);
|
||||
if (!xslDoc) {
|
||||
nsRefPtr<txStylesheet> style;
|
||||
nsresult rv = TX_CompileStylesheetPath(NS_ConvertASCIItoUCS2(aXSLPath),
|
||||
getter_AddRefs(style));
|
||||
if (NS_FAILED(rv)) {
|
||||
delete xmlDoc;
|
||||
return NS_ERROR_FAILURE;
|
||||
return rv;
|
||||
}
|
||||
// transform
|
||||
nsresult rv = transform(xmlDoc, xslDoc, aOut, aErr);
|
||||
rv = transform(xmlDoc, style, aOut, aErr);
|
||||
|
||||
delete xmlDoc;
|
||||
delete xslDoc;
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -181,15 +185,12 @@ txStandaloneXSLTProcessor::transform(Document* aXMLDoc, ostream& aOut,
|
||||
nsAutoString stylePath;
|
||||
getHrefFromStylesheetPI(*aXMLDoc, stylePath);
|
||||
|
||||
Document* xslDoc = parsePath(NS_LossyConvertUCS2toASCII(stylePath), aErr);
|
||||
if (!xslDoc) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsRefPtr<txStylesheet> style;
|
||||
nsresult rv = TX_CompileStylesheetPath(stylePath, getter_AddRefs(style));
|
||||
|
||||
// transform
|
||||
nsresult rv = transform(aXMLDoc, xslDoc, aOut, aErr);
|
||||
rv = transform(aXMLDoc, style, aOut, aErr);
|
||||
|
||||
delete xslDoc;
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -198,46 +199,28 @@ txStandaloneXSLTProcessor::transform(Document* aXMLDoc, ostream& aOut,
|
||||
* and prints the results to the given ostream argument
|
||||
*/
|
||||
nsresult
|
||||
txStandaloneXSLTProcessor::transform(Document* aSource, Node* aStylesheet,
|
||||
txStandaloneXSLTProcessor::transform(Document* aSource,
|
||||
txStylesheet* 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);
|
||||
// Create a new txEvalState
|
||||
txExecutionState es(aStylesheet);
|
||||
|
||||
ps.addErrorObserver(aErr);
|
||||
// XXX todo es.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;
|
||||
txStandaloneHandlerFactory handlerFactory(&es, &aOut);
|
||||
|
||||
#ifndef XP_WIN
|
||||
bool sync = aOut.sync_with_stdio(false);
|
||||
#endif
|
||||
es.mOutputHandlerFactory = &handlerFactory;
|
||||
|
||||
es.init(aSource, nsnull);
|
||||
|
||||
// Process root of XML source document
|
||||
txXSLTProcessor::transform(&ps);
|
||||
txXSLTProcessor::execute(es);
|
||||
es.end();
|
||||
|
||||
#ifndef XP_WIN
|
||||
aOut.sync_with_stdio(sync);
|
||||
#endif
|
||||
|
||||
@ -41,7 +41,10 @@
|
||||
#ifndef TRANSFRMX_TXSTANDALONEXSLTPROCESSOR_H
|
||||
#define TRANSFRMX_TXSTANDALONEXSLTPROCESSOR_H
|
||||
|
||||
#include "XSLTProcessor.h"
|
||||
#include "txStylesheet.h"
|
||||
#include "txXSLTProcessor.h"
|
||||
#include "ErrorObserver.h"
|
||||
|
||||
#ifndef __BORLANDC__
|
||||
#include <iostream.h>
|
||||
#include <fstream.h>
|
||||
@ -130,7 +133,7 @@ public:
|
||||
* @param aErr error observer
|
||||
* @result NS_OK if transformation was successful
|
||||
*/
|
||||
nsresult transform(Document* aXMLDoc, Node* aXSLNode,
|
||||
nsresult transform(Document* aXMLDoc, txStylesheet* aXSLNode,
|
||||
ostream& aOut, ErrorObserver& aErr);
|
||||
|
||||
protected:
|
||||
|
||||
684
mozilla/extensions/transformiix/source/xslt/txStylesheet.cpp
Normal file
684
mozilla/extensions/transformiix/source/xslt/txStylesheet.cpp
Normal file
@ -0,0 +1,684 @@
|
||||
/* -*- 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
|
||||
* Jonas Sicking.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* Jonas Sicking. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking <jonas@sicking.cc>
|
||||
*
|
||||
* 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 "txStylesheet.h"
|
||||
#include "Expr.h"
|
||||
#include "txXSLTPatterns.h"
|
||||
#include "txToplevelItems.h"
|
||||
#include "txInstructions.h"
|
||||
#include "primitives.h"
|
||||
#include "XSLTFunctions.h"
|
||||
#include "TxLog.h"
|
||||
#include "txKey.h"
|
||||
|
||||
txStylesheet::txStylesheet()
|
||||
: mRootFrame(nsnull),
|
||||
mNamedTemplates(PR_FALSE),
|
||||
mDecimalFormats(PR_TRUE),
|
||||
mAttributeSets(PR_FALSE),
|
||||
mGlobalVariables(PR_TRUE),
|
||||
mKeys(PR_TRUE)
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheet::init()
|
||||
{
|
||||
mRootFrame = new ImportFrame;
|
||||
NS_ENSURE_TRUE(mRootFrame, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// Create default templates
|
||||
// element/root template
|
||||
txInstruction** instrp = mContainerTemplate.StartAssignment();
|
||||
*instrp = new txPushParams;
|
||||
NS_ENSURE_TRUE(*instrp, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsAutoPtr<txNodeTest> nt(new txNodeTypeTest(txNodeTypeTest::NODE_TYPE));
|
||||
NS_ENSURE_TRUE(nt, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsAutoPtr<Expr> nodeExpr(new LocationStep(nt, LocationStep::CHILD_AXIS));
|
||||
NS_ENSURE_TRUE(nodeExpr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
instrp = &(*instrp)->mNext;
|
||||
txPushNewContext* pushContext = new txPushNewContext(nodeExpr);
|
||||
*instrp = pushContext;
|
||||
NS_ENSURE_TRUE(*instrp, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
instrp = &(*instrp)->mNext;
|
||||
txApplyDefaultElementTemplate* applyTemplates =
|
||||
new txApplyDefaultElementTemplate;
|
||||
*instrp = applyTemplates;
|
||||
NS_ENSURE_TRUE(*instrp, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
instrp = &(*instrp)->mNext;
|
||||
*instrp = new txLoopNodeSet(applyTemplates);
|
||||
NS_ENSURE_TRUE(*instrp, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
instrp = &(*instrp)->mNext;
|
||||
pushContext->mBailTarget = *instrp = new txPopParams;
|
||||
NS_ENSURE_TRUE(*instrp, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
instrp = &(*instrp)->mNext;
|
||||
*instrp = new txReturn();
|
||||
NS_ENSURE_TRUE(*instrp, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// attribute/textnode template
|
||||
nt = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE);
|
||||
NS_ENSURE_TRUE(nt, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nodeExpr = new LocationStep(nt, LocationStep::SELF_AXIS);
|
||||
NS_ENSURE_TRUE(nodeExpr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
mCharactersTemplate = new txValueOf(nodeExpr, PR_FALSE);
|
||||
NS_ENSURE_TRUE(mContainerTemplate, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
mCharactersTemplate->mNext = new txReturn();
|
||||
NS_ENSURE_TRUE(mContainerTemplate->mNext, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// pi/comment/namespace template
|
||||
mEmptyTemplate = new txReturn();
|
||||
NS_ENSURE_TRUE(mEmptyTemplate, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
txStylesheet::~txStylesheet()
|
||||
{
|
||||
// Delete all ImportFrames
|
||||
delete mRootFrame;
|
||||
txListIterator frameIter(&mImportFrames);
|
||||
while (frameIter.hasNext()) {
|
||||
delete NS_STATIC_CAST(ImportFrame*, frameIter.next());
|
||||
}
|
||||
|
||||
txListIterator instrIter(&mTemplateInstructions);
|
||||
while (instrIter.hasNext()) {
|
||||
delete NS_STATIC_CAST(txInstruction*, instrIter.next());
|
||||
}
|
||||
|
||||
// We can't make the map own its values because then we wouldn't be able
|
||||
// to merge attributesets of the same name
|
||||
txExpandedNameMap::iterator attrSetIter(mAttributeSets);
|
||||
while (attrSetIter.next()) {
|
||||
delete attrSetIter.value();
|
||||
}
|
||||
}
|
||||
|
||||
txInstruction*
|
||||
txStylesheet::findTemplate(Node* aNode,
|
||||
const txExpandedName& aMode,
|
||||
txIMatchContext* aContext,
|
||||
ImportFrame* aImportedBy,
|
||||
ImportFrame** aImportFrame)
|
||||
{
|
||||
NS_ASSERTION(aImportFrame, "missing ImportFrame pointer");
|
||||
NS_ASSERTION(aNode, "missing node");
|
||||
|
||||
*aImportFrame = nsnull;
|
||||
txInstruction* matchTemplate = nsnull;
|
||||
ImportFrame* endFrame = nsnull;
|
||||
txListIterator frameIter(&mImportFrames);
|
||||
|
||||
if (aImportedBy) {
|
||||
ImportFrame* curr = NS_STATIC_CAST(ImportFrame*, frameIter.next());
|
||||
while (curr != aImportedBy) {
|
||||
curr = NS_STATIC_CAST(ImportFrame*, frameIter.next());
|
||||
}
|
||||
endFrame = aImportedBy->mFirstNotImported;
|
||||
}
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
txPattern* match = 0;
|
||||
#endif
|
||||
|
||||
ImportFrame* frame;
|
||||
while (!matchTemplate &&
|
||||
(frame = NS_STATIC_CAST(ImportFrame*, frameIter.next())) &&
|
||||
frame != endFrame) {
|
||||
|
||||
// get templatelist for this mode
|
||||
txList* templates =
|
||||
NS_STATIC_CAST(txList*, frame->mMatchableTemplates.get(aMode));
|
||||
|
||||
if (templates) {
|
||||
txListIterator templateIter(templates);
|
||||
|
||||
// Find template with highest priority
|
||||
MatchableTemplate* templ;
|
||||
while (!matchTemplate &&
|
||||
(templ =
|
||||
NS_STATIC_CAST(MatchableTemplate*, templateIter.next()))) {
|
||||
if (templ->mMatch->matches(aNode, aContext)) {
|
||||
matchTemplate = templ->mFirstInstruction;
|
||||
*aImportFrame = frame;
|
||||
#ifdef PR_LOGGING
|
||||
match = templ->mMatch;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
nsAutoString mode;
|
||||
if (aMode.mLocalName) {
|
||||
aMode.mLocalName->ToString(mode);
|
||||
}
|
||||
nsAutoString nodeName;
|
||||
aNode->getNodeName(nodeName);
|
||||
if (matchTemplate) {
|
||||
nsAutoString matchAttr;
|
||||
match->toString(matchAttr);
|
||||
PR_LOG(txLog::xslt, PR_LOG_DEBUG,
|
||||
("MatchTemplate, Pattern %s, Mode %s, Node %s\n",
|
||||
NS_LossyConvertUCS2toASCII(matchAttr).get(),
|
||||
NS_LossyConvertUCS2toASCII(mode).get(),
|
||||
NS_LossyConvertUCS2toASCII(nodeName).get()));
|
||||
}
|
||||
else {
|
||||
PR_LOG(txLog::xslt, PR_LOG_DEBUG,
|
||||
("No match, Node %s, Mode %s\n",
|
||||
NS_LossyConvertUCS2toASCII(nodeName).get(),
|
||||
NS_LossyConvertUCS2toASCII(mode).get()));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!matchTemplate) {
|
||||
switch(aNode->getNodeType()) {
|
||||
case Node::ELEMENT_NODE :
|
||||
case Node::DOCUMENT_NODE :
|
||||
matchTemplate = mContainerTemplate;
|
||||
break;
|
||||
|
||||
case Node::ATTRIBUTE_NODE :
|
||||
case Node::TEXT_NODE :
|
||||
case Node::CDATA_SECTION_NODE :
|
||||
matchTemplate = mCharactersTemplate;
|
||||
break;
|
||||
|
||||
default:
|
||||
matchTemplate = mEmptyTemplate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return matchTemplate;
|
||||
}
|
||||
|
||||
txDecimalFormat*
|
||||
txStylesheet::getDecimalFormat(const txExpandedName& aName)
|
||||
{
|
||||
return NS_STATIC_CAST(txDecimalFormat*, mDecimalFormats.get(aName));
|
||||
}
|
||||
|
||||
txInstruction*
|
||||
txStylesheet::getAttributeSet(const txExpandedName& aName)
|
||||
{
|
||||
return NS_STATIC_CAST(txInstruction*, mAttributeSets.get(aName));
|
||||
}
|
||||
|
||||
txInstruction*
|
||||
txStylesheet::getNamedTemplate(const txExpandedName& aName)
|
||||
{
|
||||
return NS_STATIC_CAST(txInstruction*, mNamedTemplates.get(aName));
|
||||
}
|
||||
|
||||
txOutputFormat*
|
||||
txStylesheet::getOutputFormat()
|
||||
{
|
||||
return &mOutputFormat;
|
||||
}
|
||||
|
||||
txStylesheet::GlobalVariable*
|
||||
txStylesheet::getGlobalVariable(const txExpandedName& aName)
|
||||
{
|
||||
return NS_STATIC_CAST(GlobalVariable*, mGlobalVariables.get(aName));
|
||||
}
|
||||
|
||||
const txExpandedNameMap&
|
||||
txStylesheet::getKeyMap()
|
||||
{
|
||||
return mKeys;
|
||||
}
|
||||
|
||||
PRBool
|
||||
txStylesheet::isStripSpaceAllowed(Node* aNode, txIMatchContext* aContext)
|
||||
{
|
||||
if (!aNode) {
|
||||
return MB_FALSE;
|
||||
}
|
||||
|
||||
switch (aNode->getNodeType()) {
|
||||
case Node::ELEMENT_NODE:
|
||||
{
|
||||
// check Whitespace stipping handling list against given Node
|
||||
PRInt32 i, frameCount = mStripSpaceTests.Count();
|
||||
for (i = 0; i < frameCount; ++i) {
|
||||
txStripSpaceTest* sst =
|
||||
NS_STATIC_CAST(txStripSpaceTest*, mStripSpaceTests[i]);
|
||||
if (sst->matches(aNode, aContext)) {
|
||||
if (sst->stripsSpace() &&
|
||||
!XMLUtils::getXMLSpacePreserve(aNode)) {
|
||||
return MB_TRUE;
|
||||
}
|
||||
return MB_FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Node::TEXT_NODE:
|
||||
case Node::CDATA_SECTION_NODE:
|
||||
{
|
||||
if (!XMLUtils::isWhitespace(aNode))
|
||||
return MB_FALSE;
|
||||
return isStripSpaceAllowed(aNode->getParentNode(), aContext);
|
||||
}
|
||||
case Node::DOCUMENT_NODE:
|
||||
{
|
||||
return MB_TRUE;
|
||||
}
|
||||
}
|
||||
return MB_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheet::doneCompiling()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
// Collect all importframes into a single ordered list
|
||||
txListIterator frameIter(&mImportFrames);
|
||||
rv = frameIter.addAfter(mRootFrame);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mRootFrame = nsnull;
|
||||
frameIter.next();
|
||||
rv = addFrames(frameIter);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Loop through importframes in decreasing-precedence-order and process
|
||||
// all items
|
||||
frameIter.reset();
|
||||
ImportFrame* frame;
|
||||
while ((frame = NS_STATIC_CAST(ImportFrame*, frameIter.next()))) {
|
||||
nsVoidArray frameStripSpaceTests;
|
||||
|
||||
txListIterator itemIter(&frame->mToplevelItems);
|
||||
itemIter.resetToEnd();
|
||||
txToplevelItem* item;
|
||||
while ((item = NS_STATIC_CAST(txToplevelItem*, itemIter.previous()))) {
|
||||
switch (item->getType()) {
|
||||
case txToplevelItem::attributeSet:
|
||||
{
|
||||
rv = addAttributeSet(NS_STATIC_CAST(txAttributeSetItem*,
|
||||
item));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
break;
|
||||
}
|
||||
case txToplevelItem::dummy:
|
||||
case txToplevelItem::import:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case txToplevelItem::output:
|
||||
{
|
||||
mOutputFormat.merge(NS_STATIC_CAST(txOutputItem*, item)->mFormat);
|
||||
break;
|
||||
}
|
||||
case txToplevelItem::stripSpace:
|
||||
{
|
||||
rv = addStripSpace(NS_STATIC_CAST(txStripSpaceItem*, item),
|
||||
frameStripSpaceTests);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
break;
|
||||
}
|
||||
case txToplevelItem::templ:
|
||||
{
|
||||
rv = addTemplate(NS_STATIC_CAST(txTemplateItem*, item),
|
||||
frame);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
break;
|
||||
}
|
||||
case txToplevelItem::variable:
|
||||
{
|
||||
rv = addGlobalVariable(NS_STATIC_CAST(txVariableItem*,
|
||||
item));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete item;
|
||||
itemIter.remove(); //remove() moves to the previous
|
||||
itemIter.next();
|
||||
}
|
||||
if (!mStripSpaceTests.AppendElements(frameStripSpaceTests)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
frameStripSpaceTests.Clear();
|
||||
}
|
||||
|
||||
if (!mDecimalFormats.get(txExpandedName())) {
|
||||
nsAutoPtr<txDecimalFormat> format(new txDecimalFormat);
|
||||
NS_ENSURE_TRUE(format, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = mDecimalFormats.add(txExpandedName(), format);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
format.forget();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheet::addTemplate(txTemplateItem* aTemplate,
|
||||
ImportFrame* aImportFrame)
|
||||
{
|
||||
NS_ASSERTION(aTemplate, "missing template");
|
||||
|
||||
txInstruction* instr = aTemplate->mFirstInstruction;
|
||||
nsresult rv = mTemplateInstructions.add(instr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// mTemplateInstructions now owns the instructions
|
||||
aTemplate->mFirstInstruction.forget();
|
||||
|
||||
if (!aTemplate->mName.isNull()) {
|
||||
rv = mNamedTemplates.add(aTemplate->mName, instr);
|
||||
NS_ENSURE_TRUE(NS_SUCCEEDED(rv) || rv == NS_ERROR_XSLT_ALREADY_SET,
|
||||
rv);
|
||||
}
|
||||
|
||||
if (!aTemplate->mMatch) {
|
||||
// This is no error, see section 6 Named Templates
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// get the txList for the right mode
|
||||
txList* templates =
|
||||
NS_STATIC_CAST(txList*,
|
||||
aImportFrame->mMatchableTemplates.get(aTemplate->mMode));
|
||||
|
||||
if (!templates) {
|
||||
nsAutoPtr<txList> newList(new txList);
|
||||
NS_ENSURE_TRUE(newList, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aImportFrame->mMatchableTemplates.add(aTemplate->mMode, newList);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
templates = newList.forget();
|
||||
}
|
||||
|
||||
// Add the simple patterns to the list of matchable templates, according
|
||||
// to default priority
|
||||
txList simpleMatches;
|
||||
rv = aTemplate->mMatch->getSimplePatterns(simpleMatches);
|
||||
if (simpleMatches.get(0) == aTemplate->mMatch) {
|
||||
aTemplate->mMatch.forget();
|
||||
}
|
||||
|
||||
txListIterator simples(&simpleMatches);
|
||||
while (simples.hasNext()) {
|
||||
// XXX if we fail in this loop, we leak the remaining simple patterns
|
||||
nsAutoPtr<txPattern> simple(NS_STATIC_CAST(txPattern*, simples.next()));
|
||||
double priority = aTemplate->mPrio;
|
||||
if (Double::isNaN(priority)) {
|
||||
priority = simple->getDefaultPriority();
|
||||
NS_ASSERTION(!Double::isNaN(priority),
|
||||
"simple pattern without default priority");
|
||||
}
|
||||
nsAutoPtr<MatchableTemplate>
|
||||
nt(new MatchableTemplate(instr, simple, priority));
|
||||
NS_ENSURE_TRUE(nt, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
txListIterator templ(templates);
|
||||
while (templ.hasNext()) {
|
||||
MatchableTemplate* mt = NS_STATIC_CAST(MatchableTemplate*,
|
||||
templ.next());
|
||||
if (priority > mt->mPriority) {
|
||||
rv = templ.addBefore(nt);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nt.forget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nt) {
|
||||
rv = templates->add(nt);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nt.forget();
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheet::addFrames(txListIterator& aInsertIter)
|
||||
{
|
||||
ImportFrame* frame = NS_STATIC_CAST(ImportFrame*, aInsertIter.current());
|
||||
nsresult rv = NS_OK;
|
||||
txListIterator iter(&frame->mToplevelItems);
|
||||
txToplevelItem* item;
|
||||
while ((item = NS_STATIC_CAST(txToplevelItem*, iter.next()))) {
|
||||
if (item->getType() == txToplevelItem::import) {
|
||||
txImportItem* import = NS_STATIC_CAST(txImportItem*, item);
|
||||
import->mFrame->mFirstNotImported =
|
||||
NS_STATIC_CAST(ImportFrame*, aInsertIter.next());
|
||||
rv = aInsertIter.addBefore(import->mFrame);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
import->mFrame.forget();
|
||||
aInsertIter.previous();
|
||||
rv = addFrames(aInsertIter);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
aInsertIter.previous();
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheet::addStripSpace(txStripSpaceItem* aStripSpaceItem,
|
||||
nsVoidArray& frameStripSpaceTests)
|
||||
{
|
||||
PRInt32 testCount = aStripSpaceItem->mStripSpaceTests.Count();
|
||||
for (; testCount > 0; --testCount) {
|
||||
txStripSpaceTest* sst =
|
||||
NS_STATIC_CAST(txStripSpaceTest*,
|
||||
aStripSpaceItem->mStripSpaceTests[testCount-1]);
|
||||
double priority = sst->getDefaultPriority();
|
||||
PRInt32 i, frameCount = frameStripSpaceTests.Count();
|
||||
for (i = 0; i < frameCount; ++i) {
|
||||
txStripSpaceTest* fsst =
|
||||
NS_STATIC_CAST(txStripSpaceTest*, frameStripSpaceTests[i]);
|
||||
if (fsst->getDefaultPriority() < priority) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!frameStripSpaceTests.InsertElementAt(sst, i)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
aStripSpaceItem->mStripSpaceTests.RemoveElementAt(testCount-1);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheet::addAttributeSet(txAttributeSetItem* aAttributeSetItem)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
txInstruction* oldInstr =
|
||||
NS_STATIC_CAST(txInstruction*,
|
||||
mAttributeSets.get(aAttributeSetItem->mName));
|
||||
if (!oldInstr) {
|
||||
rv = mAttributeSets.add(aAttributeSetItem->mName,
|
||||
aAttributeSetItem->mFirstInstruction);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aAttributeSetItem->mFirstInstruction.forget();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We need to prepend the new instructions before the existing ones.
|
||||
txInstruction* instr = aAttributeSetItem->mFirstInstruction;
|
||||
txInstruction* lastNonReturn = nsnull;
|
||||
while (instr->mNext) {
|
||||
lastNonReturn = instr;
|
||||
instr = instr->mNext;
|
||||
}
|
||||
|
||||
if (!lastNonReturn) {
|
||||
// The new attributeset is empty, so lets just ignore it.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
rv = mAttributeSets.set(aAttributeSetItem->mName,
|
||||
aAttributeSetItem->mFirstInstruction);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aAttributeSetItem->mFirstInstruction.forget();
|
||||
|
||||
delete lastNonReturn->mNext; // Delete the txReturn...
|
||||
lastNonReturn->mNext = oldInstr; // ...and link up the old instructions.
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheet::addGlobalVariable(txVariableItem* aVariable)
|
||||
{
|
||||
if (mGlobalVariables.get(aVariable->mName)) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsAutoPtr<GlobalVariable> var(
|
||||
new GlobalVariable(aVariable->mValue, aVariable->mFirstInstruction,
|
||||
aVariable->mIsParam));
|
||||
NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = mGlobalVariables.add(aVariable->mName, var);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
var.forget();
|
||||
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheet::addKey(const txExpandedName& aName,
|
||||
nsAutoPtr<txPattern> aMatch, nsAutoPtr<Expr> aUse)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
txXSLKey* xslKey = NS_STATIC_CAST(txXSLKey*, mKeys.get(aName));
|
||||
if (!xslKey) {
|
||||
xslKey = new txXSLKey(aName);
|
||||
NS_ENSURE_TRUE(xslKey, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = mKeys.add(aName, xslKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete xslKey;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
if (!xslKey->addKey(aMatch, aUse)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheet::addDecimalFormat(const txExpandedName& aName,
|
||||
nsAutoPtr<txDecimalFormat> aFormat)
|
||||
{
|
||||
txDecimalFormat* existing =
|
||||
NS_STATIC_CAST(txDecimalFormat*, mDecimalFormats.get(aName));
|
||||
if (existing) {
|
||||
NS_ENSURE_TRUE(existing->isEqual(aFormat),
|
||||
NS_ERROR_XSLT_PARSE_FAILURE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = mDecimalFormats.add(aName, aFormat);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aFormat.forget();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
txStylesheet::ImportFrame::ImportFrame()
|
||||
: mMatchableTemplates(MB_TRUE),
|
||||
mFirstNotImported(nsnull)
|
||||
{
|
||||
}
|
||||
|
||||
txStylesheet::ImportFrame::~ImportFrame()
|
||||
{
|
||||
// Delete templates in mMatchableTemplates
|
||||
txExpandedNameMap::iterator mapIter(mMatchableTemplates);
|
||||
while (mapIter.next()) {
|
||||
txListIterator templIter(NS_STATIC_CAST(txList*, mapIter.value()));
|
||||
MatchableTemplate* templ;
|
||||
while ((templ = NS_STATIC_CAST(MatchableTemplate*, templIter.next()))) {
|
||||
delete templ;
|
||||
}
|
||||
}
|
||||
|
||||
txListIterator tlIter(&mToplevelItems);
|
||||
while (tlIter.hasNext()) {
|
||||
delete NS_STATIC_CAST(txToplevelItem*, tlIter.next());
|
||||
}
|
||||
}
|
||||
|
||||
txStylesheet::GlobalVariable::GlobalVariable(nsAutoPtr<Expr> aExpr,
|
||||
nsAutoPtr<txInstruction> aFirstInstruction,
|
||||
PRBool aIsParam)
|
||||
: mExpr(aExpr), mFirstInstruction(aFirstInstruction), mIsParam(aIsParam)
|
||||
{
|
||||
}
|
||||
248
mozilla/extensions/transformiix/source/xslt/txStylesheet.h
Normal file
248
mozilla/extensions/transformiix/source/xslt/txStylesheet.h
Normal file
@ -0,0 +1,248 @@
|
||||
/* -*- 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
|
||||
* Jonas Sicking.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* Jonas Sicking. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking <jonas@sicking.cc>
|
||||
*
|
||||
* 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 TX_TXSTYLESHEET_H
|
||||
#define TX_TXSTYLESHEET_H
|
||||
|
||||
#include "txOutputFormat.h"
|
||||
#include "txExpandedNameMap.h"
|
||||
#include "List.h"
|
||||
#include "Expr.h"
|
||||
#include "txXSLTPatterns.h"
|
||||
#include "txInstructions.h"
|
||||
#include "XSLTFunctions.h"
|
||||
|
||||
class txInstruction;
|
||||
class txToplevelItem;
|
||||
class txTemplateItem;
|
||||
class txVariableItem;
|
||||
class txStripSpaceItem;
|
||||
class txAttributeSetItem;
|
||||
|
||||
class txStylesheet
|
||||
{
|
||||
public:
|
||||
class ImportFrame;
|
||||
class GlobalVariable;
|
||||
friend class txStylesheetCompilerState;
|
||||
// To be able to do some cleaning up in destructor
|
||||
friend class ImportFrame;
|
||||
|
||||
txStylesheet();
|
||||
~txStylesheet();
|
||||
nsresult init();
|
||||
|
||||
nsrefcnt AddRef()
|
||||
{
|
||||
return ++mRefCnt;
|
||||
}
|
||||
nsrefcnt Release()
|
||||
{
|
||||
if (--mRefCnt == 0) {
|
||||
mRefCnt = 1; //stabilize
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
txInstruction* findTemplate(Node* aNode,
|
||||
const txExpandedName& aMode,
|
||||
txIMatchContext* aContext,
|
||||
ImportFrame* aImportedBy,
|
||||
ImportFrame** aImportFrame);
|
||||
txDecimalFormat* getDecimalFormat(const txExpandedName& aName);
|
||||
txInstruction* getAttributeSet(const txExpandedName& aName);
|
||||
txInstruction* getNamedTemplate(const txExpandedName& aName);
|
||||
txOutputFormat* getOutputFormat();
|
||||
GlobalVariable* getGlobalVariable(const txExpandedName& aName);
|
||||
const txExpandedNameMap& getKeyMap();
|
||||
PRBool isStripSpaceAllowed(Node* aNode, txIMatchContext* aContext);
|
||||
|
||||
/**
|
||||
* Called by the stylesheet compiler once all stylesheets has been read.
|
||||
*/
|
||||
nsresult doneCompiling();
|
||||
|
||||
/**
|
||||
* Add a key to the stylesheet
|
||||
*/
|
||||
nsresult addKey(const txExpandedName& aName, nsAutoPtr<txPattern> aMatch,
|
||||
nsAutoPtr<Expr> aUse);
|
||||
|
||||
/**
|
||||
* Add a decimal-format to the stylesheet
|
||||
*/
|
||||
nsresult addDecimalFormat(const txExpandedName& aName,
|
||||
nsAutoPtr<txDecimalFormat> aFormat);
|
||||
|
||||
/**
|
||||
* Contain information that is import precedence dependant.
|
||||
*/
|
||||
class ImportFrame {
|
||||
public:
|
||||
ImportFrame();
|
||||
~ImportFrame();
|
||||
|
||||
// List of toplevel items
|
||||
txList mToplevelItems;
|
||||
|
||||
// Map of template modes, each item in the map is a txList
|
||||
// of templates
|
||||
txExpandedNameMap mMatchableTemplates;
|
||||
|
||||
// ImportFrame which is the first one *not* imported by this frame
|
||||
ImportFrame* mFirstNotImported;
|
||||
};
|
||||
|
||||
class GlobalVariable : public TxObject {
|
||||
public:
|
||||
GlobalVariable(nsAutoPtr<Expr> aExpr,
|
||||
nsAutoPtr<txInstruction> aFirstInstruction,
|
||||
PRBool aIsParam);
|
||||
|
||||
nsAutoPtr<Expr> mExpr;
|
||||
nsAutoPtr<txInstruction> mFirstInstruction;
|
||||
PRBool mIsParam;
|
||||
};
|
||||
|
||||
private:
|
||||
class MatchableTemplate {
|
||||
public:
|
||||
MatchableTemplate(txInstruction* aFirstInstruction,
|
||||
nsAutoPtr<txPattern> aPattern,
|
||||
double aPriority)
|
||||
: mFirstInstruction(aFirstInstruction),
|
||||
mMatch(aPattern),
|
||||
mPriority(aPriority)
|
||||
{
|
||||
}
|
||||
txInstruction* mFirstInstruction;
|
||||
nsAutoPtr<txPattern> mMatch;
|
||||
double mPriority;
|
||||
};
|
||||
|
||||
nsresult addTemplate(txTemplateItem* aTemplate, ImportFrame* aImportFrame);
|
||||
nsresult addGlobalVariable(txVariableItem* aVariable);
|
||||
nsresult addFrames(txListIterator& aInsertIter);
|
||||
nsresult addStripSpace(txStripSpaceItem* aStripSpaceItem,
|
||||
nsVoidArray& frameStripSpaceTests);
|
||||
nsresult addAttributeSet(txAttributeSetItem* aAttributeSetItem);
|
||||
|
||||
// Refcount
|
||||
nsAutoRefCnt mRefCnt;
|
||||
|
||||
// List of ImportFrames
|
||||
txList mImportFrames;
|
||||
|
||||
// output format
|
||||
txOutputFormat mOutputFormat;
|
||||
|
||||
// List of first instructions of templates. This is the owner of all
|
||||
// instructions used in templates
|
||||
txList mTemplateInstructions;
|
||||
|
||||
// Root importframe
|
||||
ImportFrame* mRootFrame;
|
||||
|
||||
// Named templates
|
||||
txExpandedNameMap mNamedTemplates;
|
||||
|
||||
// Map with all decimal-formats
|
||||
txExpandedNameMap mDecimalFormats;
|
||||
|
||||
// Map with all named attribute sets
|
||||
txExpandedNameMap mAttributeSets;
|
||||
|
||||
// Map with all global variables and parameters
|
||||
txExpandedNameMap mGlobalVariables;
|
||||
|
||||
// Map with all keys
|
||||
txExpandedNameMap mKeys;
|
||||
|
||||
// Array of all txStripSpaceTests, sorted in acending order
|
||||
nsVoidArray mStripSpaceTests;
|
||||
|
||||
// Default templates
|
||||
nsAutoPtr<txInstruction> mContainerTemplate;
|
||||
nsAutoPtr<txInstruction> mCharactersTemplate;
|
||||
nsAutoPtr<txInstruction> mEmptyTemplate;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* txStripSpaceTest holds both an txNameTest and a bool for use in
|
||||
* whitespace stripping.
|
||||
*/
|
||||
class txStripSpaceTest {
|
||||
public:
|
||||
txStripSpaceTest(nsIAtom* aPrefix, nsIAtom* aLocalName, PRInt32 aNSID,
|
||||
MBool stripSpace)
|
||||
: mNameTest(aPrefix, aLocalName, aNSID, Node::ELEMENT_NODE),
|
||||
mStrips(stripSpace)
|
||||
{
|
||||
}
|
||||
|
||||
MBool matches(Node* aNode, txIMatchContext* aContext) {
|
||||
return mNameTest.matches(aNode, aContext);
|
||||
}
|
||||
|
||||
MBool stripsSpace() {
|
||||
return mStrips;
|
||||
}
|
||||
|
||||
double getDefaultPriority() {
|
||||
return mNameTest.getDefaultPriority();
|
||||
}
|
||||
|
||||
protected:
|
||||
txNameTest mNameTest;
|
||||
MBool mStrips;
|
||||
};
|
||||
|
||||
/**
|
||||
* Value of a global parameter
|
||||
*/
|
||||
class txIGlobalParameter : public TxObject
|
||||
{
|
||||
public:
|
||||
virtual nsresult getValue(ExprResult** aValue) = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif //TX_TXSTYLESHEET_H
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,93 @@
|
||||
/* -*- 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
|
||||
* Jonas Sicking.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* Jonas Sicking. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking <jonas@sicking.cc>
|
||||
*
|
||||
* 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_TXSTYLESHEETCOMPILEHANDLERS_H
|
||||
#define TRANSFRMX_TXSTYLESHEETCOMPILEHANDLERS_H
|
||||
|
||||
#include "txError.h"
|
||||
#include "txNamespaceMap.h"
|
||||
#include "txExpandedNameMap.h"
|
||||
|
||||
struct txStylesheetAttr;
|
||||
class txStylesheetCompilerState;
|
||||
|
||||
typedef nsresult (*HandleStartFn) (PRInt32 aNamespaceID,
|
||||
nsIAtom* aLocalName,
|
||||
nsIAtom* aPrefix,
|
||||
txStylesheetAttr* aAttributes,
|
||||
PRInt32 aAttrCount,
|
||||
txStylesheetCompilerState& aState);
|
||||
typedef nsresult (*HandleEndFn) (txStylesheetCompilerState& aState);
|
||||
typedef nsresult (*HandleTextFn) (const nsAString& aStr,
|
||||
txStylesheetCompilerState& aState);
|
||||
|
||||
struct txElementHandler {
|
||||
PRInt32 mNamespaceID;
|
||||
char* mLocalName;
|
||||
HandleStartFn mStartFunction;
|
||||
HandleEndFn mEndFunction;
|
||||
};
|
||||
|
||||
struct txHandlerTableData {
|
||||
txElementHandler mHandlers[20]; // XXX find a better solution for this
|
||||
txElementHandler mOtherHandler;
|
||||
txElementHandler mLREHandler;
|
||||
HandleTextFn mTextHandler;
|
||||
};
|
||||
|
||||
class txHandlerTable
|
||||
{
|
||||
public:
|
||||
txHandlerTable();
|
||||
nsresult init(txHandlerTableData* aTableData);
|
||||
txElementHandler* find(PRInt32 aNamespaceID, nsIAtom* aLocalName);
|
||||
|
||||
HandleTextFn mTextHandler;
|
||||
txElementHandler* mLREHandler;
|
||||
|
||||
static MBool init();
|
||||
static void shutdown();
|
||||
|
||||
private:
|
||||
txElementHandler* mOtherHandler;
|
||||
txExpandedNameMap mHandlers;
|
||||
};
|
||||
|
||||
extern txHandlerTable* gTxRootHandler;
|
||||
|
||||
#endif //TRANSFRMX_TXSTYLESHEETCOMPILEHANDLERS_H
|
||||
@ -0,0 +1,909 @@
|
||||
/* -*- 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
|
||||
* Jonas Sicking.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* Jonas Sicking. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking <jonas@sicking.cc>
|
||||
*
|
||||
* 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 "txStylesheetCompiler.h"
|
||||
#include "txStylesheetCompileHandlers.h"
|
||||
#include "txAtoms.h"
|
||||
#include "txURIUtils.h"
|
||||
#include "txTokenizer.h"
|
||||
#include "txStylesheet.h"
|
||||
#include "txInstructions.h"
|
||||
#include "txToplevelItems.h"
|
||||
#include "ExprParser.h"
|
||||
#include "txPatternParser.h"
|
||||
#include "txStringUtils.h"
|
||||
#include "XSLTFunctions.h"
|
||||
#include "TxLog.h"
|
||||
|
||||
txStylesheetCompiler::txStylesheetCompiler(const nsAString& aBaseURI,
|
||||
txACompileObserver* aObserver)
|
||||
: txStylesheetCompilerState(aObserver)
|
||||
{
|
||||
mStatus = init(aBaseURI, nsnull, nsnull);
|
||||
}
|
||||
|
||||
txStylesheetCompiler::txStylesheetCompiler(const nsAString& aBaseURI,
|
||||
txStylesheet* aStylesheet,
|
||||
txListIterator* aInsertPosition,
|
||||
txACompileObserver* aObserver)
|
||||
: txStylesheetCompilerState(aObserver)
|
||||
{
|
||||
mStatus = init(aBaseURI, aStylesheet, aInsertPosition);
|
||||
}
|
||||
|
||||
nsrefcnt
|
||||
txStylesheetCompiler::AddRef()
|
||||
{
|
||||
return ++mRefCnt;
|
||||
}
|
||||
|
||||
nsrefcnt
|
||||
txStylesheetCompiler::Release()
|
||||
{
|
||||
if (--mRefCnt == 0) {
|
||||
mRefCnt = 1; //stabilize
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompiler::startElement(PRInt32 aNamespaceID, nsIAtom* aLocalName,
|
||||
nsIAtom* aPrefix,
|
||||
txStylesheetAttr* aAttributes,
|
||||
PRInt32 aAttrCount)
|
||||
{
|
||||
if (NS_FAILED(mStatus)) {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
nsresult rv = flushCharacters();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// look for new namespace mappings
|
||||
PRBool hasOwnNamespaceMap = PR_FALSE;
|
||||
PRInt32 i;
|
||||
for (i = 0; i < aAttrCount; ++i) {
|
||||
txStylesheetAttr* attr = aAttributes + i;
|
||||
if (attr->mNamespaceID == kNameSpaceID_XMLNS) {
|
||||
rv = ensureNewElementContext();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!hasOwnNamespaceMap) {
|
||||
mElementContext->mMappings =
|
||||
new txNamespaceMap(*mElementContext->mMappings);
|
||||
NS_ENSURE_TRUE(mElementContext->mMappings,
|
||||
NS_ERROR_OUT_OF_MEMORY);
|
||||
hasOwnNamespaceMap = PR_TRUE;
|
||||
}
|
||||
|
||||
if (attr->mLocalName == txXMLAtoms::xmlns) {
|
||||
mElementContext->mMappings->addNamespace(nsnull, attr->mValue);
|
||||
}
|
||||
else {
|
||||
mElementContext->mMappings->
|
||||
addNamespace(attr->mLocalName, attr->mValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return startElementInternal(aNamespaceID, aLocalName, aPrefix,
|
||||
aAttributes, aAttrCount);
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompiler::startElement(const PRUnichar *aName,
|
||||
const PRUnichar **aAttrs,
|
||||
PRInt32 aAttrCount)
|
||||
{
|
||||
if (NS_FAILED(mStatus)) {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
nsresult rv = flushCharacters();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoArrayPtr<txStylesheetAttr> atts;
|
||||
if (aAttrCount > 0) {
|
||||
atts = new txStylesheetAttr[aAttrCount];
|
||||
NS_ENSURE_TRUE(atts, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
PRBool hasOwnNamespaceMap = PR_FALSE;
|
||||
PRInt32 i;
|
||||
for (i = 0; i < aAttrCount; ++i) {
|
||||
rv = XMLUtils::splitXMLName(nsDependentString(aAttrs[i * 2]),
|
||||
getter_AddRefs(atts[i].mPrefix),
|
||||
getter_AddRefs(atts[i].mLocalName));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
atts[i].mValue.Append(aAttrs[i * 2 + 1]);
|
||||
|
||||
nsCOMPtr<nsIAtom> prefixToBind;
|
||||
if (atts[i].mPrefix == txXMLAtoms::xmlns) {
|
||||
prefixToBind = atts[i].mLocalName;
|
||||
}
|
||||
else if (!atts[i].mPrefix && atts[i].mLocalName == txXMLAtoms::xmlns) {
|
||||
prefixToBind = txXMLAtoms::_empty;
|
||||
}
|
||||
|
||||
if (prefixToBind) {
|
||||
rv = ensureNewElementContext();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!hasOwnNamespaceMap) {
|
||||
mElementContext->mMappings =
|
||||
new txNamespaceMap(*mElementContext->mMappings);
|
||||
NS_ENSURE_TRUE(mElementContext->mMappings,
|
||||
NS_ERROR_OUT_OF_MEMORY);
|
||||
hasOwnNamespaceMap = PR_TRUE;
|
||||
}
|
||||
|
||||
rv = mElementContext->mMappings->
|
||||
addNamespace(prefixToBind, atts[i].mValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < aAttrCount; ++i) {
|
||||
if (atts[i].mPrefix && atts[i].mPrefix != txXMLAtoms::xmlns) {
|
||||
atts[i].mNamespaceID =
|
||||
mElementContext->mMappings->lookupNamespace(atts[i].mPrefix);
|
||||
NS_ENSURE_TRUE(atts[i].mNamespaceID != kNameSpaceID_Unknown,
|
||||
NS_ERROR_FAILURE);
|
||||
}
|
||||
else if (atts[i].mPrefix == txXMLAtoms::xmlns ||
|
||||
(!atts[i].mPrefix &&
|
||||
atts[i].mLocalName == txXMLAtoms::xmlns)) {
|
||||
atts[i].mNamespaceID = kNameSpaceID_XMLNS;
|
||||
}
|
||||
else {
|
||||
atts[i].mNamespaceID = kNameSpaceID_None;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> prefix, localname;
|
||||
rv = XMLUtils::splitXMLName(nsDependentString(aName),
|
||||
getter_AddRefs(prefix),
|
||||
getter_AddRefs(localname));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 namespaceID = mElementContext->mMappings->lookupNamespace(prefix);
|
||||
|
||||
NS_ENSURE_TRUE(namespaceID != kNameSpaceID_Unknown, NS_ERROR_FAILURE);
|
||||
|
||||
return startElementInternal(namespaceID, localname, prefix, atts,
|
||||
aAttrCount);
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompiler::startElementInternal(PRInt32 aNamespaceID,
|
||||
nsIAtom* aLocalName,
|
||||
nsIAtom* aPrefix,
|
||||
txStylesheetAttr* aAttributes,
|
||||
PRInt32 aAttrCount)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
PRInt32 i;
|
||||
for (i = mInScopeVariables.Count() - 1; i >= 0; --i) {
|
||||
++(NS_STATIC_CAST(txInScopeVariable*, mInScopeVariables[i]))->mLevel;
|
||||
}
|
||||
|
||||
// Update the elementcontext if we have special attributes
|
||||
for (i = 0; i < aAttrCount; ++i) {
|
||||
txStylesheetAttr* attr = aAttributes + i;
|
||||
|
||||
// xml:space
|
||||
if (attr->mNamespaceID == kNameSpaceID_XML &&
|
||||
attr->mLocalName == txXMLAtoms::space) {
|
||||
rv = ensureNewElementContext();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (TX_StringEqualsAtom(attr->mValue, txXMLAtoms::preserve)) {
|
||||
mElementContext->mPreserveWhitespace = MB_TRUE;
|
||||
}
|
||||
else if (TX_StringEqualsAtom(attr->mValue, txXMLAtoms::_default)) {
|
||||
mElementContext->mPreserveWhitespace = MB_FALSE;
|
||||
}
|
||||
else {
|
||||
return NS_ERROR_XSLT_PARSE_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// xml:base
|
||||
if (attr->mNamespaceID == kNameSpaceID_XML &&
|
||||
attr->mLocalName == txXMLAtoms::base &&
|
||||
!attr->mValue.IsEmpty()) {
|
||||
rv = ensureNewElementContext();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoString uri;
|
||||
URIUtils::resolveHref(attr->mValue, mElementContext->mBaseURI, uri);
|
||||
mElementContext->mBaseURI = uri;
|
||||
}
|
||||
|
||||
// extension-element-prefixes
|
||||
if ((attr->mNamespaceID == kNameSpaceID_XSLT &&
|
||||
attr->mLocalName == txXSLTAtoms::extensionElementPrefixes &&
|
||||
aNamespaceID != kNameSpaceID_XSLT) ||
|
||||
(attr->mNamespaceID == kNameSpaceID_None &&
|
||||
attr->mLocalName == txXSLTAtoms::extensionElementPrefixes &&
|
||||
aNamespaceID == kNameSpaceID_XSLT &&
|
||||
(aLocalName == txXSLTAtoms::stylesheet ||
|
||||
aLocalName == txXSLTAtoms::transform))) {
|
||||
rv = ensureNewElementContext();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
txTokenizer tok(attr->mValue);
|
||||
while (tok.hasMoreTokens()) {
|
||||
PRInt32 namespaceID = mElementContext->mMappings->
|
||||
lookupNamespaceWithDefault(tok.nextToken());
|
||||
|
||||
if (namespaceID == kNameSpaceID_Unknown)
|
||||
return NS_ERROR_XSLT_PARSE_FAILURE;
|
||||
|
||||
if (!mElementContext->mInstructionNamespaces.
|
||||
AppendElement(NS_INT32_TO_PTR(namespaceID))) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// version
|
||||
if ((attr->mNamespaceID == kNameSpaceID_XSLT &&
|
||||
attr->mLocalName == txXSLTAtoms::version &&
|
||||
aNamespaceID != kNameSpaceID_XSLT) ||
|
||||
(attr->mNamespaceID == kNameSpaceID_None &&
|
||||
attr->mLocalName == txXSLTAtoms::version &&
|
||||
aNamespaceID == kNameSpaceID_XSLT &&
|
||||
(aLocalName == txXSLTAtoms::stylesheet ||
|
||||
aLocalName == txXSLTAtoms::transform))) {
|
||||
rv = ensureNewElementContext();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (attr->mValue.Equals(NS_LITERAL_STRING("1.0"))) {
|
||||
mElementContext->mForwardsCompatibleParsing = MB_FALSE;
|
||||
}
|
||||
else {
|
||||
mElementContext->mForwardsCompatibleParsing = MB_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find the right elementhandler and execute it
|
||||
MBool isInstruction = MB_FALSE;
|
||||
PRInt32 count = mElementContext->mInstructionNamespaces.Count();
|
||||
for (i = 0; i < count; ++i) {
|
||||
if (NS_PTR_TO_INT32(mElementContext->mInstructionNamespaces[i]) ==
|
||||
aNamespaceID) {
|
||||
isInstruction = MB_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
txElementHandler* handler;
|
||||
do {
|
||||
handler = isInstruction ?
|
||||
mHandlerTable->find(aNamespaceID, aLocalName) :
|
||||
mHandlerTable->mLREHandler;
|
||||
|
||||
rv = (handler->mStartFunction)(aNamespaceID, aLocalName, aPrefix,
|
||||
aAttributes, aAttrCount, *this);
|
||||
} while (rv == NS_ERROR_XSLT_GET_NEW_HANDLER);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = pushPtr(handler);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mElementContext->mDepth++;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompiler::endElement()
|
||||
{
|
||||
if (NS_FAILED(mStatus)) {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
nsresult rv = flushCharacters();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 i;
|
||||
for (i = mInScopeVariables.Count() - 1; i >= 0; --i) {
|
||||
txInScopeVariable* var =
|
||||
NS_STATIC_CAST(txInScopeVariable*, mInScopeVariables[i]);
|
||||
if (!--(var->mLevel)) {
|
||||
nsAutoPtr<txInstruction> instr(new txRemoveVariable(var->mName));
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = addInstruction(instr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mInScopeVariables.RemoveElementAt(i);
|
||||
delete var;
|
||||
}
|
||||
}
|
||||
|
||||
txElementHandler* handler = NS_STATIC_CAST(txElementHandler*, popPtr());
|
||||
rv = (handler->mEndFunction)(*this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!--mElementContext->mDepth) {
|
||||
// this will delete the old object
|
||||
mElementContext = NS_STATIC_CAST(txElementContext*, popObject());
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompiler::characters(const nsAString& aStr)
|
||||
{
|
||||
if (NS_FAILED(mStatus)) {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
mCharacters.Append(aStr);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompiler::doneLoading()
|
||||
{
|
||||
if (NS_FAILED(mStatus)) {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
mDoneWithThisStylesheet = PR_TRUE;
|
||||
|
||||
return maybeDoneCompiling();
|
||||
}
|
||||
|
||||
void
|
||||
txStylesheetCompiler::cancel(nsresult aError)
|
||||
{
|
||||
if (NS_SUCCEEDED(mStatus)) {
|
||||
mStatus = aError;
|
||||
}
|
||||
|
||||
if (mObserver) {
|
||||
mObserver->onDoneCompiling(this, mStatus);
|
||||
// This will ensure that we don't call onDoneCompiling twice. Also
|
||||
// ensures that we don't keep the observer alive longer then necessary.
|
||||
mObserver = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
txStylesheet*
|
||||
txStylesheetCompiler::getStylesheet()
|
||||
{
|
||||
return mStylesheet;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompiler::loadURI(const nsAString& aUri,
|
||||
txStylesheetCompiler* aCompiler)
|
||||
{
|
||||
return mObserver ? mObserver->loadURI(aUri, aCompiler) : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
void
|
||||
txStylesheetCompiler::onDoneCompiling(txStylesheetCompiler* aCompiler,
|
||||
nsresult aResult)
|
||||
{
|
||||
if (NS_FAILED(aResult)) {
|
||||
cancel(aResult);
|
||||
return;
|
||||
}
|
||||
|
||||
mChildCompilerList.RemoveElement(aCompiler);
|
||||
|
||||
maybeDoneCompiling();
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompiler::flushCharacters()
|
||||
{
|
||||
// Bail if we don't have any characters. The handler will detect
|
||||
// ignoreable whitespace
|
||||
if (mCharacters.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
do {
|
||||
rv = (mHandlerTable->mTextHandler)(mCharacters, *this);
|
||||
} while (rv == NS_ERROR_XSLT_GET_NEW_HANDLER);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mCharacters.Truncate();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompiler::ensureNewElementContext()
|
||||
{
|
||||
// Do we already have a new context?
|
||||
if (!mElementContext->mDepth) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoPtr<txElementContext>
|
||||
context(new txElementContext(*mElementContext));
|
||||
NS_ENSURE_TRUE(context, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = pushObject(mElementContext);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mElementContext.forget();
|
||||
mElementContext = context;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompiler::maybeDoneCompiling()
|
||||
{
|
||||
if (!mDoneWithThisStylesheet || mChildCompilerList.Count()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mIsTopCompiler) {
|
||||
nsresult rv = mStylesheet->doneCompiling();
|
||||
if (NS_FAILED(rv)) {
|
||||
cancel(rv);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
if (mObserver) {
|
||||
mObserver->onDoneCompiling(this, mStatus);
|
||||
// This will ensure that we don't call onDoneCompiling twice. Also
|
||||
// ensures that we don't keep the observer alive longer then necessary.
|
||||
mObserver = nsnull;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* txStylesheetCompilerState
|
||||
*/
|
||||
|
||||
|
||||
txStylesheetCompilerState::txStylesheetCompilerState(txACompileObserver* aObserver)
|
||||
: mHandlerTable(nsnull),
|
||||
mSorter(nsnull),
|
||||
mDOE(PR_FALSE),
|
||||
mSearchingForFallback(PR_FALSE),
|
||||
mObserver(aObserver),
|
||||
mDoneWithThisStylesheet(PR_FALSE),
|
||||
mNextInstrPtr(nsnull),
|
||||
mToplevelIterator(nsnull)
|
||||
{
|
||||
// XXX Embedded stylesheets have another handler. Probably
|
||||
mHandlerTable = gTxRootHandler;
|
||||
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompilerState::init(const nsAString& aBaseURI,
|
||||
txStylesheet* aStylesheet,
|
||||
txListIterator* aInsertPosition)
|
||||
{
|
||||
NS_ASSERTION(!aStylesheet || aInsertPosition,
|
||||
"must provide insertposition if loading subsheet");
|
||||
nsresult rv = NS_OK;
|
||||
if (aStylesheet) {
|
||||
mStylesheet = aStylesheet;
|
||||
mToplevelIterator = *aInsertPosition;
|
||||
mIsTopCompiler = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
mStylesheet = new txStylesheet;
|
||||
NS_ENSURE_TRUE(mStylesheet, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = mStylesheet->init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mToplevelIterator =
|
||||
txListIterator(&mStylesheet->mRootFrame->mToplevelItems);
|
||||
mToplevelIterator.next(); // go to the end of the list
|
||||
mIsTopCompiler = PR_TRUE;
|
||||
}
|
||||
|
||||
mElementContext = new txElementContext(aBaseURI);
|
||||
NS_ENSURE_TRUE(mElementContext && mElementContext->mMappings,
|
||||
NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// Push the "old" txElementContext
|
||||
rv = pushObject(0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
txStylesheetCompilerState::~txStylesheetCompilerState()
|
||||
{
|
||||
while (!mObjectStack.isEmpty()) {
|
||||
delete popObject();
|
||||
}
|
||||
|
||||
PRInt32 i;
|
||||
for (i = mInScopeVariables.Count() - 1; i >= 0; --i) {
|
||||
delete NS_STATIC_CAST(txInScopeVariable*, mInScopeVariables[i]);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompilerState::pushHandlerTable(txHandlerTable* aTable)
|
||||
{
|
||||
nsresult rv = pushPtr(mHandlerTable);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mHandlerTable = aTable;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
txStylesheetCompilerState::popHandlerTable()
|
||||
{
|
||||
mHandlerTable = NS_STATIC_CAST(txHandlerTable*, popPtr());
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompilerState::pushSorter(txPushNewContext* aSorter)
|
||||
{
|
||||
nsresult rv = pushPtr(mSorter);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mSorter = aSorter;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
txStylesheetCompilerState::popSorter()
|
||||
{
|
||||
mSorter = NS_STATIC_CAST(txPushNewContext*, popPtr());
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompilerState::pushChooseGotoList()
|
||||
{
|
||||
nsresult rv = pushObject(mChooseGotoList);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mChooseGotoList.forget();
|
||||
mChooseGotoList = new txList;
|
||||
NS_ENSURE_TRUE(mChooseGotoList, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
txStylesheetCompilerState::popChooseGotoList()
|
||||
{
|
||||
// this will delete the old value
|
||||
mChooseGotoList = NS_STATIC_CAST(txList*, popObject());
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompilerState::pushObject(TxObject* aObject)
|
||||
{
|
||||
return mObjectStack.push(aObject);
|
||||
}
|
||||
|
||||
TxObject*
|
||||
txStylesheetCompilerState::popObject()
|
||||
{
|
||||
return NS_STATIC_CAST(TxObject*, mObjectStack.pop());
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompilerState::pushPtr(void* aPtr)
|
||||
{
|
||||
PR_LOG(txLog::xslt, PR_LOG_DEBUG, ("pushPtr: %d\n", aPtr));
|
||||
return mOtherStack.push(aPtr);
|
||||
}
|
||||
|
||||
void*
|
||||
txStylesheetCompilerState::popPtr()
|
||||
{
|
||||
void* value = mOtherStack.pop();
|
||||
PR_LOG(txLog::xslt, PR_LOG_DEBUG, ("popPtr: %d\n", value));
|
||||
return value;
|
||||
}
|
||||
|
||||
MBool
|
||||
txStylesheetCompilerState::fcp()
|
||||
{
|
||||
return mElementContext->mForwardsCompatibleParsing;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompilerState::addToplevelItem(txToplevelItem* aItem)
|
||||
{
|
||||
return mToplevelIterator.addBefore(aItem);
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompilerState::openInstructionContainer(txInstructionContainer* aContainer)
|
||||
{
|
||||
NS_PRECONDITION(!mNextInstrPtr, "can't nest instruction-containers");
|
||||
|
||||
mNextInstrPtr = aContainer->mFirstInstruction.StartAssignment();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
txStylesheetCompilerState::closeInstructionContainer()
|
||||
{
|
||||
NS_ASSERTION(mGotoTargetPointers.Count() == 0,
|
||||
"GotoTargets still exists, did you forget to add txReturn?");
|
||||
mNextInstrPtr = 0;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompilerState::addInstruction(nsAutoPtr<txInstruction> aInstruction)
|
||||
{
|
||||
NS_PRECONDITION(mNextInstrPtr, "adding instruction outside container");
|
||||
|
||||
txInstruction* newInstr = aInstruction;
|
||||
|
||||
*mNextInstrPtr = aInstruction.forget();
|
||||
mNextInstrPtr = &newInstr->mNext;
|
||||
|
||||
PRInt32 i, count = mGotoTargetPointers.Count();
|
||||
for (i = 0; i < count; ++i) {
|
||||
*NS_STATIC_CAST(txInstruction**, mGotoTargetPointers[i]) = newInstr;
|
||||
}
|
||||
mGotoTargetPointers.Clear();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompilerState::loadIncludedStylesheet(const nsAString& aURI)
|
||||
{
|
||||
NS_ENSURE_TRUE(mObserver, NS_ERROR_NOT_IMPLEMENTED);
|
||||
|
||||
nsAutoPtr<txToplevelItem> item(new txDummyItem);
|
||||
NS_ENSURE_TRUE(item, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = mToplevelIterator.addBefore(item);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
item.forget();
|
||||
|
||||
// step back to the dummy-item
|
||||
mToplevelIterator.previous();
|
||||
|
||||
txACompileObserver* observer = NS_STATIC_CAST(txStylesheetCompiler*, this);
|
||||
|
||||
nsRefPtr<txStylesheetCompiler> compiler =
|
||||
new txStylesheetCompiler(aURI, mStylesheet, &mToplevelIterator,
|
||||
observer);
|
||||
NS_ENSURE_TRUE(compiler, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// step forward before calling the observer in case of syncronous loading
|
||||
mToplevelIterator.next();
|
||||
|
||||
if (!mChildCompilerList.AppendElement(compiler)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
rv = mObserver->loadURI(aURI, compiler);
|
||||
if (NS_FAILED(rv)) {
|
||||
mChildCompilerList.RemoveElement(compiler);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompilerState::loadImportedStylesheet(const nsAString& aURI,
|
||||
txStylesheet::ImportFrame* aFrame)
|
||||
{
|
||||
NS_ENSURE_TRUE(mObserver, NS_ERROR_NOT_IMPLEMENTED);
|
||||
|
||||
txListIterator iter(&aFrame->mToplevelItems);
|
||||
iter.next(); // go to the end of the list
|
||||
|
||||
txACompileObserver* observer = NS_STATIC_CAST(txStylesheetCompiler*, this);
|
||||
|
||||
nsRefPtr<txStylesheetCompiler> compiler =
|
||||
new txStylesheetCompiler(aURI, mStylesheet, &iter, observer);
|
||||
NS_ENSURE_TRUE(compiler, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (!mChildCompilerList.AppendElement(compiler)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsresult rv = mObserver->loadURI(aURI, compiler);
|
||||
if (NS_FAILED(rv)) {
|
||||
mChildCompilerList.RemoveElement(compiler);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompilerState::addGotoTarget(txInstruction** aTargetPointer)
|
||||
{
|
||||
if (!mGotoTargetPointers.AppendElement(aTargetPointer)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompilerState::addVariable(const txExpandedName& aName)
|
||||
{
|
||||
txInScopeVariable* var = new txInScopeVariable(aName);
|
||||
NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (!mInScopeVariables.AppendElement(var)) {
|
||||
delete var;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompilerState::resolveNamespacePrefix(nsIAtom* aPrefix,
|
||||
PRInt32& aID)
|
||||
{
|
||||
NS_ASSERTION(aPrefix && aPrefix != txXMLAtoms::_empty,
|
||||
"caller should handle default namespace ''");
|
||||
aID = mElementContext->mMappings->lookupNamespace(aPrefix);
|
||||
return (aID != kNameSpaceID_Unknown) ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompilerState::resolveFunctionCall(nsIAtom* aName, PRInt32 aID,
|
||||
FunctionCall*& aFunction)
|
||||
{
|
||||
aFunction = nsnull;
|
||||
|
||||
if (aID != kNameSpaceID_None) {
|
||||
return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
|
||||
}
|
||||
if (aName == txXSLTAtoms::document) {
|
||||
aFunction = new DocumentFunctionCall(mElementContext->mBaseURI);
|
||||
NS_ENSURE_TRUE(aFunction, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
if (aName == txXSLTAtoms::key) {
|
||||
aFunction = new txKeyFunctionCall(mElementContext->mMappings);
|
||||
NS_ENSURE_TRUE(aFunction, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
if (aName == txXSLTAtoms::formatNumber) {
|
||||
aFunction = new txFormatNumberFunctionCall(mStylesheet,
|
||||
mElementContext->mMappings);
|
||||
NS_ENSURE_TRUE(aFunction, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
if (aName == txXSLTAtoms::current) {
|
||||
aFunction = new CurrentFunctionCall();
|
||||
NS_ENSURE_TRUE(aFunction, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
if (aName == txXSLTAtoms::unparsedEntityUri) {
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
if (aName == txXSLTAtoms::generateId) {
|
||||
aFunction = new GenerateIdFunctionCall();
|
||||
NS_ENSURE_TRUE(aFunction, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
if (aName == txXSLTAtoms::systemProperty) {
|
||||
aFunction = new SystemPropertyFunctionCall(mElementContext->mMappings);
|
||||
NS_ENSURE_TRUE(aFunction, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
if (aName == txXSLTAtoms::elementAvailable) {
|
||||
aFunction =
|
||||
new ElementAvailableFunctionCall(mElementContext->mMappings);
|
||||
NS_ENSURE_TRUE(aFunction, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
if (aName == txXSLTAtoms::functionAvailable) {
|
||||
aFunction =
|
||||
new FunctionAvailableFunctionCall(mElementContext->mMappings);
|
||||
NS_ENSURE_TRUE(aFunction, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
|
||||
}
|
||||
|
||||
PRBool
|
||||
txStylesheetCompilerState::caseInsensitiveNameTests()
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
txStylesheetCompilerState::receiveError(const nsAString& aMsg, nsresult aRes)
|
||||
{
|
||||
// XXX implement me
|
||||
}
|
||||
|
||||
txElementContext::txElementContext(const nsAString& aBaseURI)
|
||||
: mPreserveWhitespace(PR_FALSE),
|
||||
mForwardsCompatibleParsing(PR_TRUE),
|
||||
mBaseURI(aBaseURI),
|
||||
mMappings(new txNamespaceMap),
|
||||
mDepth(0)
|
||||
{
|
||||
mInstructionNamespaces.AppendElement(NS_INT32_TO_PTR(kNameSpaceID_XSLT));
|
||||
}
|
||||
|
||||
txElementContext::txElementContext(const txElementContext& aOther)
|
||||
: mPreserveWhitespace(aOther.mPreserveWhitespace),
|
||||
mForwardsCompatibleParsing(aOther.mForwardsCompatibleParsing),
|
||||
mBaseURI(aOther.mBaseURI),
|
||||
mMappings(aOther.mMappings),
|
||||
mDepth(0)
|
||||
{
|
||||
mInstructionNamespaces = aOther.mInstructionNamespaces;
|
||||
}
|
||||
@ -0,0 +1,228 @@
|
||||
/* -*- 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
|
||||
* Jonas Sicking.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* Jonas Sicking. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking <jonas@sicking.cc>
|
||||
*
|
||||
* 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_TXSTYLESHEETCOMPILER_H
|
||||
#define TRANSFRMX_TXSTYLESHEETCOMPILER_H
|
||||
|
||||
#include "baseutils.h"
|
||||
#include "txError.h"
|
||||
#include "txStack.h"
|
||||
#include "txXSLTPatterns.h"
|
||||
#include "Expr.h"
|
||||
#include "XMLUtils.h"
|
||||
#include "txIXPathContext.h"
|
||||
#include "txNamespaceMap.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "txStylesheet.h"
|
||||
|
||||
class txHandlerTable;
|
||||
class txElementContext;
|
||||
class txInstructionContainer;
|
||||
class txInstruction;
|
||||
class txToplevelItem;
|
||||
class txPushNewContext;
|
||||
class txStylesheetCompiler;
|
||||
|
||||
class txElementContext : public TxObject
|
||||
{
|
||||
public:
|
||||
txElementContext(const nsAString& aBaseURI);
|
||||
txElementContext(const txElementContext& aOther);
|
||||
|
||||
PRBool mPreserveWhitespace;
|
||||
PRBool mForwardsCompatibleParsing;
|
||||
nsString mBaseURI;
|
||||
nsRefPtr<txNamespaceMap> mMappings;
|
||||
nsVoidArray mInstructionNamespaces;
|
||||
PRInt32 mDepth;
|
||||
};
|
||||
|
||||
class txACompileObserver
|
||||
{
|
||||
public:
|
||||
virtual nsrefcnt AddRef() = 0;
|
||||
virtual nsrefcnt Release() = 0;
|
||||
|
||||
virtual nsresult loadURI(const nsAString& aUri,
|
||||
txStylesheetCompiler* aCompiler) = 0;
|
||||
virtual void onDoneCompiling(txStylesheetCompiler* aCompiler,
|
||||
nsresult aResult) = 0;
|
||||
};
|
||||
|
||||
#define TX_DECL_ACOMPILEOBSERVER \
|
||||
nsrefcnt AddRef(); \
|
||||
nsrefcnt Release(); \
|
||||
nsresult loadURI(const nsAString& aUri, txStylesheetCompiler* aCompiler); \
|
||||
void onDoneCompiling(txStylesheetCompiler* aCompiler, nsresult aResult)
|
||||
|
||||
class txStylesheetCompilerState : public txIParseContext
|
||||
{
|
||||
public:
|
||||
txStylesheetCompilerState(txACompileObserver* aObserver);
|
||||
~txStylesheetCompilerState();
|
||||
|
||||
nsresult init(const nsAString& aBaseURI, txStylesheet* aStylesheet,
|
||||
txListIterator* aInsertPosition);
|
||||
|
||||
// Stack functions
|
||||
nsresult pushHandlerTable(txHandlerTable* aTable);
|
||||
void popHandlerTable();
|
||||
nsresult pushSorter(txPushNewContext* aSorter);
|
||||
void popSorter();
|
||||
nsresult pushChooseGotoList();
|
||||
void popChooseGotoList();
|
||||
nsresult pushObject(TxObject* aObject);
|
||||
TxObject* popObject();
|
||||
nsresult pushPtr(void* aPtr);
|
||||
void* popPtr();
|
||||
|
||||
// State-checking functions
|
||||
MBool fcp();
|
||||
|
||||
// stylesheet functions
|
||||
nsresult addToplevelItem(txToplevelItem* aItem);
|
||||
nsresult openInstructionContainer(txInstructionContainer* aContainer);
|
||||
void closeInstructionContainer();
|
||||
nsresult addInstruction(nsAutoPtr<txInstruction> aInstruction);
|
||||
nsresult loadIncludedStylesheet(const nsAString& aURI);
|
||||
nsresult loadImportedStylesheet(const nsAString& aURI,
|
||||
txStylesheet::ImportFrame* aFrame);
|
||||
|
||||
// misc
|
||||
nsresult addGotoTarget(txInstruction** aTargetPointer);
|
||||
nsresult addVariable(const txExpandedName& aName);
|
||||
|
||||
// txIParseContext
|
||||
nsresult resolveNamespacePrefix(nsIAtom* aPrefix, PRInt32& aID);
|
||||
nsresult resolveFunctionCall(nsIAtom* aName, PRInt32 aID,
|
||||
FunctionCall*& aFunction);
|
||||
PRBool caseInsensitiveNameTests();
|
||||
void receiveError(const nsAString& aMsg, nsresult aRes);
|
||||
|
||||
|
||||
nsRefPtr<txStylesheet> mStylesheet;
|
||||
txHandlerTable* mHandlerTable;
|
||||
nsAutoPtr<txElementContext> mElementContext;
|
||||
txPushNewContext* mSorter;
|
||||
nsAutoPtr<txList> mChooseGotoList;
|
||||
PRPackedBool mDOE;
|
||||
PRPackedBool mSearchingForFallback;
|
||||
|
||||
protected:
|
||||
nsRefPtr<txACompileObserver> mObserver;
|
||||
nsVoidArray mInScopeVariables;
|
||||
nsVoidArray mChildCompilerList;
|
||||
PRPackedBool mIsTopCompiler;
|
||||
PRPackedBool mDoneWithThisStylesheet;
|
||||
|
||||
private:
|
||||
txStack mObjectStack;
|
||||
txStack mOtherStack;
|
||||
txInstruction** mNextInstrPtr;
|
||||
txListIterator mToplevelIterator;
|
||||
nsVoidArray mGotoTargetPointers;
|
||||
};
|
||||
|
||||
struct txStylesheetAttr
|
||||
{
|
||||
PRInt32 mNamespaceID;
|
||||
nsCOMPtr<nsIAtom> mLocalName;
|
||||
nsCOMPtr<nsIAtom> mPrefix;
|
||||
nsString mValue;
|
||||
};
|
||||
|
||||
class txStylesheetCompiler : private txStylesheetCompilerState,
|
||||
public txACompileObserver
|
||||
{
|
||||
public:
|
||||
txStylesheetCompiler(const nsAString& aBaseURI,
|
||||
txACompileObserver* aObserver);
|
||||
txStylesheetCompiler(const nsAString& aBaseURI,
|
||||
txStylesheet* aStylesheet,
|
||||
txListIterator* aInsertPosition,
|
||||
txACompileObserver* aObserver);
|
||||
virtual nsrefcnt AddRef();
|
||||
virtual nsrefcnt Release();
|
||||
|
||||
nsresult startElement(PRInt32 aNamespaceID, nsIAtom* aLocalName,
|
||||
nsIAtom* aPrefix, txStylesheetAttr* aAttributes,
|
||||
PRInt32 aAttrCount);
|
||||
nsresult startElement(const PRUnichar *aName,
|
||||
const PRUnichar **aAtts,
|
||||
PRInt32 aAttrCount);
|
||||
nsresult endElement();
|
||||
nsresult characters(const nsAString& aStr);
|
||||
nsresult doneLoading();
|
||||
|
||||
void cancel(nsresult aError);
|
||||
|
||||
txStylesheet* getStylesheet();
|
||||
|
||||
// txACompileObserver
|
||||
nsresult loadURI(const nsAString& aUri, txStylesheetCompiler* aCompiler);
|
||||
void onDoneCompiling(txStylesheetCompiler* aCompiler, nsresult aResult);
|
||||
|
||||
private:
|
||||
nsresult startElementInternal(PRInt32 aNamespaceID, nsIAtom* aLocalName,
|
||||
nsIAtom* aPrefix,
|
||||
txStylesheetAttr* aAttributes,
|
||||
PRInt32 aAttrCount);
|
||||
|
||||
nsresult flushCharacters();
|
||||
nsresult ensureNewElementContext();
|
||||
nsresult maybeDoneCompiling();
|
||||
|
||||
nsAutoRefCnt mRefCnt;
|
||||
nsString mCharacters;
|
||||
nsresult mStatus;
|
||||
|
||||
protected:
|
||||
// This exists soly to supress a warning from nsDerivedSafe
|
||||
txStylesheetCompiler();
|
||||
};
|
||||
|
||||
class txInScopeVariable {
|
||||
public:
|
||||
txInScopeVariable(const txExpandedName& aName) : mName(aName), mLevel(1)
|
||||
{
|
||||
}
|
||||
txExpandedName mName;
|
||||
PRInt32 mLevel;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -39,9 +39,8 @@
|
||||
#include "txTextHandler.h"
|
||||
#include "nsAString.h"
|
||||
|
||||
txTextHandler::txTextHandler(nsAString& aValue, MBool aOnlyText) : mLevel(0),
|
||||
mValue(aValue),
|
||||
mOnlyText(aOnlyText)
|
||||
txTextHandler::txTextHandler(MBool aOnlyText) : mLevel(0),
|
||||
mOnlyText(aOnlyText)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -40,18 +40,20 @@
|
||||
#define TRANSFRMX_TEXT_HANDLER_H
|
||||
|
||||
#include "txXMLEventHandler.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class txTextHandler : public txAXMLEventHandler
|
||||
{
|
||||
public:
|
||||
txTextHandler(nsAString& aValue, MBool aOnlyText);
|
||||
txTextHandler(MBool aOnlyText);
|
||||
virtual ~txTextHandler();
|
||||
|
||||
TX_DECL_TXAXMLEVENTHANDLER
|
||||
|
||||
nsString mValue;
|
||||
|
||||
private:
|
||||
PRUint32 mLevel;
|
||||
nsAString& mValue;
|
||||
MBool mOnlyText;
|
||||
};
|
||||
|
||||
|
||||
@ -0,0 +1,85 @@
|
||||
/* -*- 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
|
||||
* Jonas Sicking.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* Jonas Sicking. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking <jonas@sicking.cc>
|
||||
*
|
||||
* 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 "txToplevelItems.h"
|
||||
#include "txStylesheet.h"
|
||||
#include "txInstructions.h"
|
||||
#include "txXSLTPatterns.h"
|
||||
|
||||
TX_IMPL_GETTYPE(txAttributeSetItem, txToplevelItem::attributeSet)
|
||||
TX_IMPL_GETTYPE(txImportItem, txToplevelItem::import)
|
||||
TX_IMPL_GETTYPE(txOutputItem, txToplevelItem::output)
|
||||
TX_IMPL_GETTYPE(txDummyItem, txToplevelItem::dummy)
|
||||
|
||||
TX_IMPL_GETTYPE(txStripSpaceItem, txToplevelItem::stripSpace)
|
||||
|
||||
txStripSpaceItem::~txStripSpaceItem()
|
||||
{
|
||||
PRInt32 i, count = mStripSpaceTests.Count();
|
||||
for (i = 0; i < count; ++i) {
|
||||
delete NS_STATIC_CAST(txStripSpaceTest*, mStripSpaceTests[0]);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
txStripSpaceItem::addStripSpaceTest(txStripSpaceTest* aStripSpaceTest)
|
||||
{
|
||||
if (!mStripSpaceTests.AppendElement(aStripSpaceTest)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
TX_IMPL_GETTYPE(txTemplateItem, txToplevelItem::templ)
|
||||
|
||||
txTemplateItem::txTemplateItem(nsAutoPtr<txPattern> aMatch,
|
||||
const txExpandedName& aName,
|
||||
const txExpandedName& aMode, double aPrio)
|
||||
: mMatch(aMatch), mName(aName), mMode(aMode), mPrio(aPrio)
|
||||
{
|
||||
}
|
||||
|
||||
TX_IMPL_GETTYPE(txVariableItem, txToplevelItem::variable)
|
||||
|
||||
txVariableItem::txVariableItem(const txExpandedName& aName,
|
||||
nsAutoPtr<Expr> aValue,
|
||||
PRBool aIsParam)
|
||||
: mName(aName), mValue(aValue), mIsParam(aIsParam)
|
||||
{
|
||||
}
|
||||
163
mozilla/extensions/transformiix/source/xslt/txToplevelItems.h
Normal file
163
mozilla/extensions/transformiix/source/xslt/txToplevelItems.h
Normal file
@ -0,0 +1,163 @@
|
||||
/* -*- 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
|
||||
* Jonas Sicking.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* Jonas Sicking. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking <jonas@sicking.cc>
|
||||
*
|
||||
* 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_TXTOPLEVELITEMS_H
|
||||
#define TRANSFRMX_TXTOPLEVELITEMS_H
|
||||
|
||||
#include "txError.h"
|
||||
#include "txOutputFormat.h"
|
||||
#include "XMLUtils.h"
|
||||
#include "txStylesheet.h"
|
||||
|
||||
class txPattern;
|
||||
class Expr;
|
||||
class txInstruction;
|
||||
|
||||
class txToplevelItem
|
||||
{
|
||||
public:
|
||||
virtual ~txToplevelItem()
|
||||
{
|
||||
}
|
||||
|
||||
enum type {
|
||||
attributeSet,
|
||||
dummy,
|
||||
import,
|
||||
//namespaceAlias,
|
||||
output,
|
||||
stripSpace, //also used for preserve-space
|
||||
templ,
|
||||
variable
|
||||
};
|
||||
|
||||
virtual type getType() = 0;
|
||||
};
|
||||
|
||||
#define TX_DECL_TOPLEVELITEM virtual type getType();
|
||||
#define TX_IMPL_GETTYPE(_class, _type) \
|
||||
txToplevelItem::type \
|
||||
_class::getType() { return _type;}
|
||||
|
||||
class txInstructionContainer : public txToplevelItem
|
||||
{
|
||||
public:
|
||||
nsAutoPtr<txInstruction> mFirstInstruction;
|
||||
};
|
||||
|
||||
// xsl:attribute-set
|
||||
class txAttributeSetItem : public txInstructionContainer
|
||||
{
|
||||
public:
|
||||
txAttributeSetItem(const txExpandedName aName) : mName(aName)
|
||||
{
|
||||
}
|
||||
|
||||
TX_DECL_TOPLEVELITEM
|
||||
|
||||
txExpandedName mName;
|
||||
};
|
||||
|
||||
// xsl:import
|
||||
class txImportItem : public txToplevelItem
|
||||
{
|
||||
public:
|
||||
TX_DECL_TOPLEVELITEM
|
||||
|
||||
nsAutoPtr<txStylesheet::ImportFrame> mFrame;
|
||||
};
|
||||
|
||||
// xsl:output
|
||||
class txOutputItem : public txToplevelItem
|
||||
{
|
||||
public:
|
||||
TX_DECL_TOPLEVELITEM
|
||||
|
||||
txOutputFormat mFormat;
|
||||
};
|
||||
|
||||
// insertionpoint for xsl:include
|
||||
class txDummyItem : public txToplevelItem
|
||||
{
|
||||
public:
|
||||
TX_DECL_TOPLEVELITEM
|
||||
};
|
||||
|
||||
// xsl:strip-space and xsl:preserve-space
|
||||
class txStripSpaceItem : public txToplevelItem
|
||||
{
|
||||
public:
|
||||
virtual ~txStripSpaceItem();
|
||||
|
||||
TX_DECL_TOPLEVELITEM
|
||||
|
||||
nsresult addStripSpaceTest(txStripSpaceTest* aStripSpaceTest);
|
||||
|
||||
nsVoidArray mStripSpaceTests;
|
||||
};
|
||||
|
||||
// xsl:template
|
||||
class txTemplateItem : public txInstructionContainer
|
||||
{
|
||||
public:
|
||||
txTemplateItem(nsAutoPtr<txPattern> aMatch, const txExpandedName& aName,
|
||||
const txExpandedName& aMode, double aPrio);
|
||||
|
||||
TX_DECL_TOPLEVELITEM
|
||||
|
||||
nsAutoPtr<txPattern> mMatch;
|
||||
txExpandedName mName;
|
||||
txExpandedName mMode;
|
||||
double mPrio;
|
||||
};
|
||||
|
||||
// xsl:variable at top level
|
||||
class txVariableItem : public txInstructionContainer
|
||||
{
|
||||
public:
|
||||
txVariableItem(const txExpandedName& aName, nsAutoPtr<Expr> aValue,
|
||||
PRBool aIsParam);
|
||||
|
||||
TX_DECL_TOPLEVELITEM
|
||||
|
||||
txExpandedName mName;
|
||||
nsAutoPtr<Expr> mValue;
|
||||
PRBool mIsParam;
|
||||
};
|
||||
|
||||
#endif //TRANSFRMX_TXTOPLEVELITEMS_H
|
||||
@ -37,11 +37,12 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "txUnknownHandler.h"
|
||||
#include "ProcessorState.h"
|
||||
#include "txExecutionState.h"
|
||||
#include "txStringUtils.h"
|
||||
#include "txStylesheet.h"
|
||||
|
||||
txUnknownHandler::txUnknownHandler(ProcessorState* aPs)
|
||||
: mPs(aPs)
|
||||
txUnknownHandler::txUnknownHandler(txExecutionState* aEs)
|
||||
: mEs(aEs)
|
||||
{
|
||||
}
|
||||
|
||||
@ -69,7 +70,7 @@ void txUnknownHandler::endDocument()
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
mPs->mResultHandler->endDocument();
|
||||
mEs->mResultHandler->endDocument();
|
||||
|
||||
delete this;
|
||||
}
|
||||
@ -78,7 +79,7 @@ void txUnknownHandler::startElement(const nsAString& aName,
|
||||
const PRInt32 aNsID)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
txOutputFormat* format = mPs->getOutputFormat();
|
||||
txOutputFormat* format = mEs->mStylesheet->getOutputFormat();
|
||||
if (format->mMethod != eMethodNotSet) {
|
||||
rv = createHandlerAndFlush(format->mMethod, aName, aNsID);
|
||||
}
|
||||
@ -93,7 +94,7 @@ void txUnknownHandler::startElement(const nsAString& aName,
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
mPs->mResultHandler->startElement(aName, aNsID);
|
||||
mEs->mResultHandler->startElement(aName, aNsID);
|
||||
|
||||
delete this;
|
||||
}
|
||||
@ -104,17 +105,18 @@ nsresult txUnknownHandler::createHandlerAndFlush(txOutputMethod aMethod,
|
||||
{
|
||||
NS_ENSURE_TRUE(mBuffer, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
txOutputFormat* format = mPs->getOutputFormat();
|
||||
format->mMethod = aMethod;
|
||||
txOutputFormat format;
|
||||
format.merge(*mEs->mStylesheet->getOutputFormat());
|
||||
format.mMethod = aMethod;
|
||||
|
||||
txAXMLEventHandler* handler = 0;
|
||||
nsresult rv = mPs->mOutputHandlerFactory->createHandlerWith(format, aName,
|
||||
nsresult rv = mEs->mOutputHandlerFactory->createHandlerWith(&format, aName,
|
||||
aNsID,
|
||||
&handler);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mPs->mOutputHandler = handler;
|
||||
mPs->mResultHandler = handler;
|
||||
mEs->mOutputHandler = handler;
|
||||
mEs->mResultHandler = handler;
|
||||
|
||||
return mBuffer->flushToHandler(handler);
|
||||
}
|
||||
|
||||
@ -42,12 +42,12 @@
|
||||
#include "txBufferingHandler.h"
|
||||
#include "txOutputFormat.h"
|
||||
|
||||
class ProcessorState;
|
||||
class txExecutionState;
|
||||
|
||||
class txUnknownHandler : public txBufferingHandler
|
||||
{
|
||||
public:
|
||||
txUnknownHandler(ProcessorState* aPs);
|
||||
txUnknownHandler(txExecutionState* aEs);
|
||||
virtual ~txUnknownHandler();
|
||||
|
||||
void attribute(const nsAString& aName, const PRInt32 aNsID,
|
||||
@ -61,11 +61,11 @@ private:
|
||||
const PRInt32 aNsID);
|
||||
|
||||
/*
|
||||
* XXX we shouldn't hold to the ProcessorState, as we're supposed
|
||||
* XXX we shouldn't hold to the txExecutionState, 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;
|
||||
txExecutionState* mEs;
|
||||
};
|
||||
|
||||
#endif /* txUnknownHandler_h___ */
|
||||
|
||||
@ -46,17 +46,16 @@
|
||||
|
||||
class txVariableMap {
|
||||
public:
|
||||
txVariableMap(txVariableMap* aParentMap);
|
||||
txVariableMap();
|
||||
|
||||
nsresult bindVariable(const txExpandedName& aName,
|
||||
ExprResult* aValue, MBool aOwned);
|
||||
|
||||
ExprResult* getVariable(const txExpandedName& aName);
|
||||
|
||||
void removeVariable(const txExpandedName& aName);
|
||||
|
||||
private:
|
||||
// Parent map of variables
|
||||
txVariableMap* mParentMap;
|
||||
|
||||
// Map with owned variables
|
||||
txExpandedNameMap mOwnedVariables;
|
||||
|
||||
@ -65,9 +64,8 @@ private:
|
||||
};
|
||||
|
||||
|
||||
inline txVariableMap::txVariableMap(txVariableMap* aParentMap)
|
||||
: mParentMap(aParentMap),
|
||||
mOwnedVariables(MB_TRUE),
|
||||
inline txVariableMap::txVariableMap()
|
||||
: mOwnedVariables(MB_TRUE),
|
||||
mNonOwnedVariables(MB_FALSE)
|
||||
{
|
||||
}
|
||||
@ -75,21 +73,14 @@ inline txVariableMap::txVariableMap(txVariableMap* aParentMap)
|
||||
inline nsresult txVariableMap::bindVariable(const txExpandedName& aName,
|
||||
ExprResult* aValue, MBool aOwned)
|
||||
{
|
||||
TxObject* var = 0;
|
||||
txVariableMap* map = this;
|
||||
while (!var && map) {
|
||||
var = map->mOwnedVariables.get(aName);
|
||||
if (!var) {
|
||||
var = map->mNonOwnedVariables.get(aName);
|
||||
}
|
||||
map = map->mParentMap;
|
||||
}
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
if (!var) {
|
||||
if (aOwned) {
|
||||
if (aOwned) {
|
||||
if (!mNonOwnedVariables.get(aName)) {
|
||||
rv = mOwnedVariables.add(aName, aValue);
|
||||
}
|
||||
else {
|
||||
}
|
||||
else {
|
||||
if (!mOwnedVariables.get(aName)) {
|
||||
rv = mNonOwnedVariables.add(aName, aValue);
|
||||
}
|
||||
}
|
||||
@ -98,17 +89,17 @@ inline nsresult txVariableMap::bindVariable(const txExpandedName& aName,
|
||||
|
||||
inline ExprResult* txVariableMap::getVariable(const txExpandedName& aName)
|
||||
{
|
||||
ExprResult* var = 0;
|
||||
txVariableMap* map = this;
|
||||
while (!var && map) {
|
||||
var = (ExprResult*)map->mOwnedVariables.get(aName);
|
||||
if (!var) {
|
||||
var = (ExprResult*)map->mNonOwnedVariables.get(aName);
|
||||
}
|
||||
map = map->mParentMap;
|
||||
ExprResult* var = (ExprResult*)mOwnedVariables.get(aName);
|
||||
if (!var) {
|
||||
var = (ExprResult*)mNonOwnedVariables.get(aName);
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
inline void txVariableMap::removeVariable(const txExpandedName& aName)
|
||||
{
|
||||
mOwnedVariables.remove(aName);
|
||||
mNonOwnedVariables.remove(aName);
|
||||
}
|
||||
|
||||
#endif //TRANSFRMX_VARIABLEMAP_H
|
||||
|
||||
@ -40,7 +40,7 @@
|
||||
|
||||
const int txXMLOutput::DEFAULT_INDENT = 2;
|
||||
|
||||
txAttribute::txAttribute(PRInt32 aNsID, nsIAtom* aLocalName,
|
||||
txOutAttr::txOutAttr(PRInt32 aNsID, nsIAtom* aLocalName,
|
||||
const nsAString& aValue) :
|
||||
mName(aNsID, aLocalName),
|
||||
mValue(aValue),
|
||||
@ -78,15 +78,15 @@ void txXMLOutput::attribute(const nsAString& aName,
|
||||
XMLUtils::getLocalPart(aName, getter_AddRefs(localName));
|
||||
txExpandedName att(aNsID, localName);
|
||||
|
||||
txAttribute* setAtt = 0;
|
||||
while ((setAtt = (txAttribute*)iter.next())) {
|
||||
txOutAttr* setAtt = 0;
|
||||
while ((setAtt = (txOutAttr*)iter.next())) {
|
||||
if (setAtt->mName == att) {
|
||||
setAtt->mValue = aValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!setAtt) {
|
||||
setAtt = new txAttribute(aNsID, localName, aValue);
|
||||
setAtt = new txOutAttr(aNsID, localName, aValue);
|
||||
mAttributes.add(setAtt);
|
||||
}
|
||||
}
|
||||
@ -261,8 +261,8 @@ void txXMLOutput::closeStartTag(MBool aUseEmptyElementShorthand)
|
||||
mAfterEndTag = aUseEmptyElementShorthand;
|
||||
if (mStartTagOpen) {
|
||||
txListIterator iter(&mAttributes);
|
||||
txAttribute* att;
|
||||
while ((att = (txAttribute*)iter.next())) {
|
||||
txOutAttr* att;
|
||||
while ((att = (txOutAttr*)iter.next())) {
|
||||
*mOut << SPACE;
|
||||
const PRUnichar* attrVal;
|
||||
att->mName.mLocalName->GetUnicode(&attrVal);
|
||||
@ -273,7 +273,7 @@ void txXMLOutput::closeStartTag(MBool aUseEmptyElementShorthand)
|
||||
printWithXMLEntities(att->mValue, MB_TRUE);
|
||||
*mOut << DOUBLE_QUOTE;
|
||||
}
|
||||
delete (txAttribute*)iter.remove();
|
||||
delete (txOutAttr*)iter.remove();
|
||||
}
|
||||
|
||||
if (aUseEmptyElementShorthand)
|
||||
|
||||
@ -82,9 +82,9 @@
|
||||
#define XML_DECL "xml version="
|
||||
#define XML_VERSION "1.0"
|
||||
|
||||
class txAttribute {
|
||||
class txOutAttr {
|
||||
public:
|
||||
txAttribute(PRInt32 aNsID, nsIAtom* aLocalName, const nsAString& aValue);
|
||||
txOutAttr(PRInt32 aNsID, nsIAtom* aLocalName, const nsAString& aValue);
|
||||
txExpandedName mName;
|
||||
nsString mValue;
|
||||
MBool mShorthand;
|
||||
|
||||
@ -85,6 +85,7 @@ TX_ATOM(doctypePublic, "doctype-public");
|
||||
TX_ATOM(doctypeSystem, "doctype-system");
|
||||
TX_ATOM(elements, "elements");
|
||||
TX_ATOM(encoding, "encoding");
|
||||
TX_ATOM(extensionElementPrefixes, "extension-element-prefixes");
|
||||
TX_ATOM(format, "format");
|
||||
TX_ATOM(from, "from");
|
||||
TX_ATOM(groupingSeparator, "grouping-separator");
|
||||
@ -111,6 +112,7 @@ TX_ATOM(priority, "priority");
|
||||
TX_ATOM(select, "select");
|
||||
TX_ATOM(standalone, "standalone");
|
||||
TX_ATOM(test, "test");
|
||||
TX_ATOM(terminate, "terminate");
|
||||
TX_ATOM(use, "use");
|
||||
TX_ATOM(useAttributeSets, "use-attribute-sets");
|
||||
TX_ATOM(value, "value");
|
||||
@ -135,8 +137,12 @@ TX_ATOM(vendorUrl, "vendor-url");
|
||||
TX_ATOM(any, "any");
|
||||
TX_ATOM(ascending, "ascending");
|
||||
TX_ATOM(descending, "descending");
|
||||
TX_ATOM(html, "html");
|
||||
TX_ATOM(lowerFirst, "lower-first");
|
||||
TX_ATOM(multiple, "multiple");
|
||||
TX_ATOM(no, "no");
|
||||
TX_ATOM(single, "single");
|
||||
TX_ATOM(upperFirst, "upper-first");
|
||||
TX_ATOM(xml, "xml");
|
||||
TX_ATOM(yes, "yes");
|
||||
TX_ATOM(_poundDefault, "#default");
|
||||
|
||||
@ -40,9 +40,15 @@
|
||||
#include "txAtoms.h"
|
||||
#include "primitives.h"
|
||||
#include <math.h>
|
||||
#include "Expr.h"
|
||||
#include "ExprResult.h"
|
||||
#include "txXSLTPatterns.h"
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
nsresult txXSLTNumber::createNumber(Element* aNumberElement,
|
||||
ProcessorState* aPs,
|
||||
nsresult txXSLTNumber::createNumber(Expr* aValueExpr, txPattern* aCountPattern,
|
||||
txPattern* aFromPattern, LevelType aLevel,
|
||||
Expr* aGroupSize, Expr* aGroupSeparator,
|
||||
Expr* aFormat, txIEvalContext* aContext,
|
||||
nsAString& aResult)
|
||||
{
|
||||
aResult.Truncate();
|
||||
@ -51,13 +57,15 @@ nsresult txXSLTNumber::createNumber(Element* aNumberElement,
|
||||
// Parse format
|
||||
txList counters;
|
||||
nsAutoString head, tail;
|
||||
rv = getCounters(aNumberElement, aPs, counters, head, tail);
|
||||
rv = getCounters(aGroupSize, aGroupSeparator, aFormat, aContext, counters,
|
||||
head, tail);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Create list of values to format
|
||||
txList values;
|
||||
nsAutoString valueString;
|
||||
rv = getValueList(aNumberElement, aPs, values, valueString);
|
||||
rv = getValueList(aValueExpr, aCountPattern, aFromPattern, aLevel,
|
||||
aContext, values, valueString);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!valueString.IsEmpty()) {
|
||||
@ -99,23 +107,18 @@ nsresult txXSLTNumber::createNumber(Element* aNumberElement,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult txXSLTNumber::getValueList(Element* aNumberElement,
|
||||
ProcessorState* aPs, txList& aValues,
|
||||
nsAString& aValueString)
|
||||
nsresult
|
||||
txXSLTNumber::getValueList(Expr* aValueExpr, txPattern* aCountPattern,
|
||||
txPattern* aFromPattern, LevelType aLevel,
|
||||
txIEvalContext* aContext, txList& aValues,
|
||||
nsAString& aValueString)
|
||||
{
|
||||
aValueString.Truncate();
|
||||
|
||||
// If the value attribute exists then use that
|
||||
if (aNumberElement->hasAttr(txXSLTAtoms::value, kNameSpaceID_None)) {
|
||||
Expr* expr = aPs->getExpr(aNumberElement, ProcessorState::ValueAttr);
|
||||
NS_ENSURE_TRUE(expr, NS_ERROR_FAILURE);
|
||||
|
||||
ExprResult* result = expr->evaluate(aPs->getEvalContext());
|
||||
if (!result) {
|
||||
// XXX error reporting, evaluate failed
|
||||
delete expr;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (aValueExpr) {
|
||||
ExprResult* result = aValueExpr->evaluate(aContext);
|
||||
NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
|
||||
|
||||
double value = result->numberValue();
|
||||
delete result;
|
||||
@ -133,18 +136,13 @@ nsresult txXSLTNumber::getValueList(Element* aNumberElement,
|
||||
|
||||
// Otherwise use count/from/level
|
||||
|
||||
txPattern *countPattern = 0, *fromPattern = 0;
|
||||
txPattern* countPattern = aCountPattern;
|
||||
MBool ownsCountPattern = MB_FALSE;
|
||||
Node* currNode = aPs->getEvalContext()->getContextNode();
|
||||
Node* currNode = aContext->getContextNode();
|
||||
|
||||
// Parse count- and from-attributes
|
||||
|
||||
if (aNumberElement->hasAttr(txXSLTAtoms::count, kNameSpaceID_None)) {
|
||||
countPattern = aPs->getPattern(aNumberElement,
|
||||
ProcessorState::CountAttr);
|
||||
NS_ENSURE_TRUE(countPattern, NS_ERROR_FAILURE);
|
||||
}
|
||||
else {
|
||||
if (!aCountPattern) {
|
||||
ownsCountPattern = MB_TRUE;
|
||||
txNodeTest* nodeTest = 0;
|
||||
switch (currNode->getNodeType()) {
|
||||
@ -201,39 +199,21 @@ nsresult txXSLTNumber::getValueList(Element* aNumberElement,
|
||||
}
|
||||
}
|
||||
|
||||
if (aNumberElement->hasAttr(txXSLTAtoms::from, kNameSpaceID_None)) {
|
||||
fromPattern = aPs->getPattern(aNumberElement,
|
||||
ProcessorState::FromAttr);
|
||||
if (!fromPattern) {
|
||||
// XXX error reporting, parse failed
|
||||
if (ownsCountPattern) {
|
||||
delete countPattern;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Generate list of values depending on the value of the level-attribute
|
||||
|
||||
nsAutoString levelStr;
|
||||
nsCOMPtr<nsIAtom> level;
|
||||
if (aNumberElement->getAttr(txXSLTAtoms::level, kNameSpaceID_None, levelStr)) {
|
||||
level = do_GetAtom(levelStr);
|
||||
}
|
||||
|
||||
// level = "single"
|
||||
if (!level || level == txXSLTAtoms::single) {
|
||||
if (aLevel == eLevelSingle) {
|
||||
Node* node = currNode;
|
||||
while (node) {
|
||||
if (fromPattern && node != currNode &&
|
||||
fromPattern->matches(node, aPs)) {
|
||||
if (aFromPattern && node != currNode &&
|
||||
aFromPattern->matches(node, aContext)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (countPattern->matches(node, aPs)) {
|
||||
if (countPattern->matches(node, aContext)) {
|
||||
aValues.add(NS_INT32_TO_PTR(getSiblingCount(node, countPattern,
|
||||
aPs)));
|
||||
aContext)));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -243,10 +223,10 @@ nsresult txXSLTNumber::getValueList(Element* aNumberElement,
|
||||
// Spec says to only match ancestors that are decendants of the
|
||||
// ancestor that matches the from-pattern, so keep going to make
|
||||
// sure that there is an ancestor that does.
|
||||
if (fromPattern && aValues.getLength()) {
|
||||
if (aFromPattern && aValues.getLength()) {
|
||||
node = node->getXPathParent();
|
||||
while (node) {
|
||||
if (fromPattern->matches(node, aPs)) {
|
||||
if (aFromPattern->matches(node, aContext)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -259,21 +239,21 @@ nsresult txXSLTNumber::getValueList(Element* aNumberElement,
|
||||
}
|
||||
}
|
||||
// level = "multiple"
|
||||
else if (level == txXSLTAtoms::multiple) {
|
||||
else if (aLevel == eLevelMultiple) {
|
||||
// find all ancestor-or-selfs that matches count until...
|
||||
Node* node = currNode;
|
||||
MBool matchedFrom = MB_FALSE;
|
||||
while (node) {
|
||||
if (fromPattern && node != currNode &&
|
||||
fromPattern->matches(node, aPs)) {
|
||||
if (aFromPattern && node != currNode &&
|
||||
aFromPattern->matches(node, aContext)) {
|
||||
//... we find one that matches from
|
||||
matchedFrom = MB_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (countPattern->matches(node, aPs)) {
|
||||
if (countPattern->matches(node, aContext)) {
|
||||
aValues.add(NS_INT32_TO_PTR(getSiblingCount(node, countPattern,
|
||||
aPs)));
|
||||
aContext)));
|
||||
}
|
||||
|
||||
node = node->getXPathParent();
|
||||
@ -282,23 +262,23 @@ nsresult txXSLTNumber::getValueList(Element* aNumberElement,
|
||||
// Spec says to only match ancestors that are decendants of the
|
||||
// ancestor that matches the from-pattern, so if none did then
|
||||
// we shouldn't search anything
|
||||
if (fromPattern && !matchedFrom) {
|
||||
if (aFromPattern && !matchedFrom) {
|
||||
aValues.clear();
|
||||
}
|
||||
}
|
||||
// level = "any"
|
||||
else if (level == txXSLTAtoms::any) {
|
||||
else if (aLevel == eLevelAny) {
|
||||
Node* node = currNode;
|
||||
PRInt32 value = 0;
|
||||
MBool matchedFrom = MB_FALSE;
|
||||
while (node) {
|
||||
if (fromPattern && node != currNode &&
|
||||
fromPattern->matches(node, aPs)) {
|
||||
if (aFromPattern && node != currNode &&
|
||||
aFromPattern->matches(node, aContext)) {
|
||||
matchedFrom = MB_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (countPattern->matches(node, aPs)) {
|
||||
if (countPattern->matches(node, aContext)) {
|
||||
++value;
|
||||
}
|
||||
|
||||
@ -308,7 +288,7 @@ nsresult txXSLTNumber::getValueList(Element* aNumberElement,
|
||||
// Spec says to only count nodes that follows the first node that
|
||||
// matches the from pattern. So so if none did then we shouldn't
|
||||
// count any
|
||||
if (fromPattern && !matchedFrom) {
|
||||
if (aFromPattern && !matchedFrom) {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
@ -316,10 +296,6 @@ nsresult txXSLTNumber::getValueList(Element* aNumberElement,
|
||||
aValues.add(NS_INT32_TO_PTR(value));
|
||||
}
|
||||
}
|
||||
else {
|
||||
aPs->receiveError(NS_LITERAL_STRING("unknown value for format attribute"),
|
||||
NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
if (ownsCountPattern) {
|
||||
delete countPattern;
|
||||
@ -330,35 +306,46 @@ nsresult txXSLTNumber::getValueList(Element* aNumberElement,
|
||||
|
||||
|
||||
nsresult
|
||||
txXSLTNumber::getCounters(Element* aNumberElement, ProcessorState* aPs,
|
||||
txList& aCounters, nsAString& aHead, nsAString& aTail)
|
||||
txXSLTNumber::getCounters(Expr* aGroupSize, Expr* aGroupSeparator,
|
||||
Expr* aFormat, txIEvalContext* aContext,
|
||||
txList& aCounters, nsAString& aHead,
|
||||
nsAString& aTail)
|
||||
{
|
||||
aHead.Truncate();
|
||||
aTail.Truncate();
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsAutoString groupSizeStrAVT, groupSeparatorAVT, groupSizeStr, groupSeparator;
|
||||
nsAutoString groupSeparator;
|
||||
PRInt32 groupSize = 0;
|
||||
if (aNumberElement->getAttr(txXSLTAtoms::groupingSeparator,
|
||||
kNameSpaceID_None, groupSeparatorAVT) &&
|
||||
aNumberElement->getAttr(txXSLTAtoms::groupingSize,
|
||||
kNameSpaceID_None, groupSizeStrAVT)) {
|
||||
aPs->processAttrValueTemplate(groupSeparatorAVT, aNumberElement,
|
||||
groupSeparator);
|
||||
aPs->processAttrValueTemplate(groupSizeStrAVT, aNumberElement,
|
||||
groupSizeStr);
|
||||
double size = Double::toDouble(groupSizeStr);
|
||||
if (aGroupSize && aGroupSeparator) {
|
||||
ExprResult* sizeRes = aGroupSize->evaluate(aContext);
|
||||
NS_ENSURE_TRUE(sizeRes, NS_ERROR_FAILURE);
|
||||
|
||||
nsAutoString sizeStr;
|
||||
sizeRes->stringValue(sizeStr);
|
||||
delete sizeRes;
|
||||
|
||||
double size = Double::toDouble(sizeStr);
|
||||
groupSize = (PRInt32)size;
|
||||
if ((double)groupSize != size) {
|
||||
groupSize = 0;
|
||||
}
|
||||
|
||||
ExprResult* sepRes = aGroupSeparator->evaluate(aContext);
|
||||
NS_ENSURE_TRUE(sepRes, NS_ERROR_FAILURE);
|
||||
|
||||
sepRes->stringValue(groupSeparator);
|
||||
delete sepRes;
|
||||
}
|
||||
|
||||
nsAutoString formatAVT, format;
|
||||
if (aNumberElement->getAttr(txXSLTAtoms::format, kNameSpaceID_None,
|
||||
formatAVT)) {
|
||||
aPs->processAttrValueTemplate(formatAVT, aNumberElement, format);
|
||||
nsAutoString format;
|
||||
if (aFormat) {
|
||||
ExprResult* formatRes = aFormat->evaluate(aContext);
|
||||
NS_ENSURE_TRUE(formatRes, NS_ERROR_FAILURE);
|
||||
|
||||
formatRes->stringValue(format);
|
||||
delete formatRes;
|
||||
}
|
||||
PRUint32 formatLen = format.Length();
|
||||
PRUint32 formatPos = 0;
|
||||
|
||||
@ -39,21 +39,40 @@
|
||||
#ifndef TRANSFRMX_TXXSLTNUMBER_H
|
||||
#define TRANSFRMX_TXXSLTNUMBER_H
|
||||
|
||||
#include "ProcessorState.h"
|
||||
#include "txError.h"
|
||||
#include "List.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class Expr;
|
||||
class Node;
|
||||
class txPattern;
|
||||
class txIEvalContext;
|
||||
class txIMatchContext;
|
||||
|
||||
class txXSLTNumber {
|
||||
|
||||
public:
|
||||
static nsresult createNumber(Element* aNumberElement, ProcessorState* aPs,
|
||||
nsAString& aResult);
|
||||
private:
|
||||
static nsresult getValueList(Element* aNumberElement, ProcessorState* aPs,
|
||||
txList& aValues, nsAString& aValueString);
|
||||
enum LevelType {
|
||||
eLevelSingle,
|
||||
eLevelMultiple,
|
||||
eLevelAny
|
||||
};
|
||||
|
||||
static nsresult getCounters(Element* aNumberElement, ProcessorState* aPs,
|
||||
txList& aCounters,
|
||||
nsAString& aHead, nsAString& aTail);
|
||||
static nsresult createNumber(Expr* aValueExpr, txPattern* aCountPattern,
|
||||
txPattern* aFromPattern, LevelType aLevel,
|
||||
Expr* aGroupSize, Expr* aGroupSeparator,
|
||||
Expr* aFormat, txIEvalContext* aContext,
|
||||
nsAString& aResult);
|
||||
|
||||
private:
|
||||
static nsresult getValueList(Expr* aValueExpr, txPattern* aCountPattern,
|
||||
txPattern* aFromPattern, LevelType aLevel,
|
||||
txIEvalContext* aContext, txList& aValues,
|
||||
nsAString& aValueString);
|
||||
|
||||
static nsresult getCounters(Expr* aGroupSize, Expr* aGroupSeparator,
|
||||
Expr* aFormat, txIEvalContext* aContext,
|
||||
txList& aCounters, nsAString& aHead,
|
||||
nsAString& aTail);
|
||||
|
||||
static PRInt32 getSiblingCount(Node* aNode, txPattern* aCountPattern,
|
||||
txIMatchContext* aContext);
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsReadableUtils.h"
|
||||
#include "ProcessorState.h"
|
||||
#include "txExecutionState.h"
|
||||
#include "txXSLTPatterns.h"
|
||||
#include "txNodeSetContext.h"
|
||||
#include "txForwardContext.h"
|
||||
@ -412,15 +412,15 @@ txKeyPattern::~txKeyPattern()
|
||||
|
||||
MBool txKeyPattern::matches(Node* aNode, txIMatchContext* aContext)
|
||||
{
|
||||
txExecutionState* es = (txExecutionState*)aContext->getPrivateContext();
|
||||
Document* contextDoc;
|
||||
if (aNode->getNodeType() == Node::DOCUMENT_NODE)
|
||||
contextDoc = (Document*)aNode;
|
||||
else
|
||||
contextDoc = aNode->getOwnerDocument();
|
||||
const NodeSet* nodes = 0;
|
||||
nsresult rv = mProcessorState->getKeyNodes(mName, contextDoc, mValue,
|
||||
PR_TRUE, &nodes);
|
||||
if (NS_FAILED(rv) || !nodes || nodes->isEmpty())
|
||||
nsresult rv = es->getKeyNodes(mName, contextDoc, mValue, PR_TRUE, &nodes);
|
||||
if (NS_FAILED(rv) || !nodes)
|
||||
return MB_FALSE;
|
||||
MBool isTrue = nodes->contains(aNode);
|
||||
return isTrue;
|
||||
|
||||
@ -174,10 +174,9 @@ private:
|
||||
class txKeyPattern : public txPattern
|
||||
{
|
||||
public:
|
||||
txKeyPattern(ProcessorState* aPs, nsIAtom* aPrefix, nsIAtom* aLocalName,
|
||||
txKeyPattern(nsIAtom* aPrefix, nsIAtom* aLocalName,
|
||||
PRInt32 aNSID, const nsAString& aValue)
|
||||
: mProcessorState(aPs), mName(aNSID, aLocalName), mPrefix(aPrefix),
|
||||
mValue(aValue)
|
||||
: mName(aNSID, aLocalName), mPrefix(aPrefix), mValue(aValue)
|
||||
{
|
||||
}
|
||||
|
||||
@ -186,7 +185,6 @@ public:
|
||||
TX_DECL_PATTERN;
|
||||
|
||||
private:
|
||||
ProcessorState* mProcessorState;
|
||||
txExpandedName mName;
|
||||
nsIAtom* mPrefix;
|
||||
nsString mValue;
|
||||
|
||||
113
mozilla/extensions/transformiix/source/xslt/txXSLTProcessor.cpp
Normal file
113
mozilla/extensions/transformiix/source/xslt/txXSLTProcessor.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
/* -*- 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
|
||||
* Jonas Sicking.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* Jonas Sicking. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking <jonas@sicking.cc>
|
||||
*
|
||||
* 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 "txXSLTProcessor.h"
|
||||
#include "txInstructions.h"
|
||||
#include "txAtoms.h"
|
||||
#include "TxLog.h"
|
||||
#include "txStylesheetCompileHandlers.h"
|
||||
#include "txExecutionState.h"
|
||||
#ifdef TX_EXE
|
||||
#include "txHTMLOutput.h"
|
||||
#endif
|
||||
|
||||
TX_LG_IMPL;
|
||||
|
||||
/* static */
|
||||
MBool
|
||||
txXSLTProcessor::init()
|
||||
{
|
||||
TX_LG_CREATE;
|
||||
|
||||
#ifdef TX_EXE
|
||||
if (!txNamespaceManager::init())
|
||||
return MB_FALSE;
|
||||
|
||||
if (NS_FAILED(txHTMLOutput::init())) {
|
||||
return MB_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!txHTMLAtoms::init())
|
||||
return MB_FALSE;
|
||||
if (!txXMLAtoms::init())
|
||||
return MB_FALSE;
|
||||
if (!txXPathAtoms::init())
|
||||
return MB_FALSE;
|
||||
if (!txXSLTAtoms::init())
|
||||
return MB_FALSE;
|
||||
|
||||
if (!txHandlerTable::init())
|
||||
return MB_FALSE;
|
||||
|
||||
return MB_TRUE;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
txXSLTProcessor::shutdown()
|
||||
{
|
||||
#ifdef TX_EXE
|
||||
txNamespaceManager::shutdown();
|
||||
txHTMLOutput::shutdown();
|
||||
#endif
|
||||
|
||||
txHTMLAtoms::shutdown();
|
||||
txXMLAtoms::shutdown();
|
||||
txXPathAtoms::shutdown();
|
||||
txXSLTAtoms::shutdown();
|
||||
|
||||
txHandlerTable::shutdown();
|
||||
|
||||
TX_LG_DELETE;
|
||||
}
|
||||
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
txXSLTProcessor::execute(txExecutionState& aEs)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
txInstruction* instr;
|
||||
while ((instr = aEs.getNextInstruction())) {
|
||||
rv = instr->execute(aEs);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
/* -*- 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
|
||||
* Jonas Sicking.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* Jonas Sicking. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking <jonas@sicking.cc>
|
||||
*
|
||||
* 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_TXXSLTPROCESSOR_H
|
||||
#define TRANSFRMX_TXXSLTPROCESSOR_H
|
||||
|
||||
#include "txExecutionState.h"
|
||||
|
||||
class txXSLTProcessor
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initialisation and shutdown routines. Initilizes and cleansup all
|
||||
* dependant classes
|
||||
*/
|
||||
static MBool init();
|
||||
static void shutdown();
|
||||
|
||||
|
||||
static nsresult execute(txExecutionState& aEs);
|
||||
|
||||
// once we want to have interuption we should probably have functions for
|
||||
// running X number of steps or running until a condition is true.
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -38,11 +38,14 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "txNodeSorter.h"
|
||||
#include "ProcessorState.h"
|
||||
#include "txExecutionState.h"
|
||||
#include "txXPathResultComparator.h"
|
||||
#include "txAtoms.h"
|
||||
#include "txForwardContext.h"
|
||||
#include "ExprResult.h"
|
||||
#include "Expr.h"
|
||||
#include "txStringUtils.h"
|
||||
#include "NodeSet.h"
|
||||
|
||||
/*
|
||||
* Sorts Nodes as specified by the W3C XSLT 1.0 Recommendation
|
||||
@ -50,9 +53,7 @@
|
||||
|
||||
#define DEFAULT_LANG NS_LITERAL_STRING("en")
|
||||
|
||||
txNodeSorter::txNodeSorter(ProcessorState* aPs) : mPs(aPs),
|
||||
mNKeys(0),
|
||||
mDefaultExpr(0)
|
||||
txNodeSorter::txNodeSorter() : mNKeys(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -64,107 +65,116 @@ txNodeSorter::~txNodeSorter()
|
||||
delete key->mComparator;
|
||||
delete key;
|
||||
}
|
||||
delete mDefaultExpr;
|
||||
}
|
||||
|
||||
MBool txNodeSorter::addSortElement(Element* aSortElement)
|
||||
nsresult
|
||||
txNodeSorter::addSortElement(Expr* aSelectExpr, Expr* aLangExpr,
|
||||
Expr* aDataTypeExpr, Expr* aOrderExpr,
|
||||
Expr* aCaseOrderExpr, txIEvalContext* aContext)
|
||||
{
|
||||
SortKey* key = new SortKey;
|
||||
if (!key) {
|
||||
// XXX ErrorReport: out of memory
|
||||
return MB_FALSE;
|
||||
}
|
||||
|
||||
// Get common attributes
|
||||
nsAutoString attrValue;
|
||||
NS_ENSURE_TRUE(key, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// Select
|
||||
if (aSortElement->hasAttr(txXSLTAtoms::select, kNameSpaceID_None))
|
||||
key->mExpr = mPs->getExpr(aSortElement, ProcessorState::SelectAttr);
|
||||
else {
|
||||
if (!mDefaultExpr) {
|
||||
txNodeTest* test = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE);
|
||||
mDefaultExpr = new LocationStep(test, LocationStep::SELF_AXIS);
|
||||
}
|
||||
key->mExpr = mDefaultExpr;
|
||||
}
|
||||
|
||||
if (!key->mExpr) {
|
||||
// XXX ErrorReport: Out of memory
|
||||
delete key;
|
||||
return MB_FALSE;
|
||||
}
|
||||
key->mExpr = aSelectExpr;
|
||||
|
||||
// Order
|
||||
MBool ascending;
|
||||
MBool hasAttr = getAttrAsAVT(aSortElement, txXSLTAtoms::order, attrValue);
|
||||
if (!hasAttr || TX_StringEqualsAtom(attrValue, txXSLTAtoms::ascending)) {
|
||||
ascending = MB_TRUE;
|
||||
}
|
||||
else if (TX_StringEqualsAtom(attrValue, txXSLTAtoms::descending)) {
|
||||
ascending = MB_FALSE;
|
||||
}
|
||||
else {
|
||||
delete key;
|
||||
// XXX ErrorReport: unknown value for order attribute
|
||||
return MB_FALSE;
|
||||
MBool ascending = MB_TRUE;
|
||||
if (aOrderExpr) {
|
||||
ExprResult* exprRes = aOrderExpr->evaluate(aContext);
|
||||
NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE);
|
||||
|
||||
nsAutoString attrValue;
|
||||
exprRes->stringValue(attrValue);
|
||||
delete exprRes;
|
||||
|
||||
if (TX_StringEqualsAtom(attrValue, txXSLTAtoms::descending)) {
|
||||
ascending = MB_FALSE;
|
||||
}
|
||||
else if (!TX_StringEqualsAtom(attrValue, txXSLTAtoms::ascending)) {
|
||||
delete key;
|
||||
// XXX ErrorReport: unknown value for order attribute
|
||||
return NS_ERROR_XSLT_BAD_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Create comparator depending on datatype
|
||||
nsAutoString dataType;
|
||||
hasAttr = getAttrAsAVT(aSortElement, txXSLTAtoms::dataType, dataType);
|
||||
if (!hasAttr || TX_StringEqualsAtom(dataType, txXSLTAtoms::text)) {
|
||||
if (aDataTypeExpr) {
|
||||
ExprResult* exprRes = aDataTypeExpr->evaluate(aContext);
|
||||
NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE);
|
||||
|
||||
exprRes->stringValue(dataType);
|
||||
delete exprRes;
|
||||
}
|
||||
|
||||
if (!aDataTypeExpr || TX_StringEqualsAtom(dataType, txXSLTAtoms::text)) {
|
||||
// Text comparator
|
||||
|
||||
// Language
|
||||
nsAutoString lang;
|
||||
if (!getAttrAsAVT(aSortElement, txXSLTAtoms::lang, lang))
|
||||
lang.Append(DEFAULT_LANG);
|
||||
if (aLangExpr) {
|
||||
ExprResult* exprRes = aLangExpr->evaluate(aContext);
|
||||
NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE);
|
||||
|
||||
// Case-order
|
||||
MBool upperFirst;
|
||||
hasAttr = getAttrAsAVT(aSortElement, txXSLTAtoms::caseOrder, attrValue);
|
||||
if (!hasAttr || TX_StringEqualsAtom(attrValue,
|
||||
txXSLTAtoms::upperFirst)) {
|
||||
upperFirst = MB_TRUE;
|
||||
}
|
||||
else if (TX_StringEqualsAtom(attrValue, txXSLTAtoms::lowerFirst)) {
|
||||
upperFirst = MB_FALSE;
|
||||
exprRes->stringValue(lang);
|
||||
delete exprRes;
|
||||
}
|
||||
else {
|
||||
// XXX ErrorReport: unknown value for case-order attribute
|
||||
delete key;
|
||||
return MB_FALSE;
|
||||
lang.Append(DEFAULT_LANG);
|
||||
}
|
||||
|
||||
// Case-order
|
||||
|
||||
|
||||
MBool upperFirst = MB_TRUE;
|
||||
if (aCaseOrderExpr) {
|
||||
ExprResult* exprRes = aCaseOrderExpr->evaluate(aContext);
|
||||
NS_ENSURE_TRUE(exprRes, NS_ERROR_FAILURE);
|
||||
|
||||
nsAutoString attrValue;
|
||||
exprRes->stringValue(attrValue);
|
||||
delete exprRes;
|
||||
|
||||
if (TX_StringEqualsAtom(attrValue, txXSLTAtoms::lowerFirst)) {
|
||||
upperFirst = MB_FALSE;
|
||||
}
|
||||
else if (!TX_StringEqualsAtom(attrValue,
|
||||
txXSLTAtoms::upperFirst)) {
|
||||
delete key;
|
||||
// XXX ErrorReport: unknown value for case-order attribute
|
||||
return NS_ERROR_XSLT_BAD_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
key->mComparator = new txResultStringComparator(ascending,
|
||||
upperFirst,
|
||||
lang);
|
||||
NS_ENSURE_TRUE(key->mComparator, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
else if (TX_StringEqualsAtom(dataType, txXSLTAtoms::number)) {
|
||||
// Number comparator
|
||||
key->mComparator = new txResultNumberComparator(ascending);
|
||||
NS_ENSURE_TRUE(key->mComparator, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
else {
|
||||
// XXX ErrorReport: unknown data-type
|
||||
return MB_FALSE;
|
||||
}
|
||||
delete key;
|
||||
|
||||
if (!key->mComparator) {
|
||||
// XXX ErrorReport: out of memory
|
||||
return MB_FALSE;
|
||||
return NS_ERROR_XSLT_BAD_VALUE;
|
||||
}
|
||||
|
||||
mSortKeys.add(key);
|
||||
mNKeys++;
|
||||
return MB_TRUE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MBool txNodeSorter::sortNodeSet(NodeSet* aNodes)
|
||||
nsresult txNodeSorter::sortNodeSet(NodeSet* aNodes, txExecutionState* aEs)
|
||||
{
|
||||
if (mNKeys == 0)
|
||||
return MB_TRUE;
|
||||
return NS_OK;
|
||||
|
||||
txList sortedNodes;
|
||||
txListIterator iter(&sortedNodes);
|
||||
@ -183,11 +193,11 @@ MBool txNodeSorter::sortNodeSet(NodeSet* aNodes)
|
||||
sNode->clear(mNKeys);
|
||||
delete sNode;
|
||||
}
|
||||
return MB_FALSE;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
iter.reset();
|
||||
SortableNode* compNode = (SortableNode*)iter.next();
|
||||
while (compNode && (compareNodes(currNode, compNode, aNodes) > 0)) {
|
||||
while (compNode && (compareNodes(currNode, compNode, aNodes, aEs) > 0)) {
|
||||
compNode = (SortableNode*)iter.next();
|
||||
}
|
||||
// ... and insert in sorted list
|
||||
@ -206,12 +216,13 @@ MBool txNodeSorter::sortNodeSet(NodeSet* aNodes)
|
||||
delete sNode;
|
||||
}
|
||||
|
||||
return MB_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int txNodeSorter::compareNodes(SortableNode* aSNode1,
|
||||
SortableNode* aSNode2,
|
||||
NodeSet* aNodes)
|
||||
NodeSet* aNodes,
|
||||
txExecutionState* aEs)
|
||||
{
|
||||
txListIterator iter(&mSortKeys);
|
||||
int i;
|
||||
@ -221,10 +232,10 @@ int txNodeSorter::compareNodes(SortableNode* aSNode1,
|
||||
SortKey* key = (SortKey*)iter.next();
|
||||
// Lazy create sort values
|
||||
if (!aSNode1->mSortValues[i]) {
|
||||
txForwardContext evalContext(mPs, aSNode1->mNode, aNodes);
|
||||
txIEvalContext* priorEC = mPs->setEvalContext(&evalContext);
|
||||
txForwardContext evalContext(aEs->getEvalContext(), aSNode1->mNode, aNodes);
|
||||
aEs->pushEvalContext(&evalContext);
|
||||
ExprResult* res = key->mExpr->evaluate(&evalContext);
|
||||
mPs->setEvalContext(priorEC);
|
||||
aEs->popEvalContext();
|
||||
if (!res) {
|
||||
// XXX ErrorReport
|
||||
return -1;
|
||||
@ -237,10 +248,10 @@ int txNodeSorter::compareNodes(SortableNode* aSNode1,
|
||||
delete res;
|
||||
}
|
||||
if (!aSNode2->mSortValues[i]) {
|
||||
txForwardContext evalContext(mPs, aSNode2->mNode, aNodes);
|
||||
txIEvalContext* priorEC = mPs->setEvalContext(&evalContext);
|
||||
txForwardContext evalContext(aEs->getEvalContext(), aSNode2->mNode, aNodes);
|
||||
aEs->pushEvalContext(&evalContext);
|
||||
ExprResult* res = key->mExpr->evaluate(&evalContext);
|
||||
mPs->setEvalContext(priorEC);
|
||||
aEs->popEvalContext();
|
||||
if (!res) {
|
||||
// XXX ErrorReport
|
||||
return -1;
|
||||
@ -263,20 +274,6 @@ int txNodeSorter::compareNodes(SortableNode* aSNode1,
|
||||
return 0;
|
||||
}
|
||||
|
||||
MBool txNodeSorter::getAttrAsAVT(Element* aSortElement,
|
||||
nsIAtom* aAttrName,
|
||||
nsAString& aResult)
|
||||
{
|
||||
aResult.Truncate();
|
||||
|
||||
nsAutoString attValue;
|
||||
if (!aSortElement->getAttr(aAttrName, kNameSpaceID_None, attValue))
|
||||
return MB_FALSE;
|
||||
|
||||
mPs->processAttrValueTemplate(attValue, aSortElement, aResult);
|
||||
return MB_TRUE;
|
||||
}
|
||||
|
||||
txNodeSorter::SortableNode::SortableNode(Node* aNode, int aNValues)
|
||||
{
|
||||
mNode = aNode;
|
||||
|
||||
@ -48,9 +48,10 @@ class Element;
|
||||
class Expr;
|
||||
class Node;
|
||||
class NodeSet;
|
||||
class ProcessorState;
|
||||
class txExecutionState;
|
||||
class TxObject;
|
||||
class txXPathResultComparator;
|
||||
class txIEvalContext;
|
||||
|
||||
/*
|
||||
* Sorts Nodes as specified by the W3C XSLT 1.0 Recommendation
|
||||
@ -59,11 +60,13 @@ class txXPathResultComparator;
|
||||
class txNodeSorter
|
||||
{
|
||||
public:
|
||||
txNodeSorter(ProcessorState* aPs);
|
||||
txNodeSorter();
|
||||
~txNodeSorter();
|
||||
|
||||
MBool addSortElement(Element* aSortElement);
|
||||
MBool sortNodeSet(NodeSet* aNodes);
|
||||
nsresult addSortElement(Expr* aSelectExpr, Expr* aLangExpr,
|
||||
Expr* aDataTypeExpr, Expr* aOrderExpr,
|
||||
Expr* aCaseOrderExpr, txIEvalContext* aContext);
|
||||
nsresult sortNodeSet(NodeSet* aNodes, txExecutionState* aEs);
|
||||
|
||||
private:
|
||||
class SortableNode
|
||||
@ -82,16 +85,15 @@ private:
|
||||
|
||||
int compareNodes(SortableNode* sNode1,
|
||||
SortableNode* sNode2,
|
||||
NodeSet* aNodes);
|
||||
NodeSet* aNodes,
|
||||
txExecutionState* aEs);
|
||||
|
||||
MBool getAttrAsAVT(Element* aSortElement,
|
||||
nsIAtom* aAttrName,
|
||||
nsAString& aResult);
|
||||
|
||||
txList mSortKeys;
|
||||
ProcessorState* mPs;
|
||||
int mNKeys;
|
||||
Expr* mDefaultExpr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -96,7 +96,6 @@ SHARED_LIBRARY_LIBS = \
|
||||
$(DIST)/lib/$(LIB_PREFIX)gkconhtmlstyle_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)gkconxmlcon_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)gkconxmldoc_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)gkconxsldoc_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)gkconxbl_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)gkconxuldoc_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)gkconshared_s.$(LIB_SUFFIX) \
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user