Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/network/JSONView.js

Issue 1912973002: [DevTools] JSONView parsing smarter (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 22 matching lines...) Expand all
33 * @extends {WebInspector.VBox} 33 * @extends {WebInspector.VBox}
34 * @param {!WebInspector.ParsedJSON} parsedJSON 34 * @param {!WebInspector.ParsedJSON} parsedJSON
35 */ 35 */
36 WebInspector.JSONView = function(parsedJSON) 36 WebInspector.JSONView = function(parsedJSON)
37 { 37 {
38 WebInspector.VBox.call(this); 38 WebInspector.VBox.call(this);
39 this._parsedJSON = parsedJSON; 39 this._parsedJSON = parsedJSON;
40 this.element.classList.add("json-view"); 40 this.element.classList.add("json-view");
41 } 41 }
42 42
43 // "false", "true", "null", ",", "{", "}", "[", "]", number, double-quoted strin g. 43 /**
44 WebInspector.JSONView._jsonToken = new RegExp('(?:false|true|null|[/*&\\|;=\\(\\ ),\\{\\}\\[\\]]|(?:-?\\b(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\\b)| (?:\"(?:[^\\0-\\x08\\x0a-\\x1f\"\\\\]|\\\\(?:[\"/\\\\bfnrt]|u[0-9A-Fa-f]{4}))*\" ))', "g"); 44 * @param {?string} text
45 * @return {!Promise<?WebInspector.ParsedJSON>}
46 */
47 WebInspector.JSONView.parseJSON = function(text)
48 {
49 var returnObj = null;
50 if (text)
51 returnObj = WebInspector.JSONView._extractJSON(/** @type {string} */ (te xt));
52 if (!returnObj)
53 return Promise.resolve(/** @type {?WebInspector.ParsedJSON} */ (null));
54 return new Promise(runParser);
45 55
46 // Escaped unicode char. 56 /**
47 WebInspector.JSONView._escapedUnicode = new RegExp("\\\\(?:([^u])|u(.{4}))", "g" ); 57 * @param {function(*)} success
58 */
59 function runParser(success) {
60 var worker = new WorkerRuntime.Worker("formatter_worker");
61 worker.onmessage = /** @type function(!MessageEvent) */ (handleReturned JSON);
62 worker.postMessage({method: "relaxedJSONParser", params:{content: return Obj.data}});
48 63
49 // Map from escaped char to its literal value. 64 /**
50 WebInspector.JSONView._standardEscapes = {'"': '"', "/": "/", "\\": "\\", "b": " \b", "f": "\f", "n": "\n", "r": "\r", "t": "\t"}; 65 * @param {!MessageEvent} event
51 66 */
52 /** 67 function handleReturnedJSON(event) {
53 * @param {string} full 68 worker.terminate();
54 * @param {string} standard 69 if (!event.data) {
55 * @param {string} unicode 70 success(null);
56 * @return {string} 71 return;
57 */
58 WebInspector.JSONView._unescape = function(full, standard, unicode)
59 {
60 return standard ? WebInspector.JSONView._standardEscapes[standard] : String. fromCharCode(parseInt(unicode, 16));
61 }
62
63 /**
64 * @param {string} text
65 * @return {string}
66 */
67 WebInspector.JSONView._unescapeString = function(text)
68 {
69 return text.indexOf("\\") === -1 ? text : text.replace(WebInspector.JSONView ._escapedUnicode, WebInspector.JSONView._unescape);
70 }
71
72 /**
73 * @return {*}
74 */
75 WebInspector.JSONView._buildObjectFromJSON = function(text)
76 {
77 var regExp = WebInspector.JSONView._jsonToken;
78 regExp.lastIndex = 0;
79 var result = [];
80 var tip = result;
81 var stack = [];
82 var key = undefined;
83 var token = undefined;
84 var lastToken = undefined;
85 while (true) {
86 var match = regExp.exec(text);
87 if (match === null)
88 break;
89 lastToken = token;
90 token = match[0];
91 var code = token.charCodeAt(0);
92 if ((code === 0x5b) || (code === 0x7b)) { // [ or {
93 var newTip = (code === 0x5b) ? [] : {};
94 tip[key || tip.length] = newTip;
95 stack.push(tip);
96 tip = newTip;
97 } else if ((code === 0x5d) || (code === 0x7d)) { // ] or }
98 tip = stack.pop();
99 if (!tip)
100 break;
101 } else if (code === 0x2C) { // ,
102 if (Array.isArray(tip) && (lastToken === undefined || lastToken === "[" || lastToken === ","))
103 tip[tip.length] = undefined;
104 } else if (code === 0x22) { // "
105 token = WebInspector.JSONView._unescapeString(token.substring(1, tok en.length - 1));
106 if (!key) {
107 if (Array.isArray(tip)) {
108 key = tip.length;
109 } else {
110 key = token || "";
111 continue;
112 }
113 } 72 }
114 tip[key] = token; 73 returnObj.data = event.data;
115 } else if (code === 0x66) { // f 74 success(returnObj);
116 tip[key || tip.length] = false;
117 } else if (code === 0x6e) { // n
118 tip[key || tip.length] = null;
119 } else if (code === 0x74) { // t
120 tip[key || tip.length] = true;
121 } else if (code === 0x2f || code === 0x2a || code === 0x26 || code === 0 x7c || code === 0x3b || code === 0x3d || code === 0x28 || code === 0x29) { // /* &|;=()
122 // Looks like JavaScript
123 throw "Invalid JSON";
124 } else { // sign or digit
125 tip[key || tip.length] = +(token);
126 } 75 }
127 key = undefined;
128 } 76 }
129 return (result.length > 1) ? result : result[0];
130 } 77 }
131 78
132 /** 79 /**
133 * @param {string} text 80 * @param {string} text
134 * @return {?WebInspector.ParsedJSON} 81 * @return {?WebInspector.ParsedJSON}
135 */ 82 */
136 WebInspector.JSONView.parseJSON = function(text) 83 WebInspector.JSONView._extractJSON = function(text)
137 { 84 {
138 // Do not treat HTML as JSON. 85 // Do not treat HTML as JSON.
139 if (text.startsWith("<")) 86 if (text.startsWith("<"))
140 return null; 87 return null;
141 var inner = WebInspector.JSONView._findBrackets(text, "{", "}"); 88 var inner = WebInspector.JSONView._findBrackets(text, "{", "}");
142 var inner2 = WebInspector.JSONView._findBrackets(text, "[", "]"); 89 var inner2 = WebInspector.JSONView._findBrackets(text, "[", "]");
143 inner = inner2.length > inner.length ? inner2 : inner; 90 inner = inner2.length > inner.length ? inner2 : inner;
144 91
145 // Return on blank payloads or on payloads significantly smaller than origin al text. 92 // Return on blank payloads or on payloads significantly smaller than origin al text.
146 if (inner.length === -1 || text.length - inner.length > 80) 93 if (inner.length === -1 || text.length - inner.length > 80)
147 return null; 94 return null;
148 95
149 var prefix = text.substring(0, inner.start); 96 var prefix = text.substring(0, inner.start);
150 var suffix = text.substring(inner.end + 1); 97 var suffix = text.substring(inner.end + 1);
151 text = text.substring(inner.start, inner.end + 1); 98 text = text.substring(inner.start, inner.end + 1);
152 99
153 // Only process valid JSONP. 100 // Only process valid JSONP.
154 if (suffix.trim().length && !(suffix.trim().startsWith(")") && prefix.trim() .endsWith("("))) 101 if (suffix.trim().length && !(suffix.trim().startsWith(")") && prefix.trim() .endsWith("(")))
155 return null; 102 return null;
156 103
157 try { 104 return new WebInspector.ParsedJSON(text, prefix, suffix);
158 return new WebInspector.ParsedJSON(WebInspector.JSONView._buildObjectFro mJSON(text), prefix, suffix);
159 } catch (e) {
160 return null;
161 }
162 } 105 }
163 106
164 /** 107 /**
165 * @param {string} text 108 * @param {string} text
166 * @param {string} open 109 * @param {string} open
167 * @param {string} close 110 * @param {string} close
168 * @return {{start: number, end: number, length: number}} 111 * @return {{start: number, end: number, length: number}}
169 */ 112 */
170 WebInspector.JSONView._findBrackets = function(text, open, close) 113 WebInspector.JSONView._findBrackets = function(text, open, close)
171 { 114 {
(...skipping 13 matching lines...) Expand all
185 128
186 _initialize: function() 129 _initialize: function()
187 { 130 {
188 if (this._initialized) 131 if (this._initialized)
189 return; 132 return;
190 this._initialized = true; 133 this._initialized = true;
191 134
192 var obj = WebInspector.RemoteObject.fromLocalObject(this._parsedJSON.dat a); 135 var obj = WebInspector.RemoteObject.fromLocalObject(this._parsedJSON.dat a);
193 var title = this._parsedJSON.prefix + obj.description + this._parsedJSON .suffix; 136 var title = this._parsedJSON.prefix + obj.description + this._parsedJSON .suffix;
194 var section = new WebInspector.ObjectPropertiesSection(obj, title); 137 var section = new WebInspector.ObjectPropertiesSection(obj, title);
138 section.setEditable(false);
195 section.expand(); 139 section.expand();
196 section.editable = false;
197 this.element.appendChild(section.element); 140 this.element.appendChild(section.element);
198 }, 141 },
199 142
200 __proto__: WebInspector.VBox.prototype 143 __proto__: WebInspector.VBox.prototype
201 } 144 }
202 145
203 /** 146 /**
204 * @constructor 147 * @constructor
205 * @param {*} data 148 * @param {*} data
206 * @param {string} prefix 149 * @param {string} prefix
207 * @param {string} suffix 150 * @param {string} suffix
208 */ 151 */
209 WebInspector.ParsedJSON = function(data, prefix, suffix) 152 WebInspector.ParsedJSON = function(data, prefix, suffix)
210 { 153 {
211 this.data = data; 154 this.data = data;
212 this.prefix = prefix; 155 this.prefix = prefix;
213 this.suffix = suffix; 156 this.suffix = suffix;
214 } 157 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698