| Index: third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js
|
| diff --git a/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js b/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js
|
| index 8c254697333d46aecca7c3b30001764b04e7fbe5..a3df7117d2d7faddee6c0afc3ba0a8e3bd2a5c07 100644
|
| --- a/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js
|
| +++ b/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js
|
| @@ -27,16 +27,17 @@
|
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| */
|
| -
|
| /**
|
| - * @constructor
|
| * @implements {WebInspector.ViewportElement}
|
| - * @param {!WebInspector.ConsoleMessage} consoleMessage
|
| - * @param {!WebInspector.Linkifier} linkifier
|
| - * @param {number} nestingLevel
|
| + * @unrestricted
|
| */
|
| -WebInspector.ConsoleViewMessage = function(consoleMessage, linkifier, nestingLevel)
|
| -{
|
| +WebInspector.ConsoleViewMessage = class {
|
| + /**
|
| + * @param {!WebInspector.ConsoleMessage} consoleMessage
|
| + * @param {!WebInspector.Linkifier} linkifier
|
| + * @param {number} nestingLevel
|
| + */
|
| + constructor(consoleMessage, linkifier, nestingLevel) {
|
| this._message = consoleMessage;
|
| this._linkifier = linkifier;
|
| this._repeatCount = 1;
|
| @@ -47,1231 +48,1193 @@ WebInspector.ConsoleViewMessage = function(consoleMessage, linkifier, nestingLev
|
| this._dataGrid = null;
|
| this._previewFormatter = new WebInspector.RemoteObjectPreviewFormatter();
|
| this._searchRegex = null;
|
| -};
|
| -
|
| -WebInspector.ConsoleViewMessage.prototype = {
|
| - /**
|
| - * @return {?WebInspector.Target}
|
| - */
|
| - _target: function()
|
| - {
|
| - return this.consoleMessage().target();
|
| - },
|
| -
|
| - /**
|
| - * @override
|
| - * @return {!Element}
|
| - */
|
| - element: function()
|
| - {
|
| - return this.toMessageElement();
|
| - },
|
| -
|
| - /**
|
| - * @override
|
| - */
|
| - wasShown: function()
|
| - {
|
| - if (this._dataGrid)
|
| - this._dataGrid.updateWidths();
|
| - this._isVisible = true;
|
| - },
|
| -
|
| - onResize: function()
|
| - {
|
| - if (!this._isVisible)
|
| - return;
|
| - if (this._dataGrid)
|
| - this._dataGrid.onResize();
|
| - },
|
| -
|
| - /**
|
| - * @override
|
| - */
|
| - willHide: function()
|
| - {
|
| - this._isVisible = false;
|
| - this._cachedHeight = this.contentElement().offsetHeight;
|
| - },
|
| -
|
| - /**
|
| - * @return {number}
|
| - */
|
| - fastHeight: function()
|
| - {
|
| - if (this._cachedHeight)
|
| - return this._cachedHeight;
|
| - // This value reflects the 18px min-height of .console-message, plus the
|
| - // 1px border of .console-message-wrapper. Keep in sync with consoleView.css.
|
| - const defaultConsoleRowHeight = 19;
|
| - if (this._message.type === WebInspector.ConsoleMessage.MessageType.Table) {
|
| - var table = this._message.parameters[0];
|
| - if (table && table.preview)
|
| - return defaultConsoleRowHeight * table.preview.properties.length;
|
| - }
|
| - return defaultConsoleRowHeight;
|
| - },
|
| -
|
| - /**
|
| - * @return {!WebInspector.ConsoleMessage}
|
| - */
|
| - consoleMessage: function()
|
| - {
|
| - return this._message;
|
| - },
|
| -
|
| - /**
|
| - * @param {!WebInspector.ConsoleMessage} consoleMessage
|
| - * @return {!Element}
|
| - */
|
| - _buildTableMessage: function(consoleMessage)
|
| - {
|
| - var formattedMessage = createElement("span");
|
| - WebInspector.appendStyle(formattedMessage, "components/objectValue.css");
|
| - formattedMessage.className = "console-message-text source-code";
|
| - var anchorElement = this._buildMessageAnchor(consoleMessage);
|
| - if (anchorElement)
|
| - formattedMessage.appendChild(anchorElement);
|
| -
|
| - var table = consoleMessage.parameters && consoleMessage.parameters.length ? consoleMessage.parameters[0] : null;
|
| - if (table)
|
| - table = this._parameterToRemoteObject(table, this._target());
|
| - if (!table || !table.preview)
|
| - return formattedMessage;
|
| -
|
| - var columnNames = [];
|
| - var preview = table.preview;
|
| - var rows = [];
|
| - for (var i = 0; i < preview.properties.length; ++i) {
|
| - var rowProperty = preview.properties[i];
|
| - var rowPreview = rowProperty.valuePreview;
|
| - if (!rowPreview)
|
| - continue;
|
| -
|
| - var rowValue = {};
|
| - const maxColumnsToRender = 20;
|
| - for (var j = 0; j < rowPreview.properties.length; ++j) {
|
| - var cellProperty = rowPreview.properties[j];
|
| - var columnRendered = columnNames.indexOf(cellProperty.name) !== -1;
|
| - if (!columnRendered) {
|
| - if (columnNames.length === maxColumnsToRender)
|
| - continue;
|
| - columnRendered = true;
|
| - columnNames.push(cellProperty.name);
|
| - }
|
| -
|
| - if (columnRendered) {
|
| - var cellElement = this._renderPropertyPreviewOrAccessor(table, [rowProperty, cellProperty]);
|
| - cellElement.classList.add("console-message-nowrap-below");
|
| - rowValue[cellProperty.name] = cellElement;
|
| - }
|
| - }
|
| - rows.push([rowProperty.name, rowValue]);
|
| + }
|
| +
|
| + /**
|
| + * @return {?WebInspector.Target}
|
| + */
|
| + _target() {
|
| + return this.consoleMessage().target();
|
| + }
|
| +
|
| + /**
|
| + * @override
|
| + * @return {!Element}
|
| + */
|
| + element() {
|
| + return this.toMessageElement();
|
| + }
|
| +
|
| + /**
|
| + * @override
|
| + */
|
| + wasShown() {
|
| + if (this._dataGrid)
|
| + this._dataGrid.updateWidths();
|
| + this._isVisible = true;
|
| + }
|
| +
|
| + onResize() {
|
| + if (!this._isVisible)
|
| + return;
|
| + if (this._dataGrid)
|
| + this._dataGrid.onResize();
|
| + }
|
| +
|
| + /**
|
| + * @override
|
| + */
|
| + willHide() {
|
| + this._isVisible = false;
|
| + this._cachedHeight = this.contentElement().offsetHeight;
|
| + }
|
| +
|
| + /**
|
| + * @return {number}
|
| + */
|
| + fastHeight() {
|
| + if (this._cachedHeight)
|
| + return this._cachedHeight;
|
| + // This value reflects the 18px min-height of .console-message, plus the
|
| + // 1px border of .console-message-wrapper. Keep in sync with consoleView.css.
|
| + const defaultConsoleRowHeight = 19;
|
| + if (this._message.type === WebInspector.ConsoleMessage.MessageType.Table) {
|
| + var table = this._message.parameters[0];
|
| + if (table && table.preview)
|
| + return defaultConsoleRowHeight * table.preview.properties.length;
|
| + }
|
| + return defaultConsoleRowHeight;
|
| + }
|
| +
|
| + /**
|
| + * @return {!WebInspector.ConsoleMessage}
|
| + */
|
| + consoleMessage() {
|
| + return this._message;
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.ConsoleMessage} consoleMessage
|
| + * @return {!Element}
|
| + */
|
| + _buildTableMessage(consoleMessage) {
|
| + var formattedMessage = createElement('span');
|
| + WebInspector.appendStyle(formattedMessage, 'components/objectValue.css');
|
| + formattedMessage.className = 'console-message-text source-code';
|
| + var anchorElement = this._buildMessageAnchor(consoleMessage);
|
| + if (anchorElement)
|
| + formattedMessage.appendChild(anchorElement);
|
| +
|
| + var table = consoleMessage.parameters && consoleMessage.parameters.length ? consoleMessage.parameters[0] : null;
|
| + if (table)
|
| + table = this._parameterToRemoteObject(table, this._target());
|
| + if (!table || !table.preview)
|
| + return formattedMessage;
|
| +
|
| + var columnNames = [];
|
| + var preview = table.preview;
|
| + var rows = [];
|
| + for (var i = 0; i < preview.properties.length; ++i) {
|
| + var rowProperty = preview.properties[i];
|
| + var rowPreview = rowProperty.valuePreview;
|
| + if (!rowPreview)
|
| + continue;
|
| +
|
| + var rowValue = {};
|
| + const maxColumnsToRender = 20;
|
| + for (var j = 0; j < rowPreview.properties.length; ++j) {
|
| + var cellProperty = rowPreview.properties[j];
|
| + var columnRendered = columnNames.indexOf(cellProperty.name) !== -1;
|
| + if (!columnRendered) {
|
| + if (columnNames.length === maxColumnsToRender)
|
| + continue;
|
| + columnRendered = true;
|
| + columnNames.push(cellProperty.name);
|
| }
|
|
|
| - var flatValues = [];
|
| - for (var i = 0; i < rows.length; ++i) {
|
| - var rowName = rows[i][0];
|
| - var rowValue = rows[i][1];
|
| - flatValues.push(rowName);
|
| - for (var j = 0; j < columnNames.length; ++j)
|
| - flatValues.push(rowValue[columnNames[j]]);
|
| - }
|
| - columnNames.unshift(WebInspector.UIString("(index)"));
|
| -
|
| - if (flatValues.length) {
|
| - this._dataGrid = WebInspector.SortableDataGrid.create(columnNames, flatValues);
|
| -
|
| - var formattedResult = createElement("span");
|
| - var tableElement = formattedResult.createChild("div", "console-message-formatted-table");
|
| - var dataGridContainer = tableElement.createChild("span");
|
| - tableElement.appendChild(this._formatParameter(table, true, false));
|
| - dataGridContainer.appendChild(this._dataGrid.element);
|
| - formattedMessage.appendChild(formattedResult);
|
| - this._dataGrid.renderInline();
|
| + if (columnRendered) {
|
| + var cellElement = this._renderPropertyPreviewOrAccessor(table, [rowProperty, cellProperty]);
|
| + cellElement.classList.add('console-message-nowrap-below');
|
| + rowValue[cellProperty.name] = cellElement;
|
| }
|
| - return formattedMessage;
|
| - },
|
| + }
|
| + rows.push([rowProperty.name, rowValue]);
|
| + }
|
|
|
| - /**
|
| - * @param {!WebInspector.ConsoleMessage} consoleMessage
|
| - * @return {!Element}
|
| - */
|
| - _buildMessage: function(consoleMessage)
|
| - {
|
| - var messageElement;
|
| - if (consoleMessage.source === WebInspector.ConsoleMessage.MessageSource.ConsoleAPI) {
|
| - switch (consoleMessage.type) {
|
| - case WebInspector.ConsoleMessage.MessageType.Trace:
|
| - messageElement = this._format(consoleMessage.parameters || ["console.trace"]);
|
| - break;
|
| - case WebInspector.ConsoleMessage.MessageType.Clear:
|
| - messageElement = createElementWithClass("span", "console-info");
|
| - messageElement.textContent = WebInspector.UIString("Console was cleared");
|
| - break;
|
| - case WebInspector.ConsoleMessage.MessageType.Assert:
|
| - var args = [WebInspector.UIString("Assertion failed:")];
|
| - if (consoleMessage.parameters)
|
| - args = args.concat(consoleMessage.parameters);
|
| - messageElement = this._format(args);
|
| - break;
|
| - case WebInspector.ConsoleMessage.MessageType.Dir:
|
| - var obj = consoleMessage.parameters ? consoleMessage.parameters[0] : undefined;
|
| - var args = ["%O", obj];
|
| - messageElement = this._format(args);
|
| - break;
|
| - case WebInspector.ConsoleMessage.MessageType.Profile:
|
| - case WebInspector.ConsoleMessage.MessageType.ProfileEnd:
|
| - messageElement = this._format([consoleMessage.messageText]);
|
| - break;
|
| - default:
|
| - if (consoleMessage.parameters && consoleMessage.parameters.length === 1 && consoleMessage.parameters[0].type === "string")
|
| - messageElement = this._tryFormatAsError(/** @type {string} */(consoleMessage.parameters[0].value));
|
| - var args = consoleMessage.parameters || [consoleMessage.messageText];
|
| - messageElement = messageElement || this._format(args);
|
| - }
|
| - } else if (consoleMessage.source === WebInspector.ConsoleMessage.MessageSource.Network) {
|
| - if (consoleMessage.request) {
|
| - messageElement = createElement("span");
|
| - if (consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.Error || consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.RevokedError) {
|
| - messageElement.createTextChildren(consoleMessage.request.requestMethod, " ");
|
| - messageElement.appendChild(WebInspector.Linkifier.linkifyUsingRevealer(consoleMessage.request, consoleMessage.request.url, consoleMessage.request.url));
|
| - if (consoleMessage.request.failed)
|
| - messageElement.createTextChildren(" ", consoleMessage.request.localizedFailDescription);
|
| - else
|
| - messageElement.createTextChildren(" ", String(consoleMessage.request.statusCode), " (", consoleMessage.request.statusText, ")");
|
| - } else {
|
| - var fragment = WebInspector.linkifyStringAsFragmentWithCustomLinkifier(consoleMessage.messageText, linkifyRequest.bind(consoleMessage));
|
| - messageElement.appendChild(fragment);
|
| - }
|
| - } else {
|
| - messageElement = this._format([consoleMessage.messageText]);
|
| - }
|
| + var flatValues = [];
|
| + for (var i = 0; i < rows.length; ++i) {
|
| + var rowName = rows[i][0];
|
| + var rowValue = rows[i][1];
|
| + flatValues.push(rowName);
|
| + for (var j = 0; j < columnNames.length; ++j)
|
| + flatValues.push(rowValue[columnNames[j]]);
|
| + }
|
| + columnNames.unshift(WebInspector.UIString('(index)'));
|
| +
|
| + if (flatValues.length) {
|
| + this._dataGrid = WebInspector.SortableDataGrid.create(columnNames, flatValues);
|
| +
|
| + var formattedResult = createElement('span');
|
| + var tableElement = formattedResult.createChild('div', 'console-message-formatted-table');
|
| + var dataGridContainer = tableElement.createChild('span');
|
| + tableElement.appendChild(this._formatParameter(table, true, false));
|
| + dataGridContainer.appendChild(this._dataGrid.element);
|
| + formattedMessage.appendChild(formattedResult);
|
| + this._dataGrid.renderInline();
|
| + }
|
| + return formattedMessage;
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.ConsoleMessage} consoleMessage
|
| + * @return {!Element}
|
| + */
|
| + _buildMessage(consoleMessage) {
|
| + var messageElement;
|
| + if (consoleMessage.source === WebInspector.ConsoleMessage.MessageSource.ConsoleAPI) {
|
| + switch (consoleMessage.type) {
|
| + case WebInspector.ConsoleMessage.MessageType.Trace:
|
| + messageElement = this._format(consoleMessage.parameters || ['console.trace']);
|
| + break;
|
| + case WebInspector.ConsoleMessage.MessageType.Clear:
|
| + messageElement = createElementWithClass('span', 'console-info');
|
| + messageElement.textContent = WebInspector.UIString('Console was cleared');
|
| + break;
|
| + case WebInspector.ConsoleMessage.MessageType.Assert:
|
| + var args = [WebInspector.UIString('Assertion failed:')];
|
| + if (consoleMessage.parameters)
|
| + args = args.concat(consoleMessage.parameters);
|
| + messageElement = this._format(args);
|
| + break;
|
| + case WebInspector.ConsoleMessage.MessageType.Dir:
|
| + var obj = consoleMessage.parameters ? consoleMessage.parameters[0] : undefined;
|
| + var args = ['%O', obj];
|
| + messageElement = this._format(args);
|
| + break;
|
| + case WebInspector.ConsoleMessage.MessageType.Profile:
|
| + case WebInspector.ConsoleMessage.MessageType.ProfileEnd:
|
| + messageElement = this._format([consoleMessage.messageText]);
|
| + break;
|
| + default:
|
| + if (consoleMessage.parameters && consoleMessage.parameters.length === 1 &&
|
| + consoleMessage.parameters[0].type === 'string')
|
| + messageElement = this._tryFormatAsError(/** @type {string} */ (consoleMessage.parameters[0].value));
|
| + var args = consoleMessage.parameters || [consoleMessage.messageText];
|
| + messageElement = messageElement || this._format(args);
|
| + }
|
| + } else if (consoleMessage.source === WebInspector.ConsoleMessage.MessageSource.Network) {
|
| + if (consoleMessage.request) {
|
| + messageElement = createElement('span');
|
| + if (consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.Error ||
|
| + consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.RevokedError) {
|
| + messageElement.createTextChildren(consoleMessage.request.requestMethod, ' ');
|
| + messageElement.appendChild(WebInspector.Linkifier.linkifyUsingRevealer(
|
| + consoleMessage.request, consoleMessage.request.url, consoleMessage.request.url));
|
| + if (consoleMessage.request.failed)
|
| + messageElement.createTextChildren(' ', consoleMessage.request.localizedFailDescription);
|
| + else
|
| + messageElement.createTextChildren(
|
| + ' ', String(consoleMessage.request.statusCode), ' (', consoleMessage.request.statusText, ')');
|
| } else {
|
| - var args = consoleMessage.parameters || [consoleMessage.messageText];
|
| - messageElement = this._format(args);
|
| - }
|
| -
|
| - var formattedMessage = createElement("span");
|
| - WebInspector.appendStyle(formattedMessage, "components/objectValue.css");
|
| - formattedMessage.className = "console-message-text source-code";
|
| -
|
| - var anchorElement = this._buildMessageAnchor(consoleMessage);
|
| - if (anchorElement)
|
| - formattedMessage.appendChild(anchorElement);
|
| - formattedMessage.appendChild(messageElement);
|
| - return formattedMessage;
|
| -
|
| - /**
|
| - * @param {string} title
|
| - * @return {!Element}
|
| - * @this {WebInspector.ConsoleMessage}
|
| - */
|
| - function linkifyRequest(title)
|
| - {
|
| - return WebInspector.Linkifier.linkifyUsingRevealer(/** @type {!WebInspector.NetworkRequest} */ (this.request), title, this.request.url);
|
| + var fragment = WebInspector.linkifyStringAsFragmentWithCustomLinkifier(
|
| + consoleMessage.messageText, linkifyRequest.bind(consoleMessage));
|
| + messageElement.appendChild(fragment);
|
| }
|
| - },
|
| + } else {
|
| + messageElement = this._format([consoleMessage.messageText]);
|
| + }
|
| + } else {
|
| + var args = consoleMessage.parameters || [consoleMessage.messageText];
|
| + messageElement = this._format(args);
|
| + }
|
|
|
| - /**
|
| - * @param {!WebInspector.ConsoleMessage} consoleMessage
|
| - * @return {?Element}
|
| - */
|
| - _buildMessageAnchor: function(consoleMessage)
|
| - {
|
| - var anchorElement = null;
|
| - if (consoleMessage.source !== WebInspector.ConsoleMessage.MessageSource.Network || consoleMessage.request) {
|
| - if (consoleMessage.scriptId)
|
| - anchorElement = this._linkifyScriptId(consoleMessage.scriptId, consoleMessage.url || "", consoleMessage.line, consoleMessage.column);
|
| - else if (consoleMessage.stackTrace && consoleMessage.stackTrace.callFrames.length)
|
| - anchorElement = this._linkifyStackTraceTopFrame(consoleMessage.stackTrace);
|
| - else if (consoleMessage.url && consoleMessage.url !== "undefined")
|
| - anchorElement = this._linkifyLocation(consoleMessage.url, consoleMessage.line, consoleMessage.column);
|
| - } else if (consoleMessage.url) {
|
| - var url = consoleMessage.url;
|
| - var isExternal = !WebInspector.resourceForURL(url) && !WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(url);
|
| - anchorElement = WebInspector.linkifyURLAsNode(url, url, "console-message-url", isExternal);
|
| - }
|
| + var formattedMessage = createElement('span');
|
| + WebInspector.appendStyle(formattedMessage, 'components/objectValue.css');
|
| + formattedMessage.className = 'console-message-text source-code';
|
|
|
| - // Append a space to prevent the anchor text from being glued to the console message when the user selects and copies the console messages.
|
| - if (anchorElement)
|
| - anchorElement.appendChild(createTextNode(" "));
|
| - return anchorElement;
|
| - },
|
| + var anchorElement = this._buildMessageAnchor(consoleMessage);
|
| + if (anchorElement)
|
| + formattedMessage.appendChild(anchorElement);
|
| + formattedMessage.appendChild(messageElement);
|
| + return formattedMessage;
|
|
|
| /**
|
| - * @param {!WebInspector.ConsoleMessage} consoleMessage
|
| - * @param {!WebInspector.Target} target
|
| - * @param {!WebInspector.Linkifier} linkifier
|
| + * @param {string} title
|
| * @return {!Element}
|
| + * @this {WebInspector.ConsoleMessage}
|
| */
|
| - _buildMessageWithStackTrace: function(consoleMessage, target, linkifier)
|
| - {
|
| - var toggleElement = createElementWithClass("div", "console-message-stack-trace-toggle");
|
| - var triangleElement = toggleElement.createChild("div", "console-message-stack-trace-triangle");
|
| - var contentElement = toggleElement.createChild("div", "console-message-stack-trace-wrapper");
|
| -
|
| - var messageElement = this._buildMessage(consoleMessage);
|
| - var clickableElement = contentElement.createChild("div");
|
| - clickableElement.appendChild(messageElement);
|
| - var stackTraceElement = contentElement.createChild("div");
|
| - var stackTracePreview = WebInspector.DOMPresentationUtils.buildStackTracePreviewContents(target, linkifier, consoleMessage.stackTrace);
|
| - stackTraceElement.appendChild(stackTracePreview);
|
| - stackTraceElement.classList.add("hidden");
|
| -
|
| - /**
|
| - * @param {boolean} expand
|
| - */
|
| - function expandStackTrace(expand)
|
| - {
|
| - stackTraceElement.classList.toggle("hidden", !expand);
|
| - toggleElement.classList.toggle("expanded", expand);
|
| - }
|
| -
|
| - /**
|
| - * @param {?Event} event
|
| - */
|
| - function toggleStackTrace(event)
|
| - {
|
| - if (event.target.hasSelection())
|
| - return;
|
| - expandStackTrace(stackTraceElement.classList.contains("hidden"));
|
| - event.consume();
|
| - }
|
| -
|
| - clickableElement.addEventListener("click", toggleStackTrace, false);
|
| - triangleElement.addEventListener("click", toggleStackTrace, false);
|
| - if (consoleMessage.type === WebInspector.ConsoleMessage.MessageType.Trace)
|
| - expandStackTrace(true);
|
| + function linkifyRequest(title) {
|
| + return WebInspector.Linkifier.linkifyUsingRevealer(
|
| + /** @type {!WebInspector.NetworkRequest} */ (this.request), title, this.request.url);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.ConsoleMessage} consoleMessage
|
| + * @return {?Element}
|
| + */
|
| + _buildMessageAnchor(consoleMessage) {
|
| + var anchorElement = null;
|
| + if (consoleMessage.source !== WebInspector.ConsoleMessage.MessageSource.Network || consoleMessage.request) {
|
| + if (consoleMessage.scriptId)
|
| + anchorElement = this._linkifyScriptId(
|
| + consoleMessage.scriptId, consoleMessage.url || '', consoleMessage.line, consoleMessage.column);
|
| + else if (consoleMessage.stackTrace && consoleMessage.stackTrace.callFrames.length)
|
| + anchorElement = this._linkifyStackTraceTopFrame(consoleMessage.stackTrace);
|
| + else if (consoleMessage.url && consoleMessage.url !== 'undefined')
|
| + anchorElement = this._linkifyLocation(consoleMessage.url, consoleMessage.line, consoleMessage.column);
|
| + } else if (consoleMessage.url) {
|
| + var url = consoleMessage.url;
|
| + var isExternal =
|
| + !WebInspector.resourceForURL(url) && !WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(url);
|
| + anchorElement = WebInspector.linkifyURLAsNode(url, url, 'console-message-url', isExternal);
|
| + }
|
|
|
| - toggleElement._expandStackTraceForTest = expandStackTrace.bind(null, true);
|
| - return toggleElement;
|
| - },
|
| + // Append a space to prevent the anchor text from being glued to the console message when the user selects and copies the console messages.
|
| + if (anchorElement)
|
| + anchorElement.appendChild(createTextNode(' '));
|
| + return anchorElement;
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.ConsoleMessage} consoleMessage
|
| + * @param {!WebInspector.Target} target
|
| + * @param {!WebInspector.Linkifier} linkifier
|
| + * @return {!Element}
|
| + */
|
| + _buildMessageWithStackTrace(consoleMessage, target, linkifier) {
|
| + var toggleElement = createElementWithClass('div', 'console-message-stack-trace-toggle');
|
| + var triangleElement = toggleElement.createChild('div', 'console-message-stack-trace-triangle');
|
| + var contentElement = toggleElement.createChild('div', 'console-message-stack-trace-wrapper');
|
| +
|
| + var messageElement = this._buildMessage(consoleMessage);
|
| + var clickableElement = contentElement.createChild('div');
|
| + clickableElement.appendChild(messageElement);
|
| + var stackTraceElement = contentElement.createChild('div');
|
| + var stackTracePreview =
|
| + WebInspector.DOMPresentationUtils.buildStackTracePreviewContents(target, linkifier, consoleMessage.stackTrace);
|
| + stackTraceElement.appendChild(stackTracePreview);
|
| + stackTraceElement.classList.add('hidden');
|
|
|
| /**
|
| - * @param {string} url
|
| - * @param {number} lineNumber
|
| - * @param {number} columnNumber
|
| - * @return {?Element}
|
| + * @param {boolean} expand
|
| */
|
| - _linkifyLocation: function(url, lineNumber, columnNumber)
|
| - {
|
| - var target = this._target();
|
| - if (!target)
|
| - return null;
|
| - return this._linkifier.linkifyScriptLocation(target, null, url, lineNumber, columnNumber, "console-message-url");
|
| - },
|
| -
|
| - /**
|
| - * @param {!RuntimeAgent.StackTrace} stackTrace
|
| - * @return {?Element}
|
| - */
|
| - _linkifyStackTraceTopFrame: function(stackTrace)
|
| - {
|
| - var target = this._target();
|
| - if (!target)
|
| - return null;
|
| - return this._linkifier.linkifyStackTraceTopFrame(target, stackTrace, "console-message-url");
|
| - },
|
| + function expandStackTrace(expand) {
|
| + stackTraceElement.classList.toggle('hidden', !expand);
|
| + toggleElement.classList.toggle('expanded', expand);
|
| + }
|
|
|
| /**
|
| - * @param {string} scriptId
|
| - * @param {string} url
|
| - * @param {number} lineNumber
|
| - * @param {number} columnNumber
|
| - * @return {?Element}
|
| + * @param {?Event} event
|
| */
|
| - _linkifyScriptId: function(scriptId, url, lineNumber, columnNumber)
|
| - {
|
| - var target = this._target();
|
| - if (!target)
|
| - return null;
|
| - return this._linkifier.linkifyScriptLocation(target, scriptId, url, lineNumber, columnNumber, "console-message-url");
|
| - },
|
| + function toggleStackTrace(event) {
|
| + if (event.target.hasSelection())
|
| + return;
|
| + expandStackTrace(stackTraceElement.classList.contains('hidden'));
|
| + event.consume();
|
| + }
|
|
|
| - /**
|
| - * @param {!WebInspector.RemoteObject|!Object|string} parameter
|
| - * @param {?WebInspector.Target} target
|
| - * @return {!WebInspector.RemoteObject}
|
| - */
|
| - _parameterToRemoteObject: function(parameter, target)
|
| - {
|
| - if (parameter instanceof WebInspector.RemoteObject)
|
| - return parameter;
|
| - if (!target)
|
| - return WebInspector.RemoteObject.fromLocalObject(parameter);
|
| - if (typeof parameter === "object")
|
| - return target.runtimeModel.createRemoteObject(parameter);
|
| - return target.runtimeModel.createRemoteObjectFromPrimitiveValue(parameter);
|
| - },
|
| + clickableElement.addEventListener('click', toggleStackTrace, false);
|
| + triangleElement.addEventListener('click', toggleStackTrace, false);
|
| + if (consoleMessage.type === WebInspector.ConsoleMessage.MessageType.Trace)
|
| + expandStackTrace(true);
|
| +
|
| + toggleElement._expandStackTraceForTest = expandStackTrace.bind(null, true);
|
| + return toggleElement;
|
| + }
|
| +
|
| + /**
|
| + * @param {string} url
|
| + * @param {number} lineNumber
|
| + * @param {number} columnNumber
|
| + * @return {?Element}
|
| + */
|
| + _linkifyLocation(url, lineNumber, columnNumber) {
|
| + var target = this._target();
|
| + if (!target)
|
| + return null;
|
| + return this._linkifier.linkifyScriptLocation(target, null, url, lineNumber, columnNumber, 'console-message-url');
|
| + }
|
| +
|
| + /**
|
| + * @param {!RuntimeAgent.StackTrace} stackTrace
|
| + * @return {?Element}
|
| + */
|
| + _linkifyStackTraceTopFrame(stackTrace) {
|
| + var target = this._target();
|
| + if (!target)
|
| + return null;
|
| + return this._linkifier.linkifyStackTraceTopFrame(target, stackTrace, 'console-message-url');
|
| + }
|
| +
|
| + /**
|
| + * @param {string} scriptId
|
| + * @param {string} url
|
| + * @param {number} lineNumber
|
| + * @param {number} columnNumber
|
| + * @return {?Element}
|
| + */
|
| + _linkifyScriptId(scriptId, url, lineNumber, columnNumber) {
|
| + var target = this._target();
|
| + if (!target)
|
| + return null;
|
| + return this._linkifier.linkifyScriptLocation(
|
| + target, scriptId, url, lineNumber, columnNumber, 'console-message-url');
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.RemoteObject|!Object|string} parameter
|
| + * @param {?WebInspector.Target} target
|
| + * @return {!WebInspector.RemoteObject}
|
| + */
|
| + _parameterToRemoteObject(parameter, target) {
|
| + if (parameter instanceof WebInspector.RemoteObject)
|
| + return parameter;
|
| + if (!target)
|
| + return WebInspector.RemoteObject.fromLocalObject(parameter);
|
| + if (typeof parameter === 'object')
|
| + return target.runtimeModel.createRemoteObject(parameter);
|
| + return target.runtimeModel.createRemoteObjectFromPrimitiveValue(parameter);
|
| + }
|
| +
|
| + /**
|
| + * @param {!Array.<!WebInspector.RemoteObject|string>} parameters
|
| + * @return {!Element}
|
| + */
|
| + _format(parameters) {
|
| + // This node is used like a Builder. Values are continually appended onto it.
|
| + var formattedResult = createElement('span');
|
| + if (!parameters.length)
|
| + return formattedResult;
|
| +
|
| + // Formatting code below assumes that parameters are all wrappers whereas frontend console
|
| + // API allows passing arbitrary values as messages (strings, numbers, etc.). Wrap them here.
|
| + // FIXME: Only pass runtime wrappers here.
|
| + for (var i = 0; i < parameters.length; ++i)
|
| + parameters[i] = this._parameterToRemoteObject(parameters[i], this._target());
|
| +
|
| + // There can be string log and string eval result. We distinguish between them based on message type.
|
| + var shouldFormatMessage = WebInspector.RemoteObject.type(
|
| + (/** @type {!Array.<!WebInspector.RemoteObject>} **/ (parameters))[0]) === 'string' &&
|
| + (this._message.type !== WebInspector.ConsoleMessage.MessageType.Result ||
|
| + this._message.level === WebInspector.ConsoleMessage.MessageLevel.Error ||
|
| + this._message.level === WebInspector.ConsoleMessage.MessageLevel.RevokedError);
|
| +
|
| + // Multiple parameters with the first being a format string. Save unused substitutions.
|
| + if (shouldFormatMessage) {
|
| + var result = this._formatWithSubstitutionString(
|
| + /** @type {string} **/ (parameters[0].description), parameters.slice(1), formattedResult);
|
| + parameters = result.unusedSubstitutions;
|
| + if (parameters.length)
|
| + formattedResult.createTextChild(' ');
|
| + }
|
|
|
| - /**
|
| - * @param {!Array.<!WebInspector.RemoteObject|string>} parameters
|
| - * @return {!Element}
|
| - */
|
| - _format: function(parameters)
|
| - {
|
| - // This node is used like a Builder. Values are continually appended onto it.
|
| - var formattedResult = createElement("span");
|
| - if (!parameters.length)
|
| - return formattedResult;
|
| -
|
| - // Formatting code below assumes that parameters are all wrappers whereas frontend console
|
| - // API allows passing arbitrary values as messages (strings, numbers, etc.). Wrap them here.
|
| - // FIXME: Only pass runtime wrappers here.
|
| - for (var i = 0; i < parameters.length; ++i)
|
| - parameters[i] = this._parameterToRemoteObject(parameters[i], this._target());
|
| -
|
| - // There can be string log and string eval result. We distinguish between them based on message type.
|
| - var shouldFormatMessage = WebInspector.RemoteObject.type((/** @type {!Array.<!WebInspector.RemoteObject>} **/ (parameters))[0]) === "string" && (this._message.type !== WebInspector.ConsoleMessage.MessageType.Result || this._message.level === WebInspector.ConsoleMessage.MessageLevel.Error || this._message.level === WebInspector.ConsoleMessage.MessageLevel.RevokedError);
|
| -
|
| - // Multiple parameters with the first being a format string. Save unused substitutions.
|
| - if (shouldFormatMessage) {
|
| - var result = this._formatWithSubstitutionString(/** @type {string} **/ (parameters[0].description), parameters.slice(1), formattedResult);
|
| - parameters = result.unusedSubstitutions;
|
| - if (parameters.length)
|
| - formattedResult.createTextChild(" ");
|
| - }
|
| + // Single parameter, or unused substitutions from above.
|
| + for (var i = 0; i < parameters.length; ++i) {
|
| + // Inline strings when formatting.
|
| + if (shouldFormatMessage && parameters[i].type === 'string')
|
| + formattedResult.appendChild(WebInspector.linkifyStringAsFragment(parameters[i].description));
|
| + else
|
| + formattedResult.appendChild(this._formatParameter(parameters[i], false, true));
|
| + if (i < parameters.length - 1)
|
| + formattedResult.createTextChild(' ');
|
| + }
|
| + return formattedResult;
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.RemoteObject} output
|
| + * @param {boolean=} forceObjectFormat
|
| + * @param {boolean=} includePreview
|
| + * @return {!Element}
|
| + */
|
| + _formatParameter(output, forceObjectFormat, includePreview) {
|
| + if (output.customPreview())
|
| + return (new WebInspector.CustomPreviewComponent(output)).element;
|
| +
|
| + var type = forceObjectFormat ? 'object' : (output.subtype || output.type);
|
| + var element;
|
| + switch (type) {
|
| + case 'array':
|
| + case 'typedarray':
|
| + element = this._formatParameterAsArray(output);
|
| + break;
|
| + case 'error':
|
| + element = this._formatParameterAsError(output);
|
| + break;
|
| + case 'function':
|
| + case 'generator':
|
| + element = this._formatParameterAsFunction(output, includePreview);
|
| + break;
|
| + case 'iterator':
|
| + case 'map':
|
| + case 'object':
|
| + case 'promise':
|
| + case 'proxy':
|
| + case 'set':
|
| + element = this._formatParameterAsObject(output, includePreview);
|
| + break;
|
| + case 'node':
|
| + element = this._formatParameterAsNode(output);
|
| + break;
|
| + case 'string':
|
| + element = this._formatParameterAsString(output);
|
| + break;
|
| + case 'boolean':
|
| + case 'date':
|
| + case 'null':
|
| + case 'number':
|
| + case 'regexp':
|
| + case 'symbol':
|
| + case 'undefined':
|
| + element = this._formatParameterAsValue(output);
|
| + break;
|
| + default:
|
| + element = this._formatParameterAsValue(output);
|
| + console.error('Tried to format remote object of unknown type.');
|
| + }
|
| + element.classList.add('object-value-' + type);
|
| + element.classList.add('source-code');
|
| + return element;
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.RemoteObject} obj
|
| + * @return {!Element}
|
| + */
|
| + _formatParameterAsValue(obj) {
|
| + var result = createElement('span');
|
| + result.createTextChild(obj.description || '');
|
| + if (obj.objectId)
|
| + result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, obj), false);
|
| + return result;
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.RemoteObject} obj
|
| + * @param {boolean=} includePreview
|
| + * @return {!Element}
|
| + */
|
| + _formatParameterAsObject(obj, includePreview) {
|
| + var titleElement = createElement('span');
|
| + if (includePreview && obj.preview) {
|
| + titleElement.classList.add('console-object-preview');
|
| + this._previewFormatter.appendObjectPreview(titleElement, obj.preview);
|
| + } else if (obj.type === 'function') {
|
| + WebInspector.ObjectPropertiesSection.formatObjectAsFunction(obj, titleElement, false);
|
| + titleElement.classList.add('object-value-function');
|
| + } else {
|
| + titleElement.createTextChild(obj.description || '');
|
| + }
|
|
|
| - // Single parameter, or unused substitutions from above.
|
| - for (var i = 0; i < parameters.length; ++i) {
|
| - // Inline strings when formatting.
|
| - if (shouldFormatMessage && parameters[i].type === "string")
|
| - formattedResult.appendChild(WebInspector.linkifyStringAsFragment(parameters[i].description));
|
| - else
|
| - formattedResult.appendChild(this._formatParameter(parameters[i], false, true));
|
| - if (i < parameters.length - 1)
|
| - formattedResult.createTextChild(" ");
|
| - }
|
| - return formattedResult;
|
| - },
|
| + var section = new WebInspector.ObjectPropertiesSection(obj, titleElement, this._linkifier);
|
| + section.element.classList.add('console-view-object-properties-section');
|
| + section.enableContextMenu();
|
| + return section.element;
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.RemoteObject} func
|
| + * @param {boolean=} includePreview
|
| + * @return {!Element}
|
| + */
|
| + _formatParameterAsFunction(func, includePreview) {
|
| + var result = createElement('span');
|
| + WebInspector.RemoteFunction.objectAsFunction(func).targetFunction().then(formatTargetFunction.bind(this));
|
| + return result;
|
|
|
| /**
|
| - * @param {!WebInspector.RemoteObject} output
|
| - * @param {boolean=} forceObjectFormat
|
| - * @param {boolean=} includePreview
|
| - * @return {!Element}
|
| + * @param {!WebInspector.RemoteObject} targetFunction
|
| + * @this {WebInspector.ConsoleViewMessage}
|
| */
|
| - _formatParameter: function(output, forceObjectFormat, includePreview)
|
| - {
|
| - if (output.customPreview())
|
| - return (new WebInspector.CustomPreviewComponent(output)).element;
|
| -
|
| - var type = forceObjectFormat ? "object" : (output.subtype || output.type);
|
| - var element;
|
| - switch (type) {
|
| - case "array":
|
| - case "typedarray":
|
| - element = this._formatParameterAsArray(output);
|
| - break;
|
| - case "error":
|
| - element = this._formatParameterAsError(output);
|
| - break;
|
| - case "function":
|
| - case "generator":
|
| - element = this._formatParameterAsFunction(output, includePreview);
|
| - break;
|
| - case "iterator":
|
| - case "map":
|
| - case "object":
|
| - case "promise":
|
| - case "proxy":
|
| - case "set":
|
| - element = this._formatParameterAsObject(output, includePreview);
|
| - break;
|
| - case "node":
|
| - element = this._formatParameterAsNode(output);
|
| - break;
|
| - case "string":
|
| - element = this._formatParameterAsString(output);
|
| - break;
|
| - case "boolean":
|
| - case "date":
|
| - case "null":
|
| - case "number":
|
| - case "regexp":
|
| - case "symbol":
|
| - case "undefined":
|
| - element = this._formatParameterAsValue(output);
|
| - break;
|
| - default:
|
| - element = this._formatParameterAsValue(output);
|
| - console.error("Tried to format remote object of unknown type.");
|
| - }
|
| - element.classList.add("object-value-" + type);
|
| - element.classList.add("source-code");
|
| - return element;
|
| - },
|
| + function formatTargetFunction(targetFunction) {
|
| + var functionElement = createElement('span');
|
| + WebInspector.ObjectPropertiesSection.formatObjectAsFunction(
|
| + targetFunction, functionElement, true, includePreview);
|
| + result.appendChild(functionElement);
|
| + if (targetFunction !== func) {
|
| + var note = result.createChild('span', 'object-info-state-note');
|
| + note.title = WebInspector.UIString('Function was resolved from bound function.');
|
| + }
|
| + result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, targetFunction), false);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.RemoteObject} obj
|
| + * @param {!Event} event
|
| + */
|
| + _contextMenuEventFired(obj, event) {
|
| + var contextMenu = new WebInspector.ContextMenu(event);
|
| + contextMenu.appendApplicableItems(obj);
|
| + contextMenu.show();
|
| + }
|
| +
|
| + /**
|
| + * @param {?WebInspector.RemoteObject} object
|
| + * @param {!Array.<!RuntimeAgent.PropertyPreview>} propertyPath
|
| + * @return {!Element}
|
| + */
|
| + _renderPropertyPreviewOrAccessor(object, propertyPath) {
|
| + var property = propertyPath.peekLast();
|
| + if (property.type === 'accessor')
|
| + return this._formatAsAccessorProperty(object, propertyPath.map(property => property.name), false);
|
| + return this._previewFormatter.renderPropertyPreview(
|
| + property.type, /** @type {string} */ (property.subtype), property.value);
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.RemoteObject} object
|
| + * @return {!Element}
|
| + */
|
| + _formatParameterAsNode(object) {
|
| + var result = createElement('span');
|
| + WebInspector.Renderer.renderPromise(object).then(appendRenderer.bind(this), failedToRender.bind(this));
|
| + return result;
|
|
|
| /**
|
| - * @param {!WebInspector.RemoteObject} obj
|
| - * @return {!Element}
|
| + * @param {!Element} rendererElement
|
| + * @this {WebInspector.ConsoleViewMessage}
|
| */
|
| - _formatParameterAsValue: function(obj)
|
| - {
|
| - var result = createElement("span");
|
| - result.createTextChild(obj.description || "");
|
| - if (obj.objectId)
|
| - result.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, obj), false);
|
| - return result;
|
| - },
|
| + function appendRenderer(rendererElement) {
|
| + result.appendChild(rendererElement);
|
| + this._formattedParameterAsNodeForTest();
|
| + }
|
|
|
| /**
|
| - * @param {!WebInspector.RemoteObject} obj
|
| - * @param {boolean=} includePreview
|
| - * @return {!Element}
|
| + * @this {WebInspector.ConsoleViewMessage}
|
| */
|
| - _formatParameterAsObject: function(obj, includePreview)
|
| - {
|
| - var titleElement = createElement("span");
|
| - if (includePreview && obj.preview) {
|
| - titleElement.classList.add("console-object-preview");
|
| - this._previewFormatter.appendObjectPreview(titleElement, obj.preview);
|
| - } else if (obj.type === "function") {
|
| - WebInspector.ObjectPropertiesSection.formatObjectAsFunction(obj, titleElement, false);
|
| - titleElement.classList.add("object-value-function");
|
| - } else {
|
| - titleElement.createTextChild(obj.description || "");
|
| - }
|
| -
|
| - var section = new WebInspector.ObjectPropertiesSection(obj, titleElement, this._linkifier);
|
| - section.element.classList.add("console-view-object-properties-section");
|
| - section.enableContextMenu();
|
| - return section.element;
|
| - },
|
| + function failedToRender() {
|
| + result.appendChild(this._formatParameterAsObject(object, false));
|
| + }
|
| + }
|
| +
|
| + _formattedParameterAsNodeForTest() {
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.RemoteObject} array
|
| + * @return {!Element}
|
| + */
|
| + _formatParameterAsArray(array) {
|
| + var usePrintedArrayFormat = this._message.type !== WebInspector.ConsoleMessage.MessageType.DirXML &&
|
| + this._message.type !== WebInspector.ConsoleMessage.MessageType.Result;
|
| + var isLongArray = array.arrayLength() > 100;
|
| + if (usePrintedArrayFormat || isLongArray)
|
| + return this._formatParameterAsObject(array, usePrintedArrayFormat || !isLongArray);
|
| + var result = createElement('span');
|
| + array.getAllProperties(false, printArrayResult.bind(this));
|
| + return result;
|
|
|
| /**
|
| - * @param {!WebInspector.RemoteObject} func
|
| - * @param {boolean=} includePreview
|
| - * @return {!Element}
|
| + * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties
|
| + * @this {!WebInspector.ConsoleViewMessage}
|
| */
|
| - _formatParameterAsFunction: function(func, includePreview)
|
| - {
|
| - var result = createElement("span");
|
| - WebInspector.RemoteFunction.objectAsFunction(func).targetFunction().then(formatTargetFunction.bind(this));
|
| - return result;
|
| -
|
| - /**
|
| - * @param {!WebInspector.RemoteObject} targetFunction
|
| - * @this {WebInspector.ConsoleViewMessage}
|
| - */
|
| - function formatTargetFunction(targetFunction)
|
| - {
|
| - var functionElement = createElement("span");
|
| - WebInspector.ObjectPropertiesSection.formatObjectAsFunction(targetFunction, functionElement, true, includePreview);
|
| - result.appendChild(functionElement);
|
| - if (targetFunction !== func) {
|
| - var note = result.createChild("span", "object-info-state-note");
|
| - note.title = WebInspector.UIString("Function was resolved from bound function.");
|
| - }
|
| - result.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, targetFunction), false);
|
| + function printArrayResult(properties) {
|
| + if (!properties) {
|
| + result.appendChild(this._formatParameterAsObject(array, false));
|
| + return;
|
| + }
|
| +
|
| + var titleElement = createElement('span');
|
| + var elements = {};
|
| + for (var i = 0; i < properties.length; ++i) {
|
| + var property = properties[i];
|
| + var name = property.name;
|
| + if (isNaN(name))
|
| + continue;
|
| + if (property.getter)
|
| + elements[name] = this._formatAsAccessorProperty(array, [name], true);
|
| + else if (property.value)
|
| + elements[name] = this._formatAsArrayEntry(property.value);
|
| + }
|
| +
|
| + titleElement.createTextChild('[');
|
| + var lastNonEmptyIndex = -1;
|
| +
|
| + function appendUndefined(titleElement, index) {
|
| + if (index - lastNonEmptyIndex <= 1)
|
| + return;
|
| + var span = titleElement.createChild('span', 'object-value-undefined');
|
| + span.textContent = WebInspector.UIString('undefined × %d', index - lastNonEmptyIndex - 1);
|
| + }
|
| +
|
| + var length = array.arrayLength();
|
| + for (var i = 0; i < length; ++i) {
|
| + var element = elements[i];
|
| + if (!element)
|
| + continue;
|
| +
|
| + if (i - lastNonEmptyIndex > 1) {
|
| + appendUndefined(titleElement, i);
|
| + titleElement.createTextChild(', ');
|
| }
|
| - },
|
| -
|
| - /**
|
| - * @param {!WebInspector.RemoteObject} obj
|
| - * @param {!Event} event
|
| - */
|
| - _contextMenuEventFired: function(obj, event)
|
| - {
|
| - var contextMenu = new WebInspector.ContextMenu(event);
|
| - contextMenu.appendApplicableItems(obj);
|
| - contextMenu.show();
|
| - },
|
| -
|
| - /**
|
| - * @param {?WebInspector.RemoteObject} object
|
| - * @param {!Array.<!RuntimeAgent.PropertyPreview>} propertyPath
|
| - * @return {!Element}
|
| - */
|
| - _renderPropertyPreviewOrAccessor: function(object, propertyPath)
|
| - {
|
| - var property = propertyPath.peekLast();
|
| - if (property.type === "accessor")
|
| - return this._formatAsAccessorProperty(object, propertyPath.map(property => property.name), false);
|
| - return this._previewFormatter.renderPropertyPreview(property.type, /** @type {string} */ (property.subtype), property.value);
|
| - },
|
|
|
| - /**
|
| - * @param {!WebInspector.RemoteObject} object
|
| - * @return {!Element}
|
| - */
|
| - _formatParameterAsNode: function(object)
|
| - {
|
| - var result = createElement("span");
|
| - WebInspector.Renderer.renderPromise(object).then(appendRenderer.bind(this), failedToRender.bind(this));
|
| - return result;
|
| -
|
| - /**
|
| - * @param {!Element} rendererElement
|
| - * @this {WebInspector.ConsoleViewMessage}
|
| - */
|
| - function appendRenderer(rendererElement)
|
| - {
|
| - result.appendChild(rendererElement);
|
| - this._formattedParameterAsNodeForTest();
|
| - }
|
| + titleElement.appendChild(element);
|
| + lastNonEmptyIndex = i;
|
| + if (i < length - 1)
|
| + titleElement.createTextChild(', ');
|
| + }
|
| + appendUndefined(titleElement, length);
|
|
|
| - /**
|
| - * @this {WebInspector.ConsoleViewMessage}
|
| - */
|
| - function failedToRender()
|
| - {
|
| - result.appendChild(this._formatParameterAsObject(object, false));
|
| - }
|
| - },
|
| + titleElement.createTextChild(']');
|
|
|
| - _formattedParameterAsNodeForTest: function()
|
| - {
|
| - },
|
| + var section = new WebInspector.ObjectPropertiesSection(array, titleElement, this._linkifier);
|
| + section.element.classList.add('console-view-object-properties-section');
|
| + section.enableContextMenu();
|
| + result.appendChild(section.element);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.RemoteObject} output
|
| + * @return {!Element}
|
| + */
|
| + _formatParameterAsString(output) {
|
| + var span = createElement('span');
|
| + span.appendChild(WebInspector.linkifyStringAsFragment(output.description || ''));
|
| +
|
| + var result = createElement('span');
|
| + result.createChild('span', 'object-value-string-quote').textContent = '"';
|
| + result.appendChild(span);
|
| + result.createChild('span', 'object-value-string-quote').textContent = '"';
|
| + return result;
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.RemoteObject} output
|
| + * @return {!Element}
|
| + */
|
| + _formatParameterAsError(output) {
|
| + var result = createElement('span');
|
| + var errorSpan = this._tryFormatAsError(output.description || '');
|
| + result.appendChild(errorSpan ? errorSpan : WebInspector.linkifyStringAsFragment(output.description || ''));
|
| + return result;
|
| + }
|
| +
|
| + /**
|
| + * @param {!WebInspector.RemoteObject} output
|
| + * @return {!Element}
|
| + */
|
| + _formatAsArrayEntry(output) {
|
| + return this._previewFormatter.renderPropertyPreview(output.type, output.subtype, output.description);
|
| + }
|
| +
|
| + /**
|
| + * @param {?WebInspector.RemoteObject} object
|
| + * @param {!Array.<string>} propertyPath
|
| + * @param {boolean} isArrayEntry
|
| + * @return {!Element}
|
| + */
|
| + _formatAsAccessorProperty(object, propertyPath, isArrayEntry) {
|
| + var rootElement = WebInspector.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan(
|
| + object, propertyPath, onInvokeGetterClick.bind(this));
|
|
|
| /**
|
| - * @param {!WebInspector.RemoteObject} array
|
| - * @return {!Element}
|
| + * @param {?WebInspector.RemoteObject} result
|
| + * @param {boolean=} wasThrown
|
| + * @this {WebInspector.ConsoleViewMessage}
|
| */
|
| - _formatParameterAsArray: function(array)
|
| - {
|
| - var usePrintedArrayFormat = this._message.type !== WebInspector.ConsoleMessage.MessageType.DirXML && this._message.type !== WebInspector.ConsoleMessage.MessageType.Result;
|
| - var isLongArray = array.arrayLength() > 100;
|
| - if (usePrintedArrayFormat || isLongArray)
|
| - return this._formatParameterAsObject(array, usePrintedArrayFormat || !isLongArray);
|
| - var result = createElement("span");
|
| - array.getAllProperties(false, printArrayResult.bind(this));
|
| - return result;
|
| -
|
| - /**
|
| - * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties
|
| - * @this {!WebInspector.ConsoleViewMessage}
|
| - */
|
| - function printArrayResult(properties)
|
| - {
|
| - if (!properties) {
|
| - result.appendChild(this._formatParameterAsObject(array, false));
|
| - return;
|
| - }
|
| -
|
| - var titleElement = createElement("span");
|
| - var elements = {};
|
| - for (var i = 0; i < properties.length; ++i) {
|
| - var property = properties[i];
|
| - var name = property.name;
|
| - if (isNaN(name))
|
| - continue;
|
| - if (property.getter)
|
| - elements[name] = this._formatAsAccessorProperty(array, [name], true);
|
| - else if (property.value)
|
| - elements[name] = this._formatAsArrayEntry(property.value);
|
| - }
|
| -
|
| - titleElement.createTextChild("[");
|
| - var lastNonEmptyIndex = -1;
|
| -
|
| - function appendUndefined(titleElement, index)
|
| - {
|
| - if (index - lastNonEmptyIndex <= 1)
|
| - return;
|
| - var span = titleElement.createChild("span", "object-value-undefined");
|
| - span.textContent = WebInspector.UIString("undefined × %d", index - lastNonEmptyIndex - 1);
|
| - }
|
| -
|
| - var length = array.arrayLength();
|
| - for (var i = 0; i < length; ++i) {
|
| - var element = elements[i];
|
| - if (!element)
|
| - continue;
|
| -
|
| - if (i - lastNonEmptyIndex > 1) {
|
| - appendUndefined(titleElement, i);
|
| - titleElement.createTextChild(", ");
|
| - }
|
| -
|
| - titleElement.appendChild(element);
|
| - lastNonEmptyIndex = i;
|
| - if (i < length - 1)
|
| - titleElement.createTextChild(", ");
|
| - }
|
| - appendUndefined(titleElement, length);
|
| -
|
| - titleElement.createTextChild("]");
|
| -
|
| - var section = new WebInspector.ObjectPropertiesSection(array, titleElement, this._linkifier);
|
| - section.element.classList.add("console-view-object-properties-section");
|
| - section.enableContextMenu();
|
| - result.appendChild(section.element);
|
| + function onInvokeGetterClick(result, wasThrown) {
|
| + if (!result)
|
| + return;
|
| + rootElement.removeChildren();
|
| + if (wasThrown) {
|
| + var element = rootElement.createChild('span');
|
| + element.textContent = WebInspector.UIString('<exception>');
|
| + element.title = /** @type {string} */ (result.description);
|
| + } else if (isArrayEntry) {
|
| + rootElement.appendChild(this._formatAsArrayEntry(result));
|
| + } else {
|
| + // Make a PropertyPreview from the RemoteObject similar to the backend logic.
|
| + const maxLength = 100;
|
| + var type = result.type;
|
| + var subtype = result.subtype;
|
| + var description = '';
|
| + if (type !== 'function' && result.description) {
|
| + if (type === 'string' || subtype === 'regexp')
|
| + description = result.description.trimMiddle(maxLength);
|
| + else
|
| + description = result.description.trimEnd(maxLength);
|
| }
|
| - },
|
| + rootElement.appendChild(this._previewFormatter.renderPropertyPreview(type, subtype, description));
|
| + }
|
| + }
|
|
|
| - /**
|
| - * @param {!WebInspector.RemoteObject} output
|
| - * @return {!Element}
|
| - */
|
| - _formatParameterAsString: function(output)
|
| - {
|
| - var span = createElement("span");
|
| - span.appendChild(WebInspector.linkifyStringAsFragment(output.description || ""));
|
| -
|
| - var result = createElement("span");
|
| - result.createChild("span", "object-value-string-quote").textContent = "\"";
|
| - result.appendChild(span);
|
| - result.createChild("span", "object-value-string-quote").textContent = "\"";
|
| - return result;
|
| - },
|
| + return rootElement;
|
| + }
|
|
|
| - /**
|
| - * @param {!WebInspector.RemoteObject} output
|
| - * @return {!Element}
|
| - */
|
| - _formatParameterAsError: function(output)
|
| - {
|
| - var result = createElement("span");
|
| - var errorSpan = this._tryFormatAsError(output.description || "");
|
| - result.appendChild(errorSpan ? errorSpan : WebInspector.linkifyStringAsFragment(output.description || ""));
|
| - return result;
|
| - },
|
| -
|
| - /**
|
| - * @param {!WebInspector.RemoteObject} output
|
| - * @return {!Element}
|
| - */
|
| - _formatAsArrayEntry: function(output)
|
| - {
|
| - return this._previewFormatter.renderPropertyPreview(output.type, output.subtype, output.description);
|
| - },
|
| + /**
|
| + * @param {string} format
|
| + * @param {!Array.<!WebInspector.RemoteObject>} parameters
|
| + * @param {!Element} formattedResult
|
| + */
|
| + _formatWithSubstitutionString(format, parameters, formattedResult) {
|
| + var formatters = {};
|
|
|
| /**
|
| - * @param {?WebInspector.RemoteObject} object
|
| - * @param {!Array.<string>} propertyPath
|
| - * @param {boolean} isArrayEntry
|
| + * @param {boolean} force
|
| + * @param {!WebInspector.RemoteObject} obj
|
| * @return {!Element}
|
| + * @this {WebInspector.ConsoleViewMessage}
|
| */
|
| - _formatAsAccessorProperty: function(object, propertyPath, isArrayEntry)
|
| - {
|
| - var rootElement = WebInspector.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan(object, propertyPath, onInvokeGetterClick.bind(this));
|
| -
|
| - /**
|
| - * @param {?WebInspector.RemoteObject} result
|
| - * @param {boolean=} wasThrown
|
| - * @this {WebInspector.ConsoleViewMessage}
|
| - */
|
| - function onInvokeGetterClick(result, wasThrown)
|
| - {
|
| - if (!result)
|
| - return;
|
| - rootElement.removeChildren();
|
| - if (wasThrown) {
|
| - var element = rootElement.createChild("span");
|
| - element.textContent = WebInspector.UIString("<exception>");
|
| - element.title = /** @type {string} */ (result.description);
|
| - } else if (isArrayEntry) {
|
| - rootElement.appendChild(this._formatAsArrayEntry(result));
|
| - } else {
|
| - // Make a PropertyPreview from the RemoteObject similar to the backend logic.
|
| - const maxLength = 100;
|
| - var type = result.type;
|
| - var subtype = result.subtype;
|
| - var description = "";
|
| - if (type !== "function" && result.description) {
|
| - if (type === "string" || subtype === "regexp")
|
| - description = result.description.trimMiddle(maxLength);
|
| - else
|
| - description = result.description.trimEnd(maxLength);
|
| - }
|
| - rootElement.appendChild(this._previewFormatter.renderPropertyPreview(type, subtype, description));
|
| - }
|
| - }
|
| -
|
| - return rootElement;
|
| - },
|
| -
|
| - /**
|
| - * @param {string} format
|
| - * @param {!Array.<!WebInspector.RemoteObject>} parameters
|
| - * @param {!Element} formattedResult
|
| - */
|
| - _formatWithSubstitutionString: function(format, parameters, formattedResult)
|
| - {
|
| - var formatters = {};
|
| -
|
| - /**
|
| - * @param {boolean} force
|
| - * @param {!WebInspector.RemoteObject} obj
|
| - * @return {!Element}
|
| - * @this {WebInspector.ConsoleViewMessage}
|
| - */
|
| - function parameterFormatter(force, obj)
|
| - {
|
| - return this._formatParameter(obj, force, false);
|
| - }
|
| -
|
| - function stringFormatter(obj)
|
| - {
|
| - return obj.description;
|
| - }
|
| -
|
| - function floatFormatter(obj)
|
| - {
|
| - if (typeof obj.value !== "number")
|
| - return "NaN";
|
| - return obj.value;
|
| - }
|
| -
|
| - function integerFormatter(obj)
|
| - {
|
| - if (typeof obj.value !== "number")
|
| - return "NaN";
|
| - return Math.floor(obj.value);
|
| - }
|
| -
|
| - function bypassFormatter(obj)
|
| - {
|
| - return (obj instanceof Node) ? obj : "";
|
| - }
|
| -
|
| - var currentStyle = null;
|
| - function styleFormatter(obj)
|
| - {
|
| - currentStyle = {};
|
| - var buffer = createElement("span");
|
| - buffer.setAttribute("style", obj.description);
|
| - for (var i = 0; i < buffer.style.length; i++) {
|
| - var property = buffer.style[i];
|
| - if (isWhitelistedProperty(property))
|
| - currentStyle[property] = buffer.style[property];
|
| - }
|
| - }
|
| -
|
| - function isWhitelistedProperty(property)
|
| - {
|
| - var prefixes = ["background", "border", "color", "font", "line", "margin", "padding", "text", "-webkit-background", "-webkit-border", "-webkit-font", "-webkit-margin", "-webkit-padding", "-webkit-text"];
|
| - for (var i = 0; i < prefixes.length; i++) {
|
| - if (property.startsWith(prefixes[i]))
|
| - return true;
|
| - }
|
| - return false;
|
| - }
|
| + function parameterFormatter(force, obj) {
|
| + return this._formatParameter(obj, force, false);
|
| + }
|
|
|
| - // Firebug uses %o for formatting objects.
|
| - formatters.o = parameterFormatter.bind(this, false);
|
| - formatters.s = stringFormatter;
|
| - formatters.f = floatFormatter;
|
| - // Firebug allows both %i and %d for formatting integers.
|
| - formatters.i = integerFormatter;
|
| - formatters.d = integerFormatter;
|
| -
|
| - // Firebug uses %c for styling the message.
|
| - formatters.c = styleFormatter;
|
| -
|
| - // Support %O to force object formatting, instead of the type-based %o formatting.
|
| - formatters.O = parameterFormatter.bind(this, true);
|
| -
|
| - formatters._ = bypassFormatter;
|
| -
|
| - function append(a, b)
|
| - {
|
| - if (b instanceof Node)
|
| - a.appendChild(b);
|
| - else if (typeof b !== "undefined") {
|
| - var toAppend = WebInspector.linkifyStringAsFragment(String(b));
|
| - if (currentStyle) {
|
| - var wrapper = createElement("span");
|
| - wrapper.appendChild(toAppend);
|
| - applyCurrentStyle(wrapper);
|
| - for (var i = 0; i < wrapper.children.length; ++i)
|
| - applyCurrentStyle(wrapper.children[i]);
|
| - toAppend = wrapper;
|
| - }
|
| - a.appendChild(toAppend);
|
| - }
|
| - return a;
|
| - }
|
| + function stringFormatter(obj) {
|
| + return obj.description;
|
| + }
|
|
|
| - /**
|
| - * @param {!Element} element
|
| - */
|
| - function applyCurrentStyle(element)
|
| - {
|
| - for (var key in currentStyle)
|
| - element.style[key] = currentStyle[key];
|
| - }
|
| + function floatFormatter(obj) {
|
| + if (typeof obj.value !== 'number')
|
| + return 'NaN';
|
| + return obj.value;
|
| + }
|
|
|
| - // String.format does treat formattedResult like a Builder, result is an object.
|
| - return String.format(format, parameters, formatters, formattedResult, append);
|
| - },
|
| + function integerFormatter(obj) {
|
| + if (typeof obj.value !== 'number')
|
| + return 'NaN';
|
| + return Math.floor(obj.value);
|
| + }
|
|
|
| - /**
|
| - * @return {boolean}
|
| - */
|
| - matchesFilterRegex: function(regexObject)
|
| - {
|
| - regexObject.lastIndex = 0;
|
| - var text = this.contentElement().deepTextContent();
|
| - return regexObject.test(text);
|
| - },
|
| + function bypassFormatter(obj) {
|
| + return (obj instanceof Node) ? obj : '';
|
| + }
|
|
|
| - /**
|
| - * @param {boolean} show
|
| - */
|
| - updateTimestamp: function(show)
|
| - {
|
| - if (!this._contentElement)
|
| - return;
|
| -
|
| - if (show && !this.timestampElement) {
|
| - this.timestampElement = createElementWithClass("span", "console-timestamp");
|
| - this.timestampElement.textContent = (new Date(this._message.timestamp)).toConsoleTime() + " ";
|
| - this._contentElement.insertBefore(this.timestampElement, this._contentElement.firstChild);
|
| - return;
|
| - }
|
| + var currentStyle = null;
|
| + function styleFormatter(obj) {
|
| + currentStyle = {};
|
| + var buffer = createElement('span');
|
| + buffer.setAttribute('style', obj.description);
|
| + for (var i = 0; i < buffer.style.length; i++) {
|
| + var property = buffer.style[i];
|
| + if (isWhitelistedProperty(property))
|
| + currentStyle[property] = buffer.style[property];
|
| + }
|
| + }
|
|
|
| - if (!show && this.timestampElement) {
|
| - this.timestampElement.remove();
|
| - delete this.timestampElement;
|
| - }
|
| - },
|
| + function isWhitelistedProperty(property) {
|
| + var prefixes = [
|
| + 'background', 'border', 'color', 'font', 'line', 'margin', 'padding', 'text', '-webkit-background',
|
| + '-webkit-border', '-webkit-font', '-webkit-margin', '-webkit-padding', '-webkit-text'
|
| + ];
|
| + for (var i = 0; i < prefixes.length; i++) {
|
| + if (property.startsWith(prefixes[i]))
|
| + return true;
|
| + }
|
| + return false;
|
| + }
|
|
|
| - /**
|
| - * @return {number}
|
| - */
|
| - nestingLevel: function()
|
| - {
|
| - return this._nestingLevel;
|
| - },
|
| -
|
| - resetCloseGroupDecorationCount: function()
|
| - {
|
| - if (!this._closeGroupDecorationCount)
|
| - return;
|
| - this._closeGroupDecorationCount = 0;
|
| - this._updateCloseGroupDecorations();
|
| - },
|
| -
|
| - incrementCloseGroupDecorationCount: function()
|
| - {
|
| - ++this._closeGroupDecorationCount;
|
| - this._updateCloseGroupDecorations();
|
| - },
|
| -
|
| - _updateCloseGroupDecorations: function()
|
| - {
|
| - if (!this._nestingLevelMarkers)
|
| - return;
|
| - for (var i = 0, n = this._nestingLevelMarkers.length; i < n; ++i) {
|
| - var marker = this._nestingLevelMarkers[i];
|
| - marker.classList.toggle("group-closed", n - i <= this._closeGroupDecorationCount);
|
| + // Firebug uses %o for formatting objects.
|
| + formatters.o = parameterFormatter.bind(this, false);
|
| + formatters.s = stringFormatter;
|
| + formatters.f = floatFormatter;
|
| + // Firebug allows both %i and %d for formatting integers.
|
| + formatters.i = integerFormatter;
|
| + formatters.d = integerFormatter;
|
| +
|
| + // Firebug uses %c for styling the message.
|
| + formatters.c = styleFormatter;
|
| +
|
| + // Support %O to force object formatting, instead of the type-based %o formatting.
|
| + formatters.O = parameterFormatter.bind(this, true);
|
| +
|
| + formatters._ = bypassFormatter;
|
| +
|
| + function append(a, b) {
|
| + if (b instanceof Node)
|
| + a.appendChild(b);
|
| + else if (typeof b !== 'undefined') {
|
| + var toAppend = WebInspector.linkifyStringAsFragment(String(b));
|
| + if (currentStyle) {
|
| + var wrapper = createElement('span');
|
| + wrapper.appendChild(toAppend);
|
| + applyCurrentStyle(wrapper);
|
| + for (var i = 0; i < wrapper.children.length; ++i)
|
| + applyCurrentStyle(wrapper.children[i]);
|
| + toAppend = wrapper;
|
| }
|
| - },
|
| + a.appendChild(toAppend);
|
| + }
|
| + return a;
|
| + }
|
|
|
| /**
|
| - * @return {!Element}
|
| + * @param {!Element} element
|
| */
|
| - contentElement: function()
|
| - {
|
| - if (this._contentElement)
|
| - return this._contentElement;
|
| -
|
| - var contentElement = createElementWithClass("div", "console-message");
|
| - this._contentElement = contentElement;
|
| - if (this._message.type === WebInspector.ConsoleMessage.MessageType.StartGroup || this._message.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
|
| - contentElement.classList.add("console-group-title");
|
| -
|
| - var formattedMessage;
|
| - var consoleMessage = this._message;
|
| - var target = consoleMessage.target();
|
| - var shouldIncludeTrace = !!consoleMessage.stackTrace && (consoleMessage.source === WebInspector.ConsoleMessage.MessageSource.Network || consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.Error || consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.RevokedError || consoleMessage.type === WebInspector.ConsoleMessage.MessageType.Trace || consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.Warning);
|
| - if (target && shouldIncludeTrace)
|
| - formattedMessage = this._buildMessageWithStackTrace(consoleMessage, target, this._linkifier);
|
| - else if (this._message.type === WebInspector.ConsoleMessage.MessageType.Table)
|
| - formattedMessage = this._buildTableMessage(this._message);
|
| - else
|
| - formattedMessage = this._buildMessage(consoleMessage);
|
| - contentElement.appendChild(formattedMessage);
|
| -
|
| - this.updateTimestamp(WebInspector.moduleSetting("consoleTimestampsEnabled").get());
|
| - return this._contentElement;
|
| - },
|
| + function applyCurrentStyle(element) {
|
| + for (var key in currentStyle)
|
| + element.style[key] = currentStyle[key];
|
| + }
|
|
|
| - /**
|
| - * @return {!Element}
|
| - */
|
| - toMessageElement: function()
|
| - {
|
| - if (this._element)
|
| - return this._element;
|
| -
|
| - this._element = createElement("div");
|
| - this.updateMessageElement();
|
| - return this._element;
|
| - },
|
| -
|
| - updateMessageElement: function()
|
| - {
|
| - if (!this._element)
|
| - return;
|
| -
|
| - this._element.className = "console-message-wrapper";
|
| - this._element.removeChildren();
|
| -
|
| - this._nestingLevelMarkers = [];
|
| - for (var i = 0; i < this._nestingLevel; ++i)
|
| - this._nestingLevelMarkers.push(this._element.createChild("div", "nesting-level-marker"));
|
| - this._updateCloseGroupDecorations();
|
| - this._element.message = this;
|
| -
|
| - switch (this._message.level) {
|
| - case WebInspector.ConsoleMessage.MessageLevel.Log:
|
| - this._element.classList.add("console-log-level");
|
| - break;
|
| - case WebInspector.ConsoleMessage.MessageLevel.Debug:
|
| - this._element.classList.add("console-debug-level");
|
| - break;
|
| - case WebInspector.ConsoleMessage.MessageLevel.Warning:
|
| - this._element.classList.add("console-warning-level");
|
| - break;
|
| - case WebInspector.ConsoleMessage.MessageLevel.Error:
|
| - this._element.classList.add("console-error-level");
|
| - break;
|
| - case WebInspector.ConsoleMessage.MessageLevel.RevokedError:
|
| - this._element.classList.add("console-revokedError-level");
|
| - break;
|
| - case WebInspector.ConsoleMessage.MessageLevel.Info:
|
| - this._element.classList.add("console-info-level");
|
| - break;
|
| - }
|
| + // String.format does treat formattedResult like a Builder, result is an object.
|
| + return String.format(format, parameters, formatters, formattedResult, append);
|
| + }
|
| +
|
| + /**
|
| + * @return {boolean}
|
| + */
|
| + matchesFilterRegex(regexObject) {
|
| + regexObject.lastIndex = 0;
|
| + var text = this.contentElement().deepTextContent();
|
| + return regexObject.test(text);
|
| + }
|
| +
|
| + /**
|
| + * @param {boolean} show
|
| + */
|
| + updateTimestamp(show) {
|
| + if (!this._contentElement)
|
| + return;
|
| +
|
| + if (show && !this.timestampElement) {
|
| + this.timestampElement = createElementWithClass('span', 'console-timestamp');
|
| + this.timestampElement.textContent = (new Date(this._message.timestamp)).toConsoleTime() + ' ';
|
| + this._contentElement.insertBefore(this.timestampElement, this._contentElement.firstChild);
|
| + return;
|
| + }
|
|
|
| - this._element.appendChild(this.contentElement());
|
| - if (this._repeatCount > 1)
|
| - this._showRepeatCountElement();
|
| - },
|
| + if (!show && this.timestampElement) {
|
| + this.timestampElement.remove();
|
| + delete this.timestampElement;
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * @return {number}
|
| + */
|
| + nestingLevel() {
|
| + return this._nestingLevel;
|
| + }
|
| +
|
| + resetCloseGroupDecorationCount() {
|
| + if (!this._closeGroupDecorationCount)
|
| + return;
|
| + this._closeGroupDecorationCount = 0;
|
| + this._updateCloseGroupDecorations();
|
| + }
|
| +
|
| + incrementCloseGroupDecorationCount() {
|
| + ++this._closeGroupDecorationCount;
|
| + this._updateCloseGroupDecorations();
|
| + }
|
| +
|
| + _updateCloseGroupDecorations() {
|
| + if (!this._nestingLevelMarkers)
|
| + return;
|
| + for (var i = 0, n = this._nestingLevelMarkers.length; i < n; ++i) {
|
| + var marker = this._nestingLevelMarkers[i];
|
| + marker.classList.toggle('group-closed', n - i <= this._closeGroupDecorationCount);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * @return {!Element}
|
| + */
|
| + contentElement() {
|
| + if (this._contentElement)
|
| + return this._contentElement;
|
| +
|
| + var contentElement = createElementWithClass('div', 'console-message');
|
| + this._contentElement = contentElement;
|
| + if (this._message.type === WebInspector.ConsoleMessage.MessageType.StartGroup ||
|
| + this._message.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
|
| + contentElement.classList.add('console-group-title');
|
| +
|
| + var formattedMessage;
|
| + var consoleMessage = this._message;
|
| + var target = consoleMessage.target();
|
| + var shouldIncludeTrace = !!consoleMessage.stackTrace &&
|
| + (consoleMessage.source === WebInspector.ConsoleMessage.MessageSource.Network ||
|
| + consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.Error ||
|
| + consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.RevokedError ||
|
| + consoleMessage.type === WebInspector.ConsoleMessage.MessageType.Trace ||
|
| + consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.Warning);
|
| + if (target && shouldIncludeTrace)
|
| + formattedMessage = this._buildMessageWithStackTrace(consoleMessage, target, this._linkifier);
|
| + else if (this._message.type === WebInspector.ConsoleMessage.MessageType.Table)
|
| + formattedMessage = this._buildTableMessage(this._message);
|
| + else
|
| + formattedMessage = this._buildMessage(consoleMessage);
|
| + contentElement.appendChild(formattedMessage);
|
| +
|
| + this.updateTimestamp(WebInspector.moduleSetting('consoleTimestampsEnabled').get());
|
| + return this._contentElement;
|
| + }
|
| +
|
| + /**
|
| + * @return {!Element}
|
| + */
|
| + toMessageElement() {
|
| + if (this._element)
|
| + return this._element;
|
| +
|
| + this._element = createElement('div');
|
| + this.updateMessageElement();
|
| + return this._element;
|
| + }
|
| +
|
| + updateMessageElement() {
|
| + if (!this._element)
|
| + return;
|
| +
|
| + this._element.className = 'console-message-wrapper';
|
| + this._element.removeChildren();
|
| +
|
| + this._nestingLevelMarkers = [];
|
| + for (var i = 0; i < this._nestingLevel; ++i)
|
| + this._nestingLevelMarkers.push(this._element.createChild('div', 'nesting-level-marker'));
|
| + this._updateCloseGroupDecorations();
|
| + this._element.message = this;
|
| +
|
| + switch (this._message.level) {
|
| + case WebInspector.ConsoleMessage.MessageLevel.Log:
|
| + this._element.classList.add('console-log-level');
|
| + break;
|
| + case WebInspector.ConsoleMessage.MessageLevel.Debug:
|
| + this._element.classList.add('console-debug-level');
|
| + break;
|
| + case WebInspector.ConsoleMessage.MessageLevel.Warning:
|
| + this._element.classList.add('console-warning-level');
|
| + break;
|
| + case WebInspector.ConsoleMessage.MessageLevel.Error:
|
| + this._element.classList.add('console-error-level');
|
| + break;
|
| + case WebInspector.ConsoleMessage.MessageLevel.RevokedError:
|
| + this._element.classList.add('console-revokedError-level');
|
| + break;
|
| + case WebInspector.ConsoleMessage.MessageLevel.Info:
|
| + this._element.classList.add('console-info-level');
|
| + break;
|
| + }
|
|
|
| - /**
|
| - * @return {number}
|
| - */
|
| - repeatCount: function()
|
| - {
|
| - return this._repeatCount || 1;
|
| - },
|
| -
|
| - resetIncrementRepeatCount: function()
|
| - {
|
| - this._repeatCount = 1;
|
| - if (!this._repeatCountElement)
|
| - return;
|
| -
|
| - this._repeatCountElement.remove();
|
| - delete this._repeatCountElement;
|
| - },
|
| -
|
| - incrementRepeatCount: function()
|
| - {
|
| - this._repeatCount++;
|
| - this._showRepeatCountElement();
|
| - },
|
| -
|
| - _showRepeatCountElement: function()
|
| - {
|
| - if (!this._contentElement)
|
| - return;
|
| -
|
| - if (!this._repeatCountElement) {
|
| - this._repeatCountElement = createElementWithClass("label", "console-message-repeat-count", "dt-small-bubble");
|
| - switch (this._message.level) {
|
| - case WebInspector.ConsoleMessage.MessageLevel.Warning:
|
| - this._repeatCountElement.type = "warning";
|
| - break;
|
| - case WebInspector.ConsoleMessage.MessageLevel.Error:
|
| - this._repeatCountElement.type = "error";
|
| - break;
|
| - case WebInspector.ConsoleMessage.MessageLevel.Debug:
|
| - this._repeatCountElement.type = "debug";
|
| - break;
|
| - default:
|
| - this._repeatCountElement.type = "info";
|
| - }
|
| - this._element.insertBefore(this._repeatCountElement, this._contentElement);
|
| - this._contentElement.classList.add("repeated-message");
|
| - }
|
| - this._repeatCountElement.textContent = this._repeatCount;
|
| - },
|
| + this._element.appendChild(this.contentElement());
|
| + if (this._repeatCount > 1)
|
| + this._showRepeatCountElement();
|
| + }
|
|
|
| - get text()
|
| - {
|
| - return this._message.messageText;
|
| - },
|
| + /**
|
| + * @return {number}
|
| + */
|
| + repeatCount() {
|
| + return this._repeatCount || 1;
|
| + }
|
|
|
| - /**
|
| - * @param {?RegExp} regex
|
| - */
|
| - setSearchRegex: function(regex)
|
| - {
|
| - if (this._searchHiglightNodeChanges && this._searchHiglightNodeChanges.length)
|
| - WebInspector.revertDomChanges(this._searchHiglightNodeChanges);
|
| - this._searchRegex = regex;
|
| - this._searchHighlightNodes = [];
|
| - this._searchHiglightNodeChanges = [];
|
| - if (!this._searchRegex)
|
| - return;
|
| -
|
| - var text = this.contentElement().deepTextContent();
|
| - var match;
|
| - this._searchRegex.lastIndex = 0;
|
| - var sourceRanges = [];
|
| - while ((match = this._searchRegex.exec(text)) && match[0])
|
| - sourceRanges.push(new WebInspector.SourceRange(match.index, match[0].length));
|
| -
|
| - if (sourceRanges.length)
|
| - this._searchHighlightNodes = WebInspector.highlightSearchResults(this.contentElement(), sourceRanges, this._searchHiglightNodeChanges);
|
| - },
|
| + resetIncrementRepeatCount() {
|
| + this._repeatCount = 1;
|
| + if (!this._repeatCountElement)
|
| + return;
|
|
|
| - /**
|
| - * @return {?RegExp}
|
| - */
|
| - searchRegex: function()
|
| - {
|
| - return this._searchRegex;
|
| - },
|
| + this._repeatCountElement.remove();
|
| + delete this._repeatCountElement;
|
| + }
|
|
|
| - /**
|
| - * @return {number}
|
| - */
|
| - searchCount: function()
|
| - {
|
| - return this._searchHighlightNodes.length;
|
| - },
|
| + incrementRepeatCount() {
|
| + this._repeatCount++;
|
| + this._showRepeatCountElement();
|
| + }
|
|
|
| - /**
|
| - * @return {!Element}
|
| - */
|
| - searchHighlightNode: function(index)
|
| - {
|
| - return this._searchHighlightNodes[index];
|
| - },
|
| + _showRepeatCountElement() {
|
| + if (!this._contentElement)
|
| + return;
|
|
|
| + if (!this._repeatCountElement) {
|
| + this._repeatCountElement = createElementWithClass('label', 'console-message-repeat-count', 'dt-small-bubble');
|
| + switch (this._message.level) {
|
| + case WebInspector.ConsoleMessage.MessageLevel.Warning:
|
| + this._repeatCountElement.type = 'warning';
|
| + break;
|
| + case WebInspector.ConsoleMessage.MessageLevel.Error:
|
| + this._repeatCountElement.type = 'error';
|
| + break;
|
| + case WebInspector.ConsoleMessage.MessageLevel.Debug:
|
| + this._repeatCountElement.type = 'debug';
|
| + break;
|
| + default:
|
| + this._repeatCountElement.type = 'info';
|
| + }
|
| + this._element.insertBefore(this._repeatCountElement, this._contentElement);
|
| + this._contentElement.classList.add('repeated-message');
|
| + }
|
| + this._repeatCountElement.textContent = this._repeatCount;
|
| + }
|
| +
|
| + get text() {
|
| + return this._message.messageText;
|
| + }
|
| +
|
| + /**
|
| + * @param {?RegExp} regex
|
| + */
|
| + setSearchRegex(regex) {
|
| + if (this._searchHiglightNodeChanges && this._searchHiglightNodeChanges.length)
|
| + WebInspector.revertDomChanges(this._searchHiglightNodeChanges);
|
| + this._searchRegex = regex;
|
| + this._searchHighlightNodes = [];
|
| + this._searchHiglightNodeChanges = [];
|
| + if (!this._searchRegex)
|
| + return;
|
| +
|
| + var text = this.contentElement().deepTextContent();
|
| + var match;
|
| + this._searchRegex.lastIndex = 0;
|
| + var sourceRanges = [];
|
| + while ((match = this._searchRegex.exec(text)) && match[0])
|
| + sourceRanges.push(new WebInspector.SourceRange(match.index, match[0].length));
|
| +
|
| + if (sourceRanges.length)
|
| + this._searchHighlightNodes =
|
| + WebInspector.highlightSearchResults(this.contentElement(), sourceRanges, this._searchHiglightNodeChanges);
|
| + }
|
| +
|
| + /**
|
| + * @return {?RegExp}
|
| + */
|
| + searchRegex() {
|
| + return this._searchRegex;
|
| + }
|
| +
|
| + /**
|
| + * @return {number}
|
| + */
|
| + searchCount() {
|
| + return this._searchHighlightNodes.length;
|
| + }
|
| +
|
| + /**
|
| + * @return {!Element}
|
| + */
|
| + searchHighlightNode(index) {
|
| + return this._searchHighlightNodes[index];
|
| + }
|
| +
|
| + /**
|
| + * @param {string} string
|
| + * @return {?Element}
|
| + */
|
| + _tryFormatAsError(string) {
|
| /**
|
| - * @param {string} string
|
| - * @return {?Element}
|
| + * @param {string} prefix
|
| */
|
| - _tryFormatAsError: function(string)
|
| - {
|
| - /**
|
| - * @param {string} prefix
|
| - */
|
| - function startsWith(prefix)
|
| - {
|
| - return string.startsWith(prefix);
|
| - }
|
| + function startsWith(prefix) {
|
| + return string.startsWith(prefix);
|
| + }
|
|
|
| - var errorPrefixes = ["EvalError", "ReferenceError", "SyntaxError", "TypeError", "RangeError", "Error", "URIError"];
|
| - var target = this._target();
|
| - if (!target || !errorPrefixes.some(startsWith))
|
| - return null;
|
| - var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
|
| - if (!debuggerModel)
|
| - return null;
|
| -
|
| - var lines = string.split("\n");
|
| - var links = [];
|
| - var position = 0;
|
| - for (var i = 0; i < lines.length; ++i) {
|
| - position += i > 0 ? lines[i - 1].length + 1 : 0;
|
| - var isCallFrameLine = /^\s*at\s/.test(lines[i]);
|
| - if (!isCallFrameLine && links.length)
|
| - return null;
|
| -
|
| - if (!isCallFrameLine)
|
| - continue;
|
| -
|
| - var openBracketIndex = -1;
|
| - var closeBracketIndex = -1;
|
| - var match = /\([^\)\(]+\)/.exec(lines[i]);
|
| - if (match) {
|
| - openBracketIndex = match.index;
|
| - closeBracketIndex = match.index + match[0].length - 1;
|
| - }
|
| - var hasOpenBracket = openBracketIndex !== -1;
|
| - var left = hasOpenBracket ? openBracketIndex + 1 : lines[i].indexOf("at") + 3;
|
| - var right = hasOpenBracket ? closeBracketIndex : lines[i].length;
|
| - var linkCandidate = lines[i].substring(left, right);
|
| - var splitResult = WebInspector.ParsedURL.splitLineAndColumn(linkCandidate);
|
| - if (!splitResult)
|
| - return null;
|
| -
|
| - var parsed = splitResult.url.asParsedURL();
|
| - var url;
|
| - if (parsed)
|
| - url = parsed.url;
|
| - else if (debuggerModel.scriptsForSourceURL(splitResult.url).length)
|
| - url = splitResult.url;
|
| - else if (splitResult.url === "<anonymous>")
|
| - continue;
|
| - else
|
| - return null;
|
| -
|
| - links.push({url: url, positionLeft: position + left, positionRight: position + right, lineNumber: splitResult.lineNumber, columnNumber: splitResult.columnNumber});
|
| - }
|
| + var errorPrefixes = ['EvalError', 'ReferenceError', 'SyntaxError', 'TypeError', 'RangeError', 'Error', 'URIError'];
|
| + var target = this._target();
|
| + if (!target || !errorPrefixes.some(startsWith))
|
| + return null;
|
| + var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
|
| + if (!debuggerModel)
|
| + return null;
|
| +
|
| + var lines = string.split('\n');
|
| + var links = [];
|
| + var position = 0;
|
| + for (var i = 0; i < lines.length; ++i) {
|
| + position += i > 0 ? lines[i - 1].length + 1 : 0;
|
| + var isCallFrameLine = /^\s*at\s/.test(lines[i]);
|
| + if (!isCallFrameLine && links.length)
|
| + return null;
|
| +
|
| + if (!isCallFrameLine)
|
| + continue;
|
| +
|
| + var openBracketIndex = -1;
|
| + var closeBracketIndex = -1;
|
| + var match = /\([^\)\(]+\)/.exec(lines[i]);
|
| + if (match) {
|
| + openBracketIndex = match.index;
|
| + closeBracketIndex = match.index + match[0].length - 1;
|
| + }
|
| + var hasOpenBracket = openBracketIndex !== -1;
|
| + var left = hasOpenBracket ? openBracketIndex + 1 : lines[i].indexOf('at') + 3;
|
| + var right = hasOpenBracket ? closeBracketIndex : lines[i].length;
|
| + var linkCandidate = lines[i].substring(left, right);
|
| + var splitResult = WebInspector.ParsedURL.splitLineAndColumn(linkCandidate);
|
| + if (!splitResult)
|
| + return null;
|
| +
|
| + var parsed = splitResult.url.asParsedURL();
|
| + var url;
|
| + if (parsed)
|
| + url = parsed.url;
|
| + else if (debuggerModel.scriptsForSourceURL(splitResult.url).length)
|
| + url = splitResult.url;
|
| + else if (splitResult.url === '<anonymous>')
|
| + continue;
|
| + else
|
| + return null;
|
| +
|
| + links.push({
|
| + url: url,
|
| + positionLeft: position + left,
|
| + positionRight: position + right,
|
| + lineNumber: splitResult.lineNumber,
|
| + columnNumber: splitResult.columnNumber
|
| + });
|
| + }
|
|
|
| - if (!links.length)
|
| - return null;
|
| + if (!links.length)
|
| + return null;
|
|
|
| - var formattedResult = createElement("span");
|
| - var start = 0;
|
| - for (var i = 0; i < links.length; ++i) {
|
| - formattedResult.appendChild(WebInspector.linkifyStringAsFragment(string.substring(start, links[i].positionLeft)));
|
| - formattedResult.appendChild(this._linkifier.linkifyScriptLocation(target, null, links[i].url, links[i].lineNumber, links[i].columnNumber));
|
| - start = links[i].positionRight;
|
| - }
|
| + var formattedResult = createElement('span');
|
| + var start = 0;
|
| + for (var i = 0; i < links.length; ++i) {
|
| + formattedResult.appendChild(WebInspector.linkifyStringAsFragment(string.substring(start, links[i].positionLeft)));
|
| + formattedResult.appendChild(this._linkifier.linkifyScriptLocation(
|
| + target, null, links[i].url, links[i].lineNumber, links[i].columnNumber));
|
| + start = links[i].positionRight;
|
| + }
|
|
|
| - if (start !== string.length)
|
| - formattedResult.appendChild(WebInspector.linkifyStringAsFragment(string.substring(start)));
|
| + if (start !== string.length)
|
| + formattedResult.appendChild(WebInspector.linkifyStringAsFragment(string.substring(start)));
|
|
|
| - return formattedResult;
|
| - }
|
| + return formattedResult;
|
| + }
|
| };
|
|
|
| /**
|
| - * @constructor
|
| - * @extends {WebInspector.ConsoleViewMessage}
|
| - * @param {!WebInspector.ConsoleMessage} consoleMessage
|
| - * @param {!WebInspector.Linkifier} linkifier
|
| - * @param {number} nestingLevel
|
| + * @unrestricted
|
| */
|
| -WebInspector.ConsoleGroupViewMessage = function(consoleMessage, linkifier, nestingLevel)
|
| -{
|
| +WebInspector.ConsoleGroupViewMessage = class extends WebInspector.ConsoleViewMessage {
|
| + /**
|
| + * @param {!WebInspector.ConsoleMessage} consoleMessage
|
| + * @param {!WebInspector.Linkifier} linkifier
|
| + * @param {number} nestingLevel
|
| + */
|
| + constructor(consoleMessage, linkifier, nestingLevel) {
|
| console.assert(consoleMessage.isGroupStartMessage());
|
| - WebInspector.ConsoleViewMessage.call(this, consoleMessage, linkifier, nestingLevel);
|
| + super(consoleMessage, linkifier, nestingLevel);
|
| this.setCollapsed(consoleMessage.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed);
|
| -};
|
| -
|
| -WebInspector.ConsoleGroupViewMessage.prototype = {
|
| - /**
|
| - * @param {boolean} collapsed
|
| - */
|
| - setCollapsed: function(collapsed)
|
| - {
|
| - this._collapsed = collapsed;
|
| - if (this._element)
|
| - this._element.classList.toggle("collapsed", this._collapsed);
|
| - },
|
| -
|
| - /**
|
| - * @return {boolean}
|
| - */
|
| - collapsed: function()
|
| - {
|
| - return this._collapsed;
|
| - },
|
| -
|
| - /**
|
| - * @override
|
| - * @return {!Element}
|
| - */
|
| - toMessageElement: function()
|
| - {
|
| - if (!this._element) {
|
| - WebInspector.ConsoleViewMessage.prototype.toMessageElement.call(this);
|
| - this._element.classList.toggle("collapsed", this._collapsed);
|
| - }
|
| - return this._element;
|
| - },
|
| -
|
| - __proto__: WebInspector.ConsoleViewMessage.prototype
|
| + }
|
| +
|
| + /**
|
| + * @param {boolean} collapsed
|
| + */
|
| + setCollapsed(collapsed) {
|
| + this._collapsed = collapsed;
|
| + if (this._element)
|
| + this._element.classList.toggle('collapsed', this._collapsed);
|
| + }
|
| +
|
| + /**
|
| + * @return {boolean}
|
| + */
|
| + collapsed() {
|
| + return this._collapsed;
|
| + }
|
| +
|
| + /**
|
| + * @override
|
| + * @return {!Element}
|
| + */
|
| + toMessageElement() {
|
| + if (!this._element) {
|
| + super.toMessageElement();
|
| + this._element.classList.toggle('collapsed', this._collapsed);
|
| + }
|
| + return this._element;
|
| + }
|
| };
|
|
|