blob: b131e58c36c453fd90867640588cc0b43c315a61 [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
Jan Schefflerc5bc69f2020-07-30 09:51:5231// @ts-nocheck
32// TODO(crbug.com/1011811): Enable TypeScript compiler checks
33
Tim van der Lippe9b2f8712020-02-12 17:46:2234import * as Common from '../common/common.js';
35import * as Components from '../components/components.js';
36import * as DataGrid from '../data_grid/data_grid.js';
37import * as ObjectUI from '../object_ui/object_ui.js';
Tim van der Lippe93b57c32020-02-20 17:38:4438import * as Platform from '../platform/platform.js';
Tim van der Lippe9b2f8712020-02-12 17:46:2239import * as SDK from '../sdk/sdk.js';
40import * as TextUtils from '../text_utils/text_utils.js';
Paul Lewisca569a52020-09-09 16:11:5141import * as ThemeSupport from '../theme_support/theme_support.js';
Tim van der Lippe9b2f8712020-02-12 17:46:2242import * as UI from '../ui/ui.js';
43
Tim van der Lippeeaacb722020-01-10 12:16:0044import {ConsoleViewportElement} from './ConsoleViewport.js'; // eslint-disable-line no-unused-vars
45
Blink Reformat4c46d092018-04-07 15:32:3746/**
Tim van der Lippeeaacb722020-01-10 12:16:0047 * @implements {ConsoleViewportElement}
Blink Reformat4c46d092018-04-07 15:32:3748 * @unrestricted
49 */
Tim van der Lippeeaacb722020-01-10 12:16:0050export class ConsoleViewMessage {
Blink Reformat4c46d092018-04-07 15:32:3751 /**
Tim van der Lippe9b2f8712020-02-12 17:46:2252 * @param {!SDK.ConsoleModel.ConsoleMessage} consoleMessage
53 * @param {!Components.Linkifier.Linkifier} linkifier
Blink Reformat4c46d092018-04-07 15:32:3754 * @param {number} nestingLevel
Tim van der Lippec02a97c2020-02-14 14:39:2755 * @param {function(!Common.EventTarget.EventTargetEvent)} onResize
Blink Reformat4c46d092018-04-07 15:32:3756 */
Tim van der Lippeb45d9a02019-11-05 17:24:4157 constructor(consoleMessage, linkifier, nestingLevel, onResize) {
Blink Reformat4c46d092018-04-07 15:32:3758 this._message = consoleMessage;
59 this._linkifier = linkifier;
Blink Reformat4c46d092018-04-07 15:32:3760 this._repeatCount = 1;
61 this._closeGroupDecorationCount = 0;
62 this._nestingLevel = nestingLevel;
Erik Luo31c21f62018-12-13 03:39:3963 /** @type {!Array<{element: !Element, forceSelect: function()}>} */
Erik Luo383f21d2018-11-07 23:16:3764 this._selectableChildren = [];
Erik Luo840be6b2018-12-03 20:54:2765 this._messageResized = onResize;
Blink Reformat4c46d092018-04-07 15:32:3766
Tim van der Lippe9b2f8712020-02-12 17:46:2267 /** @type {?DataGrid.DataGrid.DataGridImpl} */
Blink Reformat4c46d092018-04-07 15:32:3768 this._dataGrid = null;
Tim van der Lippe9b2f8712020-02-12 17:46:2269 this._previewFormatter = new ObjectUI.RemoteObjectPreviewFormatter.RemoteObjectPreviewFormatter();
Blink Reformat4c46d092018-04-07 15:32:3770 this._searchRegex = null;
Tim van der Lippe9b2f8712020-02-12 17:46:2271 /** @type {?UI.Icon.Icon} */
Blink Reformat4c46d092018-04-07 15:32:3772 this._messageLevelIcon = null;
Erik Luo8ef5d0c2018-09-25 21:16:0073 this._traceExpanded = false;
74 /** @type {?function(boolean)} */
75 this._expandTrace = null;
Sigurd Schneider53f33522020-10-08 15:00:4976 /** @type {?HTMLElement} */
John Emaubb2897a2019-10-04 17:37:3277 this._anchorElement = null;
Sigurd Schneidere8e75cf2020-10-13 08:17:5278 /** @type {!Array<!UI.UIUtils.HighlightChange>} */
79 this._searchHighlightNodeChanges = [];
Blink Reformat4c46d092018-04-07 15:32:3780 }
81
82 /**
83 * @override
Sigurd Schneider53f33522020-10-08 15:00:4984 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:3785 */
86 element() {
87 return this.toMessageElement();
88 }
89
90 /**
Blink Reformat4c46d092018-04-07 15:32:3791 * @override
92 */
93 wasShown() {
Tim van der Lippe1d6e57a2019-09-30 11:55:3494 if (this._dataGrid) {
Blink Reformat4c46d092018-04-07 15:32:3795 this._dataGrid.updateWidths();
Tim van der Lippe1d6e57a2019-09-30 11:55:3496 }
Blink Reformat4c46d092018-04-07 15:32:3797 this._isVisible = true;
98 }
99
100 onResize() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34101 if (!this._isVisible) {
Blink Reformat4c46d092018-04-07 15:32:37102 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34103 }
104 if (this._dataGrid) {
Blink Reformat4c46d092018-04-07 15:32:37105 this._dataGrid.onResize();
Tim van der Lippe1d6e57a2019-09-30 11:55:34106 }
Blink Reformat4c46d092018-04-07 15:32:37107 }
108
109 /**
110 * @override
111 */
112 willHide() {
113 this._isVisible = false;
Erik Luo4b002322018-07-30 21:23:31114 this._cachedHeight = this.element().offsetHeight;
Blink Reformat4c46d092018-04-07 15:32:37115 }
116
117 /**
118 * @return {number}
119 */
120 fastHeight() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34121 if (this._cachedHeight) {
Blink Reformat4c46d092018-04-07 15:32:37122 return this._cachedHeight;
Tim van der Lippe1d6e57a2019-09-30 11:55:34123 }
Blink Reformat4c46d092018-04-07 15:32:37124 // This value reflects the 18px min-height of .console-message, plus the
125 // 1px border of .console-message-wrapper. Keep in sync with consoleView.css.
126 const defaultConsoleRowHeight = 19;
Tim van der Lippe9b2f8712020-02-12 17:46:22127 if (this._message.type === SDK.ConsoleModel.MessageType.Table) {
Blink Reformat4c46d092018-04-07 15:32:37128 const table = this._message.parameters[0];
Tim van der Lippe1d6e57a2019-09-30 11:55:34129 if (table && table.preview) {
Blink Reformat4c46d092018-04-07 15:32:37130 return defaultConsoleRowHeight * table.preview.properties.length;
Tim van der Lippe1d6e57a2019-09-30 11:55:34131 }
Blink Reformat4c46d092018-04-07 15:32:37132 }
133 return defaultConsoleRowHeight;
134 }
135
136 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22137 * @return {!SDK.ConsoleModel.ConsoleMessage}
Blink Reformat4c46d092018-04-07 15:32:37138 */
139 consoleMessage() {
140 return this._message;
141 }
142
143 /**
Sigurd Schneider53f33522020-10-08 15:00:49144 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37145 */
146 _buildTableMessage() {
Sigurd Schneider53f33522020-10-08 15:00:49147 const formattedMessage = /** @type {!HTMLElement} */ (document.createElement('span'));
Tim van der Lippef49e2322020-05-01 15:03:09148 formattedMessage.classList.add('source-code');
Erik Luo5976c8c2018-07-24 02:03:09149 this._anchorElement = this._buildMessageAnchor();
Tim van der Lippe1d6e57a2019-09-30 11:55:34150 if (this._anchorElement) {
Erik Luo5976c8c2018-07-24 02:03:09151 formattedMessage.appendChild(this._anchorElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34152 }
Blink Reformat4c46d092018-04-07 15:32:37153
Tim van der Lippe20749392020-05-27 14:33:51154 const table = this._message.parameters && this._message.parameters.length ? this._message.parameters[0] : null;
155 if (!table) {
156 return this._buildMessage();
Tim van der Lippe1d6e57a2019-09-30 11:55:34157 }
Tim van der Lippe20749392020-05-27 14:33:51158 const actualTable = this._parameterToRemoteObject(table);
159 if (!actualTable || !actualTable.preview) {
Erik Luo16e3e382018-11-09 02:56:01160 return this._buildMessage();
Tim van der Lippe1d6e57a2019-09-30 11:55:34161 }
Blink Reformat4c46d092018-04-07 15:32:37162
163 const rawValueColumnSymbol = Symbol('rawValueColumn');
164 const columnNames = [];
Tim van der Lippe20749392020-05-27 14:33:51165 const preview = actualTable.preview;
Blink Reformat4c46d092018-04-07 15:32:37166 const rows = [];
167 for (let i = 0; i < preview.properties.length; ++i) {
168 const rowProperty = preview.properties[i];
169 let rowSubProperties;
Tim van der Lippe1d6e57a2019-09-30 11:55:34170 if (rowProperty.valuePreview) {
Blink Reformat4c46d092018-04-07 15:32:37171 rowSubProperties = rowProperty.valuePreview.properties;
Tim van der Lippe1d6e57a2019-09-30 11:55:34172 } else if (rowProperty.value) {
Blink Reformat4c46d092018-04-07 15:32:37173 rowSubProperties = [{name: rawValueColumnSymbol, type: rowProperty.type, value: rowProperty.value}];
Tim van der Lippe1d6e57a2019-09-30 11:55:34174 } else {
Blink Reformat4c46d092018-04-07 15:32:37175 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34176 }
Blink Reformat4c46d092018-04-07 15:32:37177
178 const rowValue = {};
179 const maxColumnsToRender = 20;
180 for (let j = 0; j < rowSubProperties.length; ++j) {
181 const cellProperty = rowSubProperties[j];
182 let columnRendered = columnNames.indexOf(cellProperty.name) !== -1;
183 if (!columnRendered) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34184 if (columnNames.length === maxColumnsToRender) {
Blink Reformat4c46d092018-04-07 15:32:37185 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34186 }
Blink Reformat4c46d092018-04-07 15:32:37187 columnRendered = true;
188 columnNames.push(cellProperty.name);
189 }
190
191 if (columnRendered) {
Tim van der Lippe20749392020-05-27 14:33:51192 const cellElement = this._renderPropertyPreviewOrAccessor(actualTable, [rowProperty, cellProperty]);
Blink Reformat4c46d092018-04-07 15:32:37193 cellElement.classList.add('console-message-nowrap-below');
194 rowValue[cellProperty.name] = cellElement;
195 }
196 }
197 rows.push([rowProperty.name, rowValue]);
198 }
199
200 const flatValues = [];
201 for (let i = 0; i < rows.length; ++i) {
202 const rowName = rows[i][0];
203 const rowValue = rows[i][1];
204 flatValues.push(rowName);
Tim van der Lippe1d6e57a2019-09-30 11:55:34205 for (let j = 0; j < columnNames.length; ++j) {
Blink Reformat4c46d092018-04-07 15:32:37206 flatValues.push(rowValue[columnNames[j]]);
Tim van der Lippe1d6e57a2019-09-30 11:55:34207 }
Blink Reformat4c46d092018-04-07 15:32:37208 }
Tim van der Lippe9b2f8712020-02-12 17:46:22209 columnNames.unshift(Common.UIString.UIString('(index)'));
210 const columnDisplayNames =
211 columnNames.map(name => name === rawValueColumnSymbol ? Common.UIString.UIString('Value') : name);
Blink Reformat4c46d092018-04-07 15:32:37212
213 if (flatValues.length) {
Tim van der Lippe9b2f8712020-02-12 17:46:22214 this._dataGrid = DataGrid.SortableDataGrid.SortableDataGrid.create(columnDisplayNames, flatValues, ls`Console`);
Blink Reformat4c46d092018-04-07 15:32:37215 this._dataGrid.setStriped(true);
Anubha Mathurfbacf4e2019-10-28 19:08:03216 this._dataGrid.setFocusable(false);
Blink Reformat4c46d092018-04-07 15:32:37217
Tim van der Lippef49e2322020-05-01 15:03:09218 const formattedResult = document.createElement('span');
219 formattedResult.classList.add('console-message-text');
Blink Reformat4c46d092018-04-07 15:32:37220 const tableElement = formattedResult.createChild('div', 'console-message-formatted-table');
221 const dataGridContainer = tableElement.createChild('span');
Tim van der Lippe20749392020-05-27 14:33:51222 tableElement.appendChild(this._formatParameter(actualTable, true, false));
Blink Reformat4c46d092018-04-07 15:32:37223 dataGridContainer.appendChild(this._dataGrid.element);
224 formattedMessage.appendChild(formattedResult);
225 this._dataGrid.renderInline();
226 }
227 return formattedMessage;
228 }
229
230 /**
Sigurd Schneider53f33522020-10-08 15:00:49231 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37232 */
233 _buildMessage() {
234 let messageElement;
235 let messageText = this._message.messageText;
Tim van der Lippe9b2f8712020-02-12 17:46:22236 if (this._message.source === SDK.ConsoleModel.MessageSource.ConsoleAPI) {
Blink Reformat4c46d092018-04-07 15:32:37237 switch (this._message.type) {
Tim van der Lippe9b2f8712020-02-12 17:46:22238 case SDK.ConsoleModel.MessageType.Trace:
Blink Reformat4c46d092018-04-07 15:32:37239 messageElement = this._format(this._message.parameters || ['console.trace']);
240 break;
Tim van der Lippe9b2f8712020-02-12 17:46:22241 case SDK.ConsoleModel.MessageType.Clear:
Tim van der Lippef49e2322020-05-01 15:03:09242 messageElement = document.createElement('span');
243 messageElement.classList.add('console-info');
Paul Lewis2d7d65c2020-03-16 17:26:30244 if (Common.Settings.Settings.instance().moduleSetting('preserveConsoleLog').get()) {
Tim van der Lippe9b2f8712020-02-12 17:46:22245 messageElement.textContent =
246 Common.UIString.UIString('console.clear() was prevented due to \'Preserve log\'');
Tim van der Lippe1d6e57a2019-09-30 11:55:34247 } else {
Tim van der Lippe9b2f8712020-02-12 17:46:22248 messageElement.textContent = Common.UIString.UIString('Console was cleared');
Tim van der Lippe1d6e57a2019-09-30 11:55:34249 }
Tim van der Lippe9c9fb122020-09-08 15:06:17250 messageElement.title = ls`Clear all messages with ${
251 UI.ShortcutRegistry.ShortcutRegistry.instance().shortcutTitleForAction('console.clear')}`;
Blink Reformat4c46d092018-04-07 15:32:37252 break;
Tim van der Lippe9b2f8712020-02-12 17:46:22253 case SDK.ConsoleModel.MessageType.Dir: {
Blink Reformat4c46d092018-04-07 15:32:37254 const obj = this._message.parameters ? this._message.parameters[0] : undefined;
255 const args = ['%O', obj];
256 messageElement = this._format(args);
257 break;
258 }
Tim van der Lippe9b2f8712020-02-12 17:46:22259 case SDK.ConsoleModel.MessageType.Profile:
260 case SDK.ConsoleModel.MessageType.ProfileEnd:
Blink Reformat4c46d092018-04-07 15:32:37261 messageElement = this._format([messageText]);
262 break;
Tim van der Lippe9b2f8712020-02-12 17:46:22263 case SDK.ConsoleModel.MessageType.Assert:
Pavel Feldman9f0f0a32018-12-18 02:09:13264 this._messagePrefix = ls`Assertion failed: `;
265 // Fall through.
Blink Reformat4c46d092018-04-07 15:32:37266 default: {
267 if (this._message.parameters && this._message.parameters.length === 1 &&
Tim van der Lippe1d6e57a2019-09-30 11:55:34268 this._message.parameters[0].type === 'string') {
Blink Reformat4c46d092018-04-07 15:32:37269 messageElement = this._tryFormatAsError(/** @type {string} */ (this._message.parameters[0].value));
Tim van der Lippe1d6e57a2019-09-30 11:55:34270 }
Blink Reformat4c46d092018-04-07 15:32:37271 const args = this._message.parameters || [messageText];
272 messageElement = messageElement || this._format(args);
273 }
274 }
275 } else {
Tim van der Lippe9b2f8712020-02-12 17:46:22276 if (this._message.source === SDK.ConsoleModel.MessageSource.Network) {
Erik Luofc2214f2018-11-21 19:54:58277 messageElement = this._formatAsNetworkRequest() || this._format([messageText]);
278 } else {
Blink Reformat4c46d092018-04-07 15:32:37279 const messageInParameters =
280 this._message.parameters && messageText === /** @type {string} */ (this._message.parameters[0]);
Tim van der Lippe9b2f8712020-02-12 17:46:22281 if (this._message.source === SDK.ConsoleModel.MessageSource.Violation) {
282 messageText = Common.UIString.UIString('[Violation] %s', messageText);
283 } else if (this._message.source === SDK.ConsoleModel.MessageSource.Intervention) {
284 messageText = Common.UIString.UIString('[Intervention] %s', messageText);
285 } else if (this._message.source === SDK.ConsoleModel.MessageSource.Deprecation) {
286 messageText = Common.UIString.UIString('[Deprecation] %s', messageText);
Tim van der Lippe1d6e57a2019-09-30 11:55:34287 }
Blink Reformat4c46d092018-04-07 15:32:37288 const args = this._message.parameters || [messageText];
Tim van der Lippe1d6e57a2019-09-30 11:55:34289 if (messageInParameters) {
Blink Reformat4c46d092018-04-07 15:32:37290 args[0] = messageText;
Tim van der Lippe1d6e57a2019-09-30 11:55:34291 }
Blink Reformat4c46d092018-04-07 15:32:37292 messageElement = this._format(args);
293 }
294 }
295 messageElement.classList.add('console-message-text');
296
Sigurd Schneider53f33522020-10-08 15:00:49297 const formattedMessage = /** @type {!HTMLElement} */ (document.createElement('span'));
Tim van der Lippef49e2322020-05-01 15:03:09298 formattedMessage.classList.add('source-code');
Erik Luo5976c8c2018-07-24 02:03:09299 this._anchorElement = this._buildMessageAnchor();
Tim van der Lippe1d6e57a2019-09-30 11:55:34300 if (this._anchorElement) {
Erik Luo5976c8c2018-07-24 02:03:09301 formattedMessage.appendChild(this._anchorElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34302 }
Blink Reformat4c46d092018-04-07 15:32:37303 formattedMessage.appendChild(messageElement);
304 return formattedMessage;
305 }
306
307 /**
Sigurd Schneider53f33522020-10-08 15:00:49308 * @return {?HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37309 */
Erik Luofc2214f2018-11-21 19:54:58310 _formatAsNetworkRequest() {
Tim van der Lippe9b2f8712020-02-12 17:46:22311 const request = SDK.NetworkLog.NetworkLog.requestForConsoleMessage(this._message);
Tim van der Lippe1d6e57a2019-09-30 11:55:34312 if (!request) {
Erik Luofc2214f2018-11-21 19:54:58313 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34314 }
Sigurd Schneider53f33522020-10-08 15:00:49315 const messageElement = /** @type {!HTMLElement} */ (document.createElement('span'));
Tim van der Lippe9b2f8712020-02-12 17:46:22316 if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Sigurd Schneider23c52972020-10-13 09:31:14317 UI.UIUtils.createTextChild(messageElement, request.requestMethod + ' ');
Tim van der Lippe9b2f8712020-02-12 17:46:22318 const linkElement = Components.Linkifier.Linkifier.linkifyRevealable(request, request.url(), request.url());
Erik Luo182bece2018-11-29 03:15:22319 // Focus is handled by the viewport.
320 linkElement.tabIndex = -1;
Erik Luo31c21f62018-12-13 03:39:39321 this._selectableChildren.push({element: linkElement, forceSelect: () => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22322 messageElement.appendChild(linkElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34323 if (request.failed) {
Sigurd Schneider23c52972020-10-13 09:31:14324 UI.UIUtils.createTextChildren(messageElement, ' ', request.localizedFailDescription || '');
Tim van der Lippe1d6e57a2019-09-30 11:55:34325 }
326 if (request.statusCode !== 0) {
Sigurd Schneider23c52972020-10-13 09:31:14327 UI.UIUtils.createTextChildren(messageElement, ' ', String(request.statusCode));
Tim van der Lippe1d6e57a2019-09-30 11:55:34328 }
329 if (request.statusText) {
Sigurd Schneider23c52972020-10-13 09:31:14330 UI.UIUtils.createTextChildren(messageElement, ' (', request.statusText, ')');
Tim van der Lippe1d6e57a2019-09-30 11:55:34331 }
Erik Luofc2214f2018-11-21 19:54:58332 } else {
Erik Luoad5f3942019-03-26 20:53:44333 const messageText = this._message.messageText;
334 const fragment = this._linkifyWithCustomLinkifier(messageText, (text, url, lineNumber, columnNumber) => {
335 let linkElement;
336 if (url === request.url()) {
Tim van der Lippe9b2f8712020-02-12 17:46:22337 linkElement = Components.Linkifier.Linkifier.linkifyRevealable(
338 /** @type {!SDK.NetworkRequest.NetworkRequest} */ (request), url, request.url());
Erik Luoad5f3942019-03-26 20:53:44339 } else {
Tim van der Lippe9b2f8712020-02-12 17:46:22340 linkElement = Components.Linkifier.Linkifier.linkifyURL(url, {text, lineNumber, columnNumber});
Erik Luoad5f3942019-03-26 20:53:44341 }
Erik Luo182bece2018-11-29 03:15:22342 linkElement.tabIndex = -1;
Erik Luo31c21f62018-12-13 03:39:39343 this._selectableChildren.push({element: linkElement, forceSelect: () => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22344 return linkElement;
345 });
Erik Luofc2214f2018-11-21 19:54:58346 messageElement.appendChild(fragment);
347 }
348 return messageElement;
349 }
350
351 /**
Sigurd Schneider53f33522020-10-08 15:00:49352 * @return {?HTMLElement}
Erik Luofc2214f2018-11-21 19:54:58353 */
Blink Reformat4c46d092018-04-07 15:32:37354 _buildMessageAnchor() {
355 let anchorElement = null;
356 if (this._message.scriptId) {
357 anchorElement = this._linkifyScriptId(
358 this._message.scriptId, this._message.url || '', this._message.line, this._message.column);
359 } else if (this._message.stackTrace && this._message.stackTrace.callFrames.length) {
360 anchorElement = this._linkifyStackTraceTopFrame(this._message.stackTrace);
361 } else if (this._message.url && this._message.url !== 'undefined') {
362 anchorElement = this._linkifyLocation(this._message.url, this._message.line, this._message.column);
363 }
364
365 // Append a space to prevent the anchor text from being glued to the console message when the user selects and copies the console messages.
366 if (anchorElement) {
John Emauf7e30fb2019-10-04 19:12:32367 anchorElement.tabIndex = -1;
368 this._selectableChildren.push({
369 element: anchorElement,
370 forceSelect: () => anchorElement.focus(),
371 });
Sigurd Schneider53f33522020-10-08 15:00:49372 const anchorWrapperElement = /** @type {!HTMLElement} */ (document.createElement('span'));
Tim van der Lippef49e2322020-05-01 15:03:09373 anchorWrapperElement.classList.add('console-message-anchor');
Blink Reformat4c46d092018-04-07 15:32:37374 anchorWrapperElement.appendChild(anchorElement);
Sigurd Schneider23c52972020-10-13 09:31:14375 UI.UIUtils.createTextChild(anchorWrapperElement, ' ');
Blink Reformat4c46d092018-04-07 15:32:37376 return anchorWrapperElement;
377 }
378 return null;
379 }
380
381 /**
Sigurd Schneider53f33522020-10-08 15:00:49382 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37383 */
384 _buildMessageWithStackTrace() {
Sigurd Schneider53f33522020-10-08 15:00:49385 const toggleElement = /** @type {!HTMLElement} */ (document.createElement('div'));
Tim van der Lippef49e2322020-05-01 15:03:09386 toggleElement.classList.add('console-message-stack-trace-toggle');
Blink Reformat4c46d092018-04-07 15:32:37387 const contentElement = toggleElement.createChild('div', 'console-message-stack-trace-wrapper');
388
389 const messageElement = this._buildMessage();
Tim van der Lippe9b2f8712020-02-12 17:46:22390 const icon = UI.Icon.Icon.create('smallicon-triangle-right', 'console-message-expand-icon');
Blink Reformat4c46d092018-04-07 15:32:37391 const clickableElement = contentElement.createChild('div');
392 clickableElement.appendChild(icon);
Erik Luob5bfff42018-09-20 02:52:39393 // Intercept focus to avoid highlight on click.
394 clickableElement.tabIndex = -1;
Blink Reformat4c46d092018-04-07 15:32:37395
396 clickableElement.appendChild(messageElement);
397 const stackTraceElement = contentElement.createChild('div');
398 const stackTracePreview = Components.JSPresentationUtils.buildStackTracePreviewContents(
Jack Lynch7bc9bf22020-01-13 17:16:00399 this._message.runtimeModel().target(), this._linkifier, {stackTrace: this._message.stackTrace});
Erik Luo182bece2018-11-29 03:15:22400 stackTraceElement.appendChild(stackTracePreview.element);
401 for (const linkElement of stackTracePreview.links) {
Erik Luo31c21f62018-12-13 03:39:39402 this._selectableChildren.push({element: linkElement, forceSelect: () => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22403 }
Blink Reformat4c46d092018-04-07 15:32:37404 stackTraceElement.classList.add('hidden');
Brandon Goddard04a5a762019-12-10 16:45:53405 UI.ARIAUtils.markAsTreeitem(this.element());
406 UI.ARIAUtils.setExpanded(this.element(), false);
Erik Luo8ef5d0c2018-09-25 21:16:00407 this._expandTrace = expand => {
Blink Reformat4c46d092018-04-07 15:32:37408 icon.setIconType(expand ? 'smallicon-triangle-down' : 'smallicon-triangle-right');
409 stackTraceElement.classList.toggle('hidden', !expand);
Brandon Goddard04a5a762019-12-10 16:45:53410 UI.ARIAUtils.setExpanded(this.element(), expand);
Erik Luo8ef5d0c2018-09-25 21:16:00411 this._traceExpanded = expand;
412 };
Blink Reformat4c46d092018-04-07 15:32:37413
414 /**
Tim van der Lippeeaacb722020-01-10 12:16:00415 * @this {!ConsoleViewMessage}
Blink Reformat4c46d092018-04-07 15:32:37416 * @param {?Event} event
417 */
418 function toggleStackTrace(event) {
Tim van der Lippe9b2f8712020-02-12 17:46:22419 if (UI.UIUtils.isEditing() || contentElement.hasSelection()) {
Blink Reformat4c46d092018-04-07 15:32:37420 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34421 }
Erik Luo8ef5d0c2018-09-25 21:16:00422 this._expandTrace(stackTraceElement.classList.contains('hidden'));
Blink Reformat4c46d092018-04-07 15:32:37423 event.consume();
424 }
425
Erik Luo8ef5d0c2018-09-25 21:16:00426 clickableElement.addEventListener('click', toggleStackTrace.bind(this), false);
Tim van der Lippe9b2f8712020-02-12 17:46:22427 if (this._message.type === SDK.ConsoleModel.MessageType.Trace) {
Erik Luo8ef5d0c2018-09-25 21:16:00428 this._expandTrace(true);
Tim van der Lippe1d6e57a2019-09-30 11:55:34429 }
Blink Reformat4c46d092018-04-07 15:32:37430
Erik Luo8ef5d0c2018-09-25 21:16:00431 toggleElement._expandStackTraceForTest = this._expandTrace.bind(this, true);
Blink Reformat4c46d092018-04-07 15:32:37432 return toggleElement;
433 }
434
435 /**
436 * @param {string} url
437 * @param {number} lineNumber
438 * @param {number} columnNumber
Sigurd Schneider53f33522020-10-08 15:00:49439 * @return {?HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37440 */
441 _linkifyLocation(url, lineNumber, columnNumber) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34442 if (!this._message.runtimeModel()) {
Blink Reformat4c46d092018-04-07 15:32:37443 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34444 }
Blink Reformat4c46d092018-04-07 15:32:37445 return this._linkifier.linkifyScriptLocation(
Jack Lynch236e1d22020-01-07 20:33:51446 this._message.runtimeModel().target(), /* scriptId */ null, url, lineNumber, {columnNumber});
Blink Reformat4c46d092018-04-07 15:32:37447 }
448
449 /**
450 * @param {!Protocol.Runtime.StackTrace} stackTrace
Sigurd Schneider53f33522020-10-08 15:00:49451 * @return {?HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37452 */
453 _linkifyStackTraceTopFrame(stackTrace) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34454 if (!this._message.runtimeModel()) {
Blink Reformat4c46d092018-04-07 15:32:37455 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34456 }
Blink Reformat4c46d092018-04-07 15:32:37457 return this._linkifier.linkifyStackTraceTopFrame(this._message.runtimeModel().target(), stackTrace);
458 }
459
460 /**
461 * @param {string} scriptId
462 * @param {string} url
463 * @param {number} lineNumber
464 * @param {number} columnNumber
Sigurd Schneider53f33522020-10-08 15:00:49465 * @return {?HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37466 */
467 _linkifyScriptId(scriptId, url, lineNumber, columnNumber) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34468 if (!this._message.runtimeModel()) {
Blink Reformat4c46d092018-04-07 15:32:37469 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34470 }
Blink Reformat4c46d092018-04-07 15:32:37471 return this._linkifier.linkifyScriptLocation(
Jack Lynch236e1d22020-01-07 20:33:51472 this._message.runtimeModel().target(), scriptId, url, lineNumber, {columnNumber});
Blink Reformat4c46d092018-04-07 15:32:37473 }
474
475 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22476 * @param {!SDK.RemoteObject.RemoteObject|!Protocol.Runtime.RemoteObject|string} parameter
477 * @return {!SDK.RemoteObject.RemoteObject}
Blink Reformat4c46d092018-04-07 15:32:37478 */
479 _parameterToRemoteObject(parameter) {
Tim van der Lippe9b2f8712020-02-12 17:46:22480 if (parameter instanceof SDK.RemoteObject.RemoteObject) {
Blink Reformat4c46d092018-04-07 15:32:37481 return parameter;
Tim van der Lippe1d6e57a2019-09-30 11:55:34482 }
Blink Reformat4c46d092018-04-07 15:32:37483 const runtimeModel = this._message.runtimeModel();
Tim van der Lippe1d6e57a2019-09-30 11:55:34484 if (!runtimeModel) {
Tim van der Lippe9b2f8712020-02-12 17:46:22485 return SDK.RemoteObject.RemoteObject.fromLocalObject(parameter);
Tim van der Lippe1d6e57a2019-09-30 11:55:34486 }
487 if (typeof parameter === 'object') {
Blink Reformat4c46d092018-04-07 15:32:37488 return runtimeModel.createRemoteObject(parameter);
Tim van der Lippe1d6e57a2019-09-30 11:55:34489 }
Blink Reformat4c46d092018-04-07 15:32:37490 return runtimeModel.createRemoteObjectFromPrimitiveValue(parameter);
491 }
492
493 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22494 * @param {!Array.<!SDK.RemoteObject.RemoteObject|string>} rawParameters
Sigurd Schneider53f33522020-10-08 15:00:49495 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37496 */
497 _format(rawParameters) {
498 // This node is used like a Builder. Values are continually appended onto it.
Sigurd Schneider53f33522020-10-08 15:00:49499 const formattedResult = /** @type {!HTMLElement} */ (document.createElement('span'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34500 if (this._messagePrefix) {
Pavel Feldman9f0f0a32018-12-18 02:09:13501 formattedResult.createChild('span').textContent = this._messagePrefix;
Tim van der Lippe1d6e57a2019-09-30 11:55:34502 }
503 if (!rawParameters.length) {
Blink Reformat4c46d092018-04-07 15:32:37504 return formattedResult;
Tim van der Lippe1d6e57a2019-09-30 11:55:34505 }
Blink Reformat4c46d092018-04-07 15:32:37506
507 // Formatting code below assumes that parameters are all wrappers whereas frontend console
508 // API allows passing arbitrary values as messages (strings, numbers, etc.). Wrap them here.
509 // FIXME: Only pass runtime wrappers here.
510 let parameters = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:34511 for (let i = 0; i < rawParameters.length; ++i) {
Blink Reformat4c46d092018-04-07 15:32:37512 parameters[i] = this._parameterToRemoteObject(rawParameters[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:34513 }
Blink Reformat4c46d092018-04-07 15:32:37514
515 // There can be string log and string eval result. We distinguish between them based on message type.
516 const shouldFormatMessage =
Tim van der Lippe9b2f8712020-02-12 17:46:22517 SDK.RemoteObject.RemoteObject.type(
518 (/** @type {!Array.<!SDK.RemoteObject.RemoteObject>} **/ (parameters))[0]) === 'string' &&
519 (this._message.type !== SDK.ConsoleModel.MessageType.Result ||
520 this._message.level === SDK.ConsoleModel.MessageLevel.Error);
Blink Reformat4c46d092018-04-07 15:32:37521
522 // Multiple parameters with the first being a format string. Save unused substitutions.
523 if (shouldFormatMessage) {
524 const result = this._formatWithSubstitutionString(
525 /** @type {string} **/ (parameters[0].description), parameters.slice(1), formattedResult);
526 parameters = result.unusedSubstitutions;
Tim van der Lippe1d6e57a2019-09-30 11:55:34527 if (parameters.length) {
Sigurd Schneider23c52972020-10-13 09:31:14528 UI.UIUtils.createTextChild(formattedResult, ' ');
Tim van der Lippe1d6e57a2019-09-30 11:55:34529 }
Blink Reformat4c46d092018-04-07 15:32:37530 }
531
532 // Single parameter, or unused substitutions from above.
533 for (let i = 0; i < parameters.length; ++i) {
534 // Inline strings when formatting.
Tim van der Lippe1d6e57a2019-09-30 11:55:34535 if (shouldFormatMessage && parameters[i].type === 'string') {
Erik Luo383f21d2018-11-07 23:16:37536 formattedResult.appendChild(this._linkifyStringAsFragment(parameters[i].description));
Tim van der Lippe1d6e57a2019-09-30 11:55:34537 } else {
Blink Reformat4c46d092018-04-07 15:32:37538 formattedResult.appendChild(this._formatParameter(parameters[i], false, true));
Tim van der Lippe1d6e57a2019-09-30 11:55:34539 }
540 if (i < parameters.length - 1) {
Sigurd Schneider23c52972020-10-13 09:31:14541 UI.UIUtils.createTextChild(formattedResult, ' ');
Tim van der Lippe1d6e57a2019-09-30 11:55:34542 }
Blink Reformat4c46d092018-04-07 15:32:37543 }
544 return formattedResult;
545 }
546
547 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22548 * @param {!SDK.RemoteObject.RemoteObject} output
Blink Reformat4c46d092018-04-07 15:32:37549 * @param {boolean=} forceObjectFormat
550 * @param {boolean=} includePreview
Sigurd Schneider53f33522020-10-08 15:00:49551 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37552 */
553 _formatParameter(output, forceObjectFormat, includePreview) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34554 if (output.customPreview()) {
Sigurd Schneider53f33522020-10-08 15:00:49555 return /** @type {!HTMLElement} */ ((new ObjectUI.CustomPreviewComponent.CustomPreviewComponent(output)).element);
Tim van der Lippe1d6e57a2019-09-30 11:55:34556 }
Blink Reformat4c46d092018-04-07 15:32:37557
558 const type = forceObjectFormat ? 'object' : (output.subtype || output.type);
559 let element;
560 switch (type) {
561 case 'error':
562 element = this._formatParameterAsError(output);
563 break;
564 case 'function':
565 element = this._formatParameterAsFunction(output, includePreview);
566 break;
567 case 'array':
568 case 'arraybuffer':
569 case 'blob':
570 case 'dataview':
571 case 'generator':
572 case 'iterator':
573 case 'map':
574 case 'object':
575 case 'promise':
576 case 'proxy':
577 case 'set':
578 case 'typedarray':
579 case 'weakmap':
580 case 'weakset':
581 element = this._formatParameterAsObject(output, includePreview);
582 break;
583 case 'node':
584 element = output.isNode() ? this._formatParameterAsNode(output) : this._formatParameterAsObject(output, false);
585 break;
586 case 'string':
587 element = this._formatParameterAsString(output);
588 break;
589 case 'boolean':
590 case 'date':
591 case 'null':
592 case 'number':
593 case 'regexp':
594 case 'symbol':
595 case 'undefined':
596 case 'bigint':
597 element = this._formatParameterAsValue(output);
598 break;
599 default:
600 element = this._formatParameterAsValue(output);
601 console.error('Tried to format remote object of unknown type.');
602 }
603 element.classList.add('object-value-' + type);
604 element.classList.add('source-code');
605 return element;
606 }
607
608 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22609 * @param {!SDK.RemoteObject.RemoteObject} obj
Sigurd Schneider53f33522020-10-08 15:00:49610 * @return {!HTMLElement}
Tim van der Lippeeaacb722020-01-10 12:16:00611 * @suppress {accessControls}
Blink Reformat4c46d092018-04-07 15:32:37612 */
613 _formatParameterAsValue(obj) {
Sigurd Schneider53f33522020-10-08 15:00:49614 const result = /** @type {!HTMLElement} */ (document.createElement('span'));
Blink Reformat4c46d092018-04-07 15:32:37615 const description = obj.description || '';
Tim van der Lippe1d6e57a2019-09-30 11:55:34616 if (description.length > Console.ConsoleViewMessage._MaxTokenizableStringLength) {
Tim van der Lippe9b2f8712020-02-12 17:46:22617 const propertyValue = new ObjectUI.ObjectPropertiesSection.ExpandableTextPropertyValue(
Sigurd Schneider53f33522020-10-08 15:00:49618 document.createElement('span'), description, Console.ConsoleViewMessage._LongStringVisibleLength);
Connor Moody1a5c0d32019-12-19 07:23:36619 result.appendChild(propertyValue.element);
Tim van der Lippe1d6e57a2019-09-30 11:55:34620 } else {
Sigurd Schneider23c52972020-10-13 09:31:14621 UI.UIUtils.createTextChild(result, description);
Tim van der Lippe1d6e57a2019-09-30 11:55:34622 }
623 if (obj.objectId) {
Blink Reformat4c46d092018-04-07 15:32:37624 result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, obj), false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34625 }
Blink Reformat4c46d092018-04-07 15:32:37626 return result;
627 }
628
629 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22630 * @param {!SDK.RemoteObject.RemoteObject} obj
Blink Reformat4c46d092018-04-07 15:32:37631 * @param {boolean=} includePreview
Sigurd Schneider53f33522020-10-08 15:00:49632 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37633 */
634 _formatParameterAsObject(obj, includePreview) {
Sigurd Schneider53f33522020-10-08 15:00:49635 const titleElement = /** @type {!HTMLElement} */ (document.createElement('span'));
Tim van der Lippef49e2322020-05-01 15:03:09636 titleElement.classList.add('console-object');
Blink Reformat4c46d092018-04-07 15:32:37637 if (includePreview && obj.preview) {
638 titleElement.classList.add('console-object-preview');
639 this._previewFormatter.appendObjectPreview(titleElement, obj.preview, false /* isEntry */);
640 } else if (obj.type === 'function') {
641 const functionElement = titleElement.createChild('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22642 ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection.formatObjectAsFunction(obj, functionElement, false);
Blink Reformat4c46d092018-04-07 15:32:37643 titleElement.classList.add('object-value-function');
644 } else {
Sigurd Schneider23c52972020-10-13 09:31:14645 UI.UIUtils.createTextChild(titleElement, obj.description || '');
Blink Reformat4c46d092018-04-07 15:32:37646 }
647
Tim van der Lippe1d6e57a2019-09-30 11:55:34648 if (!obj.hasChildren || obj.customPreview()) {
Blink Reformat4c46d092018-04-07 15:32:37649 return titleElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:34650 }
Blink Reformat4c46d092018-04-07 15:32:37651
652 const note = titleElement.createChild('span', 'object-state-note info-note');
Tim van der Lippe9b2f8712020-02-12 17:46:22653 if (this._message.type === SDK.ConsoleModel.MessageType.QueryObjectResult) {
Blink Reformat4c46d092018-04-07 15:32:37654 note.title = ls`This value will not be collected until console is cleared.`;
Tim van der Lippe1d6e57a2019-09-30 11:55:34655 } else {
Blink Reformat4c46d092018-04-07 15:32:37656 note.title = ls`Value below was evaluated just now.`;
Tim van der Lippe1d6e57a2019-09-30 11:55:34657 }
Blink Reformat4c46d092018-04-07 15:32:37658
Tim van der Lippe9b2f8712020-02-12 17:46:22659 const section = new ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection(obj, titleElement, this._linkifier);
Blink Reformat4c46d092018-04-07 15:32:37660 section.element.classList.add('console-view-object-properties-section');
661 section.enableContextMenu();
Erik Luocc14b812018-11-03 01:33:09662 section.setShowSelectionOnKeyboardFocus(true, true);
Erik Luo383f21d2018-11-07 23:16:37663 this._selectableChildren.push(section);
Erik Luo840be6b2018-12-03 20:54:27664 section.addEventListener(UI.TreeOutline.Events.ElementAttached, this._messageResized);
665 section.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._messageResized);
666 section.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._messageResized);
Blink Reformat4c46d092018-04-07 15:32:37667 return section.element;
668 }
669
670 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22671 * @param {!SDK.RemoteObject.RemoteObject} func
Blink Reformat4c46d092018-04-07 15:32:37672 * @param {boolean=} includePreview
Sigurd Schneider53f33522020-10-08 15:00:49673 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37674 */
675 _formatParameterAsFunction(func, includePreview) {
Sigurd Schneider53f33522020-10-08 15:00:49676 const result = /** @type {!HTMLElement} */ (document.createElement('span'));
Tim van der Lippe9b2f8712020-02-12 17:46:22677 SDK.RemoteObject.RemoteFunction.objectAsFunction(func).targetFunction().then(formatTargetFunction.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37678 return result;
679
680 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22681 * @param {!SDK.RemoteObject.RemoteObject} targetFunction
Tim van der Lippeeaacb722020-01-10 12:16:00682 * @this {ConsoleViewMessage}
Blink Reformat4c46d092018-04-07 15:32:37683 */
684 function formatTargetFunction(targetFunction) {
Sigurd Schneider53f33522020-10-08 15:00:49685 const functionElement = document.createElement('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22686 const promise = ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection.formatObjectAsFunction(
Joey Arhard78a58f2018-12-05 01:59:45687 targetFunction, functionElement, true, includePreview);
Blink Reformat4c46d092018-04-07 15:32:37688 result.appendChild(functionElement);
689 if (targetFunction !== func) {
690 const note = result.createChild('span', 'object-info-state-note');
Tim van der Lippe9b2f8712020-02-12 17:46:22691 note.title = Common.UIString.UIString('Function was resolved from bound function.');
Blink Reformat4c46d092018-04-07 15:32:37692 }
693 result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, targetFunction), false);
Joey Arhard78a58f2018-12-05 01:59:45694 promise.then(() => this._formattedParameterAsFunctionForTest());
Blink Reformat4c46d092018-04-07 15:32:37695 }
696 }
697
Joey Arhard78a58f2018-12-05 01:59:45698 _formattedParameterAsFunctionForTest() {
699 }
700
Blink Reformat4c46d092018-04-07 15:32:37701 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22702 * @param {!SDK.RemoteObject.RemoteObject} obj
Blink Reformat4c46d092018-04-07 15:32:37703 * @param {!Event} event
704 */
705 _contextMenuEventFired(obj, event) {
Tim van der Lippe9b2f8712020-02-12 17:46:22706 const contextMenu = new UI.ContextMenu.ContextMenu(event);
Blink Reformat4c46d092018-04-07 15:32:37707 contextMenu.appendApplicableItems(obj);
708 contextMenu.show();
709 }
710
711 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22712 * @param {?SDK.RemoteObject.RemoteObject} object
Blink Reformat4c46d092018-04-07 15:32:37713 * @param {!Array.<!Protocol.Runtime.PropertyPreview>} propertyPath
Sigurd Schneider53f33522020-10-08 15:00:49714 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37715 */
716 _renderPropertyPreviewOrAccessor(object, propertyPath) {
717 const property = propertyPath.peekLast();
Tim van der Lippe1d6e57a2019-09-30 11:55:34718 if (property.type === 'accessor') {
Blink Reformat4c46d092018-04-07 15:32:37719 return this._formatAsAccessorProperty(object, propertyPath.map(property => property.name), false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34720 }
Blink Reformat4c46d092018-04-07 15:32:37721 return this._previewFormatter.renderPropertyPreview(
722 property.type, /** @type {string} */ (property.subtype), property.value);
723 }
724
725 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22726 * @param {!SDK.RemoteObject.RemoteObject} remoteObject
Sigurd Schneider53f33522020-10-08 15:00:49727 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37728 */
729 _formatParameterAsNode(remoteObject) {
Sigurd Schneider53f33522020-10-08 15:00:49730 const result = /** @type {!HTMLElement} */ (document.createElement('span'));
Blink Reformat4c46d092018-04-07 15:32:37731
Tim van der Lippe9b2f8712020-02-12 17:46:22732 const domModel = remoteObject.runtimeModel().target().model(SDK.DOMModel.DOMModel);
Tim van der Lippe1d6e57a2019-09-30 11:55:34733 if (!domModel) {
Blink Reformat4c46d092018-04-07 15:32:37734 return result;
Tim van der Lippe1d6e57a2019-09-30 11:55:34735 }
Erik Luo54fdd912018-11-01 17:57:01736 domModel.pushObjectAsNodeToFrontend(remoteObject).then(async node => {
Blink Reformat4c46d092018-04-07 15:32:37737 if (!node) {
738 result.appendChild(this._formatParameterAsObject(remoteObject, false));
739 return;
740 }
Tim van der Lippe9b2f8712020-02-12 17:46:22741 const renderResult = await UI.UIUtils.Renderer.render(/** @type {!Object} */ (node));
Erik Luofc6a6302018-11-02 06:48:52742 if (renderResult) {
Erik Luo840be6b2018-12-03 20:54:27743 if (renderResult.tree) {
Erik Luo383f21d2018-11-07 23:16:37744 this._selectableChildren.push(renderResult.tree);
Erik Luo840be6b2018-12-03 20:54:27745 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementAttached, this._messageResized);
746 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._messageResized);
747 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._messageResized);
748 }
Erik Luofc6a6302018-11-02 06:48:52749 result.appendChild(renderResult.node);
750 } else {
751 result.appendChild(this._formatParameterAsObject(remoteObject, false));
752 }
Erik Luo54fdd912018-11-01 17:57:01753 this._formattedParameterAsNodeForTest();
Blink Reformat4c46d092018-04-07 15:32:37754 });
755
756 return result;
757 }
758
759 _formattedParameterAsNodeForTest() {
760 }
761
762 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22763 * @param {!SDK.RemoteObject.RemoteObject} output
Sigurd Schneider53f33522020-10-08 15:00:49764 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37765 */
766 _formatParameterAsString(output) {
Sigurd Schneider53f33522020-10-08 15:00:49767 const span = /** @type {!HTMLElement} */ (document.createElement('span'));
Erik Luo383f21d2018-11-07 23:16:37768 span.appendChild(this._linkifyStringAsFragment(output.description || ''));
Blink Reformat4c46d092018-04-07 15:32:37769
Sigurd Schneider53f33522020-10-08 15:00:49770 const result = /** @type {!HTMLElement} */ (document.createElement('span'));
Blink Reformat4c46d092018-04-07 15:32:37771 result.createChild('span', 'object-value-string-quote').textContent = '"';
772 result.appendChild(span);
773 result.createChild('span', 'object-value-string-quote').textContent = '"';
774 return result;
775 }
776
777 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22778 * @param {!SDK.RemoteObject.RemoteObject} output
Sigurd Schneider53f33522020-10-08 15:00:49779 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37780 */
781 _formatParameterAsError(output) {
Sigurd Schneider53f33522020-10-08 15:00:49782 const result = /** @type {!HTMLElement} */ (document.createElement('span'));
Blink Reformat4c46d092018-04-07 15:32:37783 const errorSpan = this._tryFormatAsError(output.description || '');
Erik Luo383f21d2018-11-07 23:16:37784 result.appendChild(errorSpan ? errorSpan : this._linkifyStringAsFragment(output.description || ''));
Blink Reformat4c46d092018-04-07 15:32:37785 return result;
786 }
787
788 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22789 * @param {!SDK.RemoteObject.RemoteObject} output
Sigurd Schneider53f33522020-10-08 15:00:49790 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37791 */
792 _formatAsArrayEntry(output) {
793 return this._previewFormatter.renderPropertyPreview(output.type, output.subtype, output.description);
794 }
795
796 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22797 * @param {?SDK.RemoteObject.RemoteObject} object
Blink Reformat4c46d092018-04-07 15:32:37798 * @param {!Array.<string>} propertyPath
799 * @param {boolean} isArrayEntry
Sigurd Schneider53f33522020-10-08 15:00:49800 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37801 */
802 _formatAsAccessorProperty(object, propertyPath, isArrayEntry) {
Tim van der Lippe9b2f8712020-02-12 17:46:22803 const rootElement =
804 ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan(
805 object, propertyPath, onInvokeGetterClick.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37806
807 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22808 * @param {!SDK.RemoteObject.CallFunctionResult} result
Tim van der Lippeeaacb722020-01-10 12:16:00809 * @this {ConsoleViewMessage}
Blink Reformat4c46d092018-04-07 15:32:37810 */
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18811 function onInvokeGetterClick(result) {
812 const wasThrown = result.wasThrown;
813 const object = result.object;
Tim van der Lippe1d6e57a2019-09-30 11:55:34814 if (!object) {
Blink Reformat4c46d092018-04-07 15:32:37815 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34816 }
Blink Reformat4c46d092018-04-07 15:32:37817 rootElement.removeChildren();
818 if (wasThrown) {
819 const element = rootElement.createChild('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22820 element.textContent = Common.UIString.UIString('<exception>');
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18821 element.title = /** @type {string} */ (object.description);
Blink Reformat4c46d092018-04-07 15:32:37822 } else if (isArrayEntry) {
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18823 rootElement.appendChild(this._formatAsArrayEntry(object));
Blink Reformat4c46d092018-04-07 15:32:37824 } else {
825 // Make a PropertyPreview from the RemoteObject similar to the backend logic.
826 const maxLength = 100;
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18827 const type = object.type;
828 const subtype = object.subtype;
Blink Reformat4c46d092018-04-07 15:32:37829 let description = '';
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18830 if (type !== 'function' && object.description) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34831 if (type === 'string' || subtype === 'regexp') {
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18832 description = object.description.trimMiddle(maxLength);
Tim van der Lippe1d6e57a2019-09-30 11:55:34833 } else {
Tim van der Lippeffa78622019-09-16 12:07:12834 description = object.description.trimEndWithMaxLength(maxLength);
Tim van der Lippe1d6e57a2019-09-30 11:55:34835 }
Blink Reformat4c46d092018-04-07 15:32:37836 }
837 rootElement.appendChild(this._previewFormatter.renderPropertyPreview(type, subtype, description));
838 }
839 }
840
841 return rootElement;
842 }
843
844 /**
845 * @param {string} format
Tim van der Lippe9b2f8712020-02-12 17:46:22846 * @param {!Array.<!SDK.RemoteObject.RemoteObject>} parameters
Sigurd Schneider53f33522020-10-08 15:00:49847 * @param {!HTMLElement} formattedResult
Blink Reformat4c46d092018-04-07 15:32:37848 */
849 _formatWithSubstitutionString(format, parameters, formattedResult) {
850 const formatters = {};
851
852 /**
853 * @param {boolean} force
854 * @param {boolean} includePreview
Tim van der Lippe9b2f8712020-02-12 17:46:22855 * @param {!SDK.RemoteObject.RemoteObject} obj
Sigurd Schneider53f33522020-10-08 15:00:49856 * @return {!HTMLElement}
Tim van der Lippeeaacb722020-01-10 12:16:00857 * @this {ConsoleViewMessage}
Blink Reformat4c46d092018-04-07 15:32:37858 */
859 function parameterFormatter(force, includePreview, obj) {
860 return this._formatParameter(obj, force, includePreview);
861 }
862
863 function stringFormatter(obj) {
864 return obj.description;
865 }
866
867 function floatFormatter(obj) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34868 if (typeof obj.value !== 'number') {
Blink Reformat4c46d092018-04-07 15:32:37869 return 'NaN';
Tim van der Lippe1d6e57a2019-09-30 11:55:34870 }
Blink Reformat4c46d092018-04-07 15:32:37871 return obj.value;
872 }
873
874 function integerFormatter(obj) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34875 if (obj.type === 'bigint') {
Alexey Kozyatinskiybeb38de2018-08-10 18:54:19876 return obj.description;
Tim van der Lippe1d6e57a2019-09-30 11:55:34877 }
878 if (typeof obj.value !== 'number') {
Blink Reformat4c46d092018-04-07 15:32:37879 return 'NaN';
Tim van der Lippe1d6e57a2019-09-30 11:55:34880 }
Blink Reformat4c46d092018-04-07 15:32:37881 return Math.floor(obj.value);
882 }
883
884 function bypassFormatter(obj) {
885 return (obj instanceof Node) ? obj : '';
886 }
887
888 let currentStyle = null;
889 function styleFormatter(obj) {
890 currentStyle = {};
Sigurd Schneider53f33522020-10-08 15:00:49891 const buffer = document.createElement('span');
Blink Reformat4c46d092018-04-07 15:32:37892 buffer.setAttribute('style', obj.description);
893 for (let i = 0; i < buffer.style.length; i++) {
894 const property = buffer.style[i];
Mathias Bynens5165a7a2020-06-10 05:51:43895 if (isAllowedProperty(property)) {
Blink Reformat4c46d092018-04-07 15:32:37896 currentStyle[property] = buffer.style[property];
Tim van der Lippe1d6e57a2019-09-30 11:55:34897 }
Blink Reformat4c46d092018-04-07 15:32:37898 }
899 }
900
Mathias Bynens5165a7a2020-06-10 05:51:43901 function isAllowedProperty(property) {
Blink Reformat4c46d092018-04-07 15:32:37902 // Make sure that allowed properties do not interfere with link visibility.
903 const prefixes = [
904 'background', 'border', 'color', 'font', 'line', 'margin', 'padding', 'text', '-webkit-background',
905 '-webkit-border', '-webkit-font', '-webkit-margin', '-webkit-padding', '-webkit-text'
906 ];
907 for (let i = 0; i < prefixes.length; i++) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34908 if (property.startsWith(prefixes[i])) {
Blink Reformat4c46d092018-04-07 15:32:37909 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:34910 }
Blink Reformat4c46d092018-04-07 15:32:37911 }
912 return false;
913 }
914
915 // Firebug uses %o for formatting objects.
916 formatters.o = parameterFormatter.bind(this, false /* force */, true /* includePreview */);
917 formatters.s = stringFormatter;
918 formatters.f = floatFormatter;
919 // Firebug allows both %i and %d for formatting integers.
920 formatters.i = integerFormatter;
921 formatters.d = integerFormatter;
922
923 // Firebug uses %c for styling the message.
924 formatters.c = styleFormatter;
925
926 // Support %O to force object formatting, instead of the type-based %o formatting.
927 formatters.O = parameterFormatter.bind(this, true /* force */, false /* includePreview */);
928
929 formatters._ = bypassFormatter;
930
931 /**
Sigurd Schneider53f33522020-10-08 15:00:49932 * @param {!HTMLElement} a
Blink Reformat4c46d092018-04-07 15:32:37933 * @param {*} b
Tim van der Lippeeaacb722020-01-10 12:16:00934 * @this {!ConsoleViewMessage}
Sigurd Schneider53f33522020-10-08 15:00:49935 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37936 */
937 function append(a, b) {
938 if (b instanceof Node) {
939 a.appendChild(b);
Erik Luo17926392018-05-17 22:06:12940 return a;
941 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34942 if (typeof b === 'undefined') {
Erik Luo17926392018-05-17 22:06:12943 return a;
Tim van der Lippe1d6e57a2019-09-30 11:55:34944 }
Erik Luo17926392018-05-17 22:06:12945 if (!currentStyle) {
Erik Luo383f21d2018-11-07 23:16:37946 a.appendChild(this._linkifyStringAsFragment(String(b)));
Erik Luo17926392018-05-17 22:06:12947 return a;
948 }
949 const lines = String(b).split('\n');
950 for (let i = 0; i < lines.length; i++) {
951 const line = lines[i];
Erik Luo383f21d2018-11-07 23:16:37952 const lineFragment = this._linkifyStringAsFragment(line);
Sigurd Schneider53f33522020-10-08 15:00:49953 const wrapper = /** @type {!HTMLElement} */ (document.createElement('span'));
Erik Luo17926392018-05-17 22:06:12954 wrapper.style.setProperty('contain', 'paint');
955 wrapper.style.setProperty('display', 'inline-block');
956 wrapper.style.setProperty('max-width', '100%');
957 wrapper.appendChild(lineFragment);
958 applyCurrentStyle(wrapper);
959 for (const child of wrapper.children) {
Sigurd Schneider53f33522020-10-08 15:00:49960 if (child.classList.contains('devtools-link') && child instanceof HTMLElement) {
Erik Luo17926392018-05-17 22:06:12961 this._applyForcedVisibleStyle(child);
Tim van der Lippe1d6e57a2019-09-30 11:55:34962 }
Blink Reformat4c46d092018-04-07 15:32:37963 }
Erik Luo17926392018-05-17 22:06:12964 a.appendChild(wrapper);
Tim van der Lippe1d6e57a2019-09-30 11:55:34965 if (i < lines.length - 1) {
Sigurd Schneider53f33522020-10-08 15:00:49966 a.appendChild(document.createElement('br'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34967 }
Blink Reformat4c46d092018-04-07 15:32:37968 }
969 return a;
970 }
971
972 /**
Sigurd Schneider53f33522020-10-08 15:00:49973 * @param {!HTMLElement} element
Blink Reformat4c46d092018-04-07 15:32:37974 */
975 function applyCurrentStyle(element) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34976 for (const key in currentStyle) {
Blink Reformat4c46d092018-04-07 15:32:37977 element.style[key] = currentStyle[key];
Tim van der Lippe1d6e57a2019-09-30 11:55:34978 }
Blink Reformat4c46d092018-04-07 15:32:37979 }
980
Tim van der Lippe93b57c32020-02-20 17:38:44981 // Platform.StringUtilities.format does treat formattedResult like a Builder, result is an object.
982 return Platform.StringUtilities.format(format, parameters, formatters, formattedResult, append.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37983 }
984
985 /**
Sigurd Schneider53f33522020-10-08 15:00:49986 * @param {!HTMLElement} element
Blink Reformat4c46d092018-04-07 15:32:37987 */
988 _applyForcedVisibleStyle(element) {
989 element.style.setProperty('-webkit-text-stroke', '0', 'important');
990 element.style.setProperty('text-decoration', 'underline', 'important');
991
Paul Lewisca569a52020-09-09 16:11:51992 const themedColor = ThemeSupport.ThemeSupport.instance().patchColorText(
993 'rgb(33%, 33%, 33%)', ThemeSupport.ThemeSupport.ColorUsage.Foreground);
Blink Reformat4c46d092018-04-07 15:32:37994 element.style.setProperty('color', themedColor, 'important');
995
996 let backgroundColor = 'hsl(0, 0%, 100%)';
Tim van der Lippe9b2f8712020-02-12 17:46:22997 if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Blink Reformat4c46d092018-04-07 15:32:37998 backgroundColor = 'hsl(0, 100%, 97%)';
Tim van der Lippe9b2f8712020-02-12 17:46:22999 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning || this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371000 backgroundColor = 'hsl(50, 100%, 95%)';
Tim van der Lippe1d6e57a2019-09-30 11:55:341001 }
Paul Lewisca569a52020-09-09 16:11:511002 const themedBackgroundColor = ThemeSupport.ThemeSupport.instance().patchColorText(
1003 backgroundColor, ThemeSupport.ThemeSupport.ColorUsage.Background);
Blink Reformat4c46d092018-04-07 15:32:371004 element.style.setProperty('background-color', themedBackgroundColor, 'important');
1005 }
1006
1007 /**
1008 * @return {boolean}
1009 */
1010 matchesFilterRegex(regexObject) {
1011 regexObject.lastIndex = 0;
Erik Luo5976c8c2018-07-24 02:03:091012 const contentElement = this.contentElement();
1013 const anchorText = this._anchorElement ? this._anchorElement.deepTextContent() : '';
1014 return (anchorText && regexObject.test(anchorText.trim())) ||
1015 regexObject.test(contentElement.deepTextContent().slice(anchorText.length));
Blink Reformat4c46d092018-04-07 15:32:371016 }
1017
1018 /**
1019 * @param {string} filter
1020 * @return {boolean}
1021 */
1022 matchesFilterText(filter) {
1023 const text = this.contentElement().deepTextContent();
1024 return text.toLowerCase().includes(filter.toLowerCase());
1025 }
1026
1027 updateTimestamp() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341028 if (!this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371029 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341030 }
Blink Reformat4c46d092018-04-07 15:32:371031
Paul Lewis2d7d65c2020-03-16 17:26:301032 if (Common.Settings.Settings.instance().moduleSetting('consoleTimestampsEnabled').get()) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341033 if (!this._timestampElement) {
Tim van der Lippef49e2322020-05-01 15:03:091034 this._timestampElement = document.createElement('span');
1035 this._timestampElement.classList.add('console-timestamp');
Tim van der Lippe1d6e57a2019-09-30 11:55:341036 }
Tim van der Lippe9b2f8712020-02-12 17:46:221037 this._timestampElement.textContent = UI.UIUtils.formatTimestamp(this._message.timestamp, false) + ' ';
1038 this._timestampElement.title = UI.UIUtils.formatTimestamp(this._message.timestamp, true);
Blink Reformat4c46d092018-04-07 15:32:371039 this._contentElement.insertBefore(this._timestampElement, this._contentElement.firstChild);
1040 } else if (this._timestampElement) {
1041 this._timestampElement.remove();
1042 delete this._timestampElement;
1043 }
Blink Reformat4c46d092018-04-07 15:32:371044 }
1045
1046 /**
1047 * @return {number}
1048 */
1049 nestingLevel() {
1050 return this._nestingLevel;
1051 }
1052
1053 /**
1054 * @param {boolean} inSimilarGroup
1055 * @param {boolean=} isLast
1056 */
1057 setInSimilarGroup(inSimilarGroup, isLast) {
1058 this._inSimilarGroup = inSimilarGroup;
1059 this._lastInSimilarGroup = inSimilarGroup && !!isLast;
1060 if (this._similarGroupMarker && !inSimilarGroup) {
1061 this._similarGroupMarker.remove();
1062 this._similarGroupMarker = null;
1063 } else if (this._element && !this._similarGroupMarker && inSimilarGroup) {
Tim van der Lippef49e2322020-05-01 15:03:091064 this._similarGroupMarker = document.createElement('div');
1065 this._similarGroupMarker.classList.add('nesting-level-marker');
Blink Reformat4c46d092018-04-07 15:32:371066 this._element.insertBefore(this._similarGroupMarker, this._element.firstChild);
1067 this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
1068 }
1069 }
1070
1071 /**
1072 * @return {boolean}
1073 */
1074 isLastInSimilarGroup() {
1075 return this._inSimilarGroup && this._lastInSimilarGroup;
1076 }
1077
1078 resetCloseGroupDecorationCount() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341079 if (!this._closeGroupDecorationCount) {
Blink Reformat4c46d092018-04-07 15:32:371080 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341081 }
Blink Reformat4c46d092018-04-07 15:32:371082 this._closeGroupDecorationCount = 0;
1083 this._updateCloseGroupDecorations();
1084 }
1085
1086 incrementCloseGroupDecorationCount() {
1087 ++this._closeGroupDecorationCount;
1088 this._updateCloseGroupDecorations();
1089 }
1090
1091 _updateCloseGroupDecorations() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341092 if (!this._nestingLevelMarkers) {
Blink Reformat4c46d092018-04-07 15:32:371093 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341094 }
Blink Reformat4c46d092018-04-07 15:32:371095 for (let i = 0, n = this._nestingLevelMarkers.length; i < n; ++i) {
1096 const marker = this._nestingLevelMarkers[i];
1097 marker.classList.toggle('group-closed', n - i <= this._closeGroupDecorationCount);
1098 }
1099 }
1100
1101 /**
Erik Luo0b8282e2018-10-08 20:37:461102 * @return {number}
1103 */
1104 _focusedChildIndex() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341105 if (!this._selectableChildren.length) {
Erik Luo0b8282e2018-10-08 20:37:461106 return -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341107 }
Erik Luo383f21d2018-11-07 23:16:371108 return this._selectableChildren.findIndex(child => child.element.hasFocus());
Erik Luo0b8282e2018-10-08 20:37:461109 }
1110
1111 /**
Erik Luo8ef5d0c2018-09-25 21:16:001112 * @param {!Event} event
1113 */
1114 _onKeyDown(event) {
Tim van der Lippe9b2f8712020-02-12 17:46:221115 if (UI.UIUtils.isEditing() || !this._element.hasFocus() || this._element.hasSelection()) {
Erik Luo8ef5d0c2018-09-25 21:16:001116 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341117 }
1118 if (this.maybeHandleOnKeyDown(event)) {
Erik Luo8ef5d0c2018-09-25 21:16:001119 event.consume(true);
Tim van der Lippe1d6e57a2019-09-30 11:55:341120 }
Erik Luo8ef5d0c2018-09-25 21:16:001121 }
1122
1123 /**
1124 * @protected
1125 * @param {!Event} event
1126 */
1127 maybeHandleOnKeyDown(event) {
1128 // Handle trace expansion.
Erik Luo0b8282e2018-10-08 20:37:461129 const focusedChildIndex = this._focusedChildIndex();
1130 const isWrapperFocused = focusedChildIndex === -1;
1131 if (this._expandTrace && isWrapperFocused) {
Erik Luo8ef5d0c2018-09-25 21:16:001132 if ((event.key === 'ArrowLeft' && this._traceExpanded) || (event.key === 'ArrowRight' && !this._traceExpanded)) {
1133 this._expandTrace(!this._traceExpanded);
1134 return true;
1135 }
1136 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341137 if (!this._selectableChildren.length) {
Erik Luo0b8282e2018-10-08 20:37:461138 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341139 }
Erik Luo0b8282e2018-10-08 20:37:461140
1141 if (event.key === 'ArrowLeft') {
1142 this._element.focus();
1143 return true;
1144 }
1145 if (event.key === 'ArrowRight') {
Tim van der Lippe1d6e57a2019-09-30 11:55:341146 if (isWrapperFocused && this._selectNearestVisibleChild(0)) {
Erik Luo0b8282e2018-10-08 20:37:461147 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341148 }
Erik Luo0b8282e2018-10-08 20:37:461149 }
1150 if (event.key === 'ArrowUp') {
Erik Luo182bece2018-11-29 03:15:221151 const firstVisibleChild = this._nearestVisibleChild(0);
1152 if (this._selectableChildren[focusedChildIndex] === firstVisibleChild && firstVisibleChild) {
Erik Luo0b8282e2018-10-08 20:37:461153 this._element.focus();
1154 return true;
Mathias Bynensf06e8c02020-02-28 13:58:281155 }
1156 if (this._selectNearestVisibleChild(focusedChildIndex - 1, true /* backwards */)) {
Erik Luo0b8282e2018-10-08 20:37:461157 return true;
1158 }
1159 }
1160 if (event.key === 'ArrowDown') {
Tim van der Lippe1d6e57a2019-09-30 11:55:341161 if (isWrapperFocused && this._selectNearestVisibleChild(0)) {
Erik Luo0b8282e2018-10-08 20:37:461162 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341163 }
1164 if (!isWrapperFocused && this._selectNearestVisibleChild(focusedChildIndex + 1)) {
Erik Luo0b8282e2018-10-08 20:37:461165 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341166 }
Erik Luo0b8282e2018-10-08 20:37:461167 }
Erik Luo8ef5d0c2018-09-25 21:16:001168 return false;
1169 }
1170
Erik Luo182bece2018-11-29 03:15:221171 /**
1172 * @param {number} fromIndex
1173 * @param {boolean=} backwards
1174 * @return {boolean}
1175 */
1176 _selectNearestVisibleChild(fromIndex, backwards) {
1177 const nearestChild = this._nearestVisibleChild(fromIndex, backwards);
1178 if (nearestChild) {
Erik Luo31c21f62018-12-13 03:39:391179 nearestChild.forceSelect();
Erik Luo182bece2018-11-29 03:15:221180 return true;
1181 }
1182 return false;
1183 }
1184
1185 /**
1186 * @param {number} fromIndex
1187 * @param {boolean=} backwards
Erik Luo31c21f62018-12-13 03:39:391188 * @return {?{element: !Element, forceSelect: function()}}
Erik Luo182bece2018-11-29 03:15:221189 */
1190 _nearestVisibleChild(fromIndex, backwards) {
1191 const childCount = this._selectableChildren.length;
Tim van der Lippe1d6e57a2019-09-30 11:55:341192 if (fromIndex < 0 || fromIndex >= childCount) {
Erik Luo182bece2018-11-29 03:15:221193 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341194 }
Erik Luo182bece2018-11-29 03:15:221195 const direction = backwards ? -1 : 1;
1196 let index = fromIndex;
1197
1198 while (!this._selectableChildren[index].element.offsetParent) {
1199 index += direction;
Tim van der Lippe1d6e57a2019-09-30 11:55:341200 if (index < 0 || index >= childCount) {
Erik Luo182bece2018-11-29 03:15:221201 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341202 }
Erik Luo182bece2018-11-29 03:15:221203 }
1204 return this._selectableChildren[index];
1205 }
1206
Sigurd Schneider53f33522020-10-08 15:00:491207 /**
1208 * @override
1209 */
Erik Luo0b8282e2018-10-08 20:37:461210 focusLastChildOrSelf() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341211 if (this._element && !this._selectNearestVisibleChild(this._selectableChildren.length - 1, true /* backwards */)) {
Erik Luo0b8282e2018-10-08 20:37:461212 this._element.focus();
Tim van der Lippe1d6e57a2019-09-30 11:55:341213 }
Erik Luo0b8282e2018-10-08 20:37:461214 }
1215
1216 /**
Sigurd Schneiderb2953b22020-10-09 09:30:151217 * @protected
1218 * @param {!HTMLElement} element
1219 */
1220 setContentElement(element) {
1221 console.assert(!this._contentElement, 'Cannot set content element twice');
1222 this._contentElement = element;
1223 }
1224
1225
1226 /**
1227 * @protected
1228 * @return {?HTMLElement}
1229 */
1230 getContentElement() {
1231 return this._contentElement;
1232 }
1233
1234 /**
Sigurd Schneider53f33522020-10-08 15:00:491235 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:371236 */
1237 contentElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341238 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371239 return this._contentElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:341240 }
Blink Reformat4c46d092018-04-07 15:32:371241
Sigurd Schneider53f33522020-10-08 15:00:491242 const contentElement = /** @type {!HTMLElement} */ (document.createElement('div'));
Tim van der Lippef49e2322020-05-01 15:03:091243 contentElement.classList.add('console-message');
Tim van der Lippe1d6e57a2019-09-30 11:55:341244 if (this._messageLevelIcon) {
Blink Reformat4c46d092018-04-07 15:32:371245 contentElement.appendChild(this._messageLevelIcon);
Tim van der Lippe1d6e57a2019-09-30 11:55:341246 }
Blink Reformat4c46d092018-04-07 15:32:371247 this._contentElement = contentElement;
1248
1249 let formattedMessage;
1250 const shouldIncludeTrace = !!this._message.stackTrace &&
Tim van der Lippe9b2f8712020-02-12 17:46:221251 (this._message.source === SDK.ConsoleModel.MessageSource.Network ||
1252 this._message.source === SDK.ConsoleModel.MessageSource.Violation ||
1253 this._message.level === SDK.ConsoleModel.MessageLevel.Error ||
1254 this._message.level === SDK.ConsoleModel.MessageLevel.Warning ||
1255 this._message.type === SDK.ConsoleModel.MessageType.Trace);
Tim van der Lippe1d6e57a2019-09-30 11:55:341256 if (this._message.runtimeModel() && shouldIncludeTrace) {
Blink Reformat4c46d092018-04-07 15:32:371257 formattedMessage = this._buildMessageWithStackTrace();
Tim van der Lippe9b2f8712020-02-12 17:46:221258 } else if (this._message.type === SDK.ConsoleModel.MessageType.Table) {
Blink Reformat4c46d092018-04-07 15:32:371259 formattedMessage = this._buildTableMessage();
Tim van der Lippe1d6e57a2019-09-30 11:55:341260 } else {
Blink Reformat4c46d092018-04-07 15:32:371261 formattedMessage = this._buildMessage();
Tim van der Lippe1d6e57a2019-09-30 11:55:341262 }
Blink Reformat4c46d092018-04-07 15:32:371263 contentElement.appendChild(formattedMessage);
1264
1265 this.updateTimestamp();
1266 return this._contentElement;
1267 }
1268
1269 /**
Sigurd Schneider53f33522020-10-08 15:00:491270 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:371271 */
1272 toMessageElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341273 if (this._element) {
Blink Reformat4c46d092018-04-07 15:32:371274 return this._element;
Tim van der Lippe1d6e57a2019-09-30 11:55:341275 }
Blink Reformat4c46d092018-04-07 15:32:371276
Sigurd Schneider53f33522020-10-08 15:00:491277 this._element = /** @type {!HTMLElement} */ (document.createElement('div'));
Pavel Feldmandb310912019-01-30 00:31:201278 this._element.tabIndex = -1;
1279 this._element.addEventListener('keydown', this._onKeyDown.bind(this));
Blink Reformat4c46d092018-04-07 15:32:371280 this.updateMessageElement();
1281 return this._element;
1282 }
1283
1284 updateMessageElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341285 if (!this._element) {
Blink Reformat4c46d092018-04-07 15:32:371286 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341287 }
Blink Reformat4c46d092018-04-07 15:32:371288
1289 this._element.className = 'console-message-wrapper';
1290 this._element.removeChildren();
Tim van der Lippe1d6e57a2019-09-30 11:55:341291 if (this._message.isGroupStartMessage()) {
Blink Reformat4c46d092018-04-07 15:32:371292 this._element.classList.add('console-group-title');
Tim van der Lippe1d6e57a2019-09-30 11:55:341293 }
Tim van der Lippe9b2f8712020-02-12 17:46:221294 if (this._message.source === SDK.ConsoleModel.MessageSource.ConsoleAPI) {
Blink Reformat4c46d092018-04-07 15:32:371295 this._element.classList.add('console-from-api');
Tim van der Lippe1d6e57a2019-09-30 11:55:341296 }
Blink Reformat4c46d092018-04-07 15:32:371297 if (this._inSimilarGroup) {
1298 this._similarGroupMarker = this._element.createChild('div', 'nesting-level-marker');
1299 this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
1300 }
1301
1302 this._nestingLevelMarkers = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341303 for (let i = 0; i < this._nestingLevel; ++i) {
Blink Reformat4c46d092018-04-07 15:32:371304 this._nestingLevelMarkers.push(this._element.createChild('div', 'nesting-level-marker'));
Tim van der Lippe1d6e57a2019-09-30 11:55:341305 }
Blink Reformat4c46d092018-04-07 15:32:371306 this._updateCloseGroupDecorations();
1307 this._element.message = this;
1308
1309 switch (this._message.level) {
Tim van der Lippe9b2f8712020-02-12 17:46:221310 case SDK.ConsoleModel.MessageLevel.Verbose:
Blink Reformat4c46d092018-04-07 15:32:371311 this._element.classList.add('console-verbose-level');
Blink Reformat4c46d092018-04-07 15:32:371312 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221313 case SDK.ConsoleModel.MessageLevel.Info:
Blink Reformat4c46d092018-04-07 15:32:371314 this._element.classList.add('console-info-level');
Tim van der Lippe9b2f8712020-02-12 17:46:221315 if (this._message.type === SDK.ConsoleModel.MessageType.System) {
Blink Reformat4c46d092018-04-07 15:32:371316 this._element.classList.add('console-system-type');
Tim van der Lippe1d6e57a2019-09-30 11:55:341317 }
Blink Reformat4c46d092018-04-07 15:32:371318 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221319 case SDK.ConsoleModel.MessageLevel.Warning:
Blink Reformat4c46d092018-04-07 15:32:371320 this._element.classList.add('console-warning-level');
Blink Reformat4c46d092018-04-07 15:32:371321 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221322 case SDK.ConsoleModel.MessageLevel.Error:
Blink Reformat4c46d092018-04-07 15:32:371323 this._element.classList.add('console-error-level');
Blink Reformat4c46d092018-04-07 15:32:371324 break;
1325 }
Erik Luofd3e7d42018-09-25 02:12:351326 this._updateMessageLevelIcon();
Tim van der Lippe1d6e57a2019-09-30 11:55:341327 if (this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371328 this._element.classList.add('console-warning-level');
Tim van der Lippe1d6e57a2019-09-30 11:55:341329 }
Blink Reformat4c46d092018-04-07 15:32:371330
1331 this._element.appendChild(this.contentElement());
Tim van der Lippe1d6e57a2019-09-30 11:55:341332 if (this._repeatCount > 1) {
Blink Reformat4c46d092018-04-07 15:32:371333 this._showRepeatCountElement();
Tim van der Lippe1d6e57a2019-09-30 11:55:341334 }
Blink Reformat4c46d092018-04-07 15:32:371335 }
1336
1337 /**
1338 * @return {boolean}
1339 */
1340 _shouldRenderAsWarning() {
Tim van der Lippe9b2f8712020-02-12 17:46:221341 return (this._message.level === SDK.ConsoleModel.MessageLevel.Verbose ||
1342 this._message.level === SDK.ConsoleModel.MessageLevel.Info) &&
1343 (this._message.source === SDK.ConsoleModel.MessageSource.Violation ||
1344 this._message.source === SDK.ConsoleModel.MessageSource.Deprecation ||
1345 this._message.source === SDK.ConsoleModel.MessageSource.Intervention ||
1346 this._message.source === SDK.ConsoleModel.MessageSource.Recommendation);
Blink Reformat4c46d092018-04-07 15:32:371347 }
1348
Erik Luofd3e7d42018-09-25 02:12:351349 _updateMessageLevelIcon() {
1350 let iconType = '';
1351 let accessibleName = '';
Tim van der Lippe9b2f8712020-02-12 17:46:221352 if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning) {
Erik Luofd3e7d42018-09-25 02:12:351353 iconType = 'smallicon-warning';
1354 accessibleName = ls`Warning`;
Tim van der Lippe9b2f8712020-02-12 17:46:221355 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Erik Luofd3e7d42018-09-25 02:12:351356 iconType = 'smallicon-error';
1357 accessibleName = ls`Error`;
1358 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341359 if (!iconType && !this._messageLevelIcon) {
Blink Reformat4c46d092018-04-07 15:32:371360 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341361 }
Blink Reformat4c46d092018-04-07 15:32:371362 if (iconType && !this._messageLevelIcon) {
Tim van der Lippe9b2f8712020-02-12 17:46:221363 this._messageLevelIcon = UI.Icon.Icon.create('', 'message-level-icon');
Tim van der Lippe1d6e57a2019-09-30 11:55:341364 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371365 this._contentElement.insertBefore(this._messageLevelIcon, this._contentElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341366 }
Blink Reformat4c46d092018-04-07 15:32:371367 }
1368 this._messageLevelIcon.setIconType(iconType);
Erik Luofd3e7d42018-09-25 02:12:351369 UI.ARIAUtils.setAccessibleName(this._messageLevelIcon, accessibleName);
Blink Reformat4c46d092018-04-07 15:32:371370 }
1371
1372 /**
1373 * @return {number}
1374 */
1375 repeatCount() {
1376 return this._repeatCount || 1;
1377 }
1378
1379 resetIncrementRepeatCount() {
1380 this._repeatCount = 1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341381 if (!this._repeatCountElement) {
Blink Reformat4c46d092018-04-07 15:32:371382 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341383 }
Blink Reformat4c46d092018-04-07 15:32:371384
1385 this._repeatCountElement.remove();
Tim van der Lippe1d6e57a2019-09-30 11:55:341386 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371387 this._contentElement.classList.remove('repeated-message');
Tim van der Lippe1d6e57a2019-09-30 11:55:341388 }
Blink Reformat4c46d092018-04-07 15:32:371389 delete this._repeatCountElement;
1390 }
1391
1392 incrementRepeatCount() {
1393 this._repeatCount++;
1394 this._showRepeatCountElement();
1395 }
1396
1397 /**
1398 * @param {number} repeatCount
1399 */
1400 setRepeatCount(repeatCount) {
1401 this._repeatCount = repeatCount;
1402 this._showRepeatCountElement();
1403 }
1404
Tim van der Lippeee954d42020-05-04 10:35:571405 /**
1406 * @suppress {checkTypes}
1407 */
Blink Reformat4c46d092018-04-07 15:32:371408 _showRepeatCountElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341409 if (!this._element) {
Blink Reformat4c46d092018-04-07 15:32:371410 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341411 }
Blink Reformat4c46d092018-04-07 15:32:371412
1413 if (!this._repeatCountElement) {
Tim van der Lippeee954d42020-05-04 10:35:571414 this._repeatCountElement = document.createElement('span', {is: 'dt-small-bubble'});
1415 this._repeatCountElement.classList.add('console-message-repeat-count');
Blink Reformat4c46d092018-04-07 15:32:371416 switch (this._message.level) {
Tim van der Lippe9b2f8712020-02-12 17:46:221417 case SDK.ConsoleModel.MessageLevel.Warning:
Blink Reformat4c46d092018-04-07 15:32:371418 this._repeatCountElement.type = 'warning';
1419 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221420 case SDK.ConsoleModel.MessageLevel.Error:
Blink Reformat4c46d092018-04-07 15:32:371421 this._repeatCountElement.type = 'error';
1422 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221423 case SDK.ConsoleModel.MessageLevel.Verbose:
Blink Reformat4c46d092018-04-07 15:32:371424 this._repeatCountElement.type = 'verbose';
1425 break;
1426 default:
1427 this._repeatCountElement.type = 'info';
1428 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341429 if (this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371430 this._repeatCountElement.type = 'warning';
Tim van der Lippe1d6e57a2019-09-30 11:55:341431 }
Blink Reformat4c46d092018-04-07 15:32:371432
1433 this._element.insertBefore(this._repeatCountElement, this._contentElement);
1434 this._contentElement.classList.add('repeated-message');
1435 }
1436 this._repeatCountElement.textContent = this._repeatCount;
Erik Luofd3e7d42018-09-25 02:12:351437 let accessibleName = ls`Repeat ${this._repeatCount}`;
Tim van der Lippe9b2f8712020-02-12 17:46:221438 if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning) {
Erik Luofd3e7d42018-09-25 02:12:351439 accessibleName = ls`Warning ${accessibleName}`;
Tim van der Lippe9b2f8712020-02-12 17:46:221440 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Erik Luofd3e7d42018-09-25 02:12:351441 accessibleName = ls`Error ${accessibleName}`;
Tim van der Lippe1d6e57a2019-09-30 11:55:341442 }
Erik Luofd3e7d42018-09-25 02:12:351443 UI.ARIAUtils.setAccessibleName(this._repeatCountElement, accessibleName);
Blink Reformat4c46d092018-04-07 15:32:371444 }
1445
1446 get text() {
1447 return this._message.messageText;
1448 }
1449
1450 /**
1451 * @return {string}
1452 */
1453 toExportString() {
1454 const lines = [];
1455 const nodes = this.contentElement().childTextNodes();
Tim van der Lippe9b2f8712020-02-12 17:46:221456 const messageContent = nodes.map(Components.Linkifier.Linkifier.untruncatedNodeText).join('');
Tim van der Lippe1d6e57a2019-09-30 11:55:341457 for (let i = 0; i < this.repeatCount(); ++i) {
Blink Reformat4c46d092018-04-07 15:32:371458 lines.push(messageContent);
Tim van der Lippe1d6e57a2019-09-30 11:55:341459 }
Blink Reformat4c46d092018-04-07 15:32:371460 return lines.join('\n');
1461 }
1462
1463 /**
1464 * @param {?RegExp} regex
1465 */
1466 setSearchRegex(regex) {
Sigurd Schneidere8e75cf2020-10-13 08:17:521467 if (this._searchHighlightNodeChanges && this._searchHighlightNodeChanges.length) {
1468 UI.UIUtils.revertDomChanges(this._searchHighlightNodeChanges);
Tim van der Lippe1d6e57a2019-09-30 11:55:341469 }
Blink Reformat4c46d092018-04-07 15:32:371470 this._searchRegex = regex;
1471 this._searchHighlightNodes = [];
Sigurd Schneidere8e75cf2020-10-13 08:17:521472 this._searchHighlightNodeChanges = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341473 if (!this._searchRegex) {
Blink Reformat4c46d092018-04-07 15:32:371474 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341475 }
Blink Reformat4c46d092018-04-07 15:32:371476
1477 const text = this.contentElement().deepTextContent();
1478 let match;
1479 this._searchRegex.lastIndex = 0;
1480 const sourceRanges = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341481 while ((match = this._searchRegex.exec(text)) && match[0]) {
Tim van der Lippe9b2f8712020-02-12 17:46:221482 sourceRanges.push(new TextUtils.TextRange.SourceRange(match.index, match[0].length));
Tim van der Lippe1d6e57a2019-09-30 11:55:341483 }
Blink Reformat4c46d092018-04-07 15:32:371484
1485 if (sourceRanges.length) {
1486 this._searchHighlightNodes =
Sigurd Schneidere8e75cf2020-10-13 08:17:521487 UI.UIUtils.highlightSearchResults(this.contentElement(), sourceRanges, this._searchHighlightNodeChanges);
Blink Reformat4c46d092018-04-07 15:32:371488 }
1489 }
1490
1491 /**
1492 * @return {?RegExp}
1493 */
1494 searchRegex() {
1495 return this._searchRegex;
1496 }
1497
1498 /**
1499 * @return {number}
1500 */
1501 searchCount() {
1502 return this._searchHighlightNodes.length;
1503 }
1504
1505 /**
Sigurd Schneider53f33522020-10-08 15:00:491506 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:371507 */
1508 searchHighlightNode(index) {
1509 return this._searchHighlightNodes[index];
1510 }
1511
1512 /**
1513 * @param {string} string
Sigurd Schneider53f33522020-10-08 15:00:491514 * @return {?HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:371515 */
1516 _tryFormatAsError(string) {
1517 /**
1518 * @param {string} prefix
1519 */
1520 function startsWith(prefix) {
1521 return string.startsWith(prefix);
1522 }
1523
1524 const errorPrefixes =
1525 ['EvalError', 'ReferenceError', 'SyntaxError', 'TypeError', 'RangeError', 'Error', 'URIError'];
Tim van der Lippe1d6e57a2019-09-30 11:55:341526 if (!this._message.runtimeModel() || !errorPrefixes.some(startsWith)) {
Blink Reformat4c46d092018-04-07 15:32:371527 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341528 }
Blink Reformat4c46d092018-04-07 15:32:371529 const debuggerModel = this._message.runtimeModel().debuggerModel();
1530 const baseURL = this._message.runtimeModel().target().inspectedURL();
1531
1532 const lines = string.split('\n');
1533 const links = [];
1534 let position = 0;
1535 for (let i = 0; i < lines.length; ++i) {
1536 position += i > 0 ? lines[i - 1].length + 1 : 0;
1537 const isCallFrameLine = /^\s*at\s/.test(lines[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:341538 if (!isCallFrameLine && links.length) {
Blink Reformat4c46d092018-04-07 15:32:371539 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341540 }
Blink Reformat4c46d092018-04-07 15:32:371541
Tim van der Lippe1d6e57a2019-09-30 11:55:341542 if (!isCallFrameLine) {
Blink Reformat4c46d092018-04-07 15:32:371543 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341544 }
Blink Reformat4c46d092018-04-07 15:32:371545
1546 let openBracketIndex = -1;
1547 let closeBracketIndex = -1;
Yang Guo39256bd2019-07-18 06:02:251548 const inBracketsWithLineAndColumn = /\([^\)\(]+:\d+:\d+\)/g;
1549 const inBrackets = /\([^\)\(]+\)/g;
1550 let lastMatch = null;
1551 let currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341552 while ((currentMatch = inBracketsWithLineAndColumn.exec(lines[i]))) {
Yang Guo39256bd2019-07-18 06:02:251553 lastMatch = currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341554 }
Yang Guo39256bd2019-07-18 06:02:251555 if (!lastMatch) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341556 while ((currentMatch = inBrackets.exec(lines[i]))) {
Yang Guo39256bd2019-07-18 06:02:251557 lastMatch = currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341558 }
Yang Guo39256bd2019-07-18 06:02:251559 }
1560 if (lastMatch) {
1561 openBracketIndex = lastMatch.index;
1562 closeBracketIndex = lastMatch.index + lastMatch[0].length - 1;
Blink Reformat4c46d092018-04-07 15:32:371563 }
1564 const hasOpenBracket = openBracketIndex !== -1;
1565 const left = hasOpenBracket ? openBracketIndex + 1 : lines[i].indexOf('at') + 3;
1566 const right = hasOpenBracket ? closeBracketIndex : lines[i].length;
1567 const linkCandidate = lines[i].substring(left, right);
Tim van der Lippe9b2f8712020-02-12 17:46:221568 const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(linkCandidate);
Tim van der Lippe1d6e57a2019-09-30 11:55:341569 if (!splitResult) {
Blink Reformat4c46d092018-04-07 15:32:371570 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341571 }
Blink Reformat4c46d092018-04-07 15:32:371572
Tim van der Lippe1d6e57a2019-09-30 11:55:341573 if (splitResult.url === '<anonymous>') {
Blink Reformat4c46d092018-04-07 15:32:371574 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341575 }
Blink Reformat4c46d092018-04-07 15:32:371576 let url = parseOrScriptMatch(splitResult.url);
Tim van der Lippe9b2f8712020-02-12 17:46:221577 if (!url && Common.ParsedURL.ParsedURL.isRelativeURL(splitResult.url)) {
1578 url = parseOrScriptMatch(Common.ParsedURL.ParsedURL.completeURL(baseURL, splitResult.url));
Tim van der Lippe1d6e57a2019-09-30 11:55:341579 }
1580 if (!url) {
Blink Reformat4c46d092018-04-07 15:32:371581 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341582 }
Blink Reformat4c46d092018-04-07 15:32:371583
1584 links.push({
1585 url: url,
1586 positionLeft: position + left,
1587 positionRight: position + right,
1588 lineNumber: splitResult.lineNumber,
1589 columnNumber: splitResult.columnNumber
1590 });
1591 }
1592
Tim van der Lippe1d6e57a2019-09-30 11:55:341593 if (!links.length) {
Blink Reformat4c46d092018-04-07 15:32:371594 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341595 }
Blink Reformat4c46d092018-04-07 15:32:371596
Sigurd Schneider53f33522020-10-08 15:00:491597 const formattedResult = /** @type {!HTMLElement} */ (document.createElement('span'));
Blink Reformat4c46d092018-04-07 15:32:371598 let start = 0;
1599 for (let i = 0; i < links.length; ++i) {
Erik Luo383f21d2018-11-07 23:16:371600 formattedResult.appendChild(this._linkifyStringAsFragment(string.substring(start, links[i].positionLeft)));
Erik Luo182bece2018-11-29 03:15:221601 const scriptLocationLink = this._linkifier.linkifyScriptLocation(
Jack Lynch236e1d22020-01-07 20:33:511602 debuggerModel.target(), null, links[i].url, links[i].lineNumber, {columnNumber: links[i].columnNumber});
Erik Luo182bece2018-11-29 03:15:221603 scriptLocationLink.tabIndex = -1;
Erik Luo31c21f62018-12-13 03:39:391604 this._selectableChildren.push({element: scriptLocationLink, forceSelect: () => scriptLocationLink.focus()});
Erik Luo182bece2018-11-29 03:15:221605 formattedResult.appendChild(scriptLocationLink);
Blink Reformat4c46d092018-04-07 15:32:371606 start = links[i].positionRight;
1607 }
1608
Tim van der Lippe1d6e57a2019-09-30 11:55:341609 if (start !== string.length) {
Erik Luo383f21d2018-11-07 23:16:371610 formattedResult.appendChild(this._linkifyStringAsFragment(string.substring(start)));
Tim van der Lippe1d6e57a2019-09-30 11:55:341611 }
Blink Reformat4c46d092018-04-07 15:32:371612
1613 return formattedResult;
1614
1615 /**
1616 * @param {?string} url
1617 * @return {?string}
1618 */
1619 function parseOrScriptMatch(url) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341620 if (!url) {
Blink Reformat4c46d092018-04-07 15:32:371621 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341622 }
Tim van der Lippe9b2f8712020-02-12 17:46:221623 const parsedURL = Common.ParsedURL.ParsedURL.fromString(url);
Tim van der Lippe1d6e57a2019-09-30 11:55:341624 if (parsedURL) {
Blink Reformat4c46d092018-04-07 15:32:371625 return parsedURL.url;
Tim van der Lippe1d6e57a2019-09-30 11:55:341626 }
1627 if (debuggerModel.scriptsForSourceURL(url).length) {
Blink Reformat4c46d092018-04-07 15:32:371628 return url;
Tim van der Lippe1d6e57a2019-09-30 11:55:341629 }
Blink Reformat4c46d092018-04-07 15:32:371630 return null;
1631 }
1632 }
1633
1634 /**
1635 * @param {string} string
1636 * @param {function(string,string,number=,number=):!Node} linkifier
1637 * @return {!DocumentFragment}
Tim van der Lippeeaacb722020-01-10 12:16:001638 * @suppress {accessControls}
Blink Reformat4c46d092018-04-07 15:32:371639 */
Erik Luofc2214f2018-11-21 19:54:581640 _linkifyWithCustomLinkifier(string, linkifier) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341641 if (string.length > Console.ConsoleViewMessage._MaxTokenizableStringLength) {
Tim van der Lippe9b2f8712020-02-12 17:46:221642 const propertyValue = new ObjectUI.ObjectPropertiesSection.ExpandableTextPropertyValue(
Sigurd Schneider53f33522020-10-08 15:00:491643 document.createElement('span'), string, Console.ConsoleViewMessage._LongStringVisibleLength);
Connor Moody1a5c0d32019-12-19 07:23:361644 const fragment = createDocumentFragment();
1645 fragment.appendChild(propertyValue.element);
1646 return fragment;
Tim van der Lippe1d6e57a2019-09-30 11:55:341647 }
Blink Reformat4c46d092018-04-07 15:32:371648 const container = createDocumentFragment();
Tim van der Lippeeaacb722020-01-10 12:16:001649 const tokens = ConsoleViewMessage._tokenizeMessageText(string);
Blink Reformat4c46d092018-04-07 15:32:371650 for (const token of tokens) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341651 if (!token.text) {
Erik Luofc2214f2018-11-21 19:54:581652 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341653 }
Blink Reformat4c46d092018-04-07 15:32:371654 switch (token.type) {
1655 case 'url': {
1656 const realURL = (token.text.startsWith('www.') ? 'http://' + token.text : token.text);
Tim van der Lippe9b2f8712020-02-12 17:46:221657 const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(realURL);
Kim-Anh Tran9e49a452020-02-17 09:46:101658 const sourceURL = Common.ParsedURL.ParsedURL.removeWasmFunctionInfoFromURL(splitResult.url);
Blink Reformat4c46d092018-04-07 15:32:371659 let linkNode;
Tim van der Lippe1d6e57a2019-09-30 11:55:341660 if (splitResult) {
Kim-Anh Tran9e49a452020-02-17 09:46:101661 linkNode = linkifier(token.text, sourceURL, splitResult.lineNumber, splitResult.columnNumber);
Tim van der Lippe1d6e57a2019-09-30 11:55:341662 } else {
Blink Reformat4c46d092018-04-07 15:32:371663 linkNode = linkifier(token.text, token.value);
Tim van der Lippe1d6e57a2019-09-30 11:55:341664 }
Blink Reformat4c46d092018-04-07 15:32:371665 container.appendChild(linkNode);
1666 break;
1667 }
1668 default:
1669 container.appendChild(createTextNode(token.text));
1670 break;
1671 }
1672 }
1673 return container;
1674 }
1675
1676 /**
Blink Reformat4c46d092018-04-07 15:32:371677 * @param {string} string
1678 * @return {!DocumentFragment}
1679 */
Erik Luo383f21d2018-11-07 23:16:371680 _linkifyStringAsFragment(string) {
Erik Luofc2214f2018-11-21 19:54:581681 return this._linkifyWithCustomLinkifier(string, (text, url, lineNumber, columnNumber) => {
Tim van der Lippe9b2f8712020-02-12 17:46:221682 const linkElement = Components.Linkifier.Linkifier.linkifyURL(url, {text, lineNumber, columnNumber});
Erik Luo383f21d2018-11-07 23:16:371683 linkElement.tabIndex = -1;
Erik Luo31c21f62018-12-13 03:39:391684 this._selectableChildren.push({element: linkElement, forceSelect: () => linkElement.focus()});
Erik Luo383f21d2018-11-07 23:16:371685 return linkElement;
Blink Reformat4c46d092018-04-07 15:32:371686 });
1687 }
1688
1689 /**
1690 * @param {string} string
1691 * @return {!Array<{type: string, text: (string|undefined)}>}
Tim van der Lippeeaacb722020-01-10 12:16:001692 * @suppress {accessControls}
Blink Reformat4c46d092018-04-07 15:32:371693 */
1694 static _tokenizeMessageText(string) {
Tim van der Lippeeaacb722020-01-10 12:16:001695 if (!ConsoleViewMessage._tokenizerRegexes) {
Blink Reformat4c46d092018-04-07 15:32:371696 const controlCodes = '\\u0000-\\u0020\\u007f-\\u009f';
1697 const linkStringRegex = new RegExp(
1698 '(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\\/\\/|data:|www\\.)[^\\s' + controlCodes + '"]{2,}[^\\s' + controlCodes +
1699 '"\')}\\],:;.!?]',
1700 'u');
1701 const pathLineRegex = /(?:\/[\w\.-]*)+\:[\d]+/;
1702 const timeRegex = /took [\d]+ms/;
1703 const eventRegex = /'\w+' event/;
1704 const milestoneRegex = /\sM[6-7]\d/;
1705 const autofillRegex = /\(suggested: \"[\w-]+\"\)/;
1706 const handlers = new Map();
1707 handlers.set(linkStringRegex, 'url');
1708 handlers.set(pathLineRegex, 'url');
1709 handlers.set(timeRegex, 'time');
1710 handlers.set(eventRegex, 'event');
1711 handlers.set(milestoneRegex, 'milestone');
1712 handlers.set(autofillRegex, 'autofill');
Tim van der Lippeeaacb722020-01-10 12:16:001713 ConsoleViewMessage._tokenizerRegexes = Array.from(handlers.keys());
1714 ConsoleViewMessage._tokenizerTypes = Array.from(handlers.values());
Blink Reformat4c46d092018-04-07 15:32:371715 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341716 if (string.length > Console.ConsoleViewMessage._MaxTokenizableStringLength) {
Blink Reformat4c46d092018-04-07 15:32:371717 return [{text: string, type: undefined}];
Tim van der Lippe1d6e57a2019-09-30 11:55:341718 }
Tim van der Lippe9b2f8712020-02-12 17:46:221719 const results = TextUtils.TextUtils.Utils.splitStringByRegexes(string, ConsoleViewMessage._tokenizerRegexes);
Tim van der Lippeeaacb722020-01-10 12:16:001720 return results.map(result => ({text: result.value, type: ConsoleViewMessage._tokenizerTypes[result.regexIndex]}));
Blink Reformat4c46d092018-04-07 15:32:371721 }
1722
1723 /**
1724 * @return {string}
1725 */
1726 groupKey() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341727 if (!this._groupKey) {
Blink Reformat4c46d092018-04-07 15:32:371728 this._groupKey = this._message.groupCategoryKey() + ':' + this.groupTitle();
Tim van der Lippe1d6e57a2019-09-30 11:55:341729 }
Blink Reformat4c46d092018-04-07 15:32:371730 return this._groupKey;
1731 }
1732
1733 /**
1734 * @return {string}
1735 */
1736 groupTitle() {
Tim van der Lippeeaacb722020-01-10 12:16:001737 const tokens = ConsoleViewMessage._tokenizeMessageText(this._message.messageText);
Blink Reformat4c46d092018-04-07 15:32:371738 const result = tokens.reduce((acc, token) => {
1739 let text = token.text;
Tim van der Lippe1d6e57a2019-09-30 11:55:341740 if (token.type === 'url') {
Tim van der Lippe9b2f8712020-02-12 17:46:221741 text = Common.UIString.UIString('<URL>');
Tim van der Lippe1d6e57a2019-09-30 11:55:341742 } else if (token.type === 'time') {
Tim van der Lippe9b2f8712020-02-12 17:46:221743 text = Common.UIString.UIString('took <N>ms');
Tim van der Lippe1d6e57a2019-09-30 11:55:341744 } else if (token.type === 'event') {
Tim van der Lippe9b2f8712020-02-12 17:46:221745 text = Common.UIString.UIString('<some> event');
Tim van der Lippe1d6e57a2019-09-30 11:55:341746 } else if (token.type === 'milestone') {
Tim van der Lippe9b2f8712020-02-12 17:46:221747 text = Common.UIString.UIString(' M<XX>');
Tim van der Lippe1d6e57a2019-09-30 11:55:341748 } else if (token.type === 'autofill') {
Tim van der Lippe9b2f8712020-02-12 17:46:221749 text = Common.UIString.UIString('<attribute>');
Tim van der Lippe1d6e57a2019-09-30 11:55:341750 }
Blink Reformat4c46d092018-04-07 15:32:371751 return acc + text;
1752 }, '');
1753 return result.replace(/[%]o/g, '');
1754 }
Paul Lewisbf7aa3c2019-11-20 17:03:381755}
Blink Reformat4c46d092018-04-07 15:32:371756
1757/**
1758 * @unrestricted
1759 */
Paul Lewisbf7aa3c2019-11-20 17:03:381760export class ConsoleGroupViewMessage extends ConsoleViewMessage {
Blink Reformat4c46d092018-04-07 15:32:371761 /**
Tim van der Lippe9b2f8712020-02-12 17:46:221762 * @param {!SDK.ConsoleModel.ConsoleMessage} consoleMessage
1763 * @param {!Components.Linkifier.Linkifier} linkifier
Blink Reformat4c46d092018-04-07 15:32:371764 * @param {number} nestingLevel
Erik Luo8ef5d0c2018-09-25 21:16:001765 * @param {function()} onToggle
Tim van der Lippec02a97c2020-02-14 14:39:271766 * @param {function(!Common.EventTarget.EventTargetEvent)} onResize
Blink Reformat4c46d092018-04-07 15:32:371767 */
Tim van der Lippeb45d9a02019-11-05 17:24:411768 constructor(consoleMessage, linkifier, nestingLevel, onToggle, onResize) {
Blink Reformat4c46d092018-04-07 15:32:371769 console.assert(consoleMessage.isGroupStartMessage());
Tim van der Lippeb45d9a02019-11-05 17:24:411770 super(consoleMessage, linkifier, nestingLevel, onResize);
Tim van der Lippe9b2f8712020-02-12 17:46:221771 this._collapsed = consoleMessage.type === SDK.ConsoleModel.MessageType.StartGroupCollapsed;
1772 /** @type {?UI.Icon.Icon} */
Blink Reformat4c46d092018-04-07 15:32:371773 this._expandGroupIcon = null;
Erik Luo8ef5d0c2018-09-25 21:16:001774 this._onToggle = onToggle;
Blink Reformat4c46d092018-04-07 15:32:371775 }
1776
1777 /**
1778 * @param {boolean} collapsed
1779 */
Erik Luo8ef5d0c2018-09-25 21:16:001780 _setCollapsed(collapsed) {
Blink Reformat4c46d092018-04-07 15:32:371781 this._collapsed = collapsed;
Tim van der Lippe1d6e57a2019-09-30 11:55:341782 if (this._expandGroupIcon) {
Blink Reformat4c46d092018-04-07 15:32:371783 this._expandGroupIcon.setIconType(this._collapsed ? 'smallicon-triangle-right' : 'smallicon-triangle-down');
Tim van der Lippe1d6e57a2019-09-30 11:55:341784 }
Erik Luo8ef5d0c2018-09-25 21:16:001785 this._onToggle.call(null);
Blink Reformat4c46d092018-04-07 15:32:371786 }
1787
1788 /**
1789 * @return {boolean}
1790 */
1791 collapsed() {
1792 return this._collapsed;
1793 }
1794
1795 /**
1796 * @override
Erik Luo8ef5d0c2018-09-25 21:16:001797 * @param {!Event} event
1798 */
1799 maybeHandleOnKeyDown(event) {
Erik Luo0b8282e2018-10-08 20:37:461800 const focusedChildIndex = this._focusedChildIndex();
1801 if (focusedChildIndex === -1) {
1802 if ((event.key === 'ArrowLeft' && !this._collapsed) || (event.key === 'ArrowRight' && this._collapsed)) {
1803 this._setCollapsed(!this._collapsed);
1804 return true;
1805 }
Erik Luo8ef5d0c2018-09-25 21:16:001806 }
1807 return super.maybeHandleOnKeyDown(event);
1808 }
1809
1810 /**
1811 * @override
Sigurd Schneider53f33522020-10-08 15:00:491812 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:371813 */
1814 toMessageElement() {
1815 if (!this._element) {
1816 super.toMessageElement();
Erik Luo8ef5d0c2018-09-25 21:16:001817 const iconType = this._collapsed ? 'smallicon-triangle-right' : 'smallicon-triangle-down';
Tim van der Lippe9b2f8712020-02-12 17:46:221818 this._expandGroupIcon = UI.Icon.Icon.create(iconType, 'expand-group-icon');
Erik Luob5bfff42018-09-20 02:52:391819 // Intercept focus to avoid highlight on click.
1820 this._contentElement.tabIndex = -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341821 if (this._repeatCountElement) {
Blink Reformat4c46d092018-04-07 15:32:371822 this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341823 } else {
Blink Reformat4c46d092018-04-07 15:32:371824 this._element.insertBefore(this._expandGroupIcon, this._contentElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:341825 }
Erik Luo8ef5d0c2018-09-25 21:16:001826 this._element.addEventListener('click', () => this._setCollapsed(!this._collapsed));
Blink Reformat4c46d092018-04-07 15:32:371827 }
1828 return this._element;
1829 }
1830
1831 /**
1832 * @override
1833 */
1834 _showRepeatCountElement() {
1835 super._showRepeatCountElement();
Tim van der Lippe1d6e57a2019-09-30 11:55:341836 if (this._repeatCountElement && this._expandGroupIcon) {
Blink Reformat4c46d092018-04-07 15:32:371837 this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341838 }
Blink Reformat4c46d092018-04-07 15:32:371839 }
Paul Lewisbf7aa3c2019-11-20 17:03:381840}
Blink Reformat4c46d092018-04-07 15:32:371841
1842/**
1843 * @const
1844 * @type {number}
1845 */
Paul Lewisbf7aa3c2019-11-20 17:03:381846export const MaxLengthForLinks = 40;
Blink Reformat4c46d092018-04-07 15:32:371847
Paul Lewisbf7aa3c2019-11-20 17:03:381848export const _MaxTokenizableStringLength = 10000;
1849export const _LongStringVisibleLength = 5000;