mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-01-12 22:45:52 +08:00
fromJson delegation to native JSON parser if available
- native parser delegation - $xhr change to use native parser
This commit is contained in:
@@ -1,55 +1,28 @@
|
||||
describe('json', function() {
|
||||
xit('should parse json in a reasonable time', function() {
|
||||
var totalSubstr = 0,
|
||||
totalGetMatch = 0,
|
||||
totalConsume = 0,
|
||||
totalTime = 0,
|
||||
runTimes = [];
|
||||
|
||||
for (var i=0; i<10; i++) {
|
||||
window.substrTime = 0;
|
||||
window.getMatchTime = 0;
|
||||
window.consumeTime = 0;
|
||||
var start = Date.now();
|
||||
expect(angular.fromJson(largeJsonString)).toBeTruthy();
|
||||
var time = Date.now() - start;
|
||||
// dump('parse time', time, 'consume', window.consumeTime,
|
||||
// 'substr', window.substrTime,
|
||||
// 'getMatch', window.getMatchTime);
|
||||
totalTime += time;
|
||||
totalSubstr += window.substrTime;
|
||||
totalGetMatch += window.getMatchTime;
|
||||
totalConsume += window.consumeTime;
|
||||
runTimes.push(time);
|
||||
}
|
||||
|
||||
totalGetMatch = totalGetMatch - totalSubstr;
|
||||
|
||||
dump("totals", totalTime,
|
||||
"| consume", totalConsume, '' + Math.round(totalConsume/(totalTime/100)) + '%',
|
||||
"| substr", totalSubstr, '' + Math.round(totalSubstr/(totalTime/100)) + '%',
|
||||
"| getMatch", totalGetMatch, '' + Math.round(totalGetMatch/(totalTime/100)) + '%');
|
||||
dump("run times", runTimes);
|
||||
delete window.consumeTime;
|
||||
delete window.substrTime;
|
||||
delete window.getMatchTime;
|
||||
});
|
||||
|
||||
|
||||
it('angular parser', function() {
|
||||
var duration = time(function() {
|
||||
expect(angular.fromJson(largeJsonString)).toBeTruthy();
|
||||
}, 1);
|
||||
|
||||
expect(duration).toBeLessThan(4000);
|
||||
dump(duration/1 + ' ms per iteration');
|
||||
});
|
||||
|
||||
|
||||
it('angular delegating to native parser', function() {
|
||||
var duration = time(function() {
|
||||
expect(angular.fromJson(largeJsonString, true)).toBeTruthy();
|
||||
}, 100);
|
||||
|
||||
dump(duration/100 + ' ms per iteration');
|
||||
});
|
||||
|
||||
|
||||
it('native json', function() {
|
||||
var duration = time(function() {
|
||||
expect(JSON.parse(largeJsonString)).toBeTruthy();
|
||||
}, 1);
|
||||
}, 100);
|
||||
|
||||
expect(duration).toBeLessThan(200);
|
||||
dump(duration/100 + ' ms per iteration');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -109,7 +109,8 @@ var _undefined = undefined,
|
||||
angularService = extensionMap(angular, 'service'),
|
||||
angularCallbacks = extensionMap(angular, 'callbacks'),
|
||||
nodeName,
|
||||
rngScript = /^(|.*\/)angular(-.*?)?(\.min)?.js(\?[^#]*)?(#(.*))?$/;
|
||||
rngScript = /^(|.*\/)angular(-.*?)?(\.min)?.js(\?[^#]*)?(#(.*))?$/,
|
||||
DATE_ISOSTRING_LN = 24;
|
||||
|
||||
/**
|
||||
* @workInProgress
|
||||
|
||||
28
src/JSON.js
28
src/JSON.js
@@ -29,19 +29,41 @@ function toJson(obj, pretty) {
|
||||
* Deserializes a string in the JSON format.
|
||||
*
|
||||
* @param {string} json JSON string to deserialize.
|
||||
* @param {boolean} [useNative=false] Use native JSON parser if available
|
||||
* @returns {Object|Array|Date|string|number} Deserialized thingy.
|
||||
*/
|
||||
function fromJson(json) {
|
||||
function fromJson(json, useNative) {
|
||||
if (!json) return json;
|
||||
|
||||
var obj, p, expression;
|
||||
|
||||
try {
|
||||
var p = parser(json, true);
|
||||
var expression = p.primary();
|
||||
if (useNative && JSON && JSON.parse) {
|
||||
obj = JSON.parse(json);
|
||||
return transformDates(obj);
|
||||
}
|
||||
|
||||
p = parser(json, true);
|
||||
expression = p.primary();
|
||||
p.assertAllConsumed();
|
||||
return expression();
|
||||
|
||||
} catch (e) {
|
||||
error("fromJson error: ", json, e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
// TODO make foreach optionally recursive and remove this function
|
||||
function transformDates(obj) {
|
||||
if (isString(obj) && obj.length === DATE_ISOSTRING_LN) {
|
||||
return angularString.toDate(obj);
|
||||
} else if (isArray(obj) || isObject(obj)) {
|
||||
foreach(obj, function(val, name) {
|
||||
obj[name] = transformDates(val);
|
||||
});
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
angular['toJson'] = toJson;
|
||||
|
||||
@@ -26,7 +26,7 @@ var OPERATORS = {
|
||||
var ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'};
|
||||
|
||||
function lex(text, parseStringsForObjects){
|
||||
var dateParseLength = parseStringsForObjects ? 24 : -1,
|
||||
var dateParseLength = parseStringsForObjects ? DATE_ISOSTRING_LN : -1,
|
||||
tokens = [],
|
||||
token,
|
||||
index = 0,
|
||||
|
||||
@@ -705,7 +705,7 @@ angularServiceInject('$xhr', function($browser, $error, $log){
|
||||
$browser.xhr(method, url, post, function(code, response){
|
||||
try {
|
||||
if (isString(response) && /^\s*[\[\{]/.exec(response) && /[\}\]]\s*$/.exec(response)) {
|
||||
response = fromJson(response);
|
||||
response = fromJson(response, true);
|
||||
}
|
||||
if (code == 200) {
|
||||
callback(code, response);
|
||||
|
||||
@@ -116,6 +116,42 @@ describe('json', function(){
|
||||
expect(fromJson("{exp:1.2e-10}")).toEqual({exp:1.2E-10});
|
||||
});
|
||||
|
||||
|
||||
//run these tests only in browsers that have native JSON parser
|
||||
if (JSON && JSON.parse) {
|
||||
|
||||
describe('native parser', function() {
|
||||
|
||||
var nativeParser = JSON.parse;
|
||||
|
||||
afterEach(function() {
|
||||
JSON.parse = nativeParser;
|
||||
});
|
||||
|
||||
|
||||
it('should delegate to native parser if available and boolean flag is passed', function() {
|
||||
var spy = this.spyOn(JSON, 'parse').andCallThrough();
|
||||
|
||||
expect(fromJson('{}')).toEqual({});
|
||||
expect(spy).wasNotCalled();
|
||||
|
||||
expect(fromJson('{}', true)).toEqual({});
|
||||
expect(spy).wasCalled();
|
||||
});
|
||||
|
||||
|
||||
it('should convert timestamp strings to Date objects', function() {
|
||||
expect(fromJson('"2010-12-22T17:23:17.974Z"', true) instanceof Date).toBe(true);
|
||||
expect(fromJson('["2010-12-22T17:23:17.974Z"]', true)[0] instanceof Date).toBe(true);
|
||||
expect(fromJson('{"t":"2010-12-22T17:23:17.974Z"}', true).t instanceof Date).toBe(true);
|
||||
expect(fromJson('{"t":["2010-12-22T17:23:17.974Z"]}', true).t[0] instanceof Date).toBe(true);
|
||||
expect(fromJson('{"t":{"t":"2010-12-22T17:23:17.974Z"}}', true).t.t instanceof Date).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
describe('security', function(){
|
||||
it('should not allow naked expressions', function(){
|
||||
expect(function(){fromJson('1+2');}).
|
||||
|
||||
Reference in New Issue
Block a user