Implement exslt-date:date-time (bug 603159) r=sicking

This commit is contained in:
Julian Reschke 2011-04-26 13:46:43 +01:00
parent c65bc78451
commit cf45e69741
5 changed files with 94 additions and 1 deletions

View File

@ -263,6 +263,7 @@ GK_ATOM(cycler, "cycler")
GK_ATOM(data, "data")
GK_ATOM(datalist, "datalist")
GK_ATOM(dataType, "data-type")
GK_ATOM(dateTime, "date-time")
GK_ATOM(datasources, "datasources")
GK_ATOM(datetime, "datetime")
GK_ATOM(dblclick, "dblclick")

View File

@ -46,6 +46,7 @@
#include "txOutputFormat.h"
#include "txRtfHandler.h"
#include "txXPathTreeWalker.h"
#include "nsPrintfCString.h"
#ifndef TX_EXE
#include "nsComponentManagerUtils.h"
@ -225,6 +226,7 @@ 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
@ -245,6 +247,7 @@ static txEXSLTFunctionDescriptor descriptTable[] =
{ 1, 1, Expr::NUMBER_RESULT, &txXSLTAtoms::min, 0, kEXSLTMathNS }, // MIN
{ 1, 1, Expr::NODESET_RESULT, &txXSLTAtoms::highest, 0, kEXSLTMathNS }, // HIGHEST
{ 1, 1, Expr::NODESET_RESULT, &txXSLTAtoms::lowest, 0, kEXSLTMathNS }, // LOWEST
{ 0, 0, Expr::STRING_RESULT, &txXSLTAtoms::dateTime, 0, kEXSLTDatesAndTimesNS }, // DATE_TIME
};
@ -269,7 +272,8 @@ public:
MAX,
MIN,
HIGHEST,
LOWEST
LOWEST,
DATE_TIME
};
txEXSLTFunctionCall(eType aType)
@ -685,6 +689,36 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
NS_ADDREF(*aResult = resultSet);
return NS_OK;
}
case DATE_TIME:
{
// http://exslt.org/date/functions/date-time/
// format: YYYY-MM-DDTTHH:MM:SS.sss+00:00
char formatstr[] = "%04hd-%02ld-%02ldT%02ld:%02ld:%02ld.%03ld%c%02ld:%02ld";
const size_t max = sizeof("YYYY-MM-DDTHH:MM:SS.sss+00:00");
PRExplodedTime prtime;
PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &prtime);
PRInt32 offset = (prtime.tm_params.tp_gmt_offset +
prtime.tm_params.tp_dst_offset) / 60;
PRBool isneg = offset < 0;
if (isneg) offset = -offset;
StringResult* strRes;
rv = aContext->recycler()->getStringResult(&strRes);
NS_ENSURE_SUCCESS(rv, rv);
CopyASCIItoUTF16(nsPrintfCString(max, formatstr,
prtime.tm_year, prtime.tm_month + 1, prtime.tm_mday,
prtime.tm_hour, prtime.tm_min, prtime.tm_sec,
prtime.tm_usec / 10000,
isneg ? '-' : '+', offset / 60, offset % 60), strRes->mValue);
*aResult = strRes;
return NS_OK;
}
}

View File

@ -997,6 +997,8 @@ static txFunctionFactoryMapping kExtensionFunctions[] = {
{ "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 }
};

View File

@ -54,6 +54,7 @@ _TEST_FILES = test_bug319374.xhtml \
test_bug551654.html \
test_bug566629.html \
test_bug566629.xhtml \
test_bug603159.html \
test_exslt_regex.html \
$(NULL)

View File

@ -0,0 +1,55 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=603159
-->
<head>
<title>Test for Bug 603159</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=603159">Mozilla Bug 603159</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 603159 **/
var style =
'<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" ' +
'xmlns:date="http://exslt.org/dates-and-times" '+
'version="1.0">' +
'<xsl:output method="html"/>' +
'<xsl:template match="/">' +
'<xsl:value-of select="date:date-time()" /> ' +
'</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);
// use Gecko's Date.parse to parse, then compare the milliseconds since epoch
var xslt_ms = Date.parse(content.innerHTML);
var now_ms = new Date().getTime();
var accepted_diff = 30 * 60 * 1000; // 30 minutes
var diff = Math.abs(now_ms - xslt_ms);
ok(diff < accepted_diff, "generated timestamp should be not more than "
+ accepted_diff + " ms before 'now', but the difference was: " + diff);
content.innerHTML = '';
</script>
</pre>
</body>
</html>