[DevTools] turn Common.Renderer into UI.Renderer
Clients will need to render a generic object/DOMNode, and
be able to call `select()` to select the first child in the
resulting TreeOutline. This CL:
- Turns Common.Renderer > UI.Renderer
- Returns a tree, so interested clients can use it
Bug: 865674
Change-Id: Id877537a3c8713b99d34e6a4558037e0c8b3a111
Reviewed-on: https://chromium-review.googlesource.com/c/1298023
Reviewed-by: Dmitry Gozman <[email protected]>
Reviewed-by: Joel Einbinder <[email protected]>
Commit-Queue: Erik Luo <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#604637}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 3ea41c834168b61e1e2c1b32d23d1775f9ddbe71
diff --git a/front_end/browser_console/BrowserConsole.js b/front_end/browser_console/BrowserConsole.js
index a98df12..e8b8f6f 100644
--- a/front_end/browser_console/BrowserConsole.js
+++ b/front_end/browser_console/BrowserConsole.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
/**
- * @implements {Common.Renderer}
+ * @implements {UI.Renderer}
* @implements {UI.ContextMenu.Provider}
*/
BrowserConsole.BrowserConsole = class {
@@ -25,10 +25,9 @@
/**
* @override
* @param {!Object} object
- * @param {!Common.Renderer.Options} options
- * @return {!Promise.<?Node>}
+ * @return {!Promise<?{node: !Node, tree: ?UI.TreeOutline}>}
*/
- render(object, options) {
+ render(object) {
const consoleMessage = /** @type {!SDK.ConsoleMessage} */ (object);
const request = SDK.NetworkLog.requestForConsoleMessage(consoleMessage);
let messageElement = null;
@@ -51,6 +50,7 @@
messageElement.appendChild(fragment);
}
}
- return Promise.resolve(/** @type {?Node} */ (messageElement));
+ const result = messageElement ? {node: messageElement, tree: null} : null;
+ return Promise.resolve(/** @type {?{node: !Node, tree: ?UI.TreeOutline}} */ (result));
}
};
diff --git a/front_end/browser_console/module.json b/front_end/browser_console/module.json
index 7dbf71b..d259b77 100644
--- a/front_end/browser_console/module.json
+++ b/front_end/browser_console/module.json
@@ -8,7 +8,7 @@
"className": "BrowserConsole.BrowserConsole"
},
{
- "type": "@Common.Renderer",
+ "type": "@UI.Renderer",
"contextTypes": [
"SDK.ConsoleMessage"
],
diff --git a/front_end/common/ModuleExtensionInterfaces.js b/front_end/common/ModuleExtensionInterfaces.js
index cdc0dd3..6d88d49 100644
--- a/front_end/common/ModuleExtensionInterfaces.js
+++ b/front_end/common/ModuleExtensionInterfaces.js
@@ -5,37 +5,6 @@
/**
* @interface
*/
-Common.Renderer = function() {};
-
-Common.Renderer.prototype = {
- /**
- * @param {!Object} object
- * @param {!Common.Renderer.Options} options
- * @return {!Promise.<?Node>}
- */
- render(object, options) {}
-};
-
-/**
- * @param {?Object} object
- * @param {!Common.Renderer.Options=} options
- * @return {!Promise.<?Node>}
- */
-Common.Renderer.render = function(object, options) {
- if (!object)
- return Promise.reject(new Error('Can\'t render ' + object));
- return self.runtime.extension(Common.Renderer, object)
- .instance()
- .then(renderer => renderer.render(object, options || {}));
-};
-
-/** @typedef {!{title: (string|!Element|undefined), expanded: (boolean|undefined),
- * editable: (boolean|undefined) }} */
-Common.Renderer.Options;
-
-/**
- * @interface
- */
Common.Revealer = function() {};
/**
diff --git a/front_end/console/ConsoleViewMessage.js b/front_end/console/ConsoleViewMessage.js
index 7ab961e..b4f863a 100644
--- a/front_end/console/ConsoleViewMessage.js
+++ b/front_end/console/ConsoleViewMessage.js
@@ -252,14 +252,17 @@
} else {
let rendered = false;
this._completeElementForTestPromise = null;
- for (const extension of self.runtime.extensions(Common.Renderer, this._message)) {
+ for (const extension of self.runtime.extensions(UI.Renderer, this._message)) {
if (extension.descriptor()['source'] === this._message.source) {
messageElement = createElement('span');
let callback;
this._completeElementForTestPromise = new Promise(fulfill => callback = fulfill);
extension.instance().then(renderer => {
renderer.render(this._message)
- .then(element => messageElement.appendChild(element || this._format([messageText])))
+ .then(result => {
+ const renderedNode = result ? result.node : null;
+ messageElement.appendChild(renderedNode || this._format([messageText]));
+ })
.then(callback);
});
rendered = true;
@@ -673,18 +676,15 @@
const domModel = remoteObject.runtimeModel().target().model(SDK.DOMModel);
if (!domModel)
return result;
- domModel.pushObjectAsNodeToFrontend(remoteObject).then(node => {
+ domModel.pushObjectAsNodeToFrontend(remoteObject).then(async node => {
if (!node) {
result.appendChild(this._formatParameterAsObject(remoteObject, false));
return;
}
- Common.Renderer.render(node).then(rendererNode => {
- if (rendererNode)
- result.appendChild(rendererNode);
- else
- result.appendChild(this._formatParameterAsObject(remoteObject, false));
- this._formattedParameterAsNodeForTest();
- });
+ const renderResult = await UI.Renderer.render(/** @type {!Object} */ (node));
+ const renderedNode = renderResult ? renderResult.node : null;
+ result.appendChild(renderedNode || this._formatParameterAsObject(remoteObject, false));
+ this._formattedParameterAsNodeForTest();
});
return result;
diff --git a/front_end/elements/ElementsTreeOutline.js b/front_end/elements/ElementsTreeOutline.js
index f93b5c2..2105264 100644
--- a/front_end/elements/ElementsTreeOutline.js
+++ b/front_end/elements/ElementsTreeOutline.js
@@ -1532,19 +1532,19 @@
};
/**
- * @implements {Common.Renderer}
+ * @implements {UI.Renderer}
*/
Elements.ElementsTreeOutline.Renderer = class {
/**
* @override
* @param {!Object} object
- * @return {!Promise.<?Node>}
+ * @return {!Promise<?{node: !Node, tree: ?UI.TreeOutline}>}
*/
render(object) {
return new Promise(renderPromise);
/**
- * @param {function(!Element)} resolve
+ * @param {function(!{node: !Node, tree: ?UI.TreeOutline})} resolve
* @param {function(!Error)} reject
*/
function renderPromise(resolve, reject) {
@@ -1570,7 +1570,7 @@
treeOutline._element.classList.add('single-node');
treeOutline.setVisible(true);
treeOutline.element.treeElementForTest = treeOutline.firstChild();
- resolve(treeOutline.element);
+ resolve({node: treeOutline.element, tree: treeOutline});
}
}
}
diff --git a/front_end/elements/module.json b/front_end/elements/module.json
index 6cffd5f..d4996e0 100644
--- a/front_end/elements/module.json
+++ b/front_end/elements/module.json
@@ -18,7 +18,7 @@
"className": "Elements.ElementsPanel.ContextMenuProvider"
},
{
- "type": "@Common.Renderer",
+ "type": "@UI.Renderer",
"contextTypes": [
"SDK.DOMNode",
"SDK.DeferredDOMNode"
diff --git a/front_end/extensions/ExtensionPanel.js b/front_end/extensions/ExtensionPanel.js
index 1f1a885..fa58d12 100644
--- a/front_end/extensions/ExtensionPanel.js
+++ b/front_end/extensions/ExtensionPanel.js
@@ -277,15 +277,15 @@
return;
}
this._objectPropertiesView.element.removeChildren();
- Common.Renderer
- .render(object, {
- title: title,
- expanded: true,
- editable: false,
- })
- .then(element => {
- this._objectPropertiesView.element.appendChild(element);
- callback();
- });
+ UI.Renderer.render(object, {title, editable: false}).then(result => {
+ if (!result) {
+ callback();
+ return;
+ }
+ if (result.tree && result.tree.firstChild())
+ result.tree.firstChild().expand();
+ this._objectPropertiesView.element.appendChild(result.node);
+ callback();
+ });
}
};
diff --git a/front_end/object_ui/ObjectPropertiesSection.js b/front_end/object_ui/ObjectPropertiesSection.js
index 7e80eb4..745339d 100644
--- a/front_end/object_ui/ObjectPropertiesSection.js
+++ b/front_end/object_ui/ObjectPropertiesSection.js
@@ -1381,14 +1381,14 @@
ObjectUI.ObjectPropertiesSectionExpandController._treeOutlineId = Symbol('treeOutlineId');
/**
- * @implements {Common.Renderer}
+ * @implements {UI.Renderer}
*/
ObjectUI.ObjectPropertiesSection.Renderer = class {
/**
* @override
* @param {!Object} object
- * @param {!Common.Renderer.Options=} options
- * @return {!Promise<?Node>}
+ * @param {!UI.Renderer.Options=} options
+ * @return {!Promise<?{node: !Node, tree: ?UI.TreeOutline}>}
*/
render(object, options) {
if (!(object instanceof SDK.RemoteObject))
@@ -1398,9 +1398,8 @@
const section = new ObjectUI.ObjectPropertiesSection(object, title);
if (!title)
section.titleLessMode();
- if (options.expanded)
- section.expand();
section.editable = !!options.editable;
- return Promise.resolve(section.element);
+ return Promise.resolve(
+ /** @type {?{node: !Node, tree: ?UI.TreeOutline}} */ ({node: section.element, tree: section}));
}
};
\ No newline at end of file
diff --git a/front_end/object_ui/module.json b/front_end/object_ui/module.json
index d56753b..e2d1236 100644
--- a/front_end/object_ui/module.json
+++ b/front_end/object_ui/module.json
@@ -1,7 +1,7 @@
{
"extensions": [
{
- "type": "@Common.Renderer",
+ "type": "@UI.Renderer",
"contextTypes": [
"SDK.RemoteObject"
],
diff --git a/front_end/ui/UIUtils.js b/front_end/ui/UIUtils.js
index 9c2761c..7531b84 100644
--- a/front_end/ui/UIUtils.js
+++ b/front_end/ui/UIUtils.js
@@ -2045,3 +2045,32 @@
});
return fragment;
};
+
+/**
+ * @interface
+ */
+UI.Renderer = function() {};
+
+UI.Renderer.prototype = {
+ /**
+ * @param {!Object} object
+ * @param {!UI.Renderer.Options=} options
+ * @return {!Promise<?{node: !Node, tree: ?UI.TreeOutline}>}
+ */
+ render(object, options) {}
+};
+
+/**
+ * @param {?Object} object
+ * @param {!UI.Renderer.Options=} options
+ * @return {!Promise<?{node: !Node, tree: ?UI.TreeOutline}>}
+ */
+UI.Renderer.render = async function(object, options) {
+ if (!object)
+ throw new Error('Can\'t render ' + object);
+ const renderer = await self.runtime.extension(UI.Renderer, object).instance();
+ return renderer ? renderer.render(object, options || {}) : null;
+};
+
+/** @typedef {!{title: (string|!Element|undefined), editable: (boolean|undefined) }} */
+UI.Renderer.Options;