diff --git a/mozilla/content/html/content/src/nsHTMLAtomList.h b/mozilla/content/html/content/src/nsHTMLAtomList.h
index bce521e3155..ee24e6932dc 100644
--- a/mozilla/content/html/content/src/nsHTMLAtomList.h
+++ b/mozilla/content/html/content/src/nsHTMLAtomList.h
@@ -213,6 +213,7 @@ HTML_ATOM(msthemecompatible, "msthemecompatible")
HTML_ATOM(multicol, "multicol")
HTML_ATOM(multiple, "multiple")
HTML_ATOM(name, "name")
+HTML_ATOM(_namespace, "namespace")
HTML_ATOM(noembed, "noembed")
HTML_ATOM(noframes, "noframes")
HTML_ATOM(nohref, "nohref")
@@ -234,6 +235,7 @@ HTML_ATOM(phase, "phase") //XML Events
HTML_ATOM(plaintext, "plaintext")
HTML_ATOM(pointSize, "point-size")
HTML_ATOM(pre, "pre")
+HTML_ATOM(prefix, "prefix")
HTML_ATOM(profile, "profile")
HTML_ATOM(prompt, "prompt")
HTML_ATOM(propagate, "propagate") //XML Events
diff --git a/mozilla/content/xml/document/src/nsXMLContentSink.cpp b/mozilla/content/xml/document/src/nsXMLContentSink.cpp
index d490b4b569e..eab41385c47 100644
--- a/mozilla/content/xml/document/src/nsXMLContentSink.cpp
+++ b/mozilla/content/xml/document/src/nsXMLContentSink.cpp
@@ -96,6 +96,7 @@
#include "nsContentCreatorFunctions.h"
#include "nsIContentPolicy.h"
#include "nsContentPolicyUtils.h"
+#include "nsIDOMProcessingInstruction.h"
#ifdef MOZ_SVG
#include "nsSVGAtoms.h"
@@ -230,6 +231,50 @@ nsXMLContentSink::MaybePrettyPrint()
return printer->PrettyPrint(mDocument);
}
+static void
+CheckXSLTParamPI(nsIDOMProcessingInstruction* aPi,
+ nsIDocumentTransformer* aProcessor,
+ nsIDocument* aDocument)
+{
+ nsAutoString target, data;
+ aPi->GetTarget(target);
+
+ nsCOMPtr proc = do_QueryInterface(aProcessor);
+
+ // Check for namespace declarations
+ if (target.EqualsLiteral("xslt-param-namespace")) {
+ aPi->GetData(data);
+ nsAutoString prefix, namespaceAttr;
+ nsParserUtils::GetQuotedAttributeValue(data, nsHTMLAtoms::prefix,
+ prefix);
+ if (!prefix.IsEmpty() &&
+ nsParserUtils::GetQuotedAttributeValue(data, nsHTMLAtoms::_namespace,
+ namespaceAttr)) {
+ proc->AddXSLTParamNamespace(prefix, namespaceAttr);
+ }
+ }
+
+ // Check for actual parameters
+ else if (target.EqualsLiteral("xslt-param")) {
+ aPi->GetData(data);
+ nsAutoString name, namespaceAttr, select, value;
+ nsParserUtils::GetQuotedAttributeValue(data, nsHTMLAtoms::name,
+ name);
+ nsParserUtils::GetQuotedAttributeValue(data, nsHTMLAtoms::_namespace,
+ namespaceAttr);
+ if (!nsParserUtils::GetQuotedAttributeValue(data, nsHTMLAtoms::select, select)) {
+ select.SetIsVoid(PR_TRUE);
+ }
+ if (!nsParserUtils::GetQuotedAttributeValue(data, nsHTMLAtoms::value, value)) {
+ value.SetIsVoid(PR_TRUE);
+ }
+ if (!name.IsEmpty()) {
+ nsCOMPtr doc = do_QueryInterface(aDocument);
+ proc->AddXSLTParam(name, namespaceAttr, select, value, doc);
+ }
+ }
+}
+
NS_IMETHODIMP
nsXMLContentSink::DidBuildModel()
{
@@ -239,6 +284,21 @@ nsXMLContentSink::DidBuildModel()
}
if (mXSLTProcessor) {
+
+ // Check for xslt-param and xslt-param-namespace PIs
+ PRUint32 i;
+ nsIContent* child;
+ for (i = 0; (child = mDocument->GetChildAt(i)); ++i) {
+ if (child->IsContentOfType(nsIContent::ePROCESSING_INSTRUCTION)) {
+ nsCOMPtr pi = do_QueryInterface(child);
+ CheckXSLTParamPI(pi, mXSLTProcessor, mDocument);
+ }
+ else if (child->IsContentOfType(nsIContent::eELEMENT)) {
+ // Only honor PIs in the prolog
+ break;
+ }
+ }
+
nsCOMPtr currentDOMDoc(do_QueryInterface(mDocument));
mXSLTProcessor->SetSourceContentModel(currentDOMDoc);
// Since the processor now holds a reference to us we drop our reference
diff --git a/mozilla/content/xsl/public/nsIDocumentTransformer.h b/mozilla/content/xsl/public/nsIDocumentTransformer.h
index fd6646741dc..5018484b53c 100644
--- a/mozilla/content/xsl/public/nsIDocumentTransformer.h
+++ b/mozilla/content/xsl/public/nsIDocumentTransformer.h
@@ -80,4 +80,22 @@ public:
NS_IMETHOD CancelLoads() = 0;
};
+#define NS_IDOCUMENTTRANSFORMER18BRANCH_IID \
+ {0xf361a1c4, 0x6668, 0x4b0f, \
+ { 0x84, 0x77, 0x24, 0x51, 0x65, 0xaa, 0x33, 0xd0 }}
+
+class nsIDocumentTransformer_1_8_BRANCH : public nsISupports
+{
+public:
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_IDOCUMENTTRANSFORMER18BRANCH_IID)
+
+ NS_IMETHOD AddXSLTParamNamespace(const nsString& aPrefix,
+ const nsString& aNamespace) = 0;
+ NS_IMETHOD AddXSLTParam(const nsString& aName,
+ const nsString& aNamespace,
+ const nsString& aValue,
+ const nsString& aSelect,
+ nsIDOMNode* aContextNode) = 0;
+};
+
#endif //nsIDocumentTransformer_h__
diff --git a/mozilla/extensions/transformiix/source/base/txNamespaceMap.cpp b/mozilla/extensions/transformiix/source/base/txNamespaceMap.cpp
index b40871900f3..077cb64d6b9 100644
--- a/mozilla/extensions/transformiix/source/base/txNamespaceMap.cpp
+++ b/mozilla/extensions/transformiix/source/base/txNamespaceMap.cpp
@@ -51,12 +51,24 @@ txNamespaceMap::txNamespaceMap(const txNamespaceMap& aOther)
}
nsresult
-txNamespaceMap::addNamespace(nsIAtom* aPrefix, const nsAString& aNamespaceURI)
+txNamespaceMap::mapNamespace(nsIAtom* aPrefix, const nsAString& aNamespaceURI)
{
- nsIAtom* prefix = aPrefix == txXMLAtoms::_empty ? 0 : aPrefix;
+ nsIAtom* prefix = aPrefix == txXMLAtoms::_empty ? nsnull : aPrefix;
PRInt32 nsId;
- if (!prefix && aNamespaceURI.IsEmpty()) {
+ if (prefix && aNamespaceURI.IsEmpty()) {
+ // Remove the mapping
+ PRInt32 index = mPrefixes.IndexOf(prefix);
+ if (index >= 0) {
+ mPrefixes.RemoveObjectAt(index);
+ mNamespaces.RemoveElementAt(index);
+ }
+
+ return NS_OK;
+ }
+
+ if (aNamespaceURI.IsEmpty()) {
+ // Set default to empty namespace
nsId = kNameSpaceID_None;
}
else {
diff --git a/mozilla/extensions/transformiix/source/base/txNamespaceMap.h b/mozilla/extensions/transformiix/source/base/txNamespaceMap.h
index 040ab8a0bfc..766d709daf4 100644
--- a/mozilla/extensions/transformiix/source/base/txNamespaceMap.h
+++ b/mozilla/extensions/transformiix/source/base/txNamespaceMap.h
@@ -62,7 +62,7 @@ public:
return mRefCnt;
}
- nsresult addNamespace(nsIAtom* aPrefix, const nsAString& aNamespaceURI);
+ nsresult mapNamespace(nsIAtom* aPrefix, const nsAString& aNamespaceURI);
PRInt32 lookupNamespace(nsIAtom* aPrefix);
PRInt32 lookupNamespace(const nsAString& aPrefix);
PRInt32 lookupNamespaceWithDefault(const nsAString& aPrefix);
diff --git a/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp b/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp
index 232aef26598..7ec35e3f88a 100644
--- a/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp
+++ b/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp
@@ -65,6 +65,7 @@
#include "nsIPrincipal.h"
#include "jsapi.h"
#include "nsIEventQueueService.h"
+#include "ExprParser.h"
static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID);
@@ -249,6 +250,7 @@ NS_INTERFACE_MAP_BEGIN(txMozillaXSLTProcessor)
NS_INTERFACE_MAP_ENTRY(nsIXSLTProcessor)
NS_INTERFACE_MAP_ENTRY(nsIXSLTProcessorObsolete)
NS_INTERFACE_MAP_ENTRY(nsIDocumentTransformer)
+ NS_INTERFACE_MAP_ENTRY(nsIDocumentTransformer_1_8_BRANCH)
NS_INTERFACE_MAP_ENTRY(nsIDocumentObserver)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXSLTProcessor)
NS_INTERFACE_MAP_ENTRY_EXTERNAL_DOM_CLASSINFO(XSLTProcessor)
@@ -323,6 +325,153 @@ txMozillaXSLTProcessor::SetSourceContentModel(nsIDOMNode* aSourceDOM)
return NS_OK;
}
+NS_IMETHODIMP
+txMozillaXSLTProcessor::AddXSLTParamNamespace(const nsString& aPrefix,
+ const nsString& aNamespace)
+{
+ nsCOMPtr pre = do_GetAtom(aPrefix);
+ return mParamNamespaceMap.mapNamespace(pre, aNamespace);
+}
+
+
+class txXSLTParamContext : public txIParseContext,
+ public txIEvalContext
+{
+public:
+ txXSLTParamContext(txNamespaceMap *aResolver, txXPathNode& aContext,
+ txResultRecycler* aRecycler)
+ : mResolver(aResolver),
+ mContext(aContext),
+ mRecycler(aRecycler)
+ {
+ }
+
+ // txIParseContext
+ nsresult resolveNamespacePrefix(nsIAtom* aPrefix, PRInt32& aID)
+ {
+ aID = mResolver->lookupNamespace(aPrefix);
+ return aID == kNameSpaceID_Unknown ? NS_ERROR_DOM_NAMESPACE_ERR :
+ NS_OK;
+ }
+ nsresult resolveFunctionCall(nsIAtom* aName, PRInt32 aID,
+ FunctionCall*& aFunction)
+ {
+ return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
+ }
+ PRBool caseInsensitiveNameTests()
+ {
+ return PR_FALSE;
+ }
+ void SetErrorOffset(PRUint32 aOffset)
+ {
+ }
+
+ // txIEvalContext
+ nsresult getVariable(PRInt32 aNamespace, nsIAtom* aLName,
+ txAExprResult*& aResult)
+ {
+ aResult = nsnull;
+ return NS_ERROR_INVALID_ARG;
+ }
+ PRBool isStripSpaceAllowed(const txXPathNode& aNode)
+ {
+ return PR_FALSE;
+ }
+ void* getPrivateContext()
+ {
+ return nsnull;
+ }
+ txResultRecycler* recycler()
+ {
+ return mRecycler;
+ }
+ void receiveError(const nsAString& aMsg, nsresult aRes)
+ {
+ }
+ const txXPathNode& getContextNode()
+ {
+ return mContext;
+ }
+ PRUint32 size()
+ {
+ return 1;
+ }
+ PRUint32 position()
+ {
+ return 1;
+ }
+
+private:
+ txNamespaceMap *mResolver;
+ txXPathNode& mContext;
+ txResultRecycler* mRecycler;
+
+};
+
+
+NS_IMETHODIMP
+txMozillaXSLTProcessor::AddXSLTParam(const nsString& aName,
+ const nsString& aNamespace,
+ const nsString& aSelect,
+ const nsString& aValue,
+ nsIDOMNode* aContext)
+{
+ nsresult rv = NS_OK;
+
+ if (aSelect.IsVoid() == aValue.IsVoid()) {
+ // Ignore if neither or both are specified
+ return NS_ERROR_FAILURE;
+ }
+
+ nsRefPtr value;
+ if (!aSelect.IsVoid()) {
+
+ // Set up context
+ nsAutoPtr contextNode(
+ txXPathNativeNode::createXPathNode(aContext));
+ NS_ENSURE_TRUE(contextNode, NS_ERROR_OUT_OF_MEMORY);
+
+ if (!mRecycler) {
+ mRecycler = new txResultRecycler;
+ NS_ENSURE_TRUE(mRecycler, NS_ERROR_OUT_OF_MEMORY);
+ }
+
+ txXSLTParamContext paramContext(&mParamNamespaceMap, *contextNode,
+ mRecycler);
+
+ // Parse
+ nsAutoPtr expr;
+ rv = txExprParser::createExpr(aSelect, ¶mContext,
+ getter_Transfers(expr));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Evaluate
+ rv = expr->evaluate(¶mContext, getter_AddRefs(value));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ else {
+ value = new StringResult(aValue, nsnull);
+ NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
+ }
+
+ nsCOMPtr name = do_GetAtom(aName);
+ PRInt32 nsId = txNamespaceManager::getNamespaceID(aNamespace);
+ NS_ENSURE_FALSE(nsId == kNameSpaceID_Unknown, NS_ERROR_FAILURE);
+
+ txExpandedName varName(nsId, name);
+ txVariable* var = (txVariable*)mVariables.get(varName);
+ if (var) {
+ var->setValue(value);
+
+ return NS_OK;
+ }
+
+ var = new txVariable(value);
+ NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
+
+ return mVariables.add(varName, var);
+}
+
PR_BEGIN_EXTERN_C
void* PR_CALLBACK
HandleTransformBlockerEvent(PLEvent *aEvent)
diff --git a/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.h b/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.h
index 4c1f3e309db..5d1e4fe519a 100644
--- a/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.h
+++ b/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.h
@@ -52,11 +52,13 @@
#include "nsVoidArray.h"
#include "nsAutoPtr.h"
#include "nsIDocumentObserver.h"
+#include "txNamespaceMap.h"
class nsIURI;
class nsIXMLContentSink;
class nsIDOMNode;
class nsIPrincipal;
+class txResultRecycler;
/* bacd8ad0-552f-11d3-a9f7-000064657374 */
#define TRANSFORMIIX_XSLT_PROCESSOR_CID \
@@ -70,13 +72,17 @@ class nsIPrincipal;
class txVariable : public txIGlobalParameter
{
public:
- txVariable(nsIVariant *aValue) : mValue(aValue),
- mTxValue(nsnull)
+ txVariable(nsIVariant *aValue) : mValue(aValue)
{
+ NS_ASSERTION(aValue, "missing value");
+ }
+ txVariable(txAExprResult* aValue) : mTxValue(aValue)
+ {
+ NS_ASSERTION(aValue, "missing value");
}
nsresult getValue(txAExprResult** aValue)
{
- NS_ASSERTION(mValue, "variablevalue is null");
+ NS_ASSERTION(mValue || mTxValue, "variablevalue is null");
if (!mTxValue) {
nsresult rv = Convert(mValue, getter_AddRefs(mTxValue));
@@ -100,6 +106,12 @@ public:
mValue = aValue;
mTxValue = nsnull;
}
+ void setValue(txAExprResult* aValue)
+ {
+ NS_ASSERTION(aValue, "setting variablevalue to null");
+ mValue = nsnull;
+ mTxValue = aValue;
+ }
private:
static nsresult Convert(nsIVariant *aValue, txAExprResult** aResult);
@@ -114,6 +126,7 @@ private:
class txMozillaXSLTProcessor : public nsIXSLTProcessor,
public nsIXSLTProcessorObsolete,
public nsIDocumentTransformer,
+ public nsIDocumentTransformer_1_8_BRANCH,
public nsIDocumentObserver
{
public:
@@ -142,6 +155,13 @@ public:
nsIPrincipal* aCallerPrincipal);
NS_IMETHOD SetSourceContentModel(nsIDOMNode* aSource);
NS_IMETHOD CancelLoads() {return NS_OK;};
+ NS_IMETHOD AddXSLTParamNamespace(const nsString& aPrefix,
+ const nsString& aNamespace);
+ NS_IMETHOD AddXSLTParam(const nsString& aName,
+ const nsString& aNamespace,
+ const nsString& aSelect,
+ const nsString& aValue,
+ nsIDOMNode* aContext);
// nsIDocumentObserver interface
NS_DECL_NSIDOCUMENTOBSERVER
@@ -173,6 +193,8 @@ private:
nsString mErrorText, mSourceText;
nsCOMPtr mObserver;
txExpandedNameMap mVariables;
+ txNamespaceMap mParamNamespaceMap;
+ nsRefPtr mRecycler;
};
extern nsresult TX_LoadSheet(nsIURI* aUri, txMozillaXSLTProcessor* aProcessor,
diff --git a/mozilla/extensions/transformiix/source/xslt/txStylesheetCompiler.cpp b/mozilla/extensions/transformiix/source/xslt/txStylesheetCompiler.cpp
index 262b9a7c14c..d02d87b1e09 100644
--- a/mozilla/extensions/transformiix/source/xslt/txStylesheetCompiler.cpp
+++ b/mozilla/extensions/transformiix/source/xslt/txStylesheetCompiler.cpp
@@ -129,11 +129,11 @@ txStylesheetCompiler::startElement(PRInt32 aNamespaceID, nsIAtom* aLocalName,
}
if (attr->mLocalName == txXMLAtoms::xmlns) {
- mElementContext->mMappings->addNamespace(nsnull, attr->mValue);
+ mElementContext->mMappings->mapNamespace(nsnull, attr->mValue);
}
else {
mElementContext->mMappings->
- addNamespace(attr->mLocalName, attr->mValue);
+ mapNamespace(attr->mLocalName, attr->mValue);
}
}
}
@@ -193,7 +193,7 @@ txStylesheetCompiler::startElement(const PRUnichar *aName,
}
rv = mElementContext->mMappings->
- addNamespace(prefixToBind, atts[i].mValue);
+ mapNamespace(prefixToBind, atts[i].mValue);
NS_ENSURE_SUCCESS(rv, rv);
}
}