From 3972d2a89bfcfe177b12bb225302fc2937a1dbab Mon Sep 17 00:00:00 2001 From: Misko Hevery Date: Thu, 3 Nov 2011 20:26:13 -0700 Subject: refactor(json): break dependence on api.js --- src/JSON.js | 63 ++++++++++++++++++++++++++++++++++++++----- src/angular-mocks.js | 2 +- src/apis.js | 48 --------------------------------- src/service/filter/filters.js | 2 +- test/ApiSpecs.js | 54 ------------------------------------- test/JsonSpec.js | 59 +++++++++++++++++++++++++++++++++++++++- test/angular-mocksSpec.js | 2 +- 7 files changed, 117 insertions(+), 113 deletions(-) diff --git a/src/JSON.js b/src/JSON.js index 51a12860..40bdf44f 100644 --- a/src/JSON.js +++ b/src/JSON.js @@ -53,7 +53,7 @@ function fromJson(json, useNative) { // TODO(misko): remove this once the $http service is checked in. function transformDates(obj) { if (isString(obj) && obj.length === DATE_ISOSTRING_LN) { - return angularString.toDate(obj); + return jsonStringToDate(obj); } else if (isArray(obj) || isObject(obj)) { forEach(obj, function(val, name) { obj[name] = transformDates(val); @@ -63,8 +63,57 @@ function fromJson(json, useNative) { } } -angular.toJson = toJson; -angular.fromJson = fromJson; +var R_ISO8061_STR = /^(\d{4})-(\d\d)-(\d\d)(?:T(\d\d)(?:\:(\d\d)(?:\:(\d\d)(?:\.(\d{3}))?)?)?Z)?$/; +function jsonStringToDate(string){ + var match; + if (isString(string) && (match = string.match(R_ISO8061_STR))){ + var date = new Date(0); + date.setUTCFullYear(match[1], match[2] - 1, match[3]); + date.setUTCHours(match[4]||0, match[5]||0, match[6]||0, match[7]||0); + return date; + } + return string; +} + +function jsonDateToString(date){ + if (!date) return date; + var isoString = date.toISOString ? date.toISOString() : ''; + return (isoString.length==24) + ? isoString + : padNumber(date.getUTCFullYear(), 4) + '-' + + padNumber(date.getUTCMonth() + 1, 2) + '-' + + padNumber(date.getUTCDate(), 2) + 'T' + + padNumber(date.getUTCHours(), 2) + ':' + + padNumber(date.getUTCMinutes(), 2) + ':' + + padNumber(date.getUTCSeconds(), 2) + '.' + + padNumber(date.getUTCMilliseconds(), 3) + 'Z'; +} + +function quoteUnicode(string) { + var chars = ['"']; + for ( var i = 0; i < string.length; i++) { + var code = string.charCodeAt(i); + var ch = string.charAt(i); + switch(ch) { + case '"': chars.push('\\"'); break; + case '\\': chars.push('\\\\'); break; + case '\n': chars.push('\\n'); break; + case '\f': chars.push('\\f'); break; + case '\r': chars.push(ch = '\\r'); break; + case '\t': chars.push(ch = '\\t'); break; + default: + if (32 <= code && code <= 126) { + chars.push(ch); + } else { + var encode = "000" + code.toString(16); + chars.push("\\u" + encode.substring(encode.length - 4)); + } + } + } + chars.push('"'); + return chars.join(''); + } + function toJsonArray(buf, obj, pretty, stack) { if (isObject(obj)) { @@ -87,7 +136,7 @@ function toJsonArray(buf, obj, pretty, stack) { if (obj === null) { buf.push($null); } else if (obj instanceof RegExp) { - buf.push(angularString.quoteUnicode(obj.toString())); + buf.push(quoteUnicode(obj.toString())); } else if (isFunction(obj)) { return; } else if (isBoolean(obj)) { @@ -99,7 +148,7 @@ function toJsonArray(buf, obj, pretty, stack) { buf.push('' + obj); } } else if (isString(obj)) { - return buf.push(angularString.quoteUnicode(obj)); + return buf.push(quoteUnicode(obj)); } else if (isObject(obj)) { if (isArray(obj)) { buf.push("["); @@ -120,7 +169,7 @@ function toJsonArray(buf, obj, pretty, stack) { // TODO(misko): maybe in dev mode have a better error reporting? buf.push('DOM_ELEMENT'); } else if (isDate(obj)) { - buf.push(angularString.quoteUnicode(angular.Date.toString(obj))); + buf.push(quoteUnicode(jsonDateToString(obj))); } else { buf.push("{"); if (pretty) buf.push(pretty); @@ -141,7 +190,7 @@ function toJsonArray(buf, obj, pretty, stack) { buf.push(","); if (pretty) buf.push(pretty); } - buf.push(angularString.quote(key)); + buf.push(quoteUnicode(key)); buf.push(":"); toJsonArray(buf, value, childPretty, stack); comma = true; diff --git a/src/angular-mocks.js b/src/angular-mocks.js index 8ce3011d..497fdc58 100644 --- a/src/angular-mocks.js +++ b/src/angular-mocks.js @@ -468,7 +468,7 @@ angular.mock.TzDate = function (offset, timestamp) { if (angular.isString(timestamp)) { var tsStr = timestamp; - this.origDate = angular.String.toDate(timestamp); + this.origDate = angular.fromJson(angular.toJson({date:timestamp})).date; timestamp = this.origDate.getTime(); if (isNaN(timestamp)) diff --git a/src/apis.js b/src/apis.js index c23f9a61..db600013 100644 --- a/src/apis.js +++ b/src/apis.js @@ -797,7 +797,6 @@ var angularArray = { } }; -var R_ISO8061_STR = /^(\d{4})-(\d\d)-(\d\d)(?:T(\d\d)(?:\:(\d\d)(?:\:(\d\d)(?:\.(\d{3}))?)?)?Z)?$/; var angularString = { 'quote':function(string) { @@ -809,57 +808,10 @@ var angularString = { replace(/\t/g, '\\t'). replace(/\v/g, '\\v') + '"'; - }, - 'quoteUnicode':function(string) { - var str = angular['String']['quote'](string); - var chars = []; - for ( var i = 0; i < str.length; i++) { - var ch = str.charCodeAt(i); - if (ch < 128) { - chars.push(str.charAt(i)); - } else { - var encode = "000" + ch.toString(16); - chars.push("\\u" + encode.substring(encode.length - 4)); - } - } - return chars.join(''); - }, - - /** - * Tries to convert input to date and if successful returns the date, otherwise returns the - * input. - * - * @param {string} string - * @return {(Date|string)} - */ - 'toDate':function(string){ - var match; - if (isString(string) && (match = string.match(R_ISO8061_STR))){ - var date = new Date(0); - date.setUTCFullYear(match[1], match[2] - 1, match[3]); - date.setUTCHours(match[4]||0, match[5]||0, match[6]||0, match[7]||0); - return date; - } - return string; } }; var angularDate = { - 'toString':function(date){ - if (!date) return date; - - var isoString = date.toISOString ? date.toISOString() : ''; - - return (isoString.length==24) ? - isoString : - padNumber(date.getUTCFullYear(), 4) + '-' + - padNumber(date.getUTCMonth() + 1, 2) + '-' + - padNumber(date.getUTCDate(), 2) + 'T' + - padNumber(date.getUTCHours(), 2) + ':' + - padNumber(date.getUTCMinutes(), 2) + ':' + - padNumber(date.getUTCSeconds(), 2) + '.' + - padNumber(date.getUTCMilliseconds(), 3) + 'Z'; - } }; var angularFunction = { diff --git a/src/service/filter/filters.js b/src/service/filter/filters.js index eea3cbf2..a411bf03 100644 --- a/src/service/filter/filters.js +++ b/src/service/filter/filters.js @@ -359,7 +359,7 @@ function dateFilter($locale) { if (NUMBER_STRING.test(date)) { date = parseInt(date, 10); } else { - date = angularString.toDate(date); + date = jsonStringToDate(date); } } diff --git a/test/ApiSpecs.js b/test/ApiSpecs.js index 208169df..7b4a04fb 100644 --- a/test/ApiSpecs.js +++ b/test/ApiSpecs.js @@ -270,59 +270,5 @@ describe('api', function() { }); - - describe('string', function() { - it('should quote', function() { - assertEquals(angular.String.quote('a'), '"a"'); - assertEquals(angular.String.quote('\\'), '"\\\\"'); - assertEquals(angular.String.quote("'a'"), '"\'a\'"'); - assertEquals(angular.String.quote('"a"'), '"\\"a\\""'); - assertEquals(angular.String.quote('\n\f\r\t'), '"\\n\\f\\r\\t"'); - }); - - it('should quote slashes', function() { - assertEquals('"7\\\\\\\"7"', angular.String.quote("7\\\"7")); - }); - - it('should quote unicode', function() { - assertEquals('"abc\\u00a0def"', angular.String.quoteUnicode('abc\u00A0def')); - }); - - it('should read/write to date', function() { - var date = new Date("Sep 10 2003 13:02:03 GMT"); - assertEquals("date", angular.Object.typeOf(date)); - assertEquals("2003-09-10T13:02:03.000Z", angular.Date.toString(date)); - assertEquals(date.getTime(), angular.String.toDate(angular.Date.toString(date)).getTime()); - }); - - it('should convert to date', function() { - //full ISO8061 - expect(angular.String.toDate("2003-09-10T13:02:03.000Z")). - toEqual(new Date("Sep 10 2003 13:02:03 GMT")); - - //no millis - expect(angular.String.toDate("2003-09-10T13:02:03Z")). - toEqual(new Date("Sep 10 2003 13:02:03 GMT")); - - //no seconds - expect(angular.String.toDate("2003-09-10T13:02Z")). - toEqual(new Date("Sep 10 2003 13:02:00 GMT")); - - //no minutes - expect(angular.String.toDate("2003-09-10T13Z")). - toEqual(new Date("Sep 10 2003 13:00:00 GMT")); - - //no time - expect(angular.String.toDate("2003-09-10")). - toEqual(new Date("Sep 10 2003 00:00:00 GMT")); - }); - - it('should parse date', function() { - var date = angular.String.toDate("2003-09-10T13:02:03.000Z"); - assertEquals("date", angular.Object.typeOf(date)); - assertEquals("2003-09-10T13:02:03.000Z", angular.Date.toString(date)); - assertEquals("str", angular.String.toDate("str")); - }); - }); }); diff --git a/test/JsonSpec.js b/test/JsonSpec.js index d3f6de0f..736e6032 100644 --- a/test/JsonSpec.js +++ b/test/JsonSpec.js @@ -72,7 +72,7 @@ describe('json', function() { }); it('should serialize UTC dates', function() { - var date = angular.String.toDate("2009-10-09T01:02:03.027Z"); + var date = jsonStringToDate("2009-10-09T01:02:03.027Z"); expect(toJson(date)).toEqual('"2009-10-09T01:02:03.027Z"'); expect(fromJson('"2009-10-09T01:02:03.027Z"').getTime()).toEqual(date.getTime()); }); @@ -219,4 +219,61 @@ describe('json', function() { }); + + it('should read/write to date', function() { + var date = new Date("Sep 10 2003 13:02:03 GMT"); + assertEquals("2003-09-10T13:02:03.000Z", jsonDateToString(date)); + assertEquals(date.getTime(), jsonStringToDate(jsonDateToString(date)).getTime()); + }); + + + it('should convert to date', function() { + //full ISO8061 + expect(jsonStringToDate("2003-09-10T13:02:03.000Z")). + toEqual(new Date("Sep 10 2003 13:02:03 GMT")); + + //no millis + expect(jsonStringToDate("2003-09-10T13:02:03Z")). + toEqual(new Date("Sep 10 2003 13:02:03 GMT")); + + //no seconds + expect(jsonStringToDate("2003-09-10T13:02Z")). + toEqual(new Date("Sep 10 2003 13:02:00 GMT")); + + //no minutes + expect(jsonStringToDate("2003-09-10T13Z")). + toEqual(new Date("Sep 10 2003 13:00:00 GMT")); + + //no time + expect(jsonStringToDate("2003-09-10")). + toEqual(new Date("Sep 10 2003 00:00:00 GMT")); + }); + + + it('should parse date', function() { + var date = jsonStringToDate("2003-09-10T13:02:03.000Z"); + assertEquals("2003-09-10T13:02:03.000Z", jsonDateToString(date)); + assertEquals("str", jsonStringToDate("str")); + }); + + + describe('string', function() { + it('should quote', function() { + assertEquals(quoteUnicode('a'), '"a"'); + assertEquals(quoteUnicode('\\'), '"\\\\"'); + assertEquals(quoteUnicode("'a'"), '"\'a\'"'); + assertEquals(quoteUnicode('"a"'), '"\\"a\\""'); + assertEquals(quoteUnicode('\n\f\r\t'), '"\\n\\f\\r\\t"'); + }); + + it('should quote slashes', function() { + assertEquals('"7\\\\\\\"7"', quoteUnicode("7\\\"7")); + }); + + it('should quote unicode', function() { + assertEquals('"abc\\u00a0def"', quoteUnicode('abc\u00A0def')); + }); + + }); + }); diff --git a/test/angular-mocksSpec.js b/test/angular-mocksSpec.js index 343be966..b4ceb275 100644 --- a/test/angular-mocksSpec.js +++ b/test/angular-mocksSpec.js @@ -113,7 +113,7 @@ describe('mocks', function() { //from when created from millis - var date2 = new angular.mock.TzDate(-1, angular.String.toDate('2009-12-31T23:00:00.000Z').getTime()); + var date2 = new angular.mock.TzDate(-1, date1.getTime()); expect(date2.getUTCFullYear()).toBe(2009); expect(date2.getUTCMonth()).toBe(11); expect(date2.getUTCDate()).toBe(31); -- cgit v1.2.3