diff --git a/dom/src/json/test/json2.js b/dom/src/json/test/json2.js index b923b8989e0f..a40e7d7d5d0b 100644 --- a/dom/src/json/test/json2.js +++ b/dom/src/json/test/json2.js @@ -76,19 +76,6 @@ if (!this.crockfordJSON) { return n < 10 ? '0' + n : n; } - Date.prototype.toJSON = function () { - -// Eventually, this method will be based on the date.toISOString method. - - return this.getUTCFullYear() + '-' + - f(this.getUTCMonth() + 1) + '-' + - f(this.getUTCDate()) + 'T' + - f(this.getUTCHours()) + ':' + - f(this.getUTCMinutes()) + ':' + - f(this.getUTCSeconds()) + 'Z'; - }; - - var m = { // table of character substitutions '\b': '\\b', '\t': '\\t', diff --git a/dom/src/json/test/unit/test_encode.js b/dom/src/json/test/unit/test_encode.js index 07532e74989b..9a3940d74551 100644 --- a/dom/src/json/test/unit/test_encode.js +++ b/dom/src/json/test/unit/test_encode.js @@ -1,3 +1,4 @@ + // returns a list of [string, object] pairs to test encoding function getTestPairs() { var testPairs = [ @@ -18,7 +19,10 @@ function getTestPairs() { ['{"x":{"a":"b","c":{"y":"z"},"f":"g"}}', {"x":{"a":"b","c":{"y":"z"},"f":"g"}}], ['{"x":[1,{"y":"z"},3]}', {"x":[1,{"y":"z"},3]}], - //['{"0":"h","1":"m","2":"m"}', new String("hmm")], + ['["hmm"]', [new String("hmm")]], + ['[true]', [new Boolean(true)]], + ['[42]', [new Number(42)]], + ['["1978-09-13T12:24:34.023Z"]', [new Date(Date.UTC(1978, 8, 13, 12, 24, 34, 23))]], ['[1,null,3]',[1,,3]], [null, function test(){}], [null, dump], diff --git a/js/src/jsbool.cpp b/js/src/jsbool.cpp index d4a31003e300..9167fa1a7b4c 100644 --- a/js/src/jsbool.cpp +++ b/js/src/jsbool.cpp @@ -121,6 +121,7 @@ static JSFunctionSpec boolean_methods[] = { #endif JS_FN(js_toString_str, bool_toString, 0, JSFUN_THISP_BOOLEAN), JS_FN(js_valueOf_str, bool_valueOf, 0, JSFUN_THISP_BOOLEAN), + JS_FN(js_toJSON_str, bool_valueOf, 0, JSFUN_THISP_BOOLEAN), JS_FS_END }; diff --git a/js/src/jsdate.cpp b/js/src/jsdate.cpp index eb59f76932b8..f207f4730eae 100644 --- a/js/src/jsdate.cpp +++ b/js/src/jsdate.cpp @@ -1588,8 +1588,38 @@ static const char* months[] = "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + +// Avoid dependence on PRMJ_FormatTimeUSEnglish, because it +// requires a PRMJTime... which only has 16-bit years. Sub-ECMA. +static void +print_gmt_string(char* buf, size_t size, jsdouble utctime) +{ + JS_snprintf(buf, size, "%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT", + days[WeekDay(utctime)], + DateFromTime(utctime), + months[MonthFromTime(utctime)], + YearFromTime(utctime), + HourFromTime(utctime), + MinFromTime(utctime), + SecFromTime(utctime)); +} + +static void +print_iso_string(char* buf, size_t size, jsdouble utctime) +{ + JS_snprintf(buf, size, "%.4d-%.2d-%.2dT%.2d:%.2d:%.2d.%.3dZ", + YearFromTime(utctime), + MonthFromTime(utctime) + 1, + DateFromTime(utctime), + HourFromTime(utctime), + MinFromTime(utctime), + SecFromTime(utctime), + msFromTime(utctime)); +} + static JSBool -date_toGMTString(JSContext *cx, uintN argc, jsval *vp) +date_utc_format(JSContext *cx, jsval *vp, + void (*printFunc)(char*, size_t, jsdouble)) { char buf[100]; JSString *str; @@ -1601,17 +1631,7 @@ date_toGMTString(JSContext *cx, uintN argc, jsval *vp) if (!JSDOUBLE_IS_FINITE(utctime)) { JS_snprintf(buf, sizeof buf, js_NaN_date_str); } else { - /* Avoid dependence on PRMJ_FormatTimeUSEnglish, because it - * requires a PRMJTime... which only has 16-bit years. Sub-ECMA. - */ - JS_snprintf(buf, sizeof buf, "%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT", - days[WeekDay(utctime)], - DateFromTime(utctime), - months[MonthFromTime(utctime)], - YearFromTime(utctime), - HourFromTime(utctime), - MinFromTime(utctime), - SecFromTime(utctime)); + (*printFunc)(buf, sizeof buf, utctime); } str = JS_NewStringCopyZ(cx, buf); if (!str) @@ -1620,6 +1640,18 @@ date_toGMTString(JSContext *cx, uintN argc, jsval *vp) return JS_TRUE; } +static JSBool +date_toGMTString(JSContext *cx, uintN argc, jsval *vp) +{ + return date_utc_format(cx, vp, print_gmt_string); +} + +static JSBool +date_toISOString(JSContext *cx, uintN argc, jsval *vp) +{ + return date_utc_format(cx, vp, print_iso_string); +} + /* for Date.toLocaleString; interface to PRMJTime date struct. */ static void @@ -2027,6 +2059,9 @@ static JSFunctionSpec date_methods[] = { JS_FN("toLocaleFormat", date_toLocaleFormat, 0,0), JS_FN("toDateString", date_toDateString, 0,0), JS_FN("toTimeString", date_toTimeString, 0,0), + JS_FN("toISOString", date_toISOString, 0,0), + JS_FN(js_toJSON_str, date_toISOString, 0,0), + #if JS_HAS_TOSOURCE JS_FN(js_toSource_str, date_toSource, 0,0), #endif diff --git a/js/src/jsnum.cpp b/js/src/jsnum.cpp index 395357b9c186..b4e4907afb4b 100644 --- a/js/src/jsnum.cpp +++ b/js/src/jsnum.cpp @@ -595,6 +595,7 @@ static JSFunctionSpec number_methods[] = { num_toString_trcinfo), JS_FN(js_toLocaleString_str, num_toLocaleString, 0,JSFUN_THISP_NUMBER), JS_FN(js_valueOf_str, num_valueOf, 0,JSFUN_THISP_NUMBER), + JS_FN(js_toJSON_str, num_valueOf, 0,JSFUN_THISP_NUMBER), JS_FN("toFixed", num_toFixed, 1,JSFUN_THISP_NUMBER), JS_FN("toExponential", num_toExponential, 1,JSFUN_THISP_NUMBER), JS_FN("toPrecision", num_toPrecision, 1,JSFUN_THISP_NUMBER), diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index 599ea6f78051..560940f719b0 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -2530,6 +2530,7 @@ static JSFunctionSpec string_methods[] = { /* Java-like methods. */ JS_FN(js_toString_str, str_toString, 0,JSFUN_THISP_STRING), JS_FN(js_valueOf_str, str_toString, 0,JSFUN_THISP_STRING), + JS_FN(js_toJSON_str, str_toString, 0,JSFUN_THISP_STRING), JS_TN("substring", str_substring, 2,GENERIC_PRIMITIVE, str_substring_trcinfo), JS_TN("toLowerCase", str_toLowerCase, 0,GENERIC_PRIMITIVE, str_toLowerCase_trcinfo), JS_TN("toUpperCase", str_toUpperCase, 0,GENERIC_PRIMITIVE, str_toUpperCase_trcinfo),