blob: 36aec76fc8339591d8f408d163a093e809afc4cc [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371/*
2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
4 * Copyright (C) 2009 Joseph Pecoraro
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
Tim van der Lippe9b2f8712020-02-12 17:46:2230
31import * as Common from '../common/common.js';
32import * as Components from '../components/components.js';
33import * as DataGrid from '../data_grid/data_grid.js';
34import * as ObjectUI from '../object_ui/object_ui.js';
Tim van der Lippe93b57c32020-02-20 17:38:4435import * as Platform from '../platform/platform.js';
Tim van der Lippe9b2f8712020-02-12 17:46:2236import * as SDK from '../sdk/sdk.js';
37import * as TextUtils from '../text_utils/text_utils.js';
38import * as UI from '../ui/ui.js';
39
Tim van der Lippeeaacb722020-01-10 12:16:0040import {ConsoleViewportElement} from './ConsoleViewport.js'; // eslint-disable-line no-unused-vars
41
Blink Reformat4c46d092018-04-07 15:32:3742/**
Tim van der Lippeeaacb722020-01-10 12:16:0043 * @implements {ConsoleViewportElement}
Blink Reformat4c46d092018-04-07 15:32:3744 * @unrestricted
45 */
Tim van der Lippeeaacb722020-01-10 12:16:0046export class ConsoleViewMessage {
Blink Reformat4c46d092018-04-07 15:32:3747 /**
Tim van der Lippe9b2f8712020-02-12 17:46:2248 * @param {!SDK.ConsoleModel.ConsoleMessage} consoleMessage
49 * @param {!Components.Linkifier.Linkifier} linkifier
Blink Reformat4c46d092018-04-07 15:32:3750 * @param {number} nestingLevel
Tim van der Lippec02a97c2020-02-14 14:39:2751 * @param {function(!Common.EventTarget.EventTargetEvent)} onResize
Blink Reformat4c46d092018-04-07 15:32:3752 */
Tim van der Lippeb45d9a02019-11-05 17:24:4153 constructor(consoleMessage, linkifier, nestingLevel, onResize) {
Blink Reformat4c46d092018-04-07 15:32:3754 this._message = consoleMessage;
55 this._linkifier = linkifier;
Blink Reformat4c46d092018-04-07 15:32:3756 this._repeatCount = 1;
57 this._closeGroupDecorationCount = 0;
58 this._nestingLevel = nestingLevel;
Erik Luo31c21f62018-12-13 03:39:3959 /** @type {!Array<{element: !Element, forceSelect: function()}>} */
Erik Luo383f21d2018-11-07 23:16:3760 this._selectableChildren = [];
Erik Luo840be6b2018-12-03 20:54:2761 this._messageResized = onResize;
Blink Reformat4c46d092018-04-07 15:32:3762
Tim van der Lippe9b2f8712020-02-12 17:46:2263 /** @type {?DataGrid.DataGrid.DataGridImpl} */
Blink Reformat4c46d092018-04-07 15:32:3764 this._dataGrid = null;
Tim van der Lippe9b2f8712020-02-12 17:46:2265 this._previewFormatter = new ObjectUI.RemoteObjectPreviewFormatter.RemoteObjectPreviewFormatter();
Blink Reformat4c46d092018-04-07 15:32:3766 this._searchRegex = null;
Tim van der Lippe9b2f8712020-02-12 17:46:2267 /** @type {?UI.Icon.Icon} */
Blink Reformat4c46d092018-04-07 15:32:3768 this._messageLevelIcon = null;
Erik Luo8ef5d0c2018-09-25 21:16:0069 this._traceExpanded = false;
70 /** @type {?function(boolean)} */
71 this._expandTrace = null;
John Emaubb2897a2019-10-04 17:37:3272 /** @type {?Element} */
73 this._anchorElement = null;
Blink Reformat4c46d092018-04-07 15:32:3774 }
75
76 /**
77 * @override
78 * @return {!Element}
79 */
80 element() {
81 return this.toMessageElement();
82 }
83
84 /**
Blink Reformat4c46d092018-04-07 15:32:3785 * @override
86 */
87 wasShown() {
Tim van der Lippe1d6e57a2019-09-30 11:55:3488 if (this._dataGrid) {
Blink Reformat4c46d092018-04-07 15:32:3789 this._dataGrid.updateWidths();
Tim van der Lippe1d6e57a2019-09-30 11:55:3490 }
Blink Reformat4c46d092018-04-07 15:32:3791 this._isVisible = true;
92 }
93
94 onResize() {
Tim van der Lippe1d6e57a2019-09-30 11:55:3495 if (!this._isVisible) {
Blink Reformat4c46d092018-04-07 15:32:3796 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:3497 }
98 if (this._dataGrid) {
Blink Reformat4c46d092018-04-07 15:32:3799 this._dataGrid.onResize();
Tim van der Lippe1d6e57a2019-09-30 11:55:34100 }
Blink Reformat4c46d092018-04-07 15:32:37101 }
102
103 /**
104 * @override
105 */
106 willHide() {
107 this._isVisible = false;
Erik Luo4b002322018-07-30 21:23:31108 this._cachedHeight = this.element().offsetHeight;
Blink Reformat4c46d092018-04-07 15:32:37109 }
110
111 /**
112 * @return {number}
113 */
114 fastHeight() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34115 if (this._cachedHeight) {
Blink Reformat4c46d092018-04-07 15:32:37116 return this._cachedHeight;
Tim van der Lippe1d6e57a2019-09-30 11:55:34117 }
Blink Reformat4c46d092018-04-07 15:32:37118 // This value reflects the 18px min-height of .console-message, plus the
119 // 1px border of .console-message-wrapper. Keep in sync with consoleView.css.
120 const defaultConsoleRowHeight = 19;
Tim van der Lippe9b2f8712020-02-12 17:46:22121 if (this._message.type === SDK.ConsoleModel.MessageType.Table) {
Blink Reformat4c46d092018-04-07 15:32:37122 const table = this._message.parameters[0];
Tim van der Lippe1d6e57a2019-09-30 11:55:34123 if (table && table.preview) {
Blink Reformat4c46d092018-04-07 15:32:37124 return defaultConsoleRowHeight * table.preview.properties.length;
Tim van der Lippe1d6e57a2019-09-30 11:55:34125 }
Blink Reformat4c46d092018-04-07 15:32:37126 }
127 return defaultConsoleRowHeight;
128 }
129
130 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22131 * @return {!SDK.ConsoleModel.ConsoleMessage}
Blink Reformat4c46d092018-04-07 15:32:37132 */
133 consoleMessage() {
134 return this._message;
135 }
136
137 /**
138 * @return {!Element}
139 */
140 _buildTableMessage() {
Tim van der Lippef49e2322020-05-01 15:03:09141 const formattedMessage = document.createElement('span');
142 formattedMessage.classList.add('source-code');
Erik Luo5976c8c2018-07-24 02:03:09143 this._anchorElement = this._buildMessageAnchor();
Tim van der Lippe1d6e57a2019-09-30 11:55:34144 if (this._anchorElement) {
Erik Luo5976c8c2018-07-24 02:03:09145 formattedMessage.appendChild(this._anchorElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34146 }
Blink Reformat4c46d092018-04-07 15:32:37147
Tim van der Lippe20749392020-05-27 14:33:51148 const table = this._message.parameters && this._message.parameters.length ? this._message.parameters[0] : null;
149 if (!table) {
150 return this._buildMessage();
Tim van der Lippe1d6e57a2019-09-30 11:55:34151 }
Tim van der Lippe20749392020-05-27 14:33:51152 const actualTable = this._parameterToRemoteObject(table);
153 if (!actualTable || !actualTable.preview) {
Erik Luo16e3e382018-11-09 02:56:01154 return this._buildMessage();
Tim van der Lippe1d6e57a2019-09-30 11:55:34155 }
Blink Reformat4c46d092018-04-07 15:32:37156
157 const rawValueColumnSymbol = Symbol('rawValueColumn');
158 const columnNames = [];
Tim van der Lippe20749392020-05-27 14:33:51159 const preview = actualTable.preview;
Blink Reformat4c46d092018-04-07 15:32:37160 const rows = [];
161 for (let i = 0; i < preview.properties.length; ++i) {
162 const rowProperty = preview.properties[i];
163 let rowSubProperties;
Tim van der Lippe1d6e57a2019-09-30 11:55:34164 if (rowProperty.valuePreview) {
Blink Reformat4c46d092018-04-07 15:32:37165 rowSubProperties = rowProperty.valuePreview.properties;
Tim van der Lippe1d6e57a2019-09-30 11:55:34166 } else if (rowProperty.value) {
Blink Reformat4c46d092018-04-07 15:32:37167 rowSubProperties = [{name: rawValueColumnSymbol, type: rowProperty.type, value: rowProperty.value}];
Tim van der Lippe1d6e57a2019-09-30 11:55:34168 } else {
Blink Reformat4c46d092018-04-07 15:32:37169 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34170 }
Blink Reformat4c46d092018-04-07 15:32:37171
172 const rowValue = {};
173 const maxColumnsToRender = 20;
174 for (let j = 0; j < rowSubProperties.length; ++j) {
175 const cellProperty = rowSubProperties[j];
176 let columnRendered = columnNames.indexOf(cellProperty.name) !== -1;
177 if (!columnRendered) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34178 if (columnNames.length === maxColumnsToRender) {
Blink Reformat4c46d092018-04-07 15:32:37179 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34180 }
Blink Reformat4c46d092018-04-07 15:32:37181 columnRendered = true;
182 columnNames.push(cellProperty.name);
183 }
184
185 if (columnRendered) {
Tim van der Lippe20749392020-05-27 14:33:51186 const cellElement = this._renderPropertyPreviewOrAccessor(actualTable, [rowProperty, cellProperty]);
Blink Reformat4c46d092018-04-07 15:32:37187 cellElement.classList.add('console-message-nowrap-below');
188 rowValue[cellProperty.name] = cellElement;
189 }
190 }
191 rows.push([rowProperty.name, rowValue]);
192 }
193
194 const flatValues = [];
195 for (let i = 0; i < rows.length; ++i) {
196 const rowName = rows[i][0];
197 const rowValue = rows[i][1];
198 flatValues.push(rowName);
Tim van der Lippe1d6e57a2019-09-30 11:55:34199 for (let j = 0; j < columnNames.length; ++j) {
Blink Reformat4c46d092018-04-07 15:32:37200 flatValues.push(rowValue[columnNames[j]]);
Tim van der Lippe1d6e57a2019-09-30 11:55:34201 }
Blink Reformat4c46d092018-04-07 15:32:37202 }
Tim van der Lippe9b2f8712020-02-12 17:46:22203 columnNames.unshift(Common.UIString.UIString('(index)'));
204 const columnDisplayNames =
205 columnNames.map(name => name === rawValueColumnSymbol ? Common.UIString.UIString('Value') : name);
Blink Reformat4c46d092018-04-07 15:32:37206
207 if (flatValues.length) {
Tim van der Lippe9b2f8712020-02-12 17:46:22208 this._dataGrid = DataGrid.SortableDataGrid.SortableDataGrid.create(columnDisplayNames, flatValues, ls`Console`);
Blink Reformat4c46d092018-04-07 15:32:37209 this._dataGrid.setStriped(true);
Anubha Mathurfbacf4e2019-10-28 19:08:03210 this._dataGrid.setFocusable(false);
Blink Reformat4c46d092018-04-07 15:32:37211
Tim van der Lippef49e2322020-05-01 15:03:09212 const formattedResult = document.createElement('span');
213 formattedResult.classList.add('console-message-text');
Blink Reformat4c46d092018-04-07 15:32:37214 const tableElement = formattedResult.createChild('div', 'console-message-formatted-table');
215 const dataGridContainer = tableElement.createChild('span');
Tim van der Lippe20749392020-05-27 14:33:51216 tableElement.appendChild(this._formatParameter(actualTable, true, false));
Blink Reformat4c46d092018-04-07 15:32:37217 dataGridContainer.appendChild(this._dataGrid.element);
218 formattedMessage.appendChild(formattedResult);
219 this._dataGrid.renderInline();
220 }
221 return formattedMessage;
222 }
223
224 /**
225 * @return {!Element}
226 */
227 _buildMessage() {
228 let messageElement;
229 let messageText = this._message.messageText;
Tim van der Lippe9b2f8712020-02-12 17:46:22230 if (this._message.source === SDK.ConsoleModel.MessageSource.ConsoleAPI) {
Blink Reformat4c46d092018-04-07 15:32:37231 switch (this._message.type) {
Tim van der Lippe9b2f8712020-02-12 17:46:22232 case SDK.ConsoleModel.MessageType.Trace:
Blink Reformat4c46d092018-04-07 15:32:37233 messageElement = this._format(this._message.parameters || ['console.trace']);
234 break;
Tim van der Lippe9b2f8712020-02-12 17:46:22235 case SDK.ConsoleModel.MessageType.Clear:
Tim van der Lippef49e2322020-05-01 15:03:09236 messageElement = document.createElement('span');
237 messageElement.classList.add('console-info');
Paul Lewis2d7d65c2020-03-16 17:26:30238 if (Common.Settings.Settings.instance().moduleSetting('preserveConsoleLog').get()) {
Tim van der Lippe9b2f8712020-02-12 17:46:22239 messageElement.textContent =
240 Common.UIString.UIString('console.clear() was prevented due to \'Preserve log\'');
Tim van der Lippe1d6e57a2019-09-30 11:55:34241 } else {
Tim van der Lippe9b2f8712020-02-12 17:46:22242 messageElement.textContent = Common.UIString.UIString('Console was cleared');
Tim van der Lippe1d6e57a2019-09-30 11:55:34243 }
Blink Reformat4c46d092018-04-07 15:32:37244 messageElement.title =
Paul Lewis05eb37f2020-01-24 14:31:40245 ls`Clear all messages with ${self.UI.shortcutRegistry.shortcutTitleForAction('console.clear')}`;
Blink Reformat4c46d092018-04-07 15:32:37246 break;
Tim van der Lippe9b2f8712020-02-12 17:46:22247 case SDK.ConsoleModel.MessageType.Dir: {
Blink Reformat4c46d092018-04-07 15:32:37248 const obj = this._message.parameters ? this._message.parameters[0] : undefined;
249 const args = ['%O', obj];
250 messageElement = this._format(args);
251 break;
252 }
Tim van der Lippe9b2f8712020-02-12 17:46:22253 case SDK.ConsoleModel.MessageType.Profile:
254 case SDK.ConsoleModel.MessageType.ProfileEnd:
Blink Reformat4c46d092018-04-07 15:32:37255 messageElement = this._format([messageText]);
256 break;
Tim van der Lippe9b2f8712020-02-12 17:46:22257 case SDK.ConsoleModel.MessageType.Assert:
Pavel Feldman9f0f0a32018-12-18 02:09:13258 this._messagePrefix = ls`Assertion failed: `;
259 // Fall through.
Blink Reformat4c46d092018-04-07 15:32:37260 default: {
261 if (this._message.parameters && this._message.parameters.length === 1 &&
Tim van der Lippe1d6e57a2019-09-30 11:55:34262 this._message.parameters[0].type === 'string') {
Blink Reformat4c46d092018-04-07 15:32:37263 messageElement = this._tryFormatAsError(/** @type {string} */ (this._message.parameters[0].value));
Tim van der Lippe1d6e57a2019-09-30 11:55:34264 }
Blink Reformat4c46d092018-04-07 15:32:37265 const args = this._message.parameters || [messageText];
266 messageElement = messageElement || this._format(args);
267 }
268 }
269 } else {
Tim van der Lippe9b2f8712020-02-12 17:46:22270 if (this._message.source === SDK.ConsoleModel.MessageSource.Network) {
Erik Luofc2214f2018-11-21 19:54:58271 messageElement = this._formatAsNetworkRequest() || this._format([messageText]);
272 } else {
Blink Reformat4c46d092018-04-07 15:32:37273 const messageInParameters =
274 this._message.parameters && messageText === /** @type {string} */ (this._message.parameters[0]);
Tim van der Lippe9b2f8712020-02-12 17:46:22275 if (this._message.source === SDK.ConsoleModel.MessageSource.Violation) {
276 messageText = Common.UIString.UIString('[Violation] %s', messageText);
277 } else if (this._message.source === SDK.ConsoleModel.MessageSource.Intervention) {
278 messageText = Common.UIString.UIString('[Intervention] %s', messageText);
279 } else if (this._message.source === SDK.ConsoleModel.MessageSource.Deprecation) {
280 messageText = Common.UIString.UIString('[Deprecation] %s', messageText);
Tim van der Lippe1d6e57a2019-09-30 11:55:34281 }
Blink Reformat4c46d092018-04-07 15:32:37282 const args = this._message.parameters || [messageText];
Tim van der Lippe1d6e57a2019-09-30 11:55:34283 if (messageInParameters) {
Blink Reformat4c46d092018-04-07 15:32:37284 args[0] = messageText;
Tim van der Lippe1d6e57a2019-09-30 11:55:34285 }
Blink Reformat4c46d092018-04-07 15:32:37286 messageElement = this._format(args);
287 }
288 }
289 messageElement.classList.add('console-message-text');
290
Tim van der Lippef49e2322020-05-01 15:03:09291 const formattedMessage = document.createElement('span');
292 formattedMessage.classList.add('source-code');
Erik Luo5976c8c2018-07-24 02:03:09293 this._anchorElement = this._buildMessageAnchor();
Tim van der Lippe1d6e57a2019-09-30 11:55:34294 if (this._anchorElement) {
Erik Luo5976c8c2018-07-24 02:03:09295 formattedMessage.appendChild(this._anchorElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34296 }
Blink Reformat4c46d092018-04-07 15:32:37297 formattedMessage.appendChild(messageElement);
298 return formattedMessage;
299 }
300
301 /**
302 * @return {?Element}
303 */
Erik Luofc2214f2018-11-21 19:54:58304 _formatAsNetworkRequest() {
Tim van der Lippe9b2f8712020-02-12 17:46:22305 const request = SDK.NetworkLog.NetworkLog.requestForConsoleMessage(this._message);
Tim van der Lippe1d6e57a2019-09-30 11:55:34306 if (!request) {
Erik Luofc2214f2018-11-21 19:54:58307 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34308 }
Erik Luofc2214f2018-11-21 19:54:58309 const messageElement = createElement('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22310 if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Erik Luofc2214f2018-11-21 19:54:58311 messageElement.createTextChild(request.requestMethod + ' ');
Tim van der Lippe9b2f8712020-02-12 17:46:22312 const linkElement = Components.Linkifier.Linkifier.linkifyRevealable(request, request.url(), request.url());
Erik Luo182bece2018-11-29 03:15:22313 // Focus is handled by the viewport.
314 linkElement.tabIndex = -1;
Erik Luo31c21f62018-12-13 03:39:39315 this._selectableChildren.push({element: linkElement, forceSelect: () => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22316 messageElement.appendChild(linkElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34317 if (request.failed) {
Tim van der Lippe3cccb4f2020-05-01 13:57:17318 messageElement.createTextChildren(' ', request.localizedFailDescription || '');
Tim van der Lippe1d6e57a2019-09-30 11:55:34319 }
320 if (request.statusCode !== 0) {
Erik Luofc2214f2018-11-21 19:54:58321 messageElement.createTextChildren(' ', String(request.statusCode));
Tim van der Lippe1d6e57a2019-09-30 11:55:34322 }
323 if (request.statusText) {
Erik Luofc2214f2018-11-21 19:54:58324 messageElement.createTextChildren(' (', request.statusText, ')');
Tim van der Lippe1d6e57a2019-09-30 11:55:34325 }
Erik Luofc2214f2018-11-21 19:54:58326 } else {
Erik Luoad5f3942019-03-26 20:53:44327 const messageText = this._message.messageText;
328 const fragment = this._linkifyWithCustomLinkifier(messageText, (text, url, lineNumber, columnNumber) => {
329 let linkElement;
330 if (url === request.url()) {
Tim van der Lippe9b2f8712020-02-12 17:46:22331 linkElement = Components.Linkifier.Linkifier.linkifyRevealable(
332 /** @type {!SDK.NetworkRequest.NetworkRequest} */ (request), url, request.url());
Erik Luoad5f3942019-03-26 20:53:44333 } else {
Tim van der Lippe9b2f8712020-02-12 17:46:22334 linkElement = Components.Linkifier.Linkifier.linkifyURL(url, {text, lineNumber, columnNumber});
Erik Luoad5f3942019-03-26 20:53:44335 }
Erik Luo182bece2018-11-29 03:15:22336 linkElement.tabIndex = -1;
Erik Luo31c21f62018-12-13 03:39:39337 this._selectableChildren.push({element: linkElement, forceSelect: () => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22338 return linkElement;
339 });
Erik Luofc2214f2018-11-21 19:54:58340 messageElement.appendChild(fragment);
341 }
342 return messageElement;
343 }
344
345 /**
346 * @return {?Element}
347 */
Blink Reformat4c46d092018-04-07 15:32:37348 _buildMessageAnchor() {
349 let anchorElement = null;
350 if (this._message.scriptId) {
351 anchorElement = this._linkifyScriptId(
352 this._message.scriptId, this._message.url || '', this._message.line, this._message.column);
353 } else if (this._message.stackTrace && this._message.stackTrace.callFrames.length) {
354 anchorElement = this._linkifyStackTraceTopFrame(this._message.stackTrace);
355 } else if (this._message.url && this._message.url !== 'undefined') {
356 anchorElement = this._linkifyLocation(this._message.url, this._message.line, this._message.column);
357 }
358
359 // Append a space to prevent the anchor text from being glued to the console message when the user selects and copies the console messages.
360 if (anchorElement) {
John Emauf7e30fb2019-10-04 19:12:32361 anchorElement.tabIndex = -1;
362 this._selectableChildren.push({
363 element: anchorElement,
364 forceSelect: () => anchorElement.focus(),
365 });
Tim van der Lippef49e2322020-05-01 15:03:09366 const anchorWrapperElement = document.createElement('span');
367 anchorWrapperElement.classList.add('console-message-anchor');
Blink Reformat4c46d092018-04-07 15:32:37368 anchorWrapperElement.appendChild(anchorElement);
369 anchorWrapperElement.createTextChild(' ');
370 return anchorWrapperElement;
371 }
372 return null;
373 }
374
375 /**
Blink Reformat4c46d092018-04-07 15:32:37376 * @return {!Element}
377 */
378 _buildMessageWithStackTrace() {
Tim van der Lippef49e2322020-05-01 15:03:09379 const toggleElement = document.createElement('div');
380 toggleElement.classList.add('console-message-stack-trace-toggle');
Blink Reformat4c46d092018-04-07 15:32:37381 const contentElement = toggleElement.createChild('div', 'console-message-stack-trace-wrapper');
382
383 const messageElement = this._buildMessage();
Tim van der Lippe9b2f8712020-02-12 17:46:22384 const icon = UI.Icon.Icon.create('smallicon-triangle-right', 'console-message-expand-icon');
Blink Reformat4c46d092018-04-07 15:32:37385 const clickableElement = contentElement.createChild('div');
386 clickableElement.appendChild(icon);
Erik Luob5bfff42018-09-20 02:52:39387 // Intercept focus to avoid highlight on click.
388 clickableElement.tabIndex = -1;
Blink Reformat4c46d092018-04-07 15:32:37389
390 clickableElement.appendChild(messageElement);
391 const stackTraceElement = contentElement.createChild('div');
392 const stackTracePreview = Components.JSPresentationUtils.buildStackTracePreviewContents(
Jack Lynch7bc9bf22020-01-13 17:16:00393 this._message.runtimeModel().target(), this._linkifier, {stackTrace: this._message.stackTrace});
Erik Luo182bece2018-11-29 03:15:22394 stackTraceElement.appendChild(stackTracePreview.element);
395 for (const linkElement of stackTracePreview.links) {
Erik Luo31c21f62018-12-13 03:39:39396 this._selectableChildren.push({element: linkElement, forceSelect: () => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22397 }
Blink Reformat4c46d092018-04-07 15:32:37398 stackTraceElement.classList.add('hidden');
Brandon Goddard04a5a762019-12-10 16:45:53399 UI.ARIAUtils.markAsTreeitem(this.element());
400 UI.ARIAUtils.setExpanded(this.element(), false);
Erik Luo8ef5d0c2018-09-25 21:16:00401 this._expandTrace = expand => {
Blink Reformat4c46d092018-04-07 15:32:37402 icon.setIconType(expand ? 'smallicon-triangle-down' : 'smallicon-triangle-right');
403 stackTraceElement.classList.toggle('hidden', !expand);
Brandon Goddard04a5a762019-12-10 16:45:53404 UI.ARIAUtils.setExpanded(this.element(), expand);
Erik Luo8ef5d0c2018-09-25 21:16:00405 this._traceExpanded = expand;
406 };
Blink Reformat4c46d092018-04-07 15:32:37407
408 /**
Tim van der Lippeeaacb722020-01-10 12:16:00409 * @this {!ConsoleViewMessage}
Blink Reformat4c46d092018-04-07 15:32:37410 * @param {?Event} event
411 */
412 function toggleStackTrace(event) {
Tim van der Lippe9b2f8712020-02-12 17:46:22413 if (UI.UIUtils.isEditing() || contentElement.hasSelection()) {
Blink Reformat4c46d092018-04-07 15:32:37414 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34415 }
Erik Luo8ef5d0c2018-09-25 21:16:00416 this._expandTrace(stackTraceElement.classList.contains('hidden'));
Blink Reformat4c46d092018-04-07 15:32:37417 event.consume();
418 }
419
Erik Luo8ef5d0c2018-09-25 21:16:00420 clickableElement.addEventListener('click', toggleStackTrace.bind(this), false);
Tim van der Lippe9b2f8712020-02-12 17:46:22421 if (this._message.type === SDK.ConsoleModel.MessageType.Trace) {
Erik Luo8ef5d0c2018-09-25 21:16:00422 this._expandTrace(true);
Tim van der Lippe1d6e57a2019-09-30 11:55:34423 }
Blink Reformat4c46d092018-04-07 15:32:37424
Erik Luo8ef5d0c2018-09-25 21:16:00425 toggleElement._expandStackTraceForTest = this._expandTrace.bind(this, true);
Blink Reformat4c46d092018-04-07 15:32:37426 return toggleElement;
427 }
428
429 /**
430 * @param {string} url
431 * @param {number} lineNumber
432 * @param {number} columnNumber
433 * @return {?Element}
434 */
435 _linkifyLocation(url, lineNumber, columnNumber) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34436 if (!this._message.runtimeModel()) {
Blink Reformat4c46d092018-04-07 15:32:37437 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34438 }
Blink Reformat4c46d092018-04-07 15:32:37439 return this._linkifier.linkifyScriptLocation(
Jack Lynch236e1d22020-01-07 20:33:51440 this._message.runtimeModel().target(), /* scriptId */ null, url, lineNumber, {columnNumber});
Blink Reformat4c46d092018-04-07 15:32:37441 }
442
443 /**
444 * @param {!Protocol.Runtime.StackTrace} stackTrace
445 * @return {?Element}
446 */
447 _linkifyStackTraceTopFrame(stackTrace) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34448 if (!this._message.runtimeModel()) {
Blink Reformat4c46d092018-04-07 15:32:37449 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34450 }
Blink Reformat4c46d092018-04-07 15:32:37451 return this._linkifier.linkifyStackTraceTopFrame(this._message.runtimeModel().target(), stackTrace);
452 }
453
454 /**
455 * @param {string} scriptId
456 * @param {string} url
457 * @param {number} lineNumber
458 * @param {number} columnNumber
459 * @return {?Element}
460 */
461 _linkifyScriptId(scriptId, url, lineNumber, columnNumber) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34462 if (!this._message.runtimeModel()) {
Blink Reformat4c46d092018-04-07 15:32:37463 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34464 }
Blink Reformat4c46d092018-04-07 15:32:37465 return this._linkifier.linkifyScriptLocation(
Jack Lynch236e1d22020-01-07 20:33:51466 this._message.runtimeModel().target(), scriptId, url, lineNumber, {columnNumber});
Blink Reformat4c46d092018-04-07 15:32:37467 }
468
469 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22470 * @param {!SDK.RemoteObject.RemoteObject|!Protocol.Runtime.RemoteObject|string} parameter
471 * @return {!SDK.RemoteObject.RemoteObject}
Blink Reformat4c46d092018-04-07 15:32:37472 */
473 _parameterToRemoteObject(parameter) {
Tim van der Lippe9b2f8712020-02-12 17:46:22474 if (parameter instanceof SDK.RemoteObject.RemoteObject) {
Blink Reformat4c46d092018-04-07 15:32:37475 return parameter;
Tim van der Lippe1d6e57a2019-09-30 11:55:34476 }
Blink Reformat4c46d092018-04-07 15:32:37477 const runtimeModel = this._message.runtimeModel();
Tim van der Lippe1d6e57a2019-09-30 11:55:34478 if (!runtimeModel) {
Tim van der Lippe9b2f8712020-02-12 17:46:22479 return SDK.RemoteObject.RemoteObject.fromLocalObject(parameter);
Tim van der Lippe1d6e57a2019-09-30 11:55:34480 }
481 if (typeof parameter === 'object') {
Blink Reformat4c46d092018-04-07 15:32:37482 return runtimeModel.createRemoteObject(parameter);
Tim van der Lippe1d6e57a2019-09-30 11:55:34483 }
Blink Reformat4c46d092018-04-07 15:32:37484 return runtimeModel.createRemoteObjectFromPrimitiveValue(parameter);
485 }
486
487 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22488 * @param {!Array.<!SDK.RemoteObject.RemoteObject|string>} rawParameters
Blink Reformat4c46d092018-04-07 15:32:37489 * @return {!Element}
490 */
491 _format(rawParameters) {
492 // This node is used like a Builder. Values are continually appended onto it.
493 const formattedResult = createElement('span');
Tim van der Lippe1d6e57a2019-09-30 11:55:34494 if (this._messagePrefix) {
Pavel Feldman9f0f0a32018-12-18 02:09:13495 formattedResult.createChild('span').textContent = this._messagePrefix;
Tim van der Lippe1d6e57a2019-09-30 11:55:34496 }
497 if (!rawParameters.length) {
Blink Reformat4c46d092018-04-07 15:32:37498 return formattedResult;
Tim van der Lippe1d6e57a2019-09-30 11:55:34499 }
Blink Reformat4c46d092018-04-07 15:32:37500
501 // Formatting code below assumes that parameters are all wrappers whereas frontend console
502 // API allows passing arbitrary values as messages (strings, numbers, etc.). Wrap them here.
503 // FIXME: Only pass runtime wrappers here.
504 let parameters = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:34505 for (let i = 0; i < rawParameters.length; ++i) {
Blink Reformat4c46d092018-04-07 15:32:37506 parameters[i] = this._parameterToRemoteObject(rawParameters[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:34507 }
Blink Reformat4c46d092018-04-07 15:32:37508
509 // There can be string log and string eval result. We distinguish between them based on message type.
510 const shouldFormatMessage =
Tim van der Lippe9b2f8712020-02-12 17:46:22511 SDK.RemoteObject.RemoteObject.type(
512 (/** @type {!Array.<!SDK.RemoteObject.RemoteObject>} **/ (parameters))[0]) === 'string' &&
513 (this._message.type !== SDK.ConsoleModel.MessageType.Result ||
514 this._message.level === SDK.ConsoleModel.MessageLevel.Error);
Blink Reformat4c46d092018-04-07 15:32:37515
516 // Multiple parameters with the first being a format string. Save unused substitutions.
517 if (shouldFormatMessage) {
518 const result = this._formatWithSubstitutionString(
519 /** @type {string} **/ (parameters[0].description), parameters.slice(1), formattedResult);
520 parameters = result.unusedSubstitutions;
Tim van der Lippe1d6e57a2019-09-30 11:55:34521 if (parameters.length) {
Blink Reformat4c46d092018-04-07 15:32:37522 formattedResult.createTextChild(' ');
Tim van der Lippe1d6e57a2019-09-30 11:55:34523 }
Blink Reformat4c46d092018-04-07 15:32:37524 }
525
526 // Single parameter, or unused substitutions from above.
527 for (let i = 0; i < parameters.length; ++i) {
528 // Inline strings when formatting.
Tim van der Lippe1d6e57a2019-09-30 11:55:34529 if (shouldFormatMessage && parameters[i].type === 'string') {
Erik Luo383f21d2018-11-07 23:16:37530 formattedResult.appendChild(this._linkifyStringAsFragment(parameters[i].description));
Tim van der Lippe1d6e57a2019-09-30 11:55:34531 } else {
Blink Reformat4c46d092018-04-07 15:32:37532 formattedResult.appendChild(this._formatParameter(parameters[i], false, true));
Tim van der Lippe1d6e57a2019-09-30 11:55:34533 }
534 if (i < parameters.length - 1) {
Blink Reformat4c46d092018-04-07 15:32:37535 formattedResult.createTextChild(' ');
Tim van der Lippe1d6e57a2019-09-30 11:55:34536 }
Blink Reformat4c46d092018-04-07 15:32:37537 }
538 return formattedResult;
539 }
540
541 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22542 * @param {!SDK.RemoteObject.RemoteObject} output
Blink Reformat4c46d092018-04-07 15:32:37543 * @param {boolean=} forceObjectFormat
544 * @param {boolean=} includePreview
545 * @return {!Element}
546 */
547 _formatParameter(output, forceObjectFormat, includePreview) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34548 if (output.customPreview()) {
Tim van der Lippe9b2f8712020-02-12 17:46:22549 return (new ObjectUI.CustomPreviewComponent.CustomPreviewComponent(output)).element;
Tim van der Lippe1d6e57a2019-09-30 11:55:34550 }
Blink Reformat4c46d092018-04-07 15:32:37551
552 const type = forceObjectFormat ? 'object' : (output.subtype || output.type);
553 let element;
554 switch (type) {
555 case 'error':
556 element = this._formatParameterAsError(output);
557 break;
558 case 'function':
559 element = this._formatParameterAsFunction(output, includePreview);
560 break;
561 case 'array':
562 case 'arraybuffer':
563 case 'blob':
564 case 'dataview':
565 case 'generator':
566 case 'iterator':
567 case 'map':
568 case 'object':
569 case 'promise':
570 case 'proxy':
571 case 'set':
572 case 'typedarray':
573 case 'weakmap':
574 case 'weakset':
575 element = this._formatParameterAsObject(output, includePreview);
576 break;
577 case 'node':
578 element = output.isNode() ? this._formatParameterAsNode(output) : this._formatParameterAsObject(output, false);
579 break;
580 case 'string':
581 element = this._formatParameterAsString(output);
582 break;
583 case 'boolean':
584 case 'date':
585 case 'null':
586 case 'number':
587 case 'regexp':
588 case 'symbol':
589 case 'undefined':
590 case 'bigint':
591 element = this._formatParameterAsValue(output);
592 break;
593 default:
594 element = this._formatParameterAsValue(output);
595 console.error('Tried to format remote object of unknown type.');
596 }
597 element.classList.add('object-value-' + type);
598 element.classList.add('source-code');
599 return element;
600 }
601
602 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22603 * @param {!SDK.RemoteObject.RemoteObject} obj
Blink Reformat4c46d092018-04-07 15:32:37604 * @return {!Element}
Tim van der Lippeeaacb722020-01-10 12:16:00605 * @suppress {accessControls}
Blink Reformat4c46d092018-04-07 15:32:37606 */
607 _formatParameterAsValue(obj) {
608 const result = createElement('span');
609 const description = obj.description || '';
Tim van der Lippe1d6e57a2019-09-30 11:55:34610 if (description.length > Console.ConsoleViewMessage._MaxTokenizableStringLength) {
Tim van der Lippe9b2f8712020-02-12 17:46:22611 const propertyValue = new ObjectUI.ObjectPropertiesSection.ExpandableTextPropertyValue(
Connor Moody1a5c0d32019-12-19 07:23:36612 createElement('span'), description, Console.ConsoleViewMessage._LongStringVisibleLength);
613 result.appendChild(propertyValue.element);
Tim van der Lippe1d6e57a2019-09-30 11:55:34614 } else {
Blink Reformat4c46d092018-04-07 15:32:37615 result.createTextChild(description);
Tim van der Lippe1d6e57a2019-09-30 11:55:34616 }
617 if (obj.objectId) {
Blink Reformat4c46d092018-04-07 15:32:37618 result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, obj), false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34619 }
Blink Reformat4c46d092018-04-07 15:32:37620 return result;
621 }
622
623 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22624 * @param {!SDK.RemoteObject.RemoteObject} obj
Blink Reformat4c46d092018-04-07 15:32:37625 * @param {boolean=} includePreview
626 * @return {!Element}
627 */
628 _formatParameterAsObject(obj, includePreview) {
Tim van der Lippef49e2322020-05-01 15:03:09629 const titleElement = document.createElement('span');
630 titleElement.classList.add('console-object');
Blink Reformat4c46d092018-04-07 15:32:37631 if (includePreview && obj.preview) {
632 titleElement.classList.add('console-object-preview');
633 this._previewFormatter.appendObjectPreview(titleElement, obj.preview, false /* isEntry */);
634 } else if (obj.type === 'function') {
635 const functionElement = titleElement.createChild('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22636 ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection.formatObjectAsFunction(obj, functionElement, false);
Blink Reformat4c46d092018-04-07 15:32:37637 titleElement.classList.add('object-value-function');
638 } else {
639 titleElement.createTextChild(obj.description || '');
640 }
641
Tim van der Lippe1d6e57a2019-09-30 11:55:34642 if (!obj.hasChildren || obj.customPreview()) {
Blink Reformat4c46d092018-04-07 15:32:37643 return titleElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:34644 }
Blink Reformat4c46d092018-04-07 15:32:37645
646 const note = titleElement.createChild('span', 'object-state-note info-note');
Tim van der Lippe9b2f8712020-02-12 17:46:22647 if (this._message.type === SDK.ConsoleModel.MessageType.QueryObjectResult) {
Blink Reformat4c46d092018-04-07 15:32:37648 note.title = ls`This value will not be collected until console is cleared.`;
Tim van der Lippe1d6e57a2019-09-30 11:55:34649 } else {
Blink Reformat4c46d092018-04-07 15:32:37650 note.title = ls`Value below was evaluated just now.`;
Tim van der Lippe1d6e57a2019-09-30 11:55:34651 }
Blink Reformat4c46d092018-04-07 15:32:37652
Tim van der Lippe9b2f8712020-02-12 17:46:22653 const section = new ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection(obj, titleElement, this._linkifier);
Blink Reformat4c46d092018-04-07 15:32:37654 section.element.classList.add('console-view-object-properties-section');
655 section.enableContextMenu();
Erik Luocc14b812018-11-03 01:33:09656 section.setShowSelectionOnKeyboardFocus(true, true);
Erik Luo383f21d2018-11-07 23:16:37657 this._selectableChildren.push(section);
Erik Luo840be6b2018-12-03 20:54:27658 section.addEventListener(UI.TreeOutline.Events.ElementAttached, this._messageResized);
659 section.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._messageResized);
660 section.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._messageResized);
Blink Reformat4c46d092018-04-07 15:32:37661 return section.element;
662 }
663
664 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22665 * @param {!SDK.RemoteObject.RemoteObject} func
Blink Reformat4c46d092018-04-07 15:32:37666 * @param {boolean=} includePreview
667 * @return {!Element}
668 */
669 _formatParameterAsFunction(func, includePreview) {
670 const result = createElement('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22671 SDK.RemoteObject.RemoteFunction.objectAsFunction(func).targetFunction().then(formatTargetFunction.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37672 return result;
673
674 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22675 * @param {!SDK.RemoteObject.RemoteObject} targetFunction
Tim van der Lippeeaacb722020-01-10 12:16:00676 * @this {ConsoleViewMessage}
Blink Reformat4c46d092018-04-07 15:32:37677 */
678 function formatTargetFunction(targetFunction) {
679 const functionElement = createElement('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22680 const promise = ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection.formatObjectAsFunction(
Joey Arhard78a58f2018-12-05 01:59:45681 targetFunction, functionElement, true, includePreview);
Blink Reformat4c46d092018-04-07 15:32:37682 result.appendChild(functionElement);
683 if (targetFunction !== func) {
684 const note = result.createChild('span', 'object-info-state-note');
Tim van der Lippe9b2f8712020-02-12 17:46:22685 note.title = Common.UIString.UIString('Function was resolved from bound function.');
Blink Reformat4c46d092018-04-07 15:32:37686 }
687 result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, targetFunction), false);
Joey Arhard78a58f2018-12-05 01:59:45688 promise.then(() => this._formattedParameterAsFunctionForTest());
Blink Reformat4c46d092018-04-07 15:32:37689 }
690 }
691
Joey Arhard78a58f2018-12-05 01:59:45692 _formattedParameterAsFunctionForTest() {
693 }
694
Blink Reformat4c46d092018-04-07 15:32:37695 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22696 * @param {!SDK.RemoteObject.RemoteObject} obj
Blink Reformat4c46d092018-04-07 15:32:37697 * @param {!Event} event
698 */
699 _contextMenuEventFired(obj, event) {
Tim van der Lippe9b2f8712020-02-12 17:46:22700 const contextMenu = new UI.ContextMenu.ContextMenu(event);
Blink Reformat4c46d092018-04-07 15:32:37701 contextMenu.appendApplicableItems(obj);
702 contextMenu.show();
703 }
704
705 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22706 * @param {?SDK.RemoteObject.RemoteObject} object
Blink Reformat4c46d092018-04-07 15:32:37707 * @param {!Array.<!Protocol.Runtime.PropertyPreview>} propertyPath
708 * @return {!Element}
709 */
710 _renderPropertyPreviewOrAccessor(object, propertyPath) {
711 const property = propertyPath.peekLast();
Tim van der Lippe1d6e57a2019-09-30 11:55:34712 if (property.type === 'accessor') {
Blink Reformat4c46d092018-04-07 15:32:37713 return this._formatAsAccessorProperty(object, propertyPath.map(property => property.name), false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34714 }
Blink Reformat4c46d092018-04-07 15:32:37715 return this._previewFormatter.renderPropertyPreview(
716 property.type, /** @type {string} */ (property.subtype), property.value);
717 }
718
719 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22720 * @param {!SDK.RemoteObject.RemoteObject} remoteObject
Blink Reformat4c46d092018-04-07 15:32:37721 * @return {!Element}
722 */
723 _formatParameterAsNode(remoteObject) {
724 const result = createElement('span');
725
Tim van der Lippe9b2f8712020-02-12 17:46:22726 const domModel = remoteObject.runtimeModel().target().model(SDK.DOMModel.DOMModel);
Tim van der Lippe1d6e57a2019-09-30 11:55:34727 if (!domModel) {
Blink Reformat4c46d092018-04-07 15:32:37728 return result;
Tim van der Lippe1d6e57a2019-09-30 11:55:34729 }
Erik Luo54fdd912018-11-01 17:57:01730 domModel.pushObjectAsNodeToFrontend(remoteObject).then(async node => {
Blink Reformat4c46d092018-04-07 15:32:37731 if (!node) {
732 result.appendChild(this._formatParameterAsObject(remoteObject, false));
733 return;
734 }
Tim van der Lippe9b2f8712020-02-12 17:46:22735 const renderResult = await UI.UIUtils.Renderer.render(/** @type {!Object} */ (node));
Erik Luofc6a6302018-11-02 06:48:52736 if (renderResult) {
Erik Luo840be6b2018-12-03 20:54:27737 if (renderResult.tree) {
Erik Luo383f21d2018-11-07 23:16:37738 this._selectableChildren.push(renderResult.tree);
Erik Luo840be6b2018-12-03 20:54:27739 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementAttached, this._messageResized);
740 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._messageResized);
741 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._messageResized);
742 }
Erik Luofc6a6302018-11-02 06:48:52743 result.appendChild(renderResult.node);
744 } else {
745 result.appendChild(this._formatParameterAsObject(remoteObject, false));
746 }
Erik Luo54fdd912018-11-01 17:57:01747 this._formattedParameterAsNodeForTest();
Blink Reformat4c46d092018-04-07 15:32:37748 });
749
750 return result;
751 }
752
753 _formattedParameterAsNodeForTest() {
754 }
755
756 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22757 * @param {!SDK.RemoteObject.RemoteObject} output
Blink Reformat4c46d092018-04-07 15:32:37758 * @return {!Element}
759 */
760 _formatParameterAsString(output) {
761 const span = createElement('span');
Erik Luo383f21d2018-11-07 23:16:37762 span.appendChild(this._linkifyStringAsFragment(output.description || ''));
Blink Reformat4c46d092018-04-07 15:32:37763
764 const result = createElement('span');
765 result.createChild('span', 'object-value-string-quote').textContent = '"';
766 result.appendChild(span);
767 result.createChild('span', 'object-value-string-quote').textContent = '"';
768 return result;
769 }
770
771 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22772 * @param {!SDK.RemoteObject.RemoteObject} output
Blink Reformat4c46d092018-04-07 15:32:37773 * @return {!Element}
774 */
775 _formatParameterAsError(output) {
776 const result = createElement('span');
777 const errorSpan = this._tryFormatAsError(output.description || '');
Erik Luo383f21d2018-11-07 23:16:37778 result.appendChild(errorSpan ? errorSpan : this._linkifyStringAsFragment(output.description || ''));
Blink Reformat4c46d092018-04-07 15:32:37779 return result;
780 }
781
782 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22783 * @param {!SDK.RemoteObject.RemoteObject} output
Blink Reformat4c46d092018-04-07 15:32:37784 * @return {!Element}
785 */
786 _formatAsArrayEntry(output) {
787 return this._previewFormatter.renderPropertyPreview(output.type, output.subtype, output.description);
788 }
789
790 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22791 * @param {?SDK.RemoteObject.RemoteObject} object
Blink Reformat4c46d092018-04-07 15:32:37792 * @param {!Array.<string>} propertyPath
793 * @param {boolean} isArrayEntry
794 * @return {!Element}
795 */
796 _formatAsAccessorProperty(object, propertyPath, isArrayEntry) {
Tim van der Lippe9b2f8712020-02-12 17:46:22797 const rootElement =
798 ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan(
799 object, propertyPath, onInvokeGetterClick.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37800
801 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22802 * @param {!SDK.RemoteObject.CallFunctionResult} result
Tim van der Lippeeaacb722020-01-10 12:16:00803 * @this {ConsoleViewMessage}
Blink Reformat4c46d092018-04-07 15:32:37804 */
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18805 function onInvokeGetterClick(result) {
806 const wasThrown = result.wasThrown;
807 const object = result.object;
Tim van der Lippe1d6e57a2019-09-30 11:55:34808 if (!object) {
Blink Reformat4c46d092018-04-07 15:32:37809 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34810 }
Blink Reformat4c46d092018-04-07 15:32:37811 rootElement.removeChildren();
812 if (wasThrown) {
813 const element = rootElement.createChild('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22814 element.textContent = Common.UIString.UIString('<exception>');
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18815 element.title = /** @type {string} */ (object.description);
Blink Reformat4c46d092018-04-07 15:32:37816 } else if (isArrayEntry) {
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18817 rootElement.appendChild(this._formatAsArrayEntry(object));
Blink Reformat4c46d092018-04-07 15:32:37818 } else {
819 // Make a PropertyPreview from the RemoteObject similar to the backend logic.
820 const maxLength = 100;
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18821 const type = object.type;
822 const subtype = object.subtype;
Blink Reformat4c46d092018-04-07 15:32:37823 let description = '';
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18824 if (type !== 'function' && object.description) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34825 if (type === 'string' || subtype === 'regexp') {
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18826 description = object.description.trimMiddle(maxLength);
Tim van der Lippe1d6e57a2019-09-30 11:55:34827 } else {
Tim van der Lippeffa78622019-09-16 12:07:12828 description = object.description.trimEndWithMaxLength(maxLength);
Tim van der Lippe1d6e57a2019-09-30 11:55:34829 }
Blink Reformat4c46d092018-04-07 15:32:37830 }
831 rootElement.appendChild(this._previewFormatter.renderPropertyPreview(type, subtype, description));
832 }
833 }
834
835 return rootElement;
836 }
837
838 /**
839 * @param {string} format
Tim van der Lippe9b2f8712020-02-12 17:46:22840 * @param {!Array.<!SDK.RemoteObject.RemoteObject>} parameters
Blink Reformat4c46d092018-04-07 15:32:37841 * @param {!Element} formattedResult
842 */
843 _formatWithSubstitutionString(format, parameters, formattedResult) {
844 const formatters = {};
845
846 /**
847 * @param {boolean} force
848 * @param {boolean} includePreview
Tim van der Lippe9b2f8712020-02-12 17:46:22849 * @param {!SDK.RemoteObject.RemoteObject} obj
Blink Reformat4c46d092018-04-07 15:32:37850 * @return {!Element}
Tim van der Lippeeaacb722020-01-10 12:16:00851 * @this {ConsoleViewMessage}
Blink Reformat4c46d092018-04-07 15:32:37852 */
853 function parameterFormatter(force, includePreview, obj) {
854 return this._formatParameter(obj, force, includePreview);
855 }
856
857 function stringFormatter(obj) {
858 return obj.description;
859 }
860
861 function floatFormatter(obj) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34862 if (typeof obj.value !== 'number') {
Blink Reformat4c46d092018-04-07 15:32:37863 return 'NaN';
Tim van der Lippe1d6e57a2019-09-30 11:55:34864 }
Blink Reformat4c46d092018-04-07 15:32:37865 return obj.value;
866 }
867
868 function integerFormatter(obj) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34869 if (obj.type === 'bigint') {
Alexey Kozyatinskiybeb38de2018-08-10 18:54:19870 return obj.description;
Tim van der Lippe1d6e57a2019-09-30 11:55:34871 }
872 if (typeof obj.value !== 'number') {
Blink Reformat4c46d092018-04-07 15:32:37873 return 'NaN';
Tim van der Lippe1d6e57a2019-09-30 11:55:34874 }
Blink Reformat4c46d092018-04-07 15:32:37875 return Math.floor(obj.value);
876 }
877
878 function bypassFormatter(obj) {
879 return (obj instanceof Node) ? obj : '';
880 }
881
882 let currentStyle = null;
883 function styleFormatter(obj) {
884 currentStyle = {};
885 const buffer = createElement('span');
886 buffer.setAttribute('style', obj.description);
887 for (let i = 0; i < buffer.style.length; i++) {
888 const property = buffer.style[i];
Mathias Bynens5165a7a2020-06-10 05:51:43889 if (isAllowedProperty(property)) {
Blink Reformat4c46d092018-04-07 15:32:37890 currentStyle[property] = buffer.style[property];
Tim van der Lippe1d6e57a2019-09-30 11:55:34891 }
Blink Reformat4c46d092018-04-07 15:32:37892 }
893 }
894
Mathias Bynens5165a7a2020-06-10 05:51:43895 function isAllowedProperty(property) {
Blink Reformat4c46d092018-04-07 15:32:37896 // Make sure that allowed properties do not interfere with link visibility.
897 const prefixes = [
898 'background', 'border', 'color', 'font', 'line', 'margin', 'padding', 'text', '-webkit-background',
899 '-webkit-border', '-webkit-font', '-webkit-margin', '-webkit-padding', '-webkit-text'
900 ];
901 for (let i = 0; i < prefixes.length; i++) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34902 if (property.startsWith(prefixes[i])) {
Blink Reformat4c46d092018-04-07 15:32:37903 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:34904 }
Blink Reformat4c46d092018-04-07 15:32:37905 }
906 return false;
907 }
908
909 // Firebug uses %o for formatting objects.
910 formatters.o = parameterFormatter.bind(this, false /* force */, true /* includePreview */);
911 formatters.s = stringFormatter;
912 formatters.f = floatFormatter;
913 // Firebug allows both %i and %d for formatting integers.
914 formatters.i = integerFormatter;
915 formatters.d = integerFormatter;
916
917 // Firebug uses %c for styling the message.
918 formatters.c = styleFormatter;
919
920 // Support %O to force object formatting, instead of the type-based %o formatting.
921 formatters.O = parameterFormatter.bind(this, true /* force */, false /* includePreview */);
922
923 formatters._ = bypassFormatter;
924
925 /**
926 * @param {!Element} a
927 * @param {*} b
Tim van der Lippeeaacb722020-01-10 12:16:00928 * @this {!ConsoleViewMessage}
Erik Luo17926392018-05-17 22:06:12929 * @return {!Element}
Blink Reformat4c46d092018-04-07 15:32:37930 */
931 function append(a, b) {
932 if (b instanceof Node) {
933 a.appendChild(b);
Erik Luo17926392018-05-17 22:06:12934 return a;
935 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34936 if (typeof b === 'undefined') {
Erik Luo17926392018-05-17 22:06:12937 return a;
Tim van der Lippe1d6e57a2019-09-30 11:55:34938 }
Erik Luo17926392018-05-17 22:06:12939 if (!currentStyle) {
Erik Luo383f21d2018-11-07 23:16:37940 a.appendChild(this._linkifyStringAsFragment(String(b)));
Erik Luo17926392018-05-17 22:06:12941 return a;
942 }
943 const lines = String(b).split('\n');
944 for (let i = 0; i < lines.length; i++) {
945 const line = lines[i];
Erik Luo383f21d2018-11-07 23:16:37946 const lineFragment = this._linkifyStringAsFragment(line);
Erik Luo17926392018-05-17 22:06:12947 const wrapper = createElement('span');
948 wrapper.style.setProperty('contain', 'paint');
949 wrapper.style.setProperty('display', 'inline-block');
950 wrapper.style.setProperty('max-width', '100%');
951 wrapper.appendChild(lineFragment);
952 applyCurrentStyle(wrapper);
953 for (const child of wrapper.children) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34954 if (child.classList.contains('devtools-link')) {
Erik Luo17926392018-05-17 22:06:12955 this._applyForcedVisibleStyle(child);
Tim van der Lippe1d6e57a2019-09-30 11:55:34956 }
Blink Reformat4c46d092018-04-07 15:32:37957 }
Erik Luo17926392018-05-17 22:06:12958 a.appendChild(wrapper);
Tim van der Lippe1d6e57a2019-09-30 11:55:34959 if (i < lines.length - 1) {
Erik Luo17926392018-05-17 22:06:12960 a.appendChild(createElement('br'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34961 }
Blink Reformat4c46d092018-04-07 15:32:37962 }
963 return a;
964 }
965
966 /**
967 * @param {!Element} element
968 */
969 function applyCurrentStyle(element) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34970 for (const key in currentStyle) {
Blink Reformat4c46d092018-04-07 15:32:37971 element.style[key] = currentStyle[key];
Tim van der Lippe1d6e57a2019-09-30 11:55:34972 }
Blink Reformat4c46d092018-04-07 15:32:37973 }
974
Tim van der Lippe93b57c32020-02-20 17:38:44975 // Platform.StringUtilities.format does treat formattedResult like a Builder, result is an object.
976 return Platform.StringUtilities.format(format, parameters, formatters, formattedResult, append.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37977 }
978
979 /**
980 * @param {!Element} element
981 */
982 _applyForcedVisibleStyle(element) {
983 element.style.setProperty('-webkit-text-stroke', '0', 'important');
984 element.style.setProperty('text-decoration', 'underline', 'important');
985
Paul Lewis93d8e2c2020-01-24 16:34:55986 const themedColor =
Tim van der Lippe9b2f8712020-02-12 17:46:22987 self.UI.themeSupport.patchColorText('rgb(33%, 33%, 33%)', UI.UIUtils.ThemeSupport.ColorUsage.Foreground);
Blink Reformat4c46d092018-04-07 15:32:37988 element.style.setProperty('color', themedColor, 'important');
989
990 let backgroundColor = 'hsl(0, 0%, 100%)';
Tim van der Lippe9b2f8712020-02-12 17:46:22991 if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Blink Reformat4c46d092018-04-07 15:32:37992 backgroundColor = 'hsl(0, 100%, 97%)';
Tim van der Lippe9b2f8712020-02-12 17:46:22993 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning || this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:37994 backgroundColor = 'hsl(50, 100%, 95%)';
Tim van der Lippe1d6e57a2019-09-30 11:55:34995 }
Blink Reformat4c46d092018-04-07 15:32:37996 const themedBackgroundColor =
Tim van der Lippe9b2f8712020-02-12 17:46:22997 self.UI.themeSupport.patchColorText(backgroundColor, UI.UIUtils.ThemeSupport.ColorUsage.Background);
Blink Reformat4c46d092018-04-07 15:32:37998 element.style.setProperty('background-color', themedBackgroundColor, 'important');
999 }
1000
1001 /**
1002 * @return {boolean}
1003 */
1004 matchesFilterRegex(regexObject) {
1005 regexObject.lastIndex = 0;
Erik Luo5976c8c2018-07-24 02:03:091006 const contentElement = this.contentElement();
1007 const anchorText = this._anchorElement ? this._anchorElement.deepTextContent() : '';
1008 return (anchorText && regexObject.test(anchorText.trim())) ||
1009 regexObject.test(contentElement.deepTextContent().slice(anchorText.length));
Blink Reformat4c46d092018-04-07 15:32:371010 }
1011
1012 /**
1013 * @param {string} filter
1014 * @return {boolean}
1015 */
1016 matchesFilterText(filter) {
1017 const text = this.contentElement().deepTextContent();
1018 return text.toLowerCase().includes(filter.toLowerCase());
1019 }
1020
1021 updateTimestamp() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341022 if (!this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371023 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341024 }
Blink Reformat4c46d092018-04-07 15:32:371025
Paul Lewis2d7d65c2020-03-16 17:26:301026 if (Common.Settings.Settings.instance().moduleSetting('consoleTimestampsEnabled').get()) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341027 if (!this._timestampElement) {
Tim van der Lippef49e2322020-05-01 15:03:091028 this._timestampElement = document.createElement('span');
1029 this._timestampElement.classList.add('console-timestamp');
Tim van der Lippe1d6e57a2019-09-30 11:55:341030 }
Tim van der Lippe9b2f8712020-02-12 17:46:221031 this._timestampElement.textContent = UI.UIUtils.formatTimestamp(this._message.timestamp, false) + ' ';
1032 this._timestampElement.title = UI.UIUtils.formatTimestamp(this._message.timestamp, true);
Blink Reformat4c46d092018-04-07 15:32:371033 this._contentElement.insertBefore(this._timestampElement, this._contentElement.firstChild);
1034 } else if (this._timestampElement) {
1035 this._timestampElement.remove();
1036 delete this._timestampElement;
1037 }
Blink Reformat4c46d092018-04-07 15:32:371038 }
1039
1040 /**
1041 * @return {number}
1042 */
1043 nestingLevel() {
1044 return this._nestingLevel;
1045 }
1046
1047 /**
1048 * @param {boolean} inSimilarGroup
1049 * @param {boolean=} isLast
1050 */
1051 setInSimilarGroup(inSimilarGroup, isLast) {
1052 this._inSimilarGroup = inSimilarGroup;
1053 this._lastInSimilarGroup = inSimilarGroup && !!isLast;
1054 if (this._similarGroupMarker && !inSimilarGroup) {
1055 this._similarGroupMarker.remove();
1056 this._similarGroupMarker = null;
1057 } else if (this._element && !this._similarGroupMarker && inSimilarGroup) {
Tim van der Lippef49e2322020-05-01 15:03:091058 this._similarGroupMarker = document.createElement('div');
1059 this._similarGroupMarker.classList.add('nesting-level-marker');
Blink Reformat4c46d092018-04-07 15:32:371060 this._element.insertBefore(this._similarGroupMarker, this._element.firstChild);
1061 this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
1062 }
1063 }
1064
1065 /**
1066 * @return {boolean}
1067 */
1068 isLastInSimilarGroup() {
1069 return this._inSimilarGroup && this._lastInSimilarGroup;
1070 }
1071
1072 resetCloseGroupDecorationCount() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341073 if (!this._closeGroupDecorationCount) {
Blink Reformat4c46d092018-04-07 15:32:371074 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341075 }
Blink Reformat4c46d092018-04-07 15:32:371076 this._closeGroupDecorationCount = 0;
1077 this._updateCloseGroupDecorations();
1078 }
1079
1080 incrementCloseGroupDecorationCount() {
1081 ++this._closeGroupDecorationCount;
1082 this._updateCloseGroupDecorations();
1083 }
1084
1085 _updateCloseGroupDecorations() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341086 if (!this._nestingLevelMarkers) {
Blink Reformat4c46d092018-04-07 15:32:371087 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341088 }
Blink Reformat4c46d092018-04-07 15:32:371089 for (let i = 0, n = this._nestingLevelMarkers.length; i < n; ++i) {
1090 const marker = this._nestingLevelMarkers[i];
1091 marker.classList.toggle('group-closed', n - i <= this._closeGroupDecorationCount);
1092 }
1093 }
1094
1095 /**
Erik Luo0b8282e2018-10-08 20:37:461096 * @return {number}
1097 */
1098 _focusedChildIndex() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341099 if (!this._selectableChildren.length) {
Erik Luo0b8282e2018-10-08 20:37:461100 return -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341101 }
Erik Luo383f21d2018-11-07 23:16:371102 return this._selectableChildren.findIndex(child => child.element.hasFocus());
Erik Luo0b8282e2018-10-08 20:37:461103 }
1104
1105 /**
Erik Luo8ef5d0c2018-09-25 21:16:001106 * @param {!Event} event
1107 */
1108 _onKeyDown(event) {
Tim van der Lippe9b2f8712020-02-12 17:46:221109 if (UI.UIUtils.isEditing() || !this._element.hasFocus() || this._element.hasSelection()) {
Erik Luo8ef5d0c2018-09-25 21:16:001110 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341111 }
1112 if (this.maybeHandleOnKeyDown(event)) {
Erik Luo8ef5d0c2018-09-25 21:16:001113 event.consume(true);
Tim van der Lippe1d6e57a2019-09-30 11:55:341114 }
Erik Luo8ef5d0c2018-09-25 21:16:001115 }
1116
1117 /**
1118 * @protected
1119 * @param {!Event} event
1120 */
1121 maybeHandleOnKeyDown(event) {
1122 // Handle trace expansion.
Erik Luo0b8282e2018-10-08 20:37:461123 const focusedChildIndex = this._focusedChildIndex();
1124 const isWrapperFocused = focusedChildIndex === -1;
1125 if (this._expandTrace && isWrapperFocused) {
Erik Luo8ef5d0c2018-09-25 21:16:001126 if ((event.key === 'ArrowLeft' && this._traceExpanded) || (event.key === 'ArrowRight' && !this._traceExpanded)) {
1127 this._expandTrace(!this._traceExpanded);
1128 return true;
1129 }
1130 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341131 if (!this._selectableChildren.length) {
Erik Luo0b8282e2018-10-08 20:37:461132 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341133 }
Erik Luo0b8282e2018-10-08 20:37:461134
1135 if (event.key === 'ArrowLeft') {
1136 this._element.focus();
1137 return true;
1138 }
1139 if (event.key === 'ArrowRight') {
Tim van der Lippe1d6e57a2019-09-30 11:55:341140 if (isWrapperFocused && this._selectNearestVisibleChild(0)) {
Erik Luo0b8282e2018-10-08 20:37:461141 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341142 }
Erik Luo0b8282e2018-10-08 20:37:461143 }
1144 if (event.key === 'ArrowUp') {
Erik Luo182bece2018-11-29 03:15:221145 const firstVisibleChild = this._nearestVisibleChild(0);
1146 if (this._selectableChildren[focusedChildIndex] === firstVisibleChild && firstVisibleChild) {
Erik Luo0b8282e2018-10-08 20:37:461147 this._element.focus();
1148 return true;
Mathias Bynensf06e8c02020-02-28 13:58:281149 }
1150 if (this._selectNearestVisibleChild(focusedChildIndex - 1, true /* backwards */)) {
Erik Luo0b8282e2018-10-08 20:37:461151 return true;
1152 }
1153 }
1154 if (event.key === 'ArrowDown') {
Tim van der Lippe1d6e57a2019-09-30 11:55:341155 if (isWrapperFocused && this._selectNearestVisibleChild(0)) {
Erik Luo0b8282e2018-10-08 20:37:461156 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341157 }
1158 if (!isWrapperFocused && this._selectNearestVisibleChild(focusedChildIndex + 1)) {
Erik Luo0b8282e2018-10-08 20:37:461159 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341160 }
Erik Luo0b8282e2018-10-08 20:37:461161 }
Erik Luo8ef5d0c2018-09-25 21:16:001162 return false;
1163 }
1164
Erik Luo182bece2018-11-29 03:15:221165 /**
1166 * @param {number} fromIndex
1167 * @param {boolean=} backwards
1168 * @return {boolean}
1169 */
1170 _selectNearestVisibleChild(fromIndex, backwards) {
1171 const nearestChild = this._nearestVisibleChild(fromIndex, backwards);
1172 if (nearestChild) {
Erik Luo31c21f62018-12-13 03:39:391173 nearestChild.forceSelect();
Erik Luo182bece2018-11-29 03:15:221174 return true;
1175 }
1176 return false;
1177 }
1178
1179 /**
1180 * @param {number} fromIndex
1181 * @param {boolean=} backwards
Erik Luo31c21f62018-12-13 03:39:391182 * @return {?{element: !Element, forceSelect: function()}}
Erik Luo182bece2018-11-29 03:15:221183 */
1184 _nearestVisibleChild(fromIndex, backwards) {
1185 const childCount = this._selectableChildren.length;
Tim van der Lippe1d6e57a2019-09-30 11:55:341186 if (fromIndex < 0 || fromIndex >= childCount) {
Erik Luo182bece2018-11-29 03:15:221187 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341188 }
Erik Luo182bece2018-11-29 03:15:221189 const direction = backwards ? -1 : 1;
1190 let index = fromIndex;
1191
1192 while (!this._selectableChildren[index].element.offsetParent) {
1193 index += direction;
Tim van der Lippe1d6e57a2019-09-30 11:55:341194 if (index < 0 || index >= childCount) {
Erik Luo182bece2018-11-29 03:15:221195 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341196 }
Erik Luo182bece2018-11-29 03:15:221197 }
1198 return this._selectableChildren[index];
1199 }
1200
Erik Luo0b8282e2018-10-08 20:37:461201 focusLastChildOrSelf() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341202 if (this._element && !this._selectNearestVisibleChild(this._selectableChildren.length - 1, true /* backwards */)) {
Erik Luo0b8282e2018-10-08 20:37:461203 this._element.focus();
Tim van der Lippe1d6e57a2019-09-30 11:55:341204 }
Erik Luo0b8282e2018-10-08 20:37:461205 }
1206
1207 /**
Blink Reformat4c46d092018-04-07 15:32:371208 * @return {!Element}
1209 */
1210 contentElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341211 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371212 return this._contentElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:341213 }
Blink Reformat4c46d092018-04-07 15:32:371214
Tim van der Lippef49e2322020-05-01 15:03:091215 const contentElement = document.createElement('div');
1216 contentElement.classList.add('console-message');
Tim van der Lippe1d6e57a2019-09-30 11:55:341217 if (this._messageLevelIcon) {
Blink Reformat4c46d092018-04-07 15:32:371218 contentElement.appendChild(this._messageLevelIcon);
Tim van der Lippe1d6e57a2019-09-30 11:55:341219 }
Blink Reformat4c46d092018-04-07 15:32:371220 this._contentElement = contentElement;
1221
1222 let formattedMessage;
1223 const shouldIncludeTrace = !!this._message.stackTrace &&
Tim van der Lippe9b2f8712020-02-12 17:46:221224 (this._message.source === SDK.ConsoleModel.MessageSource.Network ||
1225 this._message.source === SDK.ConsoleModel.MessageSource.Violation ||
1226 this._message.level === SDK.ConsoleModel.MessageLevel.Error ||
1227 this._message.level === SDK.ConsoleModel.MessageLevel.Warning ||
1228 this._message.type === SDK.ConsoleModel.MessageType.Trace);
Tim van der Lippe1d6e57a2019-09-30 11:55:341229 if (this._message.runtimeModel() && shouldIncludeTrace) {
Blink Reformat4c46d092018-04-07 15:32:371230 formattedMessage = this._buildMessageWithStackTrace();
Tim van der Lippe9b2f8712020-02-12 17:46:221231 } else if (this._message.type === SDK.ConsoleModel.MessageType.Table) {
Blink Reformat4c46d092018-04-07 15:32:371232 formattedMessage = this._buildTableMessage();
Tim van der Lippe1d6e57a2019-09-30 11:55:341233 } else {
Blink Reformat4c46d092018-04-07 15:32:371234 formattedMessage = this._buildMessage();
Tim van der Lippe1d6e57a2019-09-30 11:55:341235 }
Blink Reformat4c46d092018-04-07 15:32:371236 contentElement.appendChild(formattedMessage);
1237
1238 this.updateTimestamp();
1239 return this._contentElement;
1240 }
1241
1242 /**
1243 * @return {!Element}
1244 */
1245 toMessageElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341246 if (this._element) {
Blink Reformat4c46d092018-04-07 15:32:371247 return this._element;
Tim van der Lippe1d6e57a2019-09-30 11:55:341248 }
Blink Reformat4c46d092018-04-07 15:32:371249
1250 this._element = createElement('div');
Pavel Feldmandb310912019-01-30 00:31:201251 this._element.tabIndex = -1;
1252 this._element.addEventListener('keydown', this._onKeyDown.bind(this));
Blink Reformat4c46d092018-04-07 15:32:371253 this.updateMessageElement();
1254 return this._element;
1255 }
1256
1257 updateMessageElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341258 if (!this._element) {
Blink Reformat4c46d092018-04-07 15:32:371259 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341260 }
Blink Reformat4c46d092018-04-07 15:32:371261
1262 this._element.className = 'console-message-wrapper';
1263 this._element.removeChildren();
Tim van der Lippe1d6e57a2019-09-30 11:55:341264 if (this._message.isGroupStartMessage()) {
Blink Reformat4c46d092018-04-07 15:32:371265 this._element.classList.add('console-group-title');
Tim van der Lippe1d6e57a2019-09-30 11:55:341266 }
Tim van der Lippe9b2f8712020-02-12 17:46:221267 if (this._message.source === SDK.ConsoleModel.MessageSource.ConsoleAPI) {
Blink Reformat4c46d092018-04-07 15:32:371268 this._element.classList.add('console-from-api');
Tim van der Lippe1d6e57a2019-09-30 11:55:341269 }
Blink Reformat4c46d092018-04-07 15:32:371270 if (this._inSimilarGroup) {
1271 this._similarGroupMarker = this._element.createChild('div', 'nesting-level-marker');
1272 this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
1273 }
1274
1275 this._nestingLevelMarkers = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341276 for (let i = 0; i < this._nestingLevel; ++i) {
Blink Reformat4c46d092018-04-07 15:32:371277 this._nestingLevelMarkers.push(this._element.createChild('div', 'nesting-level-marker'));
Tim van der Lippe1d6e57a2019-09-30 11:55:341278 }
Blink Reformat4c46d092018-04-07 15:32:371279 this._updateCloseGroupDecorations();
1280 this._element.message = this;
1281
1282 switch (this._message.level) {
Tim van der Lippe9b2f8712020-02-12 17:46:221283 case SDK.ConsoleModel.MessageLevel.Verbose:
Blink Reformat4c46d092018-04-07 15:32:371284 this._element.classList.add('console-verbose-level');
Blink Reformat4c46d092018-04-07 15:32:371285 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221286 case SDK.ConsoleModel.MessageLevel.Info:
Blink Reformat4c46d092018-04-07 15:32:371287 this._element.classList.add('console-info-level');
Tim van der Lippe9b2f8712020-02-12 17:46:221288 if (this._message.type === SDK.ConsoleModel.MessageType.System) {
Blink Reformat4c46d092018-04-07 15:32:371289 this._element.classList.add('console-system-type');
Tim van der Lippe1d6e57a2019-09-30 11:55:341290 }
Blink Reformat4c46d092018-04-07 15:32:371291 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221292 case SDK.ConsoleModel.MessageLevel.Warning:
Blink Reformat4c46d092018-04-07 15:32:371293 this._element.classList.add('console-warning-level');
Blink Reformat4c46d092018-04-07 15:32:371294 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221295 case SDK.ConsoleModel.MessageLevel.Error:
Blink Reformat4c46d092018-04-07 15:32:371296 this._element.classList.add('console-error-level');
Blink Reformat4c46d092018-04-07 15:32:371297 break;
1298 }
Erik Luofd3e7d42018-09-25 02:12:351299 this._updateMessageLevelIcon();
Tim van der Lippe1d6e57a2019-09-30 11:55:341300 if (this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371301 this._element.classList.add('console-warning-level');
Tim van der Lippe1d6e57a2019-09-30 11:55:341302 }
Blink Reformat4c46d092018-04-07 15:32:371303
1304 this._element.appendChild(this.contentElement());
Tim van der Lippe1d6e57a2019-09-30 11:55:341305 if (this._repeatCount > 1) {
Blink Reformat4c46d092018-04-07 15:32:371306 this._showRepeatCountElement();
Tim van der Lippe1d6e57a2019-09-30 11:55:341307 }
Blink Reformat4c46d092018-04-07 15:32:371308 }
1309
1310 /**
1311 * @return {boolean}
1312 */
1313 _shouldRenderAsWarning() {
Tim van der Lippe9b2f8712020-02-12 17:46:221314 return (this._message.level === SDK.ConsoleModel.MessageLevel.Verbose ||
1315 this._message.level === SDK.ConsoleModel.MessageLevel.Info) &&
1316 (this._message.source === SDK.ConsoleModel.MessageSource.Violation ||
1317 this._message.source === SDK.ConsoleModel.MessageSource.Deprecation ||
1318 this._message.source === SDK.ConsoleModel.MessageSource.Intervention ||
1319 this._message.source === SDK.ConsoleModel.MessageSource.Recommendation);
Blink Reformat4c46d092018-04-07 15:32:371320 }
1321
Erik Luofd3e7d42018-09-25 02:12:351322 _updateMessageLevelIcon() {
1323 let iconType = '';
1324 let accessibleName = '';
Tim van der Lippe9b2f8712020-02-12 17:46:221325 if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning) {
Erik Luofd3e7d42018-09-25 02:12:351326 iconType = 'smallicon-warning';
1327 accessibleName = ls`Warning`;
Tim van der Lippe9b2f8712020-02-12 17:46:221328 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Erik Luofd3e7d42018-09-25 02:12:351329 iconType = 'smallicon-error';
1330 accessibleName = ls`Error`;
1331 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341332 if (!iconType && !this._messageLevelIcon) {
Blink Reformat4c46d092018-04-07 15:32:371333 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341334 }
Blink Reformat4c46d092018-04-07 15:32:371335 if (iconType && !this._messageLevelIcon) {
Tim van der Lippe9b2f8712020-02-12 17:46:221336 this._messageLevelIcon = UI.Icon.Icon.create('', 'message-level-icon');
Tim van der Lippe1d6e57a2019-09-30 11:55:341337 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371338 this._contentElement.insertBefore(this._messageLevelIcon, this._contentElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341339 }
Blink Reformat4c46d092018-04-07 15:32:371340 }
1341 this._messageLevelIcon.setIconType(iconType);
Erik Luofd3e7d42018-09-25 02:12:351342 UI.ARIAUtils.setAccessibleName(this._messageLevelIcon, accessibleName);
Blink Reformat4c46d092018-04-07 15:32:371343 }
1344
1345 /**
1346 * @return {number}
1347 */
1348 repeatCount() {
1349 return this._repeatCount || 1;
1350 }
1351
1352 resetIncrementRepeatCount() {
1353 this._repeatCount = 1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341354 if (!this._repeatCountElement) {
Blink Reformat4c46d092018-04-07 15:32:371355 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341356 }
Blink Reformat4c46d092018-04-07 15:32:371357
1358 this._repeatCountElement.remove();
Tim van der Lippe1d6e57a2019-09-30 11:55:341359 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371360 this._contentElement.classList.remove('repeated-message');
Tim van der Lippe1d6e57a2019-09-30 11:55:341361 }
Blink Reformat4c46d092018-04-07 15:32:371362 delete this._repeatCountElement;
1363 }
1364
1365 incrementRepeatCount() {
1366 this._repeatCount++;
1367 this._showRepeatCountElement();
1368 }
1369
1370 /**
1371 * @param {number} repeatCount
1372 */
1373 setRepeatCount(repeatCount) {
1374 this._repeatCount = repeatCount;
1375 this._showRepeatCountElement();
1376 }
1377
Tim van der Lippeee954d42020-05-04 10:35:571378 /**
1379 * @suppress {checkTypes}
1380 */
Blink Reformat4c46d092018-04-07 15:32:371381 _showRepeatCountElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341382 if (!this._element) {
Blink Reformat4c46d092018-04-07 15:32:371383 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341384 }
Blink Reformat4c46d092018-04-07 15:32:371385
1386 if (!this._repeatCountElement) {
Tim van der Lippeee954d42020-05-04 10:35:571387 this._repeatCountElement = document.createElement('span', {is: 'dt-small-bubble'});
1388 this._repeatCountElement.classList.add('console-message-repeat-count');
Blink Reformat4c46d092018-04-07 15:32:371389 switch (this._message.level) {
Tim van der Lippe9b2f8712020-02-12 17:46:221390 case SDK.ConsoleModel.MessageLevel.Warning:
Blink Reformat4c46d092018-04-07 15:32:371391 this._repeatCountElement.type = 'warning';
1392 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221393 case SDK.ConsoleModel.MessageLevel.Error:
Blink Reformat4c46d092018-04-07 15:32:371394 this._repeatCountElement.type = 'error';
1395 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221396 case SDK.ConsoleModel.MessageLevel.Verbose:
Blink Reformat4c46d092018-04-07 15:32:371397 this._repeatCountElement.type = 'verbose';
1398 break;
1399 default:
1400 this._repeatCountElement.type = 'info';
1401 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341402 if (this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371403 this._repeatCountElement.type = 'warning';
Tim van der Lippe1d6e57a2019-09-30 11:55:341404 }
Blink Reformat4c46d092018-04-07 15:32:371405
1406 this._element.insertBefore(this._repeatCountElement, this._contentElement);
1407 this._contentElement.classList.add('repeated-message');
1408 }
1409 this._repeatCountElement.textContent = this._repeatCount;
Erik Luofd3e7d42018-09-25 02:12:351410 let accessibleName = ls`Repeat ${this._repeatCount}`;
Tim van der Lippe9b2f8712020-02-12 17:46:221411 if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning) {
Erik Luofd3e7d42018-09-25 02:12:351412 accessibleName = ls`Warning ${accessibleName}`;
Tim van der Lippe9b2f8712020-02-12 17:46:221413 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Erik Luofd3e7d42018-09-25 02:12:351414 accessibleName = ls`Error ${accessibleName}`;
Tim van der Lippe1d6e57a2019-09-30 11:55:341415 }
Erik Luofd3e7d42018-09-25 02:12:351416 UI.ARIAUtils.setAccessibleName(this._repeatCountElement, accessibleName);
Blink Reformat4c46d092018-04-07 15:32:371417 }
1418
1419 get text() {
1420 return this._message.messageText;
1421 }
1422
1423 /**
1424 * @return {string}
1425 */
1426 toExportString() {
1427 const lines = [];
1428 const nodes = this.contentElement().childTextNodes();
Tim van der Lippe9b2f8712020-02-12 17:46:221429 const messageContent = nodes.map(Components.Linkifier.Linkifier.untruncatedNodeText).join('');
Tim van der Lippe1d6e57a2019-09-30 11:55:341430 for (let i = 0; i < this.repeatCount(); ++i) {
Blink Reformat4c46d092018-04-07 15:32:371431 lines.push(messageContent);
Tim van der Lippe1d6e57a2019-09-30 11:55:341432 }
Blink Reformat4c46d092018-04-07 15:32:371433 return lines.join('\n');
1434 }
1435
1436 /**
1437 * @param {?RegExp} regex
1438 */
1439 setSearchRegex(regex) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341440 if (this._searchHiglightNodeChanges && this._searchHiglightNodeChanges.length) {
Tim van der Lippe9b2f8712020-02-12 17:46:221441 UI.UIUtils.revertDomChanges(this._searchHiglightNodeChanges);
Tim van der Lippe1d6e57a2019-09-30 11:55:341442 }
Blink Reformat4c46d092018-04-07 15:32:371443 this._searchRegex = regex;
1444 this._searchHighlightNodes = [];
1445 this._searchHiglightNodeChanges = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341446 if (!this._searchRegex) {
Blink Reformat4c46d092018-04-07 15:32:371447 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341448 }
Blink Reformat4c46d092018-04-07 15:32:371449
1450 const text = this.contentElement().deepTextContent();
1451 let match;
1452 this._searchRegex.lastIndex = 0;
1453 const sourceRanges = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341454 while ((match = this._searchRegex.exec(text)) && match[0]) {
Tim van der Lippe9b2f8712020-02-12 17:46:221455 sourceRanges.push(new TextUtils.TextRange.SourceRange(match.index, match[0].length));
Tim van der Lippe1d6e57a2019-09-30 11:55:341456 }
Blink Reformat4c46d092018-04-07 15:32:371457
1458 if (sourceRanges.length) {
1459 this._searchHighlightNodes =
Tim van der Lippe9b2f8712020-02-12 17:46:221460 UI.UIUtils.highlightSearchResults(this.contentElement(), sourceRanges, this._searchHiglightNodeChanges);
Blink Reformat4c46d092018-04-07 15:32:371461 }
1462 }
1463
1464 /**
1465 * @return {?RegExp}
1466 */
1467 searchRegex() {
1468 return this._searchRegex;
1469 }
1470
1471 /**
1472 * @return {number}
1473 */
1474 searchCount() {
1475 return this._searchHighlightNodes.length;
1476 }
1477
1478 /**
1479 * @return {!Element}
1480 */
1481 searchHighlightNode(index) {
1482 return this._searchHighlightNodes[index];
1483 }
1484
1485 /**
1486 * @param {string} string
1487 * @return {?Element}
1488 */
1489 _tryFormatAsError(string) {
1490 /**
1491 * @param {string} prefix
1492 */
1493 function startsWith(prefix) {
1494 return string.startsWith(prefix);
1495 }
1496
1497 const errorPrefixes =
1498 ['EvalError', 'ReferenceError', 'SyntaxError', 'TypeError', 'RangeError', 'Error', 'URIError'];
Tim van der Lippe1d6e57a2019-09-30 11:55:341499 if (!this._message.runtimeModel() || !errorPrefixes.some(startsWith)) {
Blink Reformat4c46d092018-04-07 15:32:371500 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341501 }
Blink Reformat4c46d092018-04-07 15:32:371502 const debuggerModel = this._message.runtimeModel().debuggerModel();
1503 const baseURL = this._message.runtimeModel().target().inspectedURL();
1504
1505 const lines = string.split('\n');
1506 const links = [];
1507 let position = 0;
1508 for (let i = 0; i < lines.length; ++i) {
1509 position += i > 0 ? lines[i - 1].length + 1 : 0;
1510 const isCallFrameLine = /^\s*at\s/.test(lines[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:341511 if (!isCallFrameLine && links.length) {
Blink Reformat4c46d092018-04-07 15:32:371512 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341513 }
Blink Reformat4c46d092018-04-07 15:32:371514
Tim van der Lippe1d6e57a2019-09-30 11:55:341515 if (!isCallFrameLine) {
Blink Reformat4c46d092018-04-07 15:32:371516 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341517 }
Blink Reformat4c46d092018-04-07 15:32:371518
1519 let openBracketIndex = -1;
1520 let closeBracketIndex = -1;
Yang Guo39256bd2019-07-18 06:02:251521 const inBracketsWithLineAndColumn = /\([^\)\(]+:\d+:\d+\)/g;
1522 const inBrackets = /\([^\)\(]+\)/g;
1523 let lastMatch = null;
1524 let currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341525 while ((currentMatch = inBracketsWithLineAndColumn.exec(lines[i]))) {
Yang Guo39256bd2019-07-18 06:02:251526 lastMatch = currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341527 }
Yang Guo39256bd2019-07-18 06:02:251528 if (!lastMatch) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341529 while ((currentMatch = inBrackets.exec(lines[i]))) {
Yang Guo39256bd2019-07-18 06:02:251530 lastMatch = currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341531 }
Yang Guo39256bd2019-07-18 06:02:251532 }
1533 if (lastMatch) {
1534 openBracketIndex = lastMatch.index;
1535 closeBracketIndex = lastMatch.index + lastMatch[0].length - 1;
Blink Reformat4c46d092018-04-07 15:32:371536 }
1537 const hasOpenBracket = openBracketIndex !== -1;
1538 const left = hasOpenBracket ? openBracketIndex + 1 : lines[i].indexOf('at') + 3;
1539 const right = hasOpenBracket ? closeBracketIndex : lines[i].length;
1540 const linkCandidate = lines[i].substring(left, right);
Tim van der Lippe9b2f8712020-02-12 17:46:221541 const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(linkCandidate);
Tim van der Lippe1d6e57a2019-09-30 11:55:341542 if (!splitResult) {
Blink Reformat4c46d092018-04-07 15:32:371543 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341544 }
Blink Reformat4c46d092018-04-07 15:32:371545
Tim van der Lippe1d6e57a2019-09-30 11:55:341546 if (splitResult.url === '<anonymous>') {
Blink Reformat4c46d092018-04-07 15:32:371547 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341548 }
Blink Reformat4c46d092018-04-07 15:32:371549 let url = parseOrScriptMatch(splitResult.url);
Tim van der Lippe9b2f8712020-02-12 17:46:221550 if (!url && Common.ParsedURL.ParsedURL.isRelativeURL(splitResult.url)) {
1551 url = parseOrScriptMatch(Common.ParsedURL.ParsedURL.completeURL(baseURL, splitResult.url));
Tim van der Lippe1d6e57a2019-09-30 11:55:341552 }
1553 if (!url) {
Blink Reformat4c46d092018-04-07 15:32:371554 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341555 }
Blink Reformat4c46d092018-04-07 15:32:371556
1557 links.push({
1558 url: url,
1559 positionLeft: position + left,
1560 positionRight: position + right,
1561 lineNumber: splitResult.lineNumber,
1562 columnNumber: splitResult.columnNumber
1563 });
1564 }
1565
Tim van der Lippe1d6e57a2019-09-30 11:55:341566 if (!links.length) {
Blink Reformat4c46d092018-04-07 15:32:371567 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341568 }
Blink Reformat4c46d092018-04-07 15:32:371569
1570 const formattedResult = createElement('span');
1571 let start = 0;
1572 for (let i = 0; i < links.length; ++i) {
Erik Luo383f21d2018-11-07 23:16:371573 formattedResult.appendChild(this._linkifyStringAsFragment(string.substring(start, links[i].positionLeft)));
Erik Luo182bece2018-11-29 03:15:221574 const scriptLocationLink = this._linkifier.linkifyScriptLocation(
Jack Lynch236e1d22020-01-07 20:33:511575 debuggerModel.target(), null, links[i].url, links[i].lineNumber, {columnNumber: links[i].columnNumber});
Erik Luo182bece2018-11-29 03:15:221576 scriptLocationLink.tabIndex = -1;
Erik Luo31c21f62018-12-13 03:39:391577 this._selectableChildren.push({element: scriptLocationLink, forceSelect: () => scriptLocationLink.focus()});
Erik Luo182bece2018-11-29 03:15:221578 formattedResult.appendChild(scriptLocationLink);
Blink Reformat4c46d092018-04-07 15:32:371579 start = links[i].positionRight;
1580 }
1581
Tim van der Lippe1d6e57a2019-09-30 11:55:341582 if (start !== string.length) {
Erik Luo383f21d2018-11-07 23:16:371583 formattedResult.appendChild(this._linkifyStringAsFragment(string.substring(start)));
Tim van der Lippe1d6e57a2019-09-30 11:55:341584 }
Blink Reformat4c46d092018-04-07 15:32:371585
1586 return formattedResult;
1587
1588 /**
1589 * @param {?string} url
1590 * @return {?string}
1591 */
1592 function parseOrScriptMatch(url) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341593 if (!url) {
Blink Reformat4c46d092018-04-07 15:32:371594 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341595 }
Tim van der Lippe9b2f8712020-02-12 17:46:221596 const parsedURL = Common.ParsedURL.ParsedURL.fromString(url);
Tim van der Lippe1d6e57a2019-09-30 11:55:341597 if (parsedURL) {
Blink Reformat4c46d092018-04-07 15:32:371598 return parsedURL.url;
Tim van der Lippe1d6e57a2019-09-30 11:55:341599 }
1600 if (debuggerModel.scriptsForSourceURL(url).length) {
Blink Reformat4c46d092018-04-07 15:32:371601 return url;
Tim van der Lippe1d6e57a2019-09-30 11:55:341602 }
Blink Reformat4c46d092018-04-07 15:32:371603 return null;
1604 }
1605 }
1606
1607 /**
1608 * @param {string} string
1609 * @param {function(string,string,number=,number=):!Node} linkifier
1610 * @return {!DocumentFragment}
Tim van der Lippeeaacb722020-01-10 12:16:001611 * @suppress {accessControls}
Blink Reformat4c46d092018-04-07 15:32:371612 */
Erik Luofc2214f2018-11-21 19:54:581613 _linkifyWithCustomLinkifier(string, linkifier) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341614 if (string.length > Console.ConsoleViewMessage._MaxTokenizableStringLength) {
Tim van der Lippe9b2f8712020-02-12 17:46:221615 const propertyValue = new ObjectUI.ObjectPropertiesSection.ExpandableTextPropertyValue(
Connor Moody1a5c0d32019-12-19 07:23:361616 createElement('span'), string, Console.ConsoleViewMessage._LongStringVisibleLength);
1617 const fragment = createDocumentFragment();
1618 fragment.appendChild(propertyValue.element);
1619 return fragment;
Tim van der Lippe1d6e57a2019-09-30 11:55:341620 }
Blink Reformat4c46d092018-04-07 15:32:371621 const container = createDocumentFragment();
Tim van der Lippeeaacb722020-01-10 12:16:001622 const tokens = ConsoleViewMessage._tokenizeMessageText(string);
Blink Reformat4c46d092018-04-07 15:32:371623 for (const token of tokens) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341624 if (!token.text) {
Erik Luofc2214f2018-11-21 19:54:581625 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341626 }
Blink Reformat4c46d092018-04-07 15:32:371627 switch (token.type) {
1628 case 'url': {
1629 const realURL = (token.text.startsWith('www.') ? 'http://' + token.text : token.text);
Tim van der Lippe9b2f8712020-02-12 17:46:221630 const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(realURL);
Kim-Anh Tran9e49a452020-02-17 09:46:101631 const sourceURL = Common.ParsedURL.ParsedURL.removeWasmFunctionInfoFromURL(splitResult.url);
Blink Reformat4c46d092018-04-07 15:32:371632 let linkNode;
Tim van der Lippe1d6e57a2019-09-30 11:55:341633 if (splitResult) {
Kim-Anh Tran9e49a452020-02-17 09:46:101634 linkNode = linkifier(token.text, sourceURL, splitResult.lineNumber, splitResult.columnNumber);
Tim van der Lippe1d6e57a2019-09-30 11:55:341635 } else {
Blink Reformat4c46d092018-04-07 15:32:371636 linkNode = linkifier(token.text, token.value);
Tim van der Lippe1d6e57a2019-09-30 11:55:341637 }
Blink Reformat4c46d092018-04-07 15:32:371638 container.appendChild(linkNode);
1639 break;
1640 }
1641 default:
1642 container.appendChild(createTextNode(token.text));
1643 break;
1644 }
1645 }
1646 return container;
1647 }
1648
1649 /**
Blink Reformat4c46d092018-04-07 15:32:371650 * @param {string} string
1651 * @return {!DocumentFragment}
1652 */
Erik Luo383f21d2018-11-07 23:16:371653 _linkifyStringAsFragment(string) {
Erik Luofc2214f2018-11-21 19:54:581654 return this._linkifyWithCustomLinkifier(string, (text, url, lineNumber, columnNumber) => {
Tim van der Lippe9b2f8712020-02-12 17:46:221655 const linkElement = Components.Linkifier.Linkifier.linkifyURL(url, {text, lineNumber, columnNumber});
Erik Luo383f21d2018-11-07 23:16:371656 linkElement.tabIndex = -1;
Erik Luo31c21f62018-12-13 03:39:391657 this._selectableChildren.push({element: linkElement, forceSelect: () => linkElement.focus()});
Erik Luo383f21d2018-11-07 23:16:371658 return linkElement;
Blink Reformat4c46d092018-04-07 15:32:371659 });
1660 }
1661
1662 /**
1663 * @param {string} string
1664 * @return {!Array<{type: string, text: (string|undefined)}>}
Tim van der Lippeeaacb722020-01-10 12:16:001665 * @suppress {accessControls}
Blink Reformat4c46d092018-04-07 15:32:371666 */
1667 static _tokenizeMessageText(string) {
Tim van der Lippeeaacb722020-01-10 12:16:001668 if (!ConsoleViewMessage._tokenizerRegexes) {
Blink Reformat4c46d092018-04-07 15:32:371669 const controlCodes = '\\u0000-\\u0020\\u007f-\\u009f';
1670 const linkStringRegex = new RegExp(
1671 '(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\\/\\/|data:|www\\.)[^\\s' + controlCodes + '"]{2,}[^\\s' + controlCodes +
1672 '"\')}\\],:;.!?]',
1673 'u');
1674 const pathLineRegex = /(?:\/[\w\.-]*)+\:[\d]+/;
1675 const timeRegex = /took [\d]+ms/;
1676 const eventRegex = /'\w+' event/;
1677 const milestoneRegex = /\sM[6-7]\d/;
1678 const autofillRegex = /\(suggested: \"[\w-]+\"\)/;
1679 const handlers = new Map();
1680 handlers.set(linkStringRegex, 'url');
1681 handlers.set(pathLineRegex, 'url');
1682 handlers.set(timeRegex, 'time');
1683 handlers.set(eventRegex, 'event');
1684 handlers.set(milestoneRegex, 'milestone');
1685 handlers.set(autofillRegex, 'autofill');
Tim van der Lippeeaacb722020-01-10 12:16:001686 ConsoleViewMessage._tokenizerRegexes = Array.from(handlers.keys());
1687 ConsoleViewMessage._tokenizerTypes = Array.from(handlers.values());
Blink Reformat4c46d092018-04-07 15:32:371688 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341689 if (string.length > Console.ConsoleViewMessage._MaxTokenizableStringLength) {
Blink Reformat4c46d092018-04-07 15:32:371690 return [{text: string, type: undefined}];
Tim van der Lippe1d6e57a2019-09-30 11:55:341691 }
Tim van der Lippe9b2f8712020-02-12 17:46:221692 const results = TextUtils.TextUtils.Utils.splitStringByRegexes(string, ConsoleViewMessage._tokenizerRegexes);
Tim van der Lippeeaacb722020-01-10 12:16:001693 return results.map(result => ({text: result.value, type: ConsoleViewMessage._tokenizerTypes[result.regexIndex]}));
Blink Reformat4c46d092018-04-07 15:32:371694 }
1695
1696 /**
1697 * @return {string}
1698 */
1699 groupKey() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341700 if (!this._groupKey) {
Blink Reformat4c46d092018-04-07 15:32:371701 this._groupKey = this._message.groupCategoryKey() + ':' + this.groupTitle();
Tim van der Lippe1d6e57a2019-09-30 11:55:341702 }
Blink Reformat4c46d092018-04-07 15:32:371703 return this._groupKey;
1704 }
1705
1706 /**
1707 * @return {string}
1708 */
1709 groupTitle() {
Tim van der Lippeeaacb722020-01-10 12:16:001710 const tokens = ConsoleViewMessage._tokenizeMessageText(this._message.messageText);
Blink Reformat4c46d092018-04-07 15:32:371711 const result = tokens.reduce((acc, token) => {
1712 let text = token.text;
Tim van der Lippe1d6e57a2019-09-30 11:55:341713 if (token.type === 'url') {
Tim van der Lippe9b2f8712020-02-12 17:46:221714 text = Common.UIString.UIString('<URL>');
Tim van der Lippe1d6e57a2019-09-30 11:55:341715 } else if (token.type === 'time') {
Tim van der Lippe9b2f8712020-02-12 17:46:221716 text = Common.UIString.UIString('took <N>ms');
Tim van der Lippe1d6e57a2019-09-30 11:55:341717 } else if (token.type === 'event') {
Tim van der Lippe9b2f8712020-02-12 17:46:221718 text = Common.UIString.UIString('<some> event');
Tim van der Lippe1d6e57a2019-09-30 11:55:341719 } else if (token.type === 'milestone') {
Tim van der Lippe9b2f8712020-02-12 17:46:221720 text = Common.UIString.UIString(' M<XX>');
Tim van der Lippe1d6e57a2019-09-30 11:55:341721 } else if (token.type === 'autofill') {
Tim van der Lippe9b2f8712020-02-12 17:46:221722 text = Common.UIString.UIString('<attribute>');
Tim van der Lippe1d6e57a2019-09-30 11:55:341723 }
Blink Reformat4c46d092018-04-07 15:32:371724 return acc + text;
1725 }, '');
1726 return result.replace(/[%]o/g, '');
1727 }
Paul Lewisbf7aa3c2019-11-20 17:03:381728}
Blink Reformat4c46d092018-04-07 15:32:371729
1730/**
1731 * @unrestricted
1732 */
Paul Lewisbf7aa3c2019-11-20 17:03:381733export class ConsoleGroupViewMessage extends ConsoleViewMessage {
Blink Reformat4c46d092018-04-07 15:32:371734 /**
Tim van der Lippe9b2f8712020-02-12 17:46:221735 * @param {!SDK.ConsoleModel.ConsoleMessage} consoleMessage
1736 * @param {!Components.Linkifier.Linkifier} linkifier
Blink Reformat4c46d092018-04-07 15:32:371737 * @param {number} nestingLevel
Erik Luo8ef5d0c2018-09-25 21:16:001738 * @param {function()} onToggle
Tim van der Lippec02a97c2020-02-14 14:39:271739 * @param {function(!Common.EventTarget.EventTargetEvent)} onResize
Blink Reformat4c46d092018-04-07 15:32:371740 */
Tim van der Lippeb45d9a02019-11-05 17:24:411741 constructor(consoleMessage, linkifier, nestingLevel, onToggle, onResize) {
Blink Reformat4c46d092018-04-07 15:32:371742 console.assert(consoleMessage.isGroupStartMessage());
Tim van der Lippeb45d9a02019-11-05 17:24:411743 super(consoleMessage, linkifier, nestingLevel, onResize);
Tim van der Lippe9b2f8712020-02-12 17:46:221744 this._collapsed = consoleMessage.type === SDK.ConsoleModel.MessageType.StartGroupCollapsed;
1745 /** @type {?UI.Icon.Icon} */
Blink Reformat4c46d092018-04-07 15:32:371746 this._expandGroupIcon = null;
Erik Luo8ef5d0c2018-09-25 21:16:001747 this._onToggle = onToggle;
Blink Reformat4c46d092018-04-07 15:32:371748 }
1749
1750 /**
1751 * @param {boolean} collapsed
1752 */
Erik Luo8ef5d0c2018-09-25 21:16:001753 _setCollapsed(collapsed) {
Blink Reformat4c46d092018-04-07 15:32:371754 this._collapsed = collapsed;
Tim van der Lippe1d6e57a2019-09-30 11:55:341755 if (this._expandGroupIcon) {
Blink Reformat4c46d092018-04-07 15:32:371756 this._expandGroupIcon.setIconType(this._collapsed ? 'smallicon-triangle-right' : 'smallicon-triangle-down');
Tim van der Lippe1d6e57a2019-09-30 11:55:341757 }
Erik Luo8ef5d0c2018-09-25 21:16:001758 this._onToggle.call(null);
Blink Reformat4c46d092018-04-07 15:32:371759 }
1760
1761 /**
1762 * @return {boolean}
1763 */
1764 collapsed() {
1765 return this._collapsed;
1766 }
1767
1768 /**
1769 * @override
Erik Luo8ef5d0c2018-09-25 21:16:001770 * @param {!Event} event
1771 */
1772 maybeHandleOnKeyDown(event) {
Erik Luo0b8282e2018-10-08 20:37:461773 const focusedChildIndex = this._focusedChildIndex();
1774 if (focusedChildIndex === -1) {
1775 if ((event.key === 'ArrowLeft' && !this._collapsed) || (event.key === 'ArrowRight' && this._collapsed)) {
1776 this._setCollapsed(!this._collapsed);
1777 return true;
1778 }
Erik Luo8ef5d0c2018-09-25 21:16:001779 }
1780 return super.maybeHandleOnKeyDown(event);
1781 }
1782
1783 /**
1784 * @override
Blink Reformat4c46d092018-04-07 15:32:371785 * @return {!Element}
1786 */
1787 toMessageElement() {
1788 if (!this._element) {
1789 super.toMessageElement();
Erik Luo8ef5d0c2018-09-25 21:16:001790 const iconType = this._collapsed ? 'smallicon-triangle-right' : 'smallicon-triangle-down';
Tim van der Lippe9b2f8712020-02-12 17:46:221791 this._expandGroupIcon = UI.Icon.Icon.create(iconType, 'expand-group-icon');
Erik Luob5bfff42018-09-20 02:52:391792 // Intercept focus to avoid highlight on click.
1793 this._contentElement.tabIndex = -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341794 if (this._repeatCountElement) {
Blink Reformat4c46d092018-04-07 15:32:371795 this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341796 } else {
Blink Reformat4c46d092018-04-07 15:32:371797 this._element.insertBefore(this._expandGroupIcon, this._contentElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:341798 }
Erik Luo8ef5d0c2018-09-25 21:16:001799 this._element.addEventListener('click', () => this._setCollapsed(!this._collapsed));
Blink Reformat4c46d092018-04-07 15:32:371800 }
1801 return this._element;
1802 }
1803
1804 /**
1805 * @override
1806 */
1807 _showRepeatCountElement() {
1808 super._showRepeatCountElement();
Tim van der Lippe1d6e57a2019-09-30 11:55:341809 if (this._repeatCountElement && this._expandGroupIcon) {
Blink Reformat4c46d092018-04-07 15:32:371810 this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341811 }
Blink Reformat4c46d092018-04-07 15:32:371812 }
Paul Lewisbf7aa3c2019-11-20 17:03:381813}
Blink Reformat4c46d092018-04-07 15:32:371814
1815/**
1816 * @const
1817 * @type {number}
1818 */
Paul Lewisbf7aa3c2019-11-20 17:03:381819export const MaxLengthForLinks = 40;
Blink Reformat4c46d092018-04-07 15:32:371820
Paul Lewisbf7aa3c2019-11-20 17:03:381821export const _MaxTokenizableStringLength = 10000;
1822export const _LongStringVisibleLength = 5000;