| Index: Source/core/inspector/InjectedScriptSource.js
|
| diff --git a/Source/core/inspector/InjectedScriptSource.js b/Source/core/inspector/InjectedScriptSource.js
|
| index bd29c2eea54dace8b183befd52118f76b7281e46..c2b4ccefb7009ff78c6535dae4ec23fdd1dbb477 100644
|
| --- a/Source/core/inspector/InjectedScriptSource.js
|
| +++ b/Source/core/inspector/InjectedScriptSource.js
|
| @@ -371,13 +371,14 @@ InjectedScript.prototype = {
|
| * @param {?Array.<string>=} columnNames
|
| * @param {boolean=} isTable
|
| * @param {boolean=} doNotBind
|
| + * @param {*=} customObjectConfig
|
| * @return {!RuntimeAgent.RemoteObject}
|
| * @suppress {checkTypes}
|
| */
|
| - _wrapObject: function(object, objectGroupName, forceValueType, generatePreview, columnNames, isTable, doNotBind)
|
| + _wrapObject: function(object, objectGroupName, forceValueType, generatePreview, columnNames, isTable, doNotBind, customObjectConfig)
|
| {
|
| try {
|
| - return new InjectedScript.RemoteObject(object, objectGroupName, doNotBind, forceValueType, generatePreview, columnNames, isTable, undefined);
|
| + return new InjectedScript.RemoteObject(object, objectGroupName, doNotBind, forceValueType, generatePreview, columnNames, isTable, undefined, customObjectConfig);
|
| } catch (e) {
|
| try {
|
| var description = injectedScript._describe(e);
|
| @@ -729,12 +730,13 @@ InjectedScript.prototype = {
|
| * @param {boolean=} generatePreview
|
| * @param {?Array.<string>=} columnNames
|
| * @param {boolean=} isTable
|
| + * @param {*=} customObjectConfig
|
| * @return {!RuntimeAgent.RemoteObject}
|
| * @this {InjectedScript}
|
| */
|
| - function wrap(object, forceValueType, generatePreview, columnNames, isTable)
|
| + function wrap(object, forceValueType, generatePreview, columnNames, isTable, customObjectConfig)
|
| {
|
| - return this._wrapObject(object, objectGroup, forceValueType, generatePreview, columnNames, isTable);
|
| + return this._wrapObject(object, objectGroup, forceValueType, generatePreview, columnNames, isTable, false, customObjectConfig);
|
| }
|
|
|
| try {
|
| @@ -764,16 +766,33 @@ InjectedScript.prototype = {
|
| * @param {*} jsonMLObject
|
| * @throws {string} error message
|
| */
|
| - _checkObjectTagsInCustomPreview: function(objectGroupName, jsonMLObject)
|
| + _substituteObjectTagsInCustomPreview: function(objectGroupName, jsonMLObject)
|
| {
|
| - if (!isArrayLike(jsonMLObject))
|
| - return;
|
| + var maxCustomPreviewRecursionDepth = 20;
|
| + this._customPreviewRecursionDepth = (this._customPreviewRecursionDepth || 0) + 1
|
| + try {
|
| + if (this._customPreviewRecursionDepth >= maxCustomPreviewRecursionDepth)
|
| + throw new Error("Too deep hierarchy of inlined custom previews");
|
| +
|
| + if (!isArrayLike(jsonMLObject))
|
| + return;
|
|
|
| - if (jsonMLObject[0] === "object")
|
| - throw "Illegal format: object tag is forbidden in header";
|
| + if (jsonMLObject[0] === "object") {
|
| + var attributes = jsonMLObject[1];
|
| + var originObject = attributes["object"];
|
| + var config = attributes["config"];
|
| + if (typeof originObject === "undefined")
|
| + throw new Error("Illegal format: obligatory attribute \"object\" isn't specified");
|
|
|
| - for (var i = 0; i < jsonMLObject.length; ++i)
|
| - this._checkObjectTagsInCustomPreview(objectGroupName, jsonMLObject[i]);
|
| + jsonMLObject[1] = this._wrapObject(originObject, objectGroupName, false, false, null, false, false, config);
|
| + return;
|
| + }
|
| +
|
| + for (var i = 0; i < jsonMLObject.length; ++i)
|
| + this._substituteObjectTagsInCustomPreview(objectGroupName, jsonMLObject[i]);
|
| + } finally {
|
| + this._customPreviewRecursionDepth--;
|
| + }
|
| },
|
|
|
| /**
|
| @@ -1233,8 +1252,9 @@ var injectedScript = new InjectedScript();
|
| * @param {?Array.<string>=} columnNames
|
| * @param {boolean=} isTable
|
| * @param {boolean=} skipEntriesPreview
|
| + * @param {*=} customObjectConfig
|
| */
|
| -InjectedScript.RemoteObject = function(object, objectGroupName, doNotBind, forceValueType, generatePreview, columnNames, isTable, skipEntriesPreview)
|
| +InjectedScript.RemoteObject = function(object, objectGroupName, doNotBind, forceValueType, generatePreview, columnNames, isTable, skipEntriesPreview, customObjectConfig)
|
| {
|
| this.type = typeof object;
|
| if (this.type === "undefined" && injectedScript._isHTMLAllCollection(object))
|
| @@ -1282,7 +1302,7 @@ InjectedScript.RemoteObject = function(object, objectGroupName, doNotBind, force
|
| this.preview = this._generatePreview(object, undefined, columnNames, isTable, skipEntriesPreview);
|
|
|
| if (injectedScript._customObjectFormatterEnabled) {
|
| - var customPreview = this._customPreview(object, objectGroupName);
|
| + var customPreview = this._customPreview(object, objectGroupName, customObjectConfig);
|
| if (customPreview)
|
| this.customPreview = customPreview;
|
| }
|
| @@ -1293,10 +1313,19 @@ InjectedScript.RemoteObject.prototype = {
|
| /**
|
| * @param {*} object
|
| * @param {string=} objectGroupName
|
| + * @param {*=} customObjectConfig
|
| * @return {?RuntimeAgent.CustomPreview}
|
| */
|
| - _customPreview: function(object, objectGroupName)
|
| + _customPreview: function(object, objectGroupName, customObjectConfig)
|
| {
|
| + /**
|
| + * @param {!Error} error
|
| + */
|
| + function logError(error)
|
| + {
|
| + Promise.resolve().then(inspectedWindow.console.error.bind(inspectedWindow.console, "Custom Formatter Failed: " + error.message));
|
| + }
|
| +
|
| try {
|
| var formatters = inspectedWindow["devtoolsFormatters"];
|
| if (!formatters || !isArrayLike(formatters))
|
| @@ -1304,20 +1333,23 @@ InjectedScript.RemoteObject.prototype = {
|
|
|
| for (var i = 0; i < formatters.length; ++i) {
|
| try {
|
| - var formatted = formatters[i].header(object);
|
| + var formatted = formatters[i].header(object, customObjectConfig);
|
| if (!formatted)
|
| continue;
|
|
|
| - var hasBody = formatters[i].hasBody(object);
|
| - injectedScript._checkObjectTagsInCustomPreview(objectGroupName, formatted);
|
| + var hasBody = formatters[i].hasBody(object, customObjectConfig);
|
| + injectedScript._substituteObjectTagsInCustomPreview(objectGroupName, formatted);
|
| var formatterObjectId = injectedScript._bind(formatters[i], objectGroupName);
|
| - return {header: JSON.stringify(formatted), hasBody: !!hasBody, formatterObjectId: formatterObjectId};
|
| + var result = {header: JSON.stringify(formatted), hasBody: !!hasBody, formatterObjectId: formatterObjectId};
|
| + if (customObjectConfig)
|
| + result["configObjectId"] = injectedScript._bind(customObjectConfig, objectGroupName);
|
| + return result;
|
| } catch (e) {
|
| - inspectedWindow.console.error("Custom Formatter Failed: " + e);
|
| + logError(e);
|
| }
|
| }
|
| } catch (e) {
|
| - inspectedWindow.console.error("Custom Formatter Failed: " + e);
|
| + logError(e);
|
| }
|
| return null;
|
| },
|
|
|