refactor(json): break dependence on api.js

This commit is contained in:
Misko Hevery 2011-11-03 20:26:13 -07:00
parent cb6f832f38
commit 3972d2a89b
7 changed files with 117 additions and 113 deletions

View file

@ -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;

View file

@ -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))

View file

@ -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 = {

View file

@ -359,7 +359,7 @@ function dateFilter($locale) {
if (NUMBER_STRING.test(date)) {
date = parseInt(date, 10);
} else {
date = angularString.toDate(date);
date = jsonStringToDate(date);
}
}

View file

@ -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"));
});
});
});

View file

@ -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'));
});
});
});

View file

@ -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);