mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Backed out 2 changesets (bug 1444119) for build bustages on dom/xslt/xslt/txEXSLTFunctions.cpp. CLOSED TREE
Backed out changeset bca28a3a066a (bug 1444119) Backed out changeset 3181f8c1a539 (bug 1444119)
This commit is contained in:
parent
3cfefa6e45
commit
c39c079687
@ -9,6 +9,9 @@ with Files("**"):
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'txIEXSLTRegExFunctions.idl',
|
||||
'txIFunctionEvaluationContext.idl',
|
||||
'txINodeSet.idl',
|
||||
'txIXPathObject.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'content_xslt'
|
||||
|
@ -17,5 +17,5 @@
|
||||
[test_bug1135764.html]
|
||||
support-files = file_bug1135764.xml file_bug1135764.xsl
|
||||
[test_bug1436040.html]
|
||||
[test_exslt.html]
|
||||
[test_exslt_regex.html]
|
||||
[test_parameter.html]
|
||||
|
@ -1,249 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test EXSLT extensions
|
||||
http://www.exslt.org/
|
||||
-->
|
||||
<head>
|
||||
<title>Test for EXSLT extensions</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
let tests = [
|
||||
{
|
||||
descr: "Testing common:node-set",
|
||||
expr: "common:node-set($tree)",
|
||||
useCopyOf: true,
|
||||
expResult: "<abc>def</abc>",
|
||||
},
|
||||
{
|
||||
descr: "Testing common:object-type(string)",
|
||||
expr: "common:object-type($string)",
|
||||
expResult: "string",
|
||||
},
|
||||
{
|
||||
descr: "Testing common:object-type(number)",
|
||||
expr: "common:object-type($number)",
|
||||
expResult: "number",
|
||||
},
|
||||
{
|
||||
descr: "Testing common:object-type(boolean)",
|
||||
expr: "common:object-type($boolean)",
|
||||
expResult: "boolean",
|
||||
},
|
||||
{
|
||||
descr: "Testing common:object-type(node-set)",
|
||||
expr: "common:object-type($node-set)",
|
||||
expResult: "node-set",
|
||||
},
|
||||
{
|
||||
descr: "Testing common:object-type(tree)",
|
||||
expr: "common:object-type($tree)",
|
||||
expResult: "RTF",
|
||||
},
|
||||
{
|
||||
descr: "Testing math:max",
|
||||
expr: "math:max(root/numbers/number)",
|
||||
expResult: "11",
|
||||
},
|
||||
{
|
||||
descr: "Testing math:min",
|
||||
expr: "math:min(root/numbers/number)",
|
||||
expResult: "4",
|
||||
},
|
||||
{
|
||||
descr: "Testing math:highest",
|
||||
expr: "math:highest(root/numbers/number)/@id",
|
||||
expResult: "eleven",
|
||||
},
|
||||
{
|
||||
descr: "Testing math:lowest",
|
||||
expr: "math:lowest(root/numbers/number)/@id",
|
||||
expResult: "four",
|
||||
},
|
||||
{
|
||||
descr: "Testing regexp:test",
|
||||
expr: "regexp:test('XSLT is great', 'XSLT', '')",
|
||||
expResult: "true",
|
||||
},
|
||||
{
|
||||
descr: "Testing regexp:match",
|
||||
expr: "regexp:match('XSLT is great', 'XSL.', '')[1]",
|
||||
expResult: "XSLT",
|
||||
},
|
||||
{
|
||||
descr: "Testing regexp:replace",
|
||||
expr: "regexp:replace('Food is great', 'Fo.d', '', 'XSLT')",
|
||||
expResult: "XSLT is great",
|
||||
},
|
||||
{
|
||||
descr: "Testing sets:difference",
|
||||
expr: "sets:difference($i, $e)",
|
||||
useCopyOf: true,
|
||||
expResult: "<city name=\"Paris\" country=\"France\"></city><city name=\"Madrid\" country=\"Spain\"></city><city name=\"Calais\" country=\"France\"></city>",
|
||||
},
|
||||
{
|
||||
descr: "Testing sets:distinct",
|
||||
expr: "strings:concat(sets:distinct(//@country))",
|
||||
expResult: "FranceSpainAustriaGermany",
|
||||
},
|
||||
{
|
||||
descr: "Testing sets:hasSameNode",
|
||||
expr: "sets:has-same-node($i, $e)",
|
||||
expResult: "true",
|
||||
},
|
||||
{
|
||||
descr: "Testing sets:hasSameNode",
|
||||
expr: "sets:has-same-node($i, $o)",
|
||||
expResult: "false",
|
||||
},
|
||||
{
|
||||
descr: "Testing sets:intersection",
|
||||
expr: "sets:intersection($i, $e)",
|
||||
useCopyOf: true,
|
||||
expResult: "<city name=\"Vienna\" country=\"Austria\"></city><city name=\"Berlin\" country=\"Germany\"></city>",
|
||||
},
|
||||
{
|
||||
descr: "Testing sets:leading",
|
||||
expr: "sets:leading($i, $e)",
|
||||
useCopyOf: true,
|
||||
expResult: "<city name=\"Paris\" country=\"France\"></city><city name=\"Madrid\" country=\"Spain\"></city>",
|
||||
},
|
||||
{
|
||||
descr: "Testing sets:leading",
|
||||
expr: "sets:leading($i, $o)",
|
||||
useCopyOf: true,
|
||||
expResult: "",
|
||||
},
|
||||
{
|
||||
descr: "Testing sets:leading",
|
||||
expr: "sets:leading($i, $empty)",
|
||||
useCopyOf: true,
|
||||
expResult: "<city name=\"Paris\" country=\"France\"></city><city name=\"Madrid\" country=\"Spain\"></city><city name=\"Vienna\" country=\"Austria\"></city><city name=\"Calais\" country=\"France\"></city><city name=\"Berlin\" country=\"Germany\"></city>",
|
||||
},
|
||||
{
|
||||
descr: "Testing sets:trailing",
|
||||
expr: "sets:trailing($i, $e)",
|
||||
useCopyOf: true,
|
||||
expResult: "<city name=\"Calais\" country=\"France\"></city><city name=\"Berlin\" country=\"Germany\"></city>",
|
||||
},
|
||||
{
|
||||
descr: "Testing sets:trailing",
|
||||
expr: "sets:trailing($i, $o)",
|
||||
useCopyOf: true,
|
||||
expResult: "",
|
||||
},
|
||||
{
|
||||
descr: "Testing sets:trailing",
|
||||
expr: "sets:trailing($i, $empty)",
|
||||
useCopyOf: true,
|
||||
expResult: "<city name=\"Paris\" country=\"France\"></city><city name=\"Madrid\" country=\"Spain\"></city><city name=\"Vienna\" country=\"Austria\"></city><city name=\"Calais\" country=\"France\"></city><city name=\"Berlin\" country=\"Germany\"></city>",
|
||||
},
|
||||
{
|
||||
descr: "Testing strings:concat",
|
||||
expr: "strings:concat(root/numbers/number/@id)",
|
||||
expResult: "seveneleveneightfour",
|
||||
},
|
||||
{
|
||||
descr: "Testing strings:split",
|
||||
expr: "strings:split('a, simple, list', ', ')",
|
||||
useCopyOf: true,
|
||||
expResult: "<token>a</token><token>simple</token><token>list</token>",
|
||||
},
|
||||
{
|
||||
descr: "Testing strings:split",
|
||||
expr: "strings:split('date math str')",
|
||||
useCopyOf: true,
|
||||
expResult: "<token>date</token><token>math</token><token>str</token>",
|
||||
},
|
||||
{
|
||||
descr: "Testing strings:split",
|
||||
expr: "strings:split('foo', '')",
|
||||
useCopyOf: true,
|
||||
expResult: "<token>f</token><token>o</token><token>o</token>",
|
||||
},
|
||||
{
|
||||
descr: "Testing strings:tokenize",
|
||||
expr: "strings:tokenize('2001-06-03T11:40:23', '-T:')",
|
||||
useCopyOf: true,
|
||||
expResult: "<token>2001</token><token>06</token><token>03</token><token>11</token><token>40</token><token>23</token>",
|
||||
},
|
||||
{
|
||||
descr: "Testing strings:tokenize",
|
||||
expr: "strings:tokenize('date math str')",
|
||||
useCopyOf: true,
|
||||
expResult: "<token>date</token><token>math</token><token>str</token>",
|
||||
},
|
||||
{
|
||||
descr: "Testing strings:tokenize",
|
||||
expr: "strings:tokenize('foo', '')",
|
||||
useCopyOf: true,
|
||||
expResult: "<token>f</token><token>o</token><token>o</token>",
|
||||
},
|
||||
];
|
||||
|
||||
let style =
|
||||
`<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
|
||||
xmlns:common="http://exslt.org/common"
|
||||
xmlns:math="http://exslt.org/math"
|
||||
xmlns:regexp="http://exslt.org/regular-expressions"
|
||||
xmlns:sets="http://exslt.org/sets"
|
||||
xmlns:strings="http://exslt.org/strings">
|
||||
<xsl:output method="html"/>
|
||||
<xsl:variable name="tree"><abc>def</abc></xsl:variable>
|
||||
<xsl:variable name="string" select="'abc'"/>
|
||||
<xsl:variable name="number" select="123"/>
|
||||
<xsl:variable name="boolean" select="true()"/>
|
||||
<xsl:variable name="node-set" select="//*"/>
|
||||
<xsl:variable name="i" select="/root/sets/city[contains(@name, 'i')]" />
|
||||
<xsl:variable name="e" select="/root/sets/city[contains(@name, 'e')]" />
|
||||
<xsl:variable name="o" select="/root/sets/city[contains(@name, 'o')]" />
|
||||
<xsl:variable name="empty" select="/root/sets/city[contains(@name, 'x')]" />
|
||||
<xsl:template match="/">
|
||||
${tests.map(({expr, useCopyOf}, i) => `<div id="${i}"><xsl:${useCopyOf ? "copy-of" : "value-of"} select="${expr}"/></div>`).join("\n")}
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>`;
|
||||
|
||||
let styleDoc = new DOMParser().parseFromString(style, "text/xml");
|
||||
|
||||
let data = `<root>
|
||||
<numbers>
|
||||
<number id="seven">7</number>
|
||||
<number id="eleven">11</number>
|
||||
<number id="eight">8</number>
|
||||
<number id="four">4</number>
|
||||
</numbers>
|
||||
<sets>
|
||||
<city name="Paris" country="France" />
|
||||
<city name="Madrid" country="Spain" />
|
||||
<city name="Vienna" country="Austria" />
|
||||
<city name="Barcelona" country="Spain" />
|
||||
<city name="Salzburg" country="Austria" />
|
||||
<city name="Bonn" country="Germany" />
|
||||
<city name="Lyon" country="France" />
|
||||
<city name="Hannover" country="Germany" />
|
||||
<city name="Calais" country="France" />
|
||||
<city name="Berlin" country="Germany" />
|
||||
</sets>
|
||||
</root>`;
|
||||
let originalDoc = new DOMParser().parseFromString(data, "text/xml");
|
||||
|
||||
let processor = new XSLTProcessor();
|
||||
processor.importStylesheet(styleDoc);
|
||||
|
||||
let fragment = processor.transformToFragment(originalDoc, document);
|
||||
|
||||
tests.forEach(({descr, expResult}, i) => {
|
||||
let result = fragment.getElementById(i);
|
||||
is(result.innerHTML, expResult, descr);
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
60
dom/xslt/tests/mochitest/test_exslt_regex.html
Normal file
60
dom/xslt/tests/mochitest/test_exslt_regex.html
Normal file
@ -0,0 +1,60 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test EXSLT Regular Expression Extension
|
||||
http://www.exslt.org/regexp/index.html
|
||||
-->
|
||||
<head>
|
||||
<title>Test for EXSLT Regular Expression Extensions</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
var tests = [
|
||||
{ descr: "Testing regexp:test",
|
||||
expr: "regexp:test('XSLT is great', 'XSLT', '')",
|
||||
expResult: "true" },
|
||||
|
||||
{ descr: "Testing regexp:match",
|
||||
expr: "regexp:match('XSLT is great', 'XSL.', '')[1]",
|
||||
expResult: "XSLT" },
|
||||
|
||||
{ descr: "Testing regexp:replace",
|
||||
expr: "regexp:replace('Food is great', 'Fo.d', '', 'XSLT')",
|
||||
expResult: "XSLT is great" }
|
||||
];
|
||||
|
||||
for (test of tests) {
|
||||
var style =
|
||||
'<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" ' +
|
||||
'xmlns:regexp="http://exslt.org/regular-expressions" '+
|
||||
'version="1.0">' +
|
||||
'<xsl:output method="html"/>' +
|
||||
'<xsl:template match="/">' +
|
||||
'<xsl:value-of select="'+test.expr+'" /> ' +
|
||||
'</xsl:template>' +
|
||||
'</xsl:stylesheet>';
|
||||
var styleDoc = new DOMParser().parseFromString (style, "text/xml");
|
||||
|
||||
var data = '<root/>';
|
||||
var originalDoc = new DOMParser().parseFromString(data, "text/xml");
|
||||
|
||||
var processor = new XSLTProcessor();
|
||||
processor.importStylesheet(styleDoc);
|
||||
|
||||
var fragment = processor.transformToFragment(originalDoc, document);
|
||||
var content = document.getElementById("content");
|
||||
content.appendChild(fragment);
|
||||
is(content.innerHTML, test.expResult, test.descr);
|
||||
|
||||
content.innerHTML = '';
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -5,17 +5,15 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIDOMDocument;
|
||||
interface nsIDOMDocumentFragment;
|
||||
interface txIFunctionEvaluationContext;
|
||||
interface txINodeSet;
|
||||
|
||||
[scriptable, uuid(c180e993-aced-4839-95a0-ecd5ff138be9)]
|
||||
interface txIEXSLTRegExFunctions : nsISupports
|
||||
{
|
||||
// Make this take Document and return DocumentFragment once https://bugzil.la/1444991
|
||||
// is fixed.
|
||||
nsIDOMDocumentFragment match(in DOMString aString, in DOMString aRegEx,
|
||||
in DOMString aFlags,
|
||||
in nsIDOMDocument aResultDocument);
|
||||
txINodeSet match(in txIFunctionEvaluationContext aContext,
|
||||
in DOMString aString, in DOMString aRegEx,
|
||||
in DOMString aFlags);
|
||||
DOMString replace(in DOMString aString, in DOMString aRegEx,
|
||||
in DOMString aFlags, in DOMString aReplace);
|
||||
boolean test(in DOMString aString, in DOMString aRegEx,
|
||||
|
18
dom/xslt/txIFunctionEvaluationContext.idl
Normal file
18
dom/xslt/txIFunctionEvaluationContext.idl
Normal file
@ -0,0 +1,18 @@
|
||||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIDOMNode;
|
||||
interface txINodeSet;
|
||||
|
||||
[scriptable, uuid(0ecbb00c-6a78-11d9-9791-000a95dc234c)]
|
||||
interface txIFunctionEvaluationContext : nsISupports
|
||||
{
|
||||
readonly attribute uint32_t position;
|
||||
readonly attribute uint32_t size;
|
||||
readonly attribute nsIDOMNode contextNode;
|
||||
readonly attribute nsISupports state;
|
||||
};
|
16
dom/xslt/txINodeSet.idl
Normal file
16
dom/xslt/txINodeSet.idl
Normal file
@ -0,0 +1,16 @@
|
||||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "domstubs.idl"
|
||||
|
||||
[scriptable, uuid(15d424c0-6b47-11d9-9791-000a95dc234c)]
|
||||
interface txINodeSet : nsISupports
|
||||
{
|
||||
nsIDOMNode item(in unsigned long index);
|
||||
double itemAsNumber(in unsigned long index);
|
||||
DOMString itemAsString(in unsigned long index);
|
||||
readonly attribute unsigned long length;
|
||||
void add(in nsIDOMNode node);
|
||||
};
|
18
dom/xslt/txIXPathObject.idl
Normal file
18
dom/xslt/txIXPathObject.idl
Normal file
@ -0,0 +1,18 @@
|
||||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
%{ C++
|
||||
class txAExprResult;
|
||||
%}
|
||||
|
||||
[ptr] native txAExprResultPtr(txAExprResult);
|
||||
|
||||
[scriptable, uuid(67706346-dece-4c9b-9fc2-57cf19071014)]
|
||||
interface txIXPathObject : nsISupports
|
||||
{
|
||||
[noscript, notxpcom] txAExprResultPtr getResult();
|
||||
};
|
@ -27,6 +27,7 @@ UNIFIED_SOURCES += [
|
||||
'txNamedAttributeStep.cpp',
|
||||
'txNameTest.cpp',
|
||||
'txNodeSet.cpp',
|
||||
'txNodeSetAdaptor.cpp',
|
||||
'txNodeSetContext.cpp',
|
||||
'txNodeTypeTest.cpp',
|
||||
'txNumberExpr.cpp',
|
||||
@ -43,6 +44,7 @@ UNIFIED_SOURCES += [
|
||||
'txUnionNodeTest.cpp',
|
||||
'txVariableRefExpr.cpp',
|
||||
'txXPathOptimizer.cpp',
|
||||
'txXPCOMExtensionFunction.cpp',
|
||||
'XPathEvaluator.cpp',
|
||||
'XPathExpression.cpp',
|
||||
'XPathResult.cpp',
|
||||
|
88
dom/xslt/xpath/txNodeSetAdaptor.cpp
Normal file
88
dom/xslt/xpath/txNodeSetAdaptor.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "txNodeSetAdaptor.h"
|
||||
#include "txXPathTreeWalker.h"
|
||||
|
||||
txNodeSetAdaptor::txNodeSetAdaptor()
|
||||
: txXPathObjectAdaptor(),
|
||||
mWritable(true)
|
||||
{
|
||||
}
|
||||
|
||||
txNodeSetAdaptor::txNodeSetAdaptor(txNodeSet *aNodeSet)
|
||||
: txXPathObjectAdaptor(aNodeSet),
|
||||
mWritable(false)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(txNodeSetAdaptor, txXPathObjectAdaptor, txINodeSet)
|
||||
|
||||
nsresult
|
||||
txNodeSetAdaptor::Init()
|
||||
{
|
||||
if (!mValue) {
|
||||
mValue = new txNodeSet(nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
txNodeSetAdaptor::Item(uint32_t aIndex, nsIDOMNode **aResult)
|
||||
{
|
||||
*aResult = nullptr;
|
||||
|
||||
if (aIndex > (uint32_t)NodeSet()->size()) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
return txXPathNativeNode::getNode(NodeSet()->get(aIndex), aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
txNodeSetAdaptor::ItemAsNumber(uint32_t aIndex, double *aResult)
|
||||
{
|
||||
if (aIndex > (uint32_t)NodeSet()->size()) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
nsAutoString result;
|
||||
txXPathNodeUtils::appendNodeValue(NodeSet()->get(aIndex), result);
|
||||
|
||||
*aResult = txDouble::toDouble(result);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
txNodeSetAdaptor::ItemAsString(uint32_t aIndex, nsAString &aResult)
|
||||
{
|
||||
if (aIndex > (uint32_t)NodeSet()->size()) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
txXPathNodeUtils::appendNodeValue(NodeSet()->get(aIndex), aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
txNodeSetAdaptor::GetLength(uint32_t *aLength)
|
||||
{
|
||||
*aLength = (uint32_t)NodeSet()->size();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
txNodeSetAdaptor::Add(nsIDOMNode *aNode)
|
||||
{
|
||||
NS_ENSURE_TRUE(mWritable, NS_ERROR_FAILURE);
|
||||
|
||||
nsAutoPtr<txXPathNode> node(txXPathNativeNode::createXPathNode(aNode,
|
||||
true));
|
||||
|
||||
return node ? NodeSet()->add(*node) : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
41
dom/xslt/xpath/txNodeSetAdaptor.h
Normal file
41
dom/xslt/xpath/txNodeSetAdaptor.h
Normal file
@ -0,0 +1,41 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef txNodeSetAdaptor_h__
|
||||
#define txNodeSetAdaptor_h__
|
||||
|
||||
#include "txINodeSet.h"
|
||||
#include "txNodeSet.h"
|
||||
#include "txXPathObjectAdaptor.h"
|
||||
|
||||
/**
|
||||
* Implements an XPCOM wrapper around an XPath NodeSet.
|
||||
*/
|
||||
|
||||
class txNodeSetAdaptor : public txXPathObjectAdaptor,
|
||||
public txINodeSet
|
||||
{
|
||||
public:
|
||||
txNodeSetAdaptor();
|
||||
explicit txNodeSetAdaptor(txNodeSet* aNodeSet);
|
||||
|
||||
nsresult Init();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_TXINODESET
|
||||
|
||||
protected:
|
||||
~txNodeSetAdaptor() {}
|
||||
|
||||
private:
|
||||
txNodeSet* NodeSet()
|
||||
{
|
||||
return static_cast<txNodeSet*>(mValue.get());
|
||||
}
|
||||
|
||||
bool mWritable;
|
||||
};
|
||||
|
||||
#endif // txNodeSetAdaptor_h__
|
618
dom/xslt/xpath/txXPCOMExtensionFunction.cpp
Normal file
618
dom/xslt/xpath/txXPCOMExtensionFunction.cpp
Normal file
@ -0,0 +1,618 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsDependentString.h"
|
||||
#include "nsAtom.h"
|
||||
#include "nsIInterfaceInfoManager.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "txExpr.h"
|
||||
#include "txIFunctionEvaluationContext.h"
|
||||
#include "txIXPathContext.h"
|
||||
#include "txNodeSetAdaptor.h"
|
||||
#include "txXPathTreeWalker.h"
|
||||
#include "xptcall.h"
|
||||
#include "txXPathObjectAdaptor.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "nsIClassInfo.h"
|
||||
#include "nsIInterfaceInfo.h"
|
||||
#include "js/RootingAPI.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(txXPathObjectAdaptor, txIXPathObject)
|
||||
|
||||
class txFunctionEvaluationContext final : public txIFunctionEvaluationContext
|
||||
{
|
||||
public:
|
||||
txFunctionEvaluationContext(txIEvalContext *aContext, nsISupports *aState);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_TXIFUNCTIONEVALUATIONCONTEXT
|
||||
|
||||
void ClearContext()
|
||||
{
|
||||
mContext = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
~txFunctionEvaluationContext() {}
|
||||
|
||||
txIEvalContext *mContext;
|
||||
nsCOMPtr<nsISupports> mState;
|
||||
};
|
||||
|
||||
txFunctionEvaluationContext::txFunctionEvaluationContext(txIEvalContext *aContext,
|
||||
nsISupports *aState)
|
||||
: mContext(aContext),
|
||||
mState(aState)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(txFunctionEvaluationContext, txIFunctionEvaluationContext)
|
||||
|
||||
NS_IMETHODIMP
|
||||
txFunctionEvaluationContext::GetPosition(uint32_t *aPosition)
|
||||
{
|
||||
NS_ENSURE_TRUE(mContext, NS_ERROR_FAILURE);
|
||||
|
||||
*aPosition = mContext->position();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
txFunctionEvaluationContext::GetSize(uint32_t *aSize)
|
||||
{
|
||||
NS_ENSURE_TRUE(mContext, NS_ERROR_FAILURE);
|
||||
|
||||
*aSize = mContext->size();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
txFunctionEvaluationContext::GetContextNode(nsIDOMNode **aNode)
|
||||
{
|
||||
NS_ENSURE_TRUE(mContext, NS_ERROR_FAILURE);
|
||||
|
||||
return txXPathNativeNode::getNode(mContext->getContextNode(), aNode);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
txFunctionEvaluationContext::GetState(nsISupports **aState)
|
||||
{
|
||||
NS_IF_ADDREF(*aState = mState);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
enum txArgumentType {
|
||||
eBOOLEAN = nsXPTType::T_BOOL,
|
||||
eNUMBER = nsXPTType::T_DOUBLE,
|
||||
eSTRING = nsXPTType::T_DOMSTRING,
|
||||
eNODESET,
|
||||
eCONTEXT,
|
||||
eOBJECT,
|
||||
eUNKNOWN
|
||||
};
|
||||
|
||||
class txXPCOMExtensionFunctionCall : public FunctionCall
|
||||
{
|
||||
public:
|
||||
txXPCOMExtensionFunctionCall(nsISupports *aHelper, const nsIID &aIID,
|
||||
uint16_t aMethodIndex,
|
||||
#ifdef TX_TO_STRING
|
||||
nsAtom *aName,
|
||||
#endif
|
||||
nsISupports *aState);
|
||||
|
||||
TX_DECL_FUNCTION
|
||||
|
||||
private:
|
||||
txArgumentType GetParamType(const nsXPTParamInfo &aParam,
|
||||
nsIInterfaceInfo *aInfo);
|
||||
|
||||
nsCOMPtr<nsISupports> mHelper;
|
||||
nsIID mIID;
|
||||
uint16_t mMethodIndex;
|
||||
#ifdef TX_TO_STRING
|
||||
RefPtr<nsAtom> mName;
|
||||
#endif
|
||||
nsCOMPtr<nsISupports> mState;
|
||||
};
|
||||
|
||||
txXPCOMExtensionFunctionCall::txXPCOMExtensionFunctionCall(nsISupports *aHelper,
|
||||
const nsIID &aIID,
|
||||
uint16_t aMethodIndex,
|
||||
#ifdef TX_TO_STRING
|
||||
nsAtom *aName,
|
||||
#endif
|
||||
nsISupports *aState)
|
||||
: mHelper(aHelper),
|
||||
mIID(aIID),
|
||||
mMethodIndex(aMethodIndex),
|
||||
#ifdef TX_TO_STRING
|
||||
mName(aName),
|
||||
#endif
|
||||
mState(aState)
|
||||
{
|
||||
}
|
||||
|
||||
class txInterfacesArrayHolder
|
||||
{
|
||||
public:
|
||||
txInterfacesArrayHolder(nsIID **aArray, uint32_t aCount) : mArray(aArray),
|
||||
mCount(aCount)
|
||||
{
|
||||
}
|
||||
~txInterfacesArrayHolder()
|
||||
{
|
||||
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(mCount, mArray);
|
||||
}
|
||||
|
||||
private:
|
||||
nsIID **mArray;
|
||||
uint32_t mCount;
|
||||
};
|
||||
|
||||
static nsresult
|
||||
LookupFunction(const char *aContractID, nsAtom* aName, nsIID &aIID,
|
||||
uint16_t &aMethodIndex, nsISupports **aHelper)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISupports> helper = do_GetService(aContractID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIClassInfo> classInfo = do_QueryInterface(helper, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIInterfaceInfoManager> iim =
|
||||
do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(iim, NS_ERROR_FAILURE);
|
||||
|
||||
nsIID** iidArray = nullptr;
|
||||
uint32_t iidCount = 0;
|
||||
rv = classInfo->GetInterfaces(&iidCount, &iidArray);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
txInterfacesArrayHolder holder(iidArray, iidCount);
|
||||
|
||||
// Remove any minus signs and uppercase the following letter (so
|
||||
// foo-bar becomes fooBar). Note that if there are any names that already
|
||||
// have uppercase letters they might cause false matches (both fooBar and
|
||||
// foo-bar matching fooBar).
|
||||
const char16_t *name = aName->GetUTF16String();
|
||||
nsAutoCString methodName;
|
||||
char16_t letter;
|
||||
bool upperNext = false;
|
||||
while ((letter = *name)) {
|
||||
if (letter == '-') {
|
||||
upperNext = true;
|
||||
}
|
||||
else {
|
||||
MOZ_ASSERT(nsCRT::IsAscii(letter),
|
||||
"invalid static_cast coming up");
|
||||
methodName.Append(upperNext ?
|
||||
nsCRT::ToUpper(static_cast<char>(letter)) :
|
||||
letter);
|
||||
upperNext = false;
|
||||
}
|
||||
++name;
|
||||
}
|
||||
|
||||
uint32_t i;
|
||||
for (i = 0; i < iidCount; ++i) {
|
||||
nsIID *iid = iidArray[i];
|
||||
|
||||
nsCOMPtr<nsIInterfaceInfo> info;
|
||||
rv = iim->GetInfoForIID(iid, getter_AddRefs(info));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
uint16_t methodIndex;
|
||||
const nsXPTMethodInfo *methodInfo;
|
||||
rv = info->GetMethodInfoForName(methodName.get(), &methodIndex,
|
||||
&methodInfo);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Exclude notxpcom and hidden. Also check that we have at least a
|
||||
// return value (the xpidl compiler ensures that that return value
|
||||
// is the last argument).
|
||||
uint8_t paramCount = methodInfo->GetParamCount();
|
||||
if (methodInfo->IsNotXPCOM() || methodInfo->IsHidden() ||
|
||||
paramCount == 0 ||
|
||||
!methodInfo->GetParam(paramCount - 1).IsRetval()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
aIID = *iid;
|
||||
aMethodIndex = methodIndex;
|
||||
return helper->QueryInterface(aIID, (void**)aHelper);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
TX_ResolveFunctionCallXPCOM(const nsCString &aContractID, int32_t aNamespaceID,
|
||||
nsAtom* aName, nsISupports *aState,
|
||||
FunctionCall **aFunction)
|
||||
{
|
||||
nsIID iid;
|
||||
uint16_t methodIndex = 0;
|
||||
nsCOMPtr<nsISupports> helper;
|
||||
|
||||
nsresult rv = LookupFunction(aContractID.get(), aName, iid, methodIndex,
|
||||
getter_AddRefs(helper));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!aFunction) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*aFunction = new txXPCOMExtensionFunctionCall(helper, iid, methodIndex,
|
||||
#ifdef TX_TO_STRING
|
||||
aName,
|
||||
#endif
|
||||
aState);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
txArgumentType
|
||||
txXPCOMExtensionFunctionCall::GetParamType(const nsXPTParamInfo &aParam,
|
||||
nsIInterfaceInfo *aInfo)
|
||||
{
|
||||
uint8_t tag = aParam.GetType().TagPart();
|
||||
switch (tag) {
|
||||
case nsXPTType::T_BOOL:
|
||||
case nsXPTType::T_DOUBLE:
|
||||
case nsXPTType::T_DOMSTRING:
|
||||
{
|
||||
return txArgumentType(tag);
|
||||
}
|
||||
case nsXPTType::T_INTERFACE:
|
||||
case nsXPTType::T_INTERFACE_IS:
|
||||
{
|
||||
nsIID iid;
|
||||
aInfo->GetIIDForParamNoAlloc(mMethodIndex, &aParam, &iid);
|
||||
if (iid.Equals(NS_GET_IID(txINodeSet))) {
|
||||
return eNODESET;
|
||||
}
|
||||
if (iid.Equals(NS_GET_IID(txIFunctionEvaluationContext))) {
|
||||
return eCONTEXT;
|
||||
}
|
||||
if (iid.Equals(NS_GET_IID(txIXPathObject))) {
|
||||
return eOBJECT;
|
||||
}
|
||||
return eUNKNOWN;
|
||||
}
|
||||
default:
|
||||
{
|
||||
// XXX Error!
|
||||
return eUNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class txParamArrayHolder
|
||||
{
|
||||
public:
|
||||
txParamArrayHolder()
|
||||
: mCount(0)
|
||||
{
|
||||
}
|
||||
txParamArrayHolder(txParamArrayHolder&& rhs)
|
||||
: mArray(mozilla::Move(rhs.mArray))
|
||||
, mCount(rhs.mCount)
|
||||
{
|
||||
rhs.mCount = 0;
|
||||
}
|
||||
~txParamArrayHolder();
|
||||
|
||||
bool Init(uint8_t aCount);
|
||||
operator nsXPTCVariant*() const
|
||||
{
|
||||
return mArray.get();
|
||||
}
|
||||
|
||||
void trace(JSTracer* trc) {
|
||||
for (uint8_t i = 0; i < mCount; ++i) {
|
||||
if (mArray[i].type == nsXPTType::T_JSVAL) {
|
||||
JS::UnsafeTraceRoot(trc, &mArray[i].val.j.asValueRef(), "txParam value");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
mozilla::UniquePtr<nsXPTCVariant[]> mArray;
|
||||
uint8_t mCount;
|
||||
};
|
||||
|
||||
txParamArrayHolder::~txParamArrayHolder()
|
||||
{
|
||||
uint8_t i;
|
||||
for (i = 0; i < mCount; ++i) {
|
||||
nsXPTCVariant &variant = mArray[i];
|
||||
if (variant.DoesValNeedCleanup()) {
|
||||
if (variant.type.TagPart() == nsXPTType::T_DOMSTRING)
|
||||
delete (nsAString*)variant.val.p;
|
||||
else {
|
||||
MOZ_ASSERT(variant.type.TagPart() == nsXPTType::T_INTERFACE ||
|
||||
variant.type.TagPart() == nsXPTType::T_INTERFACE_IS,
|
||||
"We only support cleanup of strings and interfaces "
|
||||
"here, and this looks like neither!");
|
||||
if (variant.val.p != nullptr) {
|
||||
static_cast<nsISupports*>(variant.val.p)->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
txParamArrayHolder::Init(uint8_t aCount)
|
||||
{
|
||||
mCount = aCount;
|
||||
mArray = mozilla::MakeUnique<nsXPTCVariant[]>(mCount);
|
||||
if (!mArray) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(mArray.get(), 0, mCount * sizeof(nsXPTCVariant));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txXPCOMExtensionFunctionCall::evaluate(txIEvalContext* aContext,
|
||||
txAExprResult** aResult)
|
||||
{
|
||||
nsCOMPtr<nsIInterfaceInfoManager> iim =
|
||||
do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(iim, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIInterfaceInfo> info;
|
||||
nsresult rv = iim->GetInfoForIID(&mIID, getter_AddRefs(info));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
const nsXPTMethodInfo *methodInfo;
|
||||
rv = info->GetMethodInfo(mMethodIndex, &methodInfo);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
uint8_t paramCount = methodInfo->GetParamCount();
|
||||
uint8_t inArgs = paramCount - 1;
|
||||
|
||||
JS::Rooted<txParamArrayHolder> invokeParams(mozilla::dom::RootingCx());
|
||||
if (!invokeParams.get().Init(paramCount)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
const nsXPTParamInfo ¶mInfo = methodInfo->GetParam(0);
|
||||
txArgumentType type = GetParamType(paramInfo, info);
|
||||
if (type == eUNKNOWN) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
txFunctionEvaluationContext *context;
|
||||
uint32_t paramStart = 0;
|
||||
if (type == eCONTEXT) {
|
||||
if (paramInfo.IsOut()) {
|
||||
// We don't support out values.
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Create context wrapper.
|
||||
context = new txFunctionEvaluationContext(aContext, mState);
|
||||
|
||||
nsXPTCVariant &invokeParam = invokeParams.get()[0];
|
||||
invokeParam.type = paramInfo.GetType();
|
||||
invokeParam.SetValNeedsCleanup();
|
||||
NS_ADDREF((txIFunctionEvaluationContext*&)invokeParam.val.p = context);
|
||||
|
||||
// Skip first argument, since it's the context.
|
||||
paramStart = 1;
|
||||
}
|
||||
else {
|
||||
context = nullptr;
|
||||
}
|
||||
|
||||
// XXX varargs
|
||||
if (!requireParams(inArgs - paramStart, inArgs - paramStart, aContext)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
uint32_t i;
|
||||
for (i = paramStart; i < inArgs; ++i) {
|
||||
Expr* expr = mParams[i - paramStart];
|
||||
|
||||
const nsXPTParamInfo ¶mInfo = methodInfo->GetParam(i);
|
||||
txArgumentType type = GetParamType(paramInfo, info);
|
||||
if (type == eUNKNOWN) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsXPTCVariant &invokeParam = invokeParams.get()[i];
|
||||
if (paramInfo.IsOut()) {
|
||||
// We don't support out values.
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
invokeParam.type = paramInfo.GetType();
|
||||
switch (type) {
|
||||
case eNODESET:
|
||||
{
|
||||
RefPtr<txNodeSet> nodes;
|
||||
rv = evaluateToNodeSet(expr, aContext, getter_AddRefs(nodes));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
txNodeSetAdaptor *adaptor = new txNodeSetAdaptor(nodes);
|
||||
if (!adaptor) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsCOMPtr<txINodeSet> nodeSet = adaptor;
|
||||
rv = adaptor->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
invokeParam.SetValNeedsCleanup();
|
||||
nodeSet.swap((txINodeSet*&)invokeParam.val.p);
|
||||
break;
|
||||
}
|
||||
case eBOOLEAN:
|
||||
{
|
||||
rv = expr->evaluateToBool(aContext, invokeParam.val.b);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
break;
|
||||
}
|
||||
case eNUMBER:
|
||||
{
|
||||
double dbl;
|
||||
rv = evaluateToNumber(mParams[0], aContext, &dbl);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
invokeParam.val.d = dbl;
|
||||
break;
|
||||
}
|
||||
case eSTRING:
|
||||
{
|
||||
nsString *value = new nsString();
|
||||
if (!value) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
rv = expr->evaluateToString(aContext, *value);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
invokeParam.SetValNeedsCleanup();
|
||||
invokeParam.val.p = value;
|
||||
break;
|
||||
}
|
||||
case eOBJECT:
|
||||
{
|
||||
RefPtr<txAExprResult> exprRes;
|
||||
rv = expr->evaluate(aContext, getter_AddRefs(exprRes));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<txIXPathObject> adaptor =
|
||||
new txXPathObjectAdaptor(exprRes);
|
||||
if (!adaptor) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
invokeParam.SetValNeedsCleanup();
|
||||
adaptor.swap((txIXPathObject*&)invokeParam.val.p);
|
||||
break;
|
||||
}
|
||||
case eCONTEXT:
|
||||
case eUNKNOWN:
|
||||
{
|
||||
// We only support passing the context as the *first* argument.
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const nsXPTParamInfo &returnInfo = methodInfo->GetParam(inArgs);
|
||||
txArgumentType returnType = GetParamType(returnInfo, info);
|
||||
if (returnType == eUNKNOWN) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsXPTCVariant &returnParam = invokeParams.get()[inArgs];
|
||||
returnParam.type = returnInfo.GetType();
|
||||
if (returnType == eSTRING) {
|
||||
nsString *value = new nsString();
|
||||
returnParam.SetValNeedsCleanup();
|
||||
returnParam.val.p = value;
|
||||
}
|
||||
else {
|
||||
returnParam.SetIndirect();
|
||||
if (returnType == eNODESET || returnType == eOBJECT) {
|
||||
returnParam.SetValNeedsCleanup();
|
||||
}
|
||||
}
|
||||
|
||||
rv = NS_InvokeByIndex(mHelper, mMethodIndex, paramCount, invokeParams.get());
|
||||
|
||||
// In case someone is holding on to the txFunctionEvaluationContext which
|
||||
// could thus stay alive longer than this function.
|
||||
if (context) {
|
||||
context->ClearContext();
|
||||
}
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
switch (returnType) {
|
||||
case eNODESET:
|
||||
{
|
||||
txINodeSet* nodeSet = static_cast<txINodeSet*>(returnParam.val.p);
|
||||
nsCOMPtr<txIXPathObject> object = do_QueryInterface(nodeSet, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ADDREF(*aResult = object->GetResult());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
case eBOOLEAN:
|
||||
{
|
||||
aContext->recycler()->getBoolResult(returnParam.val.b, aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
case eNUMBER:
|
||||
{
|
||||
return aContext->recycler()->getNumberResult(returnParam.val.d,
|
||||
aResult);
|
||||
}
|
||||
case eSTRING:
|
||||
{
|
||||
nsString *returned = static_cast<nsString*>
|
||||
(returnParam.val.p);
|
||||
return aContext->recycler()->getStringResult(*returned, aResult);
|
||||
}
|
||||
case eOBJECT:
|
||||
{
|
||||
txIXPathObject *object =
|
||||
static_cast<txIXPathObject*>(returnParam.val.p);
|
||||
|
||||
NS_ADDREF(*aResult = object->GetResult());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
default:
|
||||
{
|
||||
// Huh?
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Expr::ResultType
|
||||
txXPCOMExtensionFunctionCall::getReturnType()
|
||||
{
|
||||
// It doesn't really matter what we return here, but it might
|
||||
// be a good idea to try to keep this as unoptimizable as possible
|
||||
return ANY_RESULT;
|
||||
}
|
||||
|
||||
bool
|
||||
txXPCOMExtensionFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
// It doesn't really matter what we return here, but it might
|
||||
// be a good idea to try to keep this as unoptimizable as possible
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
txXPCOMExtensionFunctionCall::appendName(nsAString& aDest)
|
||||
{
|
||||
aDest.Append(mName->GetUTF16String());
|
||||
}
|
||||
#endif
|
45
dom/xslt/xpath/txXPathObjectAdaptor.h
Normal file
45
dom/xslt/xpath/txXPathObjectAdaptor.h
Normal file
@ -0,0 +1,45 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef txXPathObjectAdaptor_h__
|
||||
#define txXPathObjectAdaptor_h__
|
||||
|
||||
#include "txExprResult.h"
|
||||
#include "txINodeSet.h"
|
||||
#include "txIXPathObject.h"
|
||||
|
||||
/**
|
||||
* Implements an XPCOM wrapper around XPath data types boolean, number, string,
|
||||
* or nodeset.
|
||||
*/
|
||||
|
||||
class txXPathObjectAdaptor : public txIXPathObject
|
||||
{
|
||||
public:
|
||||
explicit txXPathObjectAdaptor(txAExprResult* aValue) : mValue(aValue)
|
||||
{
|
||||
NS_ASSERTION(aValue,
|
||||
"Don't create a txXPathObjectAdaptor if you don't have a "
|
||||
"txAExprResult");
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD_(txAExprResult*) GetResult() override
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
protected:
|
||||
txXPathObjectAdaptor() : mValue(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~txXPathObjectAdaptor() {}
|
||||
|
||||
RefPtr<txAExprResult> mValue;
|
||||
};
|
||||
|
||||
#endif // txXPathObjectAdaptor_h__
|
@ -4,10 +4,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/EnumeratedArray.h"
|
||||
#include "mozilla/EnumeratedRange.h"
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
#include "mozilla/MacroForEach.h"
|
||||
|
||||
#include "nsAtom.h"
|
||||
#include "nsGkAtoms.h"
|
||||
@ -28,7 +25,6 @@
|
||||
#include "nsTextNode.h"
|
||||
#include "mozilla/dom/DocumentFragment.h"
|
||||
#include "prtime.h"
|
||||
#include "txIEXSLTRegExFunctions.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@ -39,29 +35,20 @@ class txStylesheetCompilerState;
|
||||
// Utility functions
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
static nsIDocument*
|
||||
getSourceDocument(txIEvalContext *aContext)
|
||||
static nsresult
|
||||
convertRtfToNode(txIEvalContext *aContext, txResultTreeFragment *aRtf)
|
||||
{
|
||||
txExecutionState* es =
|
||||
static_cast<txExecutionState*>(aContext->getPrivateContext());
|
||||
if (!es) {
|
||||
NS_ERROR("Need txExecutionState!");
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const txXPathNode& document = es->getSourceDocument();
|
||||
return txXPathNativeNode::getDocument(document);
|
||||
}
|
||||
|
||||
static nsresult
|
||||
convertRtfToNode(txIEvalContext *aContext, txResultTreeFragment *aRtf)
|
||||
{
|
||||
nsIDocument *doc = getSourceDocument(aContext);
|
||||
if (!doc) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
const txXPathNode& document = es->getSourceDocument();
|
||||
|
||||
nsIDocument *doc = txXPathNativeNode::getDocument(document);
|
||||
nsCOMPtr<nsIDOMDocumentFragment> domFragment =
|
||||
new DocumentFragment(doc->NodeInfoManager());
|
||||
|
||||
@ -88,11 +75,17 @@ static nsresult
|
||||
createTextNode(txIEvalContext *aContext, nsString& aValue,
|
||||
txXPathNode* *aResult)
|
||||
{
|
||||
nsIDocument *doc = getSourceDocument(aContext);
|
||||
if (!doc) {
|
||||
txExecutionState* es =
|
||||
static_cast<txExecutionState*>(aContext->getPrivateContext());
|
||||
if (!es) {
|
||||
NS_ERROR("Need txExecutionState!");
|
||||
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
const txXPathNode& document = es->getSourceDocument();
|
||||
|
||||
nsIDocument *doc = txXPathNativeNode::getDocument(document);
|
||||
nsCOMPtr<nsIContent> text = new nsTextNode(doc->NodeInfoManager());
|
||||
|
||||
nsresult rv = text->SetText(aValue, false);
|
||||
@ -104,6 +97,25 @@ createTextNode(txIEvalContext *aContext, nsString& aValue,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static already_AddRefed<DocumentFragment>
|
||||
createDocFragment(txIEvalContext *aContext)
|
||||
{
|
||||
txExecutionState* es =
|
||||
static_cast<txExecutionState*>(aContext->getPrivateContext());
|
||||
if (!es) {
|
||||
NS_ERROR("Need txExecutionState!");
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const txXPathNode& document = es->getSourceDocument();
|
||||
nsIDocument *doc = txXPathNativeNode::getDocument(document);
|
||||
RefPtr<DocumentFragment> fragment =
|
||||
new DocumentFragment(doc->NodeInfoManager());
|
||||
|
||||
return fragment.forget();
|
||||
}
|
||||
|
||||
static nsresult
|
||||
createAndAddToResult(nsAtom* aName, const nsAString& aValue,
|
||||
txNodeSet* aResultSet, nsIContent* aResultHolder)
|
||||
@ -151,97 +163,79 @@ static const char * const sTypes[] = {
|
||||
// Function implementations
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
enum class txEXSLTType {
|
||||
// http://exslt.org/common
|
||||
NODE_SET,
|
||||
OBJECT_TYPE,
|
||||
|
||||
// http://exslt.org/dates-and-times
|
||||
DATE_TIME,
|
||||
|
||||
// http://exslt.org/math
|
||||
MAX,
|
||||
MIN,
|
||||
HIGHEST,
|
||||
LOWEST,
|
||||
|
||||
// http://exslt.org/regular-expressions
|
||||
MATCH,
|
||||
REPLACE,
|
||||
TEST,
|
||||
|
||||
// http://exslt.org/sets
|
||||
DIFFERENCE,
|
||||
DISTINCT,
|
||||
HAS_SAME_NODE,
|
||||
INTERSECTION,
|
||||
LEADING,
|
||||
TRAILING,
|
||||
|
||||
// http://exslt.org/strings
|
||||
CONCAT,
|
||||
SPLIT,
|
||||
TOKENIZE,
|
||||
|
||||
_LIMIT,
|
||||
};
|
||||
|
||||
struct txEXSLTFunctionDescriptor
|
||||
{
|
||||
int8_t mMinParams;
|
||||
int8_t mMaxParams;
|
||||
Expr::ResultType mReturnType;
|
||||
bool (*mCreator)(txEXSLTType, FunctionCall**);
|
||||
int32_t mNamespaceID;
|
||||
nsStaticAtom* mName;
|
||||
nsStaticAtom** mName;
|
||||
const char* mNamespaceURI;
|
||||
};
|
||||
|
||||
static EnumeratedArray<txEXSLTType, txEXSLTType::_LIMIT, txEXSLTFunctionDescriptor>
|
||||
descriptTable;
|
||||
static const char kEXSLTCommonNS[] = "http://exslt.org/common";
|
||||
static const char kEXSLTSetsNS[] = "http://exslt.org/sets";
|
||||
static const char kEXSLTStringsNS[] = "http://exslt.org/strings";
|
||||
static const char kEXSLTMathNS[] = "http://exslt.org/math";
|
||||
static const char kEXSLTDatesAndTimesNS[] = "http://exslt.org/dates-and-times";
|
||||
|
||||
// The order of this table must be the same as the
|
||||
// txEXSLTFunctionCall::eType enum
|
||||
static txEXSLTFunctionDescriptor descriptTable[] =
|
||||
{
|
||||
{ 1, 1, Expr::NODESET_RESULT, 0, &nsGkAtoms::nodeSet, kEXSLTCommonNS }, // NODE_SET
|
||||
{ 1, 1, Expr::STRING_RESULT, 0, &nsGkAtoms::objectType, kEXSLTCommonNS }, // OBJECT_TYPE
|
||||
{ 2, 2, Expr::NODESET_RESULT, 0, &nsGkAtoms::difference, kEXSLTSetsNS }, // DIFFERENCE
|
||||
{ 1, 1, Expr::NODESET_RESULT, 0, &nsGkAtoms::distinct, kEXSLTSetsNS }, // DISTINCT
|
||||
{ 2, 2, Expr::BOOLEAN_RESULT, 0, &nsGkAtoms::hasSameNode, kEXSLTSetsNS }, // HAS_SAME_NODE
|
||||
{ 2, 2, Expr::NODESET_RESULT, 0, &nsGkAtoms::intersection, kEXSLTSetsNS }, // INTERSECTION
|
||||
{ 2, 2, Expr::NODESET_RESULT, 0, &nsGkAtoms::leading, kEXSLTSetsNS }, // LEADING
|
||||
{ 2, 2, Expr::NODESET_RESULT, 0, &nsGkAtoms::trailing, kEXSLTSetsNS }, // TRAILING
|
||||
{ 1, 1, Expr::STRING_RESULT, 0, &nsGkAtoms::concat, kEXSLTStringsNS }, // CONCAT
|
||||
{ 1, 2, Expr::STRING_RESULT, 0, &nsGkAtoms::split, kEXSLTStringsNS }, // SPLIT
|
||||
{ 1, 2, Expr::STRING_RESULT, 0, &nsGkAtoms::tokenize, kEXSLTStringsNS }, // TOKENIZE
|
||||
{ 1, 1, Expr::NUMBER_RESULT, 0, &nsGkAtoms::max, kEXSLTMathNS }, // MAX
|
||||
{ 1, 1, Expr::NUMBER_RESULT, 0, &nsGkAtoms::min, kEXSLTMathNS }, // MIN
|
||||
{ 1, 1, Expr::NODESET_RESULT, 0, &nsGkAtoms::highest, kEXSLTMathNS }, // HIGHEST
|
||||
{ 1, 1, Expr::NODESET_RESULT, 0, &nsGkAtoms::lowest, kEXSLTMathNS }, // LOWEST
|
||||
{ 0, 0, Expr::STRING_RESULT, 0, &nsGkAtoms::dateTime, kEXSLTDatesAndTimesNS }, // DATE_TIME
|
||||
|
||||
};
|
||||
|
||||
class txEXSLTFunctionCall : public FunctionCall
|
||||
{
|
||||
public:
|
||||
explicit txEXSLTFunctionCall(txEXSLTType aType)
|
||||
: mType(aType)
|
||||
{}
|
||||
// The order of this enum must be the same as the descriptTable
|
||||
// table above
|
||||
enum eType {
|
||||
// Set functions
|
||||
NODE_SET,
|
||||
OBJECT_TYPE,
|
||||
DIFFERENCE,
|
||||
DISTINCT,
|
||||
HAS_SAME_NODE,
|
||||
INTERSECTION,
|
||||
LEADING,
|
||||
TRAILING,
|
||||
CONCAT,
|
||||
SPLIT,
|
||||
TOKENIZE,
|
||||
MAX,
|
||||
MIN,
|
||||
HIGHEST,
|
||||
LOWEST,
|
||||
DATE_TIME
|
||||
};
|
||||
|
||||
static bool Create(txEXSLTType aType, FunctionCall** aFunction)
|
||||
explicit txEXSLTFunctionCall(eType aType)
|
||||
: mType(aType)
|
||||
{
|
||||
*aFunction = new txEXSLTFunctionCall(aType);
|
||||
return true;
|
||||
}
|
||||
|
||||
TX_DECL_FUNCTION
|
||||
|
||||
private:
|
||||
txEXSLTType mType;
|
||||
};
|
||||
|
||||
class txEXSLTRegExFunctionCall : public FunctionCall
|
||||
{
|
||||
public:
|
||||
txEXSLTRegExFunctionCall(txEXSLTType aType, txIEXSLTRegExFunctions* aRegExService)
|
||||
: mType(aType)
|
||||
, mRegExService(aRegExService)
|
||||
{}
|
||||
|
||||
static bool Create(txEXSLTType aType, FunctionCall** aFunction)
|
||||
{
|
||||
nsCOMPtr<txIEXSLTRegExFunctions> regExService =
|
||||
do_GetService("@mozilla.org/exslt/regexp;1");
|
||||
if (!regExService) {
|
||||
return false;
|
||||
}
|
||||
*aFunction = new txEXSLTRegExFunctionCall(aType, regExService);
|
||||
return true;
|
||||
}
|
||||
|
||||
TX_DECL_FUNCTION
|
||||
|
||||
private:
|
||||
txEXSLTType mType;
|
||||
nsCOMPtr<txIEXSLTRegExFunctions> mRegExService;
|
||||
eType mType;
|
||||
};
|
||||
|
||||
nsresult
|
||||
@ -257,7 +251,7 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
switch (mType) {
|
||||
case txEXSLTType::NODE_SET:
|
||||
case NODE_SET:
|
||||
{
|
||||
RefPtr<txAExprResult> exprResult;
|
||||
rv = mParams[0]->evaluate(aContext, getter_AddRefs(exprResult));
|
||||
@ -305,7 +299,7 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
case txEXSLTType::OBJECT_TYPE:
|
||||
case OBJECT_TYPE:
|
||||
{
|
||||
RefPtr<txAExprResult> exprResult;
|
||||
nsresult rv = mParams[0]->evaluate(aContext,
|
||||
@ -323,8 +317,8 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
case txEXSLTType::DIFFERENCE:
|
||||
case txEXSLTType::INTERSECTION:
|
||||
case DIFFERENCE:
|
||||
case INTERSECTION:
|
||||
{
|
||||
RefPtr<txNodeSet> nodes1;
|
||||
rv = evaluateToNodeSet(mParams[0], aContext,
|
||||
@ -340,7 +334,7 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
rv = aContext->recycler()->getNodeSet(getter_AddRefs(resultSet));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool insertOnFound = mType == txEXSLTType::INTERSECTION;
|
||||
bool insertOnFound = mType == INTERSECTION;
|
||||
|
||||
int32_t searchPos = 0;
|
||||
int32_t i, len = nodes1->size();
|
||||
@ -361,7 +355,7 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
case txEXSLTType::DISTINCT:
|
||||
case DISTINCT:
|
||||
{
|
||||
RefPtr<txNodeSet> nodes;
|
||||
rv = evaluateToNodeSet(mParams[0], aContext,
|
||||
@ -390,7 +384,7 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
case txEXSLTType::HAS_SAME_NODE:
|
||||
case HAS_SAME_NODE:
|
||||
{
|
||||
RefPtr<txNodeSet> nodes1;
|
||||
rv = evaluateToNodeSet(mParams[0], aContext,
|
||||
@ -415,8 +409,8 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
case txEXSLTType::LEADING:
|
||||
case txEXSLTType::TRAILING:
|
||||
case LEADING:
|
||||
case TRAILING:
|
||||
{
|
||||
RefPtr<txNodeSet> nodes1;
|
||||
rv = evaluateToNodeSet(mParams[0], aContext,
|
||||
@ -442,7 +436,7 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
int32_t end = nodes1->indexOf(nodes2->get(0));
|
||||
if (end >= 0) {
|
||||
int32_t i = 0;
|
||||
if (mType == txEXSLTType::TRAILING) {
|
||||
if (mType == TRAILING) {
|
||||
i = end + 1;
|
||||
end = nodes1->size();
|
||||
}
|
||||
@ -456,7 +450,7 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
case txEXSLTType::CONCAT:
|
||||
case CONCAT:
|
||||
{
|
||||
RefPtr<txNodeSet> nodes;
|
||||
rv = evaluateToNodeSet(mParams[0], aContext,
|
||||
@ -471,8 +465,8 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
|
||||
return aContext->recycler()->getStringResult(str, aResult);
|
||||
}
|
||||
case txEXSLTType::SPLIT:
|
||||
case txEXSLTType::TOKENIZE:
|
||||
case SPLIT:
|
||||
case TOKENIZE:
|
||||
{
|
||||
// Evaluate parameters
|
||||
nsAutoString string;
|
||||
@ -484,7 +478,7 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
rv = mParams[1]->evaluateToString(aContext, pattern);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else if (mType == txEXSLTType::SPLIT) {
|
||||
else if (mType == SPLIT) {
|
||||
pattern.Assign(' ');
|
||||
}
|
||||
else {
|
||||
@ -492,11 +486,8 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
}
|
||||
|
||||
// Set up holders for the result
|
||||
nsIDocument* sourceDoc = getSourceDocument(aContext);
|
||||
NS_ENSURE_STATE(sourceDoc);
|
||||
|
||||
RefPtr<DocumentFragment> docFrag =
|
||||
new DocumentFragment(sourceDoc->NodeInfoManager());
|
||||
RefPtr<DocumentFragment> docFrag = createDocFragment(aContext);
|
||||
NS_ENSURE_STATE(docFrag);
|
||||
|
||||
RefPtr<txNodeSet> resultSet;
|
||||
rv = aContext->recycler()->getNodeSet(getter_AddRefs(resultSet));
|
||||
@ -517,7 +508,7 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
|
||||
tailIndex = string.Length();
|
||||
}
|
||||
else if (mType == txEXSLTType::SPLIT) {
|
||||
else if (mType == SPLIT) {
|
||||
nsAString::const_iterator strStart, strEnd;
|
||||
string.BeginReading(strStart);
|
||||
string.EndReading(strEnd);
|
||||
@ -565,8 +556,8 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
case txEXSLTType::MAX:
|
||||
case txEXSLTType::MIN:
|
||||
case MAX:
|
||||
case MIN:
|
||||
{
|
||||
RefPtr<txNodeSet> nodes;
|
||||
rv = evaluateToNodeSet(mParams[0], aContext,
|
||||
@ -578,7 +569,7 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
getNumberResult(UnspecifiedNaN<double>(), aResult);
|
||||
}
|
||||
|
||||
bool findMax = mType == txEXSLTType::MAX;
|
||||
bool findMax = mType == MAX;
|
||||
|
||||
double res = findMax ? mozilla::NegativeInfinity<double>() :
|
||||
mozilla::PositiveInfinity<double>();
|
||||
@ -599,8 +590,8 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
|
||||
return aContext->recycler()->getNumberResult(res, aResult);
|
||||
}
|
||||
case txEXSLTType::HIGHEST:
|
||||
case txEXSLTType::LOWEST:
|
||||
case HIGHEST:
|
||||
case LOWEST:
|
||||
{
|
||||
RefPtr<txNodeSet> nodes;
|
||||
rv = evaluateToNodeSet(mParams[0], aContext,
|
||||
@ -617,7 +608,7 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
rv = aContext->recycler()->getNodeSet(getter_AddRefs(resultSet));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool findMax = mType == txEXSLTType::HIGHEST;
|
||||
bool findMax = mType == HIGHEST;
|
||||
double res = findMax ? mozilla::NegativeInfinity<double>() :
|
||||
mozilla::PositiveInfinity<double>();
|
||||
int32_t i, len = nodes->size();
|
||||
@ -645,7 +636,7 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
case txEXSLTType::DATE_TIME:
|
||||
case DATE_TIME:
|
||||
{
|
||||
// http://exslt.org/date/functions/date-time/
|
||||
|
||||
@ -675,15 +666,10 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
default:
|
||||
{
|
||||
aContext->receiveError(NS_LITERAL_STRING("Internal error"),
|
||||
NS_ERROR_UNEXPECTED);
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
NS_NOTREACHED("Missing switch case.");
|
||||
aContext->receiveError(NS_LITERAL_STRING("Internal error"),
|
||||
NS_ERROR_UNEXPECTED);
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
@ -696,8 +682,7 @@ txEXSLTFunctionCall::getReturnType()
|
||||
bool
|
||||
txEXSLTFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
if (mType == txEXSLTType::NODE_SET || mType == txEXSLTType::SPLIT ||
|
||||
mType == txEXSLTType::TOKENIZE) {
|
||||
if (mType == NODE_SET || mType == SPLIT || mType == TOKENIZE) {
|
||||
return (aContext & PRIVATE_CONTEXT) || argsSensitiveTo(aContext);
|
||||
}
|
||||
return argsSensitiveTo(aContext);
|
||||
@ -707,124 +692,7 @@ txEXSLTFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
||||
void
|
||||
txEXSLTFunctionCall::appendName(nsAString& aDest)
|
||||
{
|
||||
aDest.Append(descriptTable[mType].mName->GetUTF16String());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
nsresult
|
||||
txEXSLTRegExFunctionCall::evaluate(txIEvalContext* aContext,
|
||||
txAExprResult** aResult)
|
||||
{
|
||||
*aResult = nullptr;
|
||||
if (!requireParams(descriptTable[mType].mMinParams,
|
||||
descriptTable[mType].mMaxParams,
|
||||
aContext)) {
|
||||
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
|
||||
}
|
||||
|
||||
nsAutoString string;
|
||||
nsresult rv = mParams[0]->evaluateToString(aContext, string);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoString regex;
|
||||
rv = mParams[1]->evaluateToString(aContext, regex);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoString flags;
|
||||
if (mParams.Length() >= 3) {
|
||||
rv = mParams[2]->evaluateToString(aContext, flags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
switch (mType) {
|
||||
case txEXSLTType::MATCH:
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocument> sourceDoc =
|
||||
do_QueryInterface(getSourceDocument(aContext));
|
||||
NS_ENSURE_STATE(sourceDoc);
|
||||
|
||||
nsCOMPtr<nsIDOMDocumentFragment> domDocFrag;
|
||||
rv = mRegExService->Match(string, regex, flags, sourceDoc,
|
||||
getter_AddRefs(domDocFrag));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIContent> docFrag = do_QueryInterface(domDocFrag, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
RefPtr<txNodeSet> resultSet;
|
||||
rv = aContext->recycler()->getNodeSet(getter_AddRefs(resultSet));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txXPathNode> node;
|
||||
for (nsIContent* result = docFrag->GetFirstChild(); result;
|
||||
result = result->GetNextSibling()) {
|
||||
node = txXPathNativeNode::createXPathNode(result, true);
|
||||
rv = resultSet->add(*node);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
resultSet.forget(aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
case txEXSLTType::REPLACE:
|
||||
{
|
||||
nsAutoString replace;
|
||||
rv = mParams[3]->evaluateToString(aContext, replace);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsString result;
|
||||
rv = mRegExService->Replace(string, regex, flags, replace, result);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aContext->recycler()->getStringResult(result, aResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
case txEXSLTType::TEST:
|
||||
{
|
||||
bool result;
|
||||
rv = mRegExService->Test(string, regex, flags, &result);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aContext->recycler()->getBoolResult(result, aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
default:
|
||||
{
|
||||
aContext->receiveError(NS_LITERAL_STRING("Internal error"),
|
||||
NS_ERROR_UNEXPECTED);
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
NS_NOTREACHED("Missing switch case.");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
Expr::ResultType
|
||||
txEXSLTRegExFunctionCall::getReturnType()
|
||||
{
|
||||
return descriptTable[mType].mReturnType;
|
||||
}
|
||||
|
||||
bool
|
||||
txEXSLTRegExFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
if (mType == txEXSLTType::MATCH) {
|
||||
return (aContext & PRIVATE_CONTEXT) || argsSensitiveTo(aContext);
|
||||
}
|
||||
return argsSensitiveTo(aContext);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
txEXSLTRegExFunctionCall::appendName(nsAString& aDest)
|
||||
{
|
||||
aDest.Append(descriptTable[mType].mName->GetUTF16String());
|
||||
aDest.Append((*descriptTable[mType].mName)->GetUTF16String());
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -834,10 +702,13 @@ TX_ConstructEXSLTFunction(nsAtom *aName,
|
||||
txStylesheetCompilerState* aState,
|
||||
FunctionCall **aResult)
|
||||
{
|
||||
for (auto i : MakeEnumeratedRange(txEXSLTType::_LIMIT)) {
|
||||
const txEXSLTFunctionDescriptor& desc = descriptTable[i];
|
||||
if (aName == desc.mName && aNamespaceID == desc.mNamespaceID) {
|
||||
return desc.mCreator(i, aResult) ? NS_OK : NS_ERROR_FAILURE;
|
||||
uint32_t i;
|
||||
for (i = 0; i < ArrayLength(descriptTable); ++i) {
|
||||
txEXSLTFunctionDescriptor& desc = descriptTable[i];
|
||||
if (aName == *desc.mName && aNamespaceID == desc.mNamespaceID) {
|
||||
*aResult = new txEXSLTFunctionCall(
|
||||
static_cast<txEXSLTFunctionCall::eType>(i));
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@ -847,56 +718,17 @@ TX_ConstructEXSLTFunction(nsAtom *aName,
|
||||
extern bool
|
||||
TX_InitEXSLTFunction()
|
||||
{
|
||||
#define EXSLT_FUNC_HELPER(NS, CLASS, ...) EXSLT_FUNC(NS, CLASS, __VA_ARGS__)
|
||||
#define EXSLT_FUNC_HELPER2(NS, CLASS, ...) EXSLT_FUNC_HELPER(NS, CLASS, MOZ_UNWRAP_ARGS __VA_ARGS__)
|
||||
uint32_t i;
|
||||
for (i = 0; i < ArrayLength(descriptTable); ++i) {
|
||||
txEXSLTFunctionDescriptor& desc = descriptTable[i];
|
||||
NS_ConvertASCIItoUTF16 namespaceURI(desc.mNamespaceURI);
|
||||
desc.mNamespaceID =
|
||||
txNamespaceManager::getNamespaceID(namespaceURI);
|
||||
|
||||
#define EXSLT_FUNCS(NS, CLASS, ...) \
|
||||
{ \
|
||||
int32_t nsid = txNamespaceManager::getNamespaceID(NS_LITERAL_STRING(NS)); \
|
||||
if (nsid == kNameSpaceID_Unknown) { \
|
||||
return false; \
|
||||
} \
|
||||
MOZ_FOR_EACH(EXSLT_FUNC_HELPER2, (nsid, CLASS,), (__VA_ARGS__)) \
|
||||
if (desc.mNamespaceID == kNameSpaceID_Unknown) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#define EXSLT_FUNC(NS, CLASS, TYPE, MIN_ARGS, MAX_ARGS, RESULT_TYPE, NAME) \
|
||||
descriptTable[txEXSLTType::TYPE] = { MIN_ARGS, MAX_ARGS, RESULT_TYPE, CLASS::Create, NS, NAME };
|
||||
|
||||
EXSLT_FUNCS("http://exslt.org/common", txEXSLTFunctionCall,
|
||||
(NODE_SET, 1, 1, Expr::NODESET_RESULT, nsGkAtoms::nodeSet),
|
||||
(OBJECT_TYPE, 1, 1, Expr::STRING_RESULT, nsGkAtoms::objectType))
|
||||
|
||||
EXSLT_FUNCS("http://exslt.org/dates-and-times", txEXSLTFunctionCall,
|
||||
(DATE_TIME, 0, 0, Expr::STRING_RESULT, nsGkAtoms::dateTime))
|
||||
|
||||
EXSLT_FUNCS("http://exslt.org/math", txEXSLTFunctionCall,
|
||||
(MAX, 1, 1, Expr::NUMBER_RESULT, nsGkAtoms::max),
|
||||
(MIN, 1, 1, Expr::NUMBER_RESULT, nsGkAtoms::min),
|
||||
(HIGHEST, 1, 1, Expr::NODESET_RESULT, nsGkAtoms::highest),
|
||||
(LOWEST, 1, 1, Expr::NODESET_RESULT, nsGkAtoms::lowest))
|
||||
|
||||
EXSLT_FUNCS("http://exslt.org/regular-expressions", txEXSLTRegExFunctionCall,
|
||||
(MATCH, 2, 3, Expr::NODESET_RESULT, nsGkAtoms::match),
|
||||
(REPLACE, 4, 4, Expr::STRING_RESULT, nsGkAtoms::replace),
|
||||
(TEST, 2, 3, Expr::BOOLEAN_RESULT, nsGkAtoms::test))
|
||||
|
||||
EXSLT_FUNCS("http://exslt.org/sets", txEXSLTFunctionCall,
|
||||
(DIFFERENCE, 2, 2, Expr::NODESET_RESULT, nsGkAtoms::difference),
|
||||
(DISTINCT, 1, 1, Expr::NODESET_RESULT, nsGkAtoms::distinct),
|
||||
(HAS_SAME_NODE, 2, 2, Expr::BOOLEAN_RESULT, nsGkAtoms::hasSameNode),
|
||||
(INTERSECTION, 2, 2, Expr::NODESET_RESULT, nsGkAtoms::intersection),
|
||||
(LEADING, 2, 2, Expr::NODESET_RESULT, nsGkAtoms::leading),
|
||||
(TRAILING, 2, 2, Expr::NODESET_RESULT, nsGkAtoms::trailing))
|
||||
|
||||
EXSLT_FUNCS("http://exslt.org/strings", txEXSLTFunctionCall,
|
||||
(CONCAT, 1, 1, Expr::STRING_RESULT, nsGkAtoms::concat),
|
||||
(SPLIT, 1, 2, Expr::STRING_RESULT, nsGkAtoms::split),
|
||||
(TOKENIZE, 1, 2, Expr::STRING_RESULT, nsGkAtoms::tokenize))
|
||||
|
||||
#undef EXSLT_FUNCS
|
||||
#undef EXSLT_FUNC
|
||||
#undef EXSLT_FUNC_HELPER
|
||||
#undef EXSLT_FUNC_HELPER2
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -6,6 +6,9 @@
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const EXSLT_REGEXP_CID = Components.ID("{18a03189-067b-4978-b4f1-bafe35292ed6}");
|
||||
const EXSLT_REGEXP_CONTRACTID = "@mozilla.org/exslt/regexp;1";
|
||||
|
||||
const NODESET_CONTRACTID = "@mozilla.org/transformiix-nodeset;1";
|
||||
|
||||
function txEXSLTRegExFunctions()
|
||||
{
|
||||
@ -18,21 +21,34 @@ txEXSLTRegExFunctions.prototype = {
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.txIEXSLTRegExFunctions]),
|
||||
|
||||
classInfo: XPCOMUtils.generateCI({classID: EXSLT_REGEXP_CID,
|
||||
contractID: EXSLT_REGEXP_CONTRACTID,
|
||||
interfaces: [Ci.txIEXSLTRegExFunctions]}),
|
||||
|
||||
// txIEXSLTRegExFunctions
|
||||
match: function(str, regex, flags, doc) {
|
||||
var docFrag = doc.createDocumentFragment();
|
||||
match: function(context, str, regex, flags) {
|
||||
var nodeset = Cc[NODESET_CONTRACTID]
|
||||
.createInstance(Ci.txINodeSet);
|
||||
|
||||
var re = new RegExp(regex, flags);
|
||||
var matches = str.match(re);
|
||||
if (matches != null) {
|
||||
if (matches != null && matches.length > 0) {
|
||||
var contextNode = context.contextNode;
|
||||
var doc = contextNode.nodeType == Ci.nsIDOMNode.DOCUMENT_NODE ?
|
||||
contextNode : contextNode.ownerDocument;
|
||||
var docFrag = doc.createDocumentFragment();
|
||||
|
||||
for (var i = 0; i < matches.length; ++i) {
|
||||
var match = matches[i];
|
||||
var elem = doc.createElementNS(null, "match");
|
||||
var text = doc.createTextNode(match ? match : '');
|
||||
elem.appendChild(text);
|
||||
docFrag.appendChild(elem);
|
||||
nodeset.add(elem);
|
||||
}
|
||||
}
|
||||
return docFrag;
|
||||
|
||||
return nodeset;
|
||||
},
|
||||
|
||||
replace: function(str, regex, flags, replace) {
|
||||
|
@ -1,2 +1,3 @@
|
||||
component {18a03189-067b-4978-b4f1-bafe35292ed6} txEXSLTRegExFunctions.js
|
||||
contract @mozilla.org/exslt/regexp;1 {18a03189-067b-4978-b4f1-bafe35292ed6}
|
||||
category XSLT-extension-functions http://exslt.org/regular-expressions @mozilla.org/exslt/regexp;1
|
||||
|
@ -899,7 +899,8 @@ txErrorFunctionCall::appendName(nsAString& aDest)
|
||||
#endif
|
||||
|
||||
static nsresult
|
||||
TX_ConstructXSLTFunction(nsAtom* aName, txStylesheetCompilerState* aState,
|
||||
TX_ConstructXSLTFunction(nsAtom* aName, int32_t aNamespaceID,
|
||||
txStylesheetCompilerState* aState,
|
||||
FunctionCall** aFunction)
|
||||
{
|
||||
if (aName == nsGkAtoms::document) {
|
||||
@ -950,21 +951,115 @@ TX_ConstructXSLTFunction(nsAtom* aName, txStylesheetCompilerState* aState,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
typedef nsresult (*txFunctionFactory)(nsAtom* aName,
|
||||
int32_t aNamespaceID,
|
||||
txStylesheetCompilerState* aState,
|
||||
FunctionCall** aResult);
|
||||
struct txFunctionFactoryMapping
|
||||
{
|
||||
const char* const mNamespaceURI;
|
||||
int32_t mNamespaceID;
|
||||
txFunctionFactory mFactory;
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
TX_ConstructEXSLTFunction(nsAtom *aName,
|
||||
int32_t aNamespaceID,
|
||||
txStylesheetCompilerState* aState,
|
||||
FunctionCall **aResult);
|
||||
|
||||
static txFunctionFactoryMapping kExtensionFunctions[] = {
|
||||
{ "", kNameSpaceID_Unknown, TX_ConstructXSLTFunction },
|
||||
{ "http://exslt.org/common", kNameSpaceID_Unknown,
|
||||
TX_ConstructEXSLTFunction },
|
||||
{ "http://exslt.org/sets", kNameSpaceID_Unknown,
|
||||
TX_ConstructEXSLTFunction },
|
||||
{ "http://exslt.org/strings", kNameSpaceID_Unknown,
|
||||
TX_ConstructEXSLTFunction },
|
||||
{ "http://exslt.org/math", kNameSpaceID_Unknown,
|
||||
TX_ConstructEXSLTFunction },
|
||||
{ "http://exslt.org/dates-and-times", kNameSpaceID_Unknown,
|
||||
TX_ConstructEXSLTFunction }
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
TX_ResolveFunctionCallXPCOM(const nsCString &aContractID, int32_t aNamespaceID,
|
||||
nsAtom *aName, nsISupports *aState,
|
||||
FunctionCall **aFunction);
|
||||
|
||||
struct txXPCOMFunctionMapping
|
||||
{
|
||||
int32_t mNamespaceID;
|
||||
nsCString mContractID;
|
||||
};
|
||||
|
||||
static nsTArray<txXPCOMFunctionMapping> *sXPCOMFunctionMappings = nullptr;
|
||||
|
||||
static nsresult
|
||||
findFunction(nsAtom* aName, int32_t aNamespaceID,
|
||||
txStylesheetCompilerState* aState, FunctionCall** aResult)
|
||||
{
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
return TX_ConstructXSLTFunction(aName, aState, aResult);
|
||||
if (kExtensionFunctions[0].mNamespaceID == kNameSpaceID_Unknown) {
|
||||
uint32_t i;
|
||||
for (i = 0; i < ArrayLength(kExtensionFunctions); ++i) {
|
||||
txFunctionFactoryMapping& mapping = kExtensionFunctions[i];
|
||||
NS_ConvertASCIItoUTF16 namespaceURI(mapping.mNamespaceURI);
|
||||
mapping.mNamespaceID =
|
||||
txNamespaceManager::getNamespaceID(namespaceURI);
|
||||
}
|
||||
}
|
||||
|
||||
return TX_ConstructEXSLTFunction(aName, aNamespaceID, aState, aResult);
|
||||
uint32_t i;
|
||||
for (i = 0; i < ArrayLength(kExtensionFunctions); ++i) {
|
||||
const txFunctionFactoryMapping& mapping = kExtensionFunctions[i];
|
||||
if (mapping.mNamespaceID == aNamespaceID) {
|
||||
return mapping.mFactory(aName, aNamespaceID, aState, aResult);
|
||||
}
|
||||
}
|
||||
|
||||
if (!sXPCOMFunctionMappings) {
|
||||
sXPCOMFunctionMappings = new nsTArray<txXPCOMFunctionMapping>;
|
||||
}
|
||||
|
||||
txXPCOMFunctionMapping *map = nullptr;
|
||||
uint32_t count = sXPCOMFunctionMappings->Length();
|
||||
for (i = 0; i < count; ++i) {
|
||||
map = &sXPCOMFunctionMappings->ElementAt(i);
|
||||
if (map->mNamespaceID == aNamespaceID) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == count) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICategoryManager> catman =
|
||||
do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoString namespaceURI;
|
||||
rv = txNamespaceManager::getNamespaceURI(aNamespaceID, namespaceURI);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCString contractID;
|
||||
rv = catman->GetCategoryEntry("XSLT-extension-functions",
|
||||
NS_ConvertUTF16toUTF8(namespaceURI).get(),
|
||||
getter_Copies(contractID));
|
||||
if (rv == NS_ERROR_NOT_AVAILABLE) {
|
||||
return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
map = sXPCOMFunctionMappings->AppendElement();
|
||||
if (!map) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
map->mNamespaceID = aNamespaceID;
|
||||
map->mContractID = contractID;
|
||||
}
|
||||
|
||||
return TX_ResolveFunctionCallXPCOM(map->mContractID, aNamespaceID, aName,
|
||||
nullptr, aResult);
|
||||
}
|
||||
|
||||
extern bool
|
||||
@ -1009,6 +1104,14 @@ txStylesheetCompilerState::SetErrorOffset(uint32_t aOffset)
|
||||
// XXX implement me
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
txStylesheetCompilerState::shutdown()
|
||||
{
|
||||
delete sXPCOMFunctionMappings;
|
||||
sXPCOMFunctionMappings = nullptr;
|
||||
}
|
||||
|
||||
txElementContext::txElementContext(const nsAString& aBaseURI)
|
||||
: mPreserveWhitespace(false),
|
||||
mForwardsCompatibleParsing(true),
|
||||
|
@ -152,6 +152,8 @@ public:
|
||||
fcp();
|
||||
}
|
||||
|
||||
static void shutdown();
|
||||
|
||||
|
||||
RefPtr<txStylesheet> mStylesheet;
|
||||
txHandlerTable* mHandlerTable;
|
||||
|
@ -34,6 +34,7 @@ txXSLTProcessor::init()
|
||||
void
|
||||
txXSLTProcessor::shutdown()
|
||||
{
|
||||
txStylesheetCompilerState::shutdown();
|
||||
txHandlerTable::shutdown();
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,7 @@
|
||||
|
||||
// Transformiix stuff
|
||||
#include "mozilla/dom/XPathEvaluator.h"
|
||||
#include "txNodeSetAdaptor.h"
|
||||
|
||||
#include "mozilla/dom/DOMParser.h"
|
||||
#include "nsDOMSerializer.h"
|
||||
@ -193,6 +194,14 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsParserUtils)
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(HTMLEditor)
|
||||
|
||||
// Transformiix
|
||||
/* 5d5d92cd-6bf8-11d9-bf4a-000a95dc234c */
|
||||
#define TRANSFORMIIX_NODESET_CID \
|
||||
{ 0x5d5d92cd, 0x6bf8, 0x11d9, { 0xbf, 0x4a, 0x0, 0x0a, 0x95, 0xdc, 0x23, 0x4c } }
|
||||
|
||||
#define TRANSFORMIIX_NODESET_CONTRACTID \
|
||||
"@mozilla.org/transformiix-nodeset;1"
|
||||
|
||||
// PresentationDeviceManager
|
||||
/* e1e79dec-4085-4994-ac5b-744b016697e6 */
|
||||
#define PRESENTATION_DEVICE_MANAGER_CID \
|
||||
@ -204,6 +213,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(HTMLEditor)
|
||||
already_AddRefed<nsIPresentationService> NS_CreatePresentationService();
|
||||
|
||||
// Factory Constructor
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(txNodeSetAdaptor, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMSerializer)
|
||||
typedef nsHostObjectURI::Mutator nsHostObjectURIMutator;
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsHostObjectURIMutator)
|
||||
@ -567,6 +577,7 @@ NS_DEFINE_NAMED_CID(NS_PLUGINDOCLOADERFACTORY_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_PLUGINDOCUMENT_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_VIDEODOCUMENT_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_STYLESHEETSERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(TRANSFORMIIX_NODESET_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_XMLSERIALIZER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_HOSTOBJECTURI_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_HOSTOBJECTURIMUTATOR_CID);
|
||||
@ -815,6 +826,7 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
|
||||
{ &kNS_PLUGINDOCUMENT_CID, false, nullptr, CreatePluginDocument },
|
||||
{ &kNS_VIDEODOCUMENT_CID, false, nullptr, CreateVideoDocument },
|
||||
{ &kNS_STYLESHEETSERVICE_CID, false, nullptr, nsStyleSheetServiceConstructor },
|
||||
{ &kTRANSFORMIIX_NODESET_CID, false, nullptr, txNodeSetAdaptorConstructor },
|
||||
{ &kNS_XMLSERIALIZER_CID, false, nullptr, nsDOMSerializerConstructor },
|
||||
{ &kNS_HOSTOBJECTURI_CID, false, nullptr, nsHostObjectURIMutatorConstructor }, // do_CreateInstance returns mutator
|
||||
{ &kNS_HOSTOBJECTURIMUTATOR_CID, false, nullptr, nsHostObjectURIMutatorConstructor },
|
||||
@ -928,6 +940,7 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
|
||||
{ NS_WINDOWCONTROLLER_CONTRACTID, &kNS_WINDOWCONTROLLER_CID },
|
||||
{ PLUGIN_DLF_CONTRACTID, &kNS_PLUGINDOCLOADERFACTORY_CID },
|
||||
{ NS_STYLESHEETSERVICE_CONTRACTID, &kNS_STYLESHEETSERVICE_CID },
|
||||
{ TRANSFORMIIX_NODESET_CONTRACTID, &kTRANSFORMIIX_NODESET_CID },
|
||||
{ NS_XMLSERIALIZER_CONTRACTID, &kNS_XMLSERIALIZER_CID },
|
||||
{ NS_DOMPARSER_CONTRACTID, &kNS_DOMPARSER_CID },
|
||||
{ "@mozilla.org/dom/localStorage-manager;1", &kNS_DOMLOCALSTORAGEMANAGER_CID },
|
||||
|
Loading…
Reference in New Issue
Block a user