OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007 Apple Inc. All rights reserved. |
3 * Copyright (C) 2013 Google Inc. All rights reserved. | 3 * Copyright (C) 2013 Google Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * | 8 * |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 | 364 |
365 /** | 365 /** |
366 * This method cannot throw. | 366 * This method cannot throw. |
367 * @param {*} object | 367 * @param {*} object |
368 * @param {string=} objectGroupName | 368 * @param {string=} objectGroupName |
369 * @param {boolean=} forceValueType | 369 * @param {boolean=} forceValueType |
370 * @param {boolean=} generatePreview | 370 * @param {boolean=} generatePreview |
371 * @param {?Array.<string>=} columnNames | 371 * @param {?Array.<string>=} columnNames |
372 * @param {boolean=} isTable | 372 * @param {boolean=} isTable |
373 * @param {boolean=} doNotBind | 373 * @param {boolean=} doNotBind |
| 374 * @param {*=} customObjectConfig |
374 * @return {!RuntimeAgent.RemoteObject} | 375 * @return {!RuntimeAgent.RemoteObject} |
375 * @suppress {checkTypes} | 376 * @suppress {checkTypes} |
376 */ | 377 */ |
377 _wrapObject: function(object, objectGroupName, forceValueType, generatePrevi
ew, columnNames, isTable, doNotBind) | 378 _wrapObject: function(object, objectGroupName, forceValueType, generatePrevi
ew, columnNames, isTable, doNotBind, customObjectConfig) |
378 { | 379 { |
379 try { | 380 try { |
380 return new InjectedScript.RemoteObject(object, objectGroupName, doNo
tBind, forceValueType, generatePreview, columnNames, isTable, undefined); | 381 return new InjectedScript.RemoteObject(object, objectGroupName, doNo
tBind, forceValueType, generatePreview, columnNames, isTable, undefined, customO
bjectConfig); |
381 } catch (e) { | 382 } catch (e) { |
382 try { | 383 try { |
383 var description = injectedScript._describe(e); | 384 var description = injectedScript._describe(e); |
384 } catch (ex) { | 385 } catch (ex) { |
385 var description = "<failed to convert exception to string>"; | 386 var description = "<failed to convert exception to string>"; |
386 } | 387 } |
387 return new InjectedScript.RemoteObject(description); | 388 return new InjectedScript.RemoteObject(description); |
388 } | 389 } |
389 }, | 390 }, |
390 | 391 |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 | 723 |
723 var objectGroup = InjectedScriptHost.idToObjectGroupName(parsedObjectId.
id); | 724 var objectGroup = InjectedScriptHost.idToObjectGroupName(parsedObjectId.
id); |
724 | 725 |
725 /** | 726 /** |
726 * @suppressReceiverCheck | 727 * @suppressReceiverCheck |
727 * @param {*} object | 728 * @param {*} object |
728 * @param {boolean=} forceValueType | 729 * @param {boolean=} forceValueType |
729 * @param {boolean=} generatePreview | 730 * @param {boolean=} generatePreview |
730 * @param {?Array.<string>=} columnNames | 731 * @param {?Array.<string>=} columnNames |
731 * @param {boolean=} isTable | 732 * @param {boolean=} isTable |
| 733 * @param {*=} customObjectConfig |
732 * @return {!RuntimeAgent.RemoteObject} | 734 * @return {!RuntimeAgent.RemoteObject} |
733 * @this {InjectedScript} | 735 * @this {InjectedScript} |
734 */ | 736 */ |
735 function wrap(object, forceValueType, generatePreview, columnNames, isTa
ble) | 737 function wrap(object, forceValueType, generatePreview, columnNames, isTa
ble, customObjectConfig) |
736 { | 738 { |
737 return this._wrapObject(object, objectGroup, forceValueType, generat
ePreview, columnNames, isTable); | 739 return this._wrapObject(object, objectGroup, forceValueType, generat
ePreview, columnNames, isTable, false, customObjectConfig); |
738 } | 740 } |
739 | 741 |
740 try { | 742 try { |
741 | 743 |
742 var remoteObjectAPI = { bindRemoteObject: bind(wrap, this), __proto_
_: null}; | 744 var remoteObjectAPI = { bindRemoteObject: bind(wrap, this), __proto_
_: null}; |
743 InjectedScriptHost.setNonEnumProperty(inspectedWindow, "__remoteObje
ctAPI", remoteObjectAPI); | 745 InjectedScriptHost.setNonEnumProperty(inspectedWindow, "__remoteObje
ctAPI", remoteObjectAPI); |
744 | 746 |
745 var func = InjectedScriptHost.eval("with (typeof __remoteObjectAPI !
== 'undefined' ? __remoteObjectAPI : { __proto__: null }) {(" + expression + ")}
"); | 747 var func = InjectedScriptHost.eval("with (typeof __remoteObjectAPI !
== 'undefined' ? __remoteObjectAPI : { __proto__: null }) {(" + expression + ")}
"); |
746 if (typeof func !== "function") | 748 if (typeof func !== "function") |
747 return "Given expression does not evaluate to a function"; | 749 return "Given expression does not evaluate to a function"; |
748 | 750 |
749 return { wasThrown: false, | 751 return { wasThrown: false, |
750 result: this._wrapObject(InjectedScriptHost.callFunction(fu
nc, object, resolvedArgs), objectGroup, returnByValue), | 752 result: this._wrapObject(InjectedScriptHost.callFunction(fu
nc, object, resolvedArgs), objectGroup, returnByValue), |
751 __proto__: null }; | 753 __proto__: null }; |
752 } catch (e) { | 754 } catch (e) { |
753 return this._createThrownValue(e, objectGroup, false); | 755 return this._createThrownValue(e, objectGroup, false); |
754 } finally { | 756 } finally { |
755 try { | 757 try { |
756 delete inspectedWindow["__remoteObjectAPI"]; | 758 delete inspectedWindow["__remoteObjectAPI"]; |
757 } catch(e) { | 759 } catch(e) { |
758 } | 760 } |
759 } | 761 } |
760 }, | 762 }, |
761 | 763 |
762 /** | 764 /** |
763 * @param {string|undefined} objectGroupName | 765 * @param {string|undefined} objectGroupName |
764 * @param {*} jsonMLObject | 766 * @param {*} jsonMLObject |
765 * @throws {string} error message | 767 * @throws {string} error message |
766 */ | 768 */ |
767 _checkObjectTagsInCustomPreview: function(objectGroupName, jsonMLObject) | 769 _substituteObjectTagsInCustomPreview: function(objectGroupName, jsonMLObject
) |
768 { | 770 { |
769 if (!isArrayLike(jsonMLObject)) | 771 var maxCustomPreviewRecursionDepth = 20; |
770 return; | 772 this._customPreviewRecursionDepth = (this._customPreviewRecursionDepth |
| 0) + 1 |
| 773 try { |
| 774 if (this._customPreviewRecursionDepth >= maxCustomPreviewRecursionDe
pth) |
| 775 throw new Error("Too deep hierarchy of inlined custom previews")
; |
771 | 776 |
772 if (jsonMLObject[0] === "object") | 777 if (!isArrayLike(jsonMLObject)) |
773 throw "Illegal format: object tag is forbidden in header"; | 778 return; |
774 | 779 |
775 for (var i = 0; i < jsonMLObject.length; ++i) | 780 if (jsonMLObject[0] === "object") { |
776 this._checkObjectTagsInCustomPreview(objectGroupName, jsonMLObject[i
]); | 781 var attributes = jsonMLObject[1]; |
| 782 var originObject = attributes["object"]; |
| 783 var config = attributes["config"]; |
| 784 if (typeof originObject === "undefined") |
| 785 throw new Error("Illegal format: obligatory attribute \"obje
ct\" isn't specified"); |
| 786 |
| 787 jsonMLObject[1] = this._wrapObject(originObject, objectGroupName
, false, false, null, false, false, config); |
| 788 return; |
| 789 } |
| 790 |
| 791 for (var i = 0; i < jsonMLObject.length; ++i) |
| 792 this._substituteObjectTagsInCustomPreview(objectGroupName, jsonM
LObject[i]); |
| 793 } finally { |
| 794 this._customPreviewRecursionDepth--; |
| 795 } |
777 }, | 796 }, |
778 | 797 |
779 /** | 798 /** |
780 * Resolves a value from CallArgument description. | 799 * Resolves a value from CallArgument description. |
781 * @param {!RuntimeAgent.CallArgument} callArgumentJson | 800 * @param {!RuntimeAgent.CallArgument} callArgumentJson |
782 * @return {*} resolved value | 801 * @return {*} resolved value |
783 * @throws {string} error message | 802 * @throws {string} error message |
784 */ | 803 */ |
785 _resolveCallArgument: function(callArgumentJson) | 804 _resolveCallArgument: function(callArgumentJson) |
786 { | 805 { |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1226 /** | 1245 /** |
1227 * @constructor | 1246 * @constructor |
1228 * @param {*} object | 1247 * @param {*} object |
1229 * @param {string=} objectGroupName | 1248 * @param {string=} objectGroupName |
1230 * @param {boolean=} doNotBind | 1249 * @param {boolean=} doNotBind |
1231 * @param {boolean=} forceValueType | 1250 * @param {boolean=} forceValueType |
1232 * @param {boolean=} generatePreview | 1251 * @param {boolean=} generatePreview |
1233 * @param {?Array.<string>=} columnNames | 1252 * @param {?Array.<string>=} columnNames |
1234 * @param {boolean=} isTable | 1253 * @param {boolean=} isTable |
1235 * @param {boolean=} skipEntriesPreview | 1254 * @param {boolean=} skipEntriesPreview |
| 1255 * @param {*=} customObjectConfig |
1236 */ | 1256 */ |
1237 InjectedScript.RemoteObject = function(object, objectGroupName, doNotBind, force
ValueType, generatePreview, columnNames, isTable, skipEntriesPreview) | 1257 InjectedScript.RemoteObject = function(object, objectGroupName, doNotBind, force
ValueType, generatePreview, columnNames, isTable, skipEntriesPreview, customObje
ctConfig) |
1238 { | 1258 { |
1239 this.type = typeof object; | 1259 this.type = typeof object; |
1240 if (this.type === "undefined" && injectedScript._isHTMLAllCollection(object)
) | 1260 if (this.type === "undefined" && injectedScript._isHTMLAllCollection(object)
) |
1241 this.type = "object"; | 1261 this.type = "object"; |
1242 | 1262 |
1243 if (injectedScript.isPrimitiveValue(object) || object === null || forceValue
Type) { | 1263 if (injectedScript.isPrimitiveValue(object) || object === null || forceValue
Type) { |
1244 // We don't send undefined values over JSON. | 1264 // We don't send undefined values over JSON. |
1245 if (this.type !== "undefined") | 1265 if (this.type !== "undefined") |
1246 this.value = object; | 1266 this.value = object; |
1247 | 1267 |
(...skipping 27 matching lines...) Expand all Loading... |
1275 this.subtype = subtype; | 1295 this.subtype = subtype; |
1276 var className = InjectedScriptHost.internalConstructorName(object); | 1296 var className = InjectedScriptHost.internalConstructorName(object); |
1277 if (className) | 1297 if (className) |
1278 this.className = className; | 1298 this.className = className; |
1279 this.description = injectedScript._describe(object); | 1299 this.description = injectedScript._describe(object); |
1280 | 1300 |
1281 if (generatePreview && this.type === "object" && this.subtype !== "node") | 1301 if (generatePreview && this.type === "object" && this.subtype !== "node") |
1282 this.preview = this._generatePreview(object, undefined, columnNames, isT
able, skipEntriesPreview); | 1302 this.preview = this._generatePreview(object, undefined, columnNames, isT
able, skipEntriesPreview); |
1283 | 1303 |
1284 if (injectedScript._customObjectFormatterEnabled) { | 1304 if (injectedScript._customObjectFormatterEnabled) { |
1285 var customPreview = this._customPreview(object, objectGroupName); | 1305 var customPreview = this._customPreview(object, objectGroupName, customO
bjectConfig); |
1286 if (customPreview) | 1306 if (customPreview) |
1287 this.customPreview = customPreview; | 1307 this.customPreview = customPreview; |
1288 } | 1308 } |
1289 } | 1309 } |
1290 | 1310 |
1291 InjectedScript.RemoteObject.prototype = { | 1311 InjectedScript.RemoteObject.prototype = { |
1292 | 1312 |
1293 /** | 1313 /** |
1294 * @param {*} object | 1314 * @param {*} object |
1295 * @param {string=} objectGroupName | 1315 * @param {string=} objectGroupName |
| 1316 * @param {*=} customObjectConfig |
1296 * @return {?RuntimeAgent.CustomPreview} | 1317 * @return {?RuntimeAgent.CustomPreview} |
1297 */ | 1318 */ |
1298 _customPreview: function(object, objectGroupName) | 1319 _customPreview: function(object, objectGroupName, customObjectConfig) |
1299 { | 1320 { |
| 1321 /** |
| 1322 * @param {!Error} error |
| 1323 */ |
| 1324 function logError(error) |
| 1325 { |
| 1326 Promise.resolve().then(inspectedWindow.console.error.bind(inspectedW
indow.console, "Custom Formatter Failed: " + error.message)); |
| 1327 } |
| 1328 |
1300 try { | 1329 try { |
1301 var formatters = inspectedWindow["devtoolsFormatters"]; | 1330 var formatters = inspectedWindow["devtoolsFormatters"]; |
1302 if (!formatters || !isArrayLike(formatters)) | 1331 if (!formatters || !isArrayLike(formatters)) |
1303 return null; | 1332 return null; |
1304 | 1333 |
1305 for (var i = 0; i < formatters.length; ++i) { | 1334 for (var i = 0; i < formatters.length; ++i) { |
1306 try { | 1335 try { |
1307 var formatted = formatters[i].header(object); | 1336 var formatted = formatters[i].header(object, customObjectCon
fig); |
1308 if (!formatted) | 1337 if (!formatted) |
1309 continue; | 1338 continue; |
1310 | 1339 |
1311 var hasBody = formatters[i].hasBody(object); | 1340 var hasBody = formatters[i].hasBody(object, customObjectConf
ig); |
1312 injectedScript._checkObjectTagsInCustomPreview(objectGroupNa
me, formatted); | 1341 injectedScript._substituteObjectTagsInCustomPreview(objectGr
oupName, formatted); |
| 1342 var customObjectId = customObjectConfig ? injectedScript._bi
nd(customObjectConfig, objectGroupName) : undefined; |
1313 var formatterObjectId = injectedScript._bind(formatters[i],
objectGroupName); | 1343 var formatterObjectId = injectedScript._bind(formatters[i],
objectGroupName); |
1314 return {header: JSON.stringify(formatted), hasBody: !!hasBod
y, formatterObjectId: formatterObjectId}; | 1344 return {header: JSON.stringify(formatted), hasBody: !!hasBod
y, formatterObjectId: formatterObjectId, configObjectId: customObjectId}; |
1315 } catch (e) { | 1345 } catch (e) { |
1316 inspectedWindow.console.error("Custom Formatter Failed: " +
e); | 1346 logError(e); |
1317 } | 1347 } |
1318 } | 1348 } |
1319 } catch (e) { | 1349 } catch (e) { |
1320 inspectedWindow.console.error("Custom Formatter Failed: " + e); | 1350 logError(e); |
1321 } | 1351 } |
1322 return null; | 1352 return null; |
1323 }, | 1353 }, |
1324 | 1354 |
1325 /** | 1355 /** |
1326 * @return {!RuntimeAgent.ObjectPreview} preview | 1356 * @return {!RuntimeAgent.ObjectPreview} preview |
1327 */ | 1357 */ |
1328 _createEmptyPreview: function() | 1358 _createEmptyPreview: function() |
1329 { | 1359 { |
1330 var preview = { | 1360 var preview = { |
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1989 */ | 2019 */ |
1990 _logEvent: function(event) | 2020 _logEvent: function(event) |
1991 { | 2021 { |
1992 inspectedWindow.console.log(event.type, event); | 2022 inspectedWindow.console.log(event.type, event); |
1993 } | 2023 } |
1994 } | 2024 } |
1995 | 2025 |
1996 injectedScript._commandLineAPIImpl = new CommandLineAPIImpl(); | 2026 injectedScript._commandLineAPIImpl = new CommandLineAPIImpl(); |
1997 return injectedScript; | 2027 return injectedScript; |
1998 }) | 2028 }) |
OLD | NEW |