blob: d25c6588aebf6db2855867d75324ef91897caf06 [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
Tim van der Lippe9b2f8712020-02-12 17:46:2231import * as Common from '../common/common.js';
32import * as Components from '../components/components.js';
33import * as DataGrid from '../data_grid/data_grid.js';
34import * as ObjectUI from '../object_ui/object_ui.js';
Tim van der Lippe93b57c32020-02-20 17:38:4435import * as Platform from '../platform/platform.js';
Tim van der Lippe9b2f8712020-02-12 17:46:2236import * as SDK from '../sdk/sdk.js';
37import * as TextUtils from '../text_utils/text_utils.js';
Paul Lewisca569a52020-09-09 16:11:5138import * as ThemeSupport from '../theme_support/theme_support.js';
Tim van der Lippe9b2f8712020-02-12 17:46:2239import * as UI from '../ui/ui.js';
40
Tim van der Lippeeaacb722020-01-10 12:16:0041import {ConsoleViewportElement} from './ConsoleViewport.js'; // eslint-disable-line no-unused-vars
42
Sigurd Schneiderca7b4ff2020-10-14 07:45:4743/** @type {!WeakMap<!Element, !ConsoleViewMessage>} */
44const elementToMessage = new WeakMap();
45
46/**
47 * @param {!Element} element
48 */
49export const getMessageForElement = element => {
50 return elementToMessage.get(element);
51};
52
Sigurd Schneider8bfb4212020-10-27 10:27:3753// This value reflects the 18px min-height of .console-message, plus the
54// 1px border of .console-message-wrapper. Keep in sync with consoleView.css.
55const defaultConsoleRowHeight = 19;
56
57/**
58 * @param {?SDK.RuntimeModel.RuntimeModel} runtimeModel
59 */
60const parameterToRemoteObject = runtimeModel =>
61 /**
62 * @param {!SDK.RemoteObject.RemoteObject|!Protocol.Runtime.RemoteObject|string|undefined} parameter
63 * @return {!SDK.RemoteObject.RemoteObject}
64 */
65 parameter => {
66 if (parameter instanceof SDK.RemoteObject.RemoteObject) {
67 return parameter;
68 }
69 if (!runtimeModel) {
70 return SDK.RemoteObject.RemoteObject.fromLocalObject(parameter);
71 }
72 if (typeof parameter === 'object') {
73 return runtimeModel.createRemoteObject(parameter);
74 }
75 return runtimeModel.createRemoteObjectFromPrimitiveValue(parameter);
76 };
77
Blink Reformat4c46d092018-04-07 15:32:3778/**
Tim van der Lippeeaacb722020-01-10 12:16:0079 * @implements {ConsoleViewportElement}
Blink Reformat4c46d092018-04-07 15:32:3780 */
Tim van der Lippeeaacb722020-01-10 12:16:0081export class ConsoleViewMessage {
Blink Reformat4c46d092018-04-07 15:32:3782 /**
Tim van der Lippe9b2f8712020-02-12 17:46:2283 * @param {!SDK.ConsoleModel.ConsoleMessage} consoleMessage
84 * @param {!Components.Linkifier.Linkifier} linkifier
Blink Reformat4c46d092018-04-07 15:32:3785 * @param {number} nestingLevel
Sigurd Schneider45f32c32020-10-13 13:32:0586 * @param {function(!Common.EventTarget.EventTargetEvent): void} onResize
Blink Reformat4c46d092018-04-07 15:32:3787 */
Tim van der Lippeb45d9a02019-11-05 17:24:4188 constructor(consoleMessage, linkifier, nestingLevel, onResize) {
Blink Reformat4c46d092018-04-07 15:32:3789 this._message = consoleMessage;
90 this._linkifier = linkifier;
Blink Reformat4c46d092018-04-07 15:32:3791 this._repeatCount = 1;
92 this._closeGroupDecorationCount = 0;
93 this._nestingLevel = nestingLevel;
Sigurd Schneider45f32c32020-10-13 13:32:0594 /** @type {!Array<{element: !HTMLElement, forceSelect: function():void}>} */
Erik Luo383f21d2018-11-07 23:16:3795 this._selectableChildren = [];
Erik Luo840be6b2018-12-03 20:54:2796 this._messageResized = onResize;
Sigurd Schneider53e98632020-10-26 15:29:5097 /** @type {?HTMLElement} */
98 this._element = null;
Blink Reformat4c46d092018-04-07 15:32:3799
Tim van der Lippe9b2f8712020-02-12 17:46:22100 this._previewFormatter = new ObjectUI.RemoteObjectPreviewFormatter.RemoteObjectPreviewFormatter();
Blink Reformat4c46d092018-04-07 15:32:37101 this._searchRegex = null;
Tim van der Lippe9b2f8712020-02-12 17:46:22102 /** @type {?UI.Icon.Icon} */
Blink Reformat4c46d092018-04-07 15:32:37103 this._messageLevelIcon = null;
Erik Luo8ef5d0c2018-09-25 21:16:00104 this._traceExpanded = false;
Sigurd Schneider45f32c32020-10-13 13:32:05105 /** @type {?function(boolean):void} */
Erik Luo8ef5d0c2018-09-25 21:16:00106 this._expandTrace = null;
Sigurd Schneider53f33522020-10-08 15:00:49107 /** @type {?HTMLElement} */
John Emaubb2897a2019-10-04 17:37:32108 this._anchorElement = null;
Sigurd Schneider45f32c32020-10-13 13:32:05109 /** @type {?HTMLElement} */
110 this._contentElement = null;
111 /** @type {?Array<!HTMLElement>} */
112 this._nestingLevelMarkers = null;
113 /** @type {!Array<!Element>} */
114 this._searchHighlightNodes = [];
Sigurd Schneidere8e75cf2020-10-13 08:17:52115 /** @type {!Array<!UI.UIUtils.HighlightChange>} */
116 this._searchHighlightNodeChanges = [];
Sigurd Schneider53e98632020-10-26 15:29:50117 this._isVisible = false;
118 this._cachedHeight = 0;
119 this._messagePrefix = '';
120 /** @type {?HTMLElement} */
121 this._timestampElement = null;
122 this._inSimilarGroup = false;
123 /** @type {?HTMLElement} */
124 this._similarGroupMarker = null;
125 this._lastInSimilarGroup = false;
126 this._groupKey = '';
127 /** @type {?UI.UIUtils.DevToolsSmallBubble} */
128 this._repeatCountElement = null;
Blink Reformat4c46d092018-04-07 15:32:37129 }
130
131 /**
132 * @override
Sigurd Schneider53f33522020-10-08 15:00:49133 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37134 */
135 element() {
136 return this.toMessageElement();
137 }
138
139 /**
Blink Reformat4c46d092018-04-07 15:32:37140 * @override
141 */
142 wasShown() {
Blink Reformat4c46d092018-04-07 15:32:37143 this._isVisible = true;
144 }
145
146 onResize() {
Blink Reformat4c46d092018-04-07 15:32:37147 }
148
149 /**
150 * @override
151 */
152 willHide() {
153 this._isVisible = false;
Erik Luo4b002322018-07-30 21:23:31154 this._cachedHeight = this.element().offsetHeight;
Blink Reformat4c46d092018-04-07 15:32:37155 }
156
Sigurd Schneider8bfb4212020-10-27 10:27:37157 isVisible() {
158 return this._isVisible;
159 }
160
Blink Reformat4c46d092018-04-07 15:32:37161 /**
162 * @return {number}
163 */
164 fastHeight() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34165 if (this._cachedHeight) {
Blink Reformat4c46d092018-04-07 15:32:37166 return this._cachedHeight;
Tim van der Lippe1d6e57a2019-09-30 11:55:34167 }
Sigurd Schneider8bfb4212020-10-27 10:27:37168 return this.approximateFastHeight();
169 }
170
171 approximateFastHeight() {
Blink Reformat4c46d092018-04-07 15:32:37172 return defaultConsoleRowHeight;
173 }
174
175 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22176 * @return {!SDK.ConsoleModel.ConsoleMessage}
Blink Reformat4c46d092018-04-07 15:32:37177 */
178 consoleMessage() {
179 return this._message;
180 }
181
182 /**
Sigurd Schneider53f33522020-10-08 15:00:49183 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37184 */
Blink Reformat4c46d092018-04-07 15:32:37185 _buildMessage() {
186 let messageElement;
187 let messageText = this._message.messageText;
Tim van der Lippe9b2f8712020-02-12 17:46:22188 if (this._message.source === SDK.ConsoleModel.MessageSource.ConsoleAPI) {
Blink Reformat4c46d092018-04-07 15:32:37189 switch (this._message.type) {
Tim van der Lippe9b2f8712020-02-12 17:46:22190 case SDK.ConsoleModel.MessageType.Trace:
Blink Reformat4c46d092018-04-07 15:32:37191 messageElement = this._format(this._message.parameters || ['console.trace']);
192 break;
Tim van der Lippe9b2f8712020-02-12 17:46:22193 case SDK.ConsoleModel.MessageType.Clear:
Tim van der Lippef49e2322020-05-01 15:03:09194 messageElement = document.createElement('span');
195 messageElement.classList.add('console-info');
Paul Lewis2d7d65c2020-03-16 17:26:30196 if (Common.Settings.Settings.instance().moduleSetting('preserveConsoleLog').get()) {
Tim van der Lippe9b2f8712020-02-12 17:46:22197 messageElement.textContent =
198 Common.UIString.UIString('console.clear() was prevented due to \'Preserve log\'');
Tim van der Lippe1d6e57a2019-09-30 11:55:34199 } else {
Tim van der Lippe9b2f8712020-02-12 17:46:22200 messageElement.textContent = Common.UIString.UIString('Console was cleared');
Tim van der Lippe1d6e57a2019-09-30 11:55:34201 }
Tim van der Lippe9c9fb122020-09-08 15:06:17202 messageElement.title = ls`Clear all messages with ${
203 UI.ShortcutRegistry.ShortcutRegistry.instance().shortcutTitleForAction('console.clear')}`;
Blink Reformat4c46d092018-04-07 15:32:37204 break;
Tim van der Lippe9b2f8712020-02-12 17:46:22205 case SDK.ConsoleModel.MessageType.Dir: {
Blink Reformat4c46d092018-04-07 15:32:37206 const obj = this._message.parameters ? this._message.parameters[0] : undefined;
207 const args = ['%O', obj];
208 messageElement = this._format(args);
209 break;
210 }
Tim van der Lippe9b2f8712020-02-12 17:46:22211 case SDK.ConsoleModel.MessageType.Profile:
212 case SDK.ConsoleModel.MessageType.ProfileEnd:
Blink Reformat4c46d092018-04-07 15:32:37213 messageElement = this._format([messageText]);
214 break;
Blink Reformat4c46d092018-04-07 15:32:37215 default: {
Sigurd Schneider45f32c32020-10-13 13:32:05216 if (this._message.type === SDK.ConsoleModel.MessageType.Assert) {
217 this._messagePrefix = ls`Assertion failed: `;
218 }
219 if (this._message.parameters && this._message.parameters.length === 1) {
220 const parameter = this._message.parameters[0];
221 if (typeof parameter !== 'string' && parameter.type === 'string') {
222 messageElement = this._tryFormatAsError(/** @type {string} */ (parameter.value));
223 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34224 }
Blink Reformat4c46d092018-04-07 15:32:37225 const args = this._message.parameters || [messageText];
226 messageElement = messageElement || this._format(args);
227 }
228 }
229 } else {
Tim van der Lippe9b2f8712020-02-12 17:46:22230 if (this._message.source === SDK.ConsoleModel.MessageSource.Network) {
Erik Luofc2214f2018-11-21 19:54:58231 messageElement = this._formatAsNetworkRequest() || this._format([messageText]);
232 } else {
Blink Reformat4c46d092018-04-07 15:32:37233 const messageInParameters =
234 this._message.parameters && messageText === /** @type {string} */ (this._message.parameters[0]);
Tim van der Lippe9b2f8712020-02-12 17:46:22235 if (this._message.source === SDK.ConsoleModel.MessageSource.Violation) {
236 messageText = Common.UIString.UIString('[Violation] %s', messageText);
237 } else if (this._message.source === SDK.ConsoleModel.MessageSource.Intervention) {
238 messageText = Common.UIString.UIString('[Intervention] %s', messageText);
239 } else if (this._message.source === SDK.ConsoleModel.MessageSource.Deprecation) {
240 messageText = Common.UIString.UIString('[Deprecation] %s', messageText);
Tim van der Lippe1d6e57a2019-09-30 11:55:34241 }
Blink Reformat4c46d092018-04-07 15:32:37242 const args = this._message.parameters || [messageText];
Tim van der Lippe1d6e57a2019-09-30 11:55:34243 if (messageInParameters) {
Blink Reformat4c46d092018-04-07 15:32:37244 args[0] = messageText;
Tim van der Lippe1d6e57a2019-09-30 11:55:34245 }
Blink Reformat4c46d092018-04-07 15:32:37246 messageElement = this._format(args);
247 }
248 }
249 messageElement.classList.add('console-message-text');
250
Sigurd Schneider53f33522020-10-08 15:00:49251 const formattedMessage = /** @type {!HTMLElement} */ (document.createElement('span'));
Tim van der Lippef49e2322020-05-01 15:03:09252 formattedMessage.classList.add('source-code');
Erik Luo5976c8c2018-07-24 02:03:09253 this._anchorElement = this._buildMessageAnchor();
Tim van der Lippe1d6e57a2019-09-30 11:55:34254 if (this._anchorElement) {
Erik Luo5976c8c2018-07-24 02:03:09255 formattedMessage.appendChild(this._anchorElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34256 }
Blink Reformat4c46d092018-04-07 15:32:37257 formattedMessage.appendChild(messageElement);
258 return formattedMessage;
259 }
260
261 /**
Sigurd Schneider53f33522020-10-08 15:00:49262 * @return {?HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37263 */
Erik Luofc2214f2018-11-21 19:54:58264 _formatAsNetworkRequest() {
Tim van der Lippe9b2f8712020-02-12 17:46:22265 const request = SDK.NetworkLog.NetworkLog.requestForConsoleMessage(this._message);
Tim van der Lippe1d6e57a2019-09-30 11:55:34266 if (!request) {
Erik Luofc2214f2018-11-21 19:54:58267 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34268 }
Sigurd Schneider53f33522020-10-08 15:00:49269 const messageElement = /** @type {!HTMLElement} */ (document.createElement('span'));
Tim van der Lippe9b2f8712020-02-12 17:46:22270 if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Sigurd Schneider23c52972020-10-13 09:31:14271 UI.UIUtils.createTextChild(messageElement, request.requestMethod + ' ');
Tim van der Lippe9b2f8712020-02-12 17:46:22272 const linkElement = Components.Linkifier.Linkifier.linkifyRevealable(request, request.url(), request.url());
Erik Luo182bece2018-11-29 03:15:22273 // Focus is handled by the viewport.
274 linkElement.tabIndex = -1;
Erik Luo31c21f62018-12-13 03:39:39275 this._selectableChildren.push({element: linkElement, forceSelect: () => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22276 messageElement.appendChild(linkElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34277 if (request.failed) {
Sigurd Schneider23c52972020-10-13 09:31:14278 UI.UIUtils.createTextChildren(messageElement, ' ', request.localizedFailDescription || '');
Tim van der Lippe1d6e57a2019-09-30 11:55:34279 }
280 if (request.statusCode !== 0) {
Sigurd Schneider23c52972020-10-13 09:31:14281 UI.UIUtils.createTextChildren(messageElement, ' ', String(request.statusCode));
Tim van der Lippe1d6e57a2019-09-30 11:55:34282 }
283 if (request.statusText) {
Sigurd Schneider23c52972020-10-13 09:31:14284 UI.UIUtils.createTextChildren(messageElement, ' (', request.statusText, ')');
Tim van der Lippe1d6e57a2019-09-30 11:55:34285 }
Erik Luofc2214f2018-11-21 19:54:58286 } else {
Erik Luoad5f3942019-03-26 20:53:44287 const messageText = this._message.messageText;
288 const fragment = this._linkifyWithCustomLinkifier(messageText, (text, url, lineNumber, columnNumber) => {
Sigurd Schneider45f32c32020-10-13 13:32:05289 const linkElement = url === request.url() ?
290 Components.Linkifier.Linkifier.linkifyRevealable(
291 /** @type {!SDK.NetworkRequest.NetworkRequest} */ (request), url, request.url()) :
292 Components.Linkifier.Linkifier.linkifyURL(
293 url, /** @type {!Components.Linkifier.LinkifyURLOptions} */ ({text, lineNumber, columnNumber}));
Erik Luo182bece2018-11-29 03:15:22294 linkElement.tabIndex = -1;
Erik Luo31c21f62018-12-13 03:39:39295 this._selectableChildren.push({element: linkElement, forceSelect: () => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22296 return linkElement;
297 });
Erik Luofc2214f2018-11-21 19:54:58298 messageElement.appendChild(fragment);
299 }
300 return messageElement;
301 }
302
303 /**
Sigurd Schneider53f33522020-10-08 15:00:49304 * @return {?HTMLElement}
Erik Luofc2214f2018-11-21 19:54:58305 */
Blink Reformat4c46d092018-04-07 15:32:37306 _buildMessageAnchor() {
Sigurd Schneider45f32c32020-10-13 13:32:05307 /**
308 * @param {!SDK.ConsoleModel.ConsoleMessage} message
309 * @return {?HTMLElement}
310 */
311 const linkify = message => {
312 if (message.scriptId) {
313 return this._linkifyScriptId(message.scriptId, message.url || '', message.line, message.column);
314 }
315 if (message.stackTrace && message.stackTrace.callFrames.length) {
316 return this._linkifyStackTraceTopFrame(message.stackTrace);
317 }
318 if (message.url && message.url !== 'undefined') {
319 return this._linkifyLocation(message.url, message.line, message.column);
320 }
321 return null;
322 };
323 const anchorElement = linkify(this._message);
Blink Reformat4c46d092018-04-07 15:32:37324 // Append a space to prevent the anchor text from being glued to the console message when the user selects and copies the console messages.
325 if (anchorElement) {
John Emauf7e30fb2019-10-04 19:12:32326 anchorElement.tabIndex = -1;
327 this._selectableChildren.push({
328 element: anchorElement,
329 forceSelect: () => anchorElement.focus(),
330 });
Sigurd Schneider53f33522020-10-08 15:00:49331 const anchorWrapperElement = /** @type {!HTMLElement} */ (document.createElement('span'));
Tim van der Lippef49e2322020-05-01 15:03:09332 anchorWrapperElement.classList.add('console-message-anchor');
Blink Reformat4c46d092018-04-07 15:32:37333 anchorWrapperElement.appendChild(anchorElement);
Sigurd Schneider23c52972020-10-13 09:31:14334 UI.UIUtils.createTextChild(anchorWrapperElement, ' ');
Blink Reformat4c46d092018-04-07 15:32:37335 return anchorWrapperElement;
336 }
337 return null;
338 }
339
340 /**
Sigurd Schneider45f32c32020-10-13 13:32:05341 * @param {!SDK.RuntimeModel.RuntimeModel} runtimeModel
Sigurd Schneider53f33522020-10-08 15:00:49342 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37343 */
Sigurd Schneider45f32c32020-10-13 13:32:05344 _buildMessageWithStackTrace(runtimeModel) {
Sigurd Schneider53f33522020-10-08 15:00:49345 const toggleElement = /** @type {!HTMLElement} */ (document.createElement('div'));
Tim van der Lippef49e2322020-05-01 15:03:09346 toggleElement.classList.add('console-message-stack-trace-toggle');
Blink Reformat4c46d092018-04-07 15:32:37347 const contentElement = toggleElement.createChild('div', 'console-message-stack-trace-wrapper');
348
349 const messageElement = this._buildMessage();
Tim van der Lippe9b2f8712020-02-12 17:46:22350 const icon = UI.Icon.Icon.create('smallicon-triangle-right', 'console-message-expand-icon');
Blink Reformat4c46d092018-04-07 15:32:37351 const clickableElement = contentElement.createChild('div');
352 clickableElement.appendChild(icon);
Erik Luob5bfff42018-09-20 02:52:39353 // Intercept focus to avoid highlight on click.
354 clickableElement.tabIndex = -1;
Blink Reformat4c46d092018-04-07 15:32:37355 clickableElement.appendChild(messageElement);
356 const stackTraceElement = contentElement.createChild('div');
357 const stackTracePreview = Components.JSPresentationUtils.buildStackTracePreviewContents(
Sigurd Schneider45f32c32020-10-13 13:32:05358 runtimeModel.target(), this._linkifier,
359 {stackTrace: this._message.stackTrace, contentUpdated: undefined, tabStops: undefined});
Erik Luo182bece2018-11-29 03:15:22360 stackTraceElement.appendChild(stackTracePreview.element);
361 for (const linkElement of stackTracePreview.links) {
Erik Luo31c21f62018-12-13 03:39:39362 this._selectableChildren.push({element: linkElement, forceSelect: () => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22363 }
Blink Reformat4c46d092018-04-07 15:32:37364 stackTraceElement.classList.add('hidden');
Brandon Goddard04a5a762019-12-10 16:45:53365 UI.ARIAUtils.markAsTreeitem(this.element());
366 UI.ARIAUtils.setExpanded(this.element(), false);
Erik Luo8ef5d0c2018-09-25 21:16:00367 this._expandTrace = expand => {
Blink Reformat4c46d092018-04-07 15:32:37368 icon.setIconType(expand ? 'smallicon-triangle-down' : 'smallicon-triangle-right');
369 stackTraceElement.classList.toggle('hidden', !expand);
Brandon Goddard04a5a762019-12-10 16:45:53370 UI.ARIAUtils.setExpanded(this.element(), expand);
Erik Luo8ef5d0c2018-09-25 21:16:00371 this._traceExpanded = expand;
372 };
Blink Reformat4c46d092018-04-07 15:32:37373
374 /**
Tim van der Lippeeaacb722020-01-10 12:16:00375 * @this {!ConsoleViewMessage}
Sigurd Schneider45f32c32020-10-13 13:32:05376 * @param {!Event} event
Blink Reformat4c46d092018-04-07 15:32:37377 */
Sigurd Schneider45f32c32020-10-13 13:32:05378 const toggleStackTrace = event => {
Tim van der Lippe9b2f8712020-02-12 17:46:22379 if (UI.UIUtils.isEditing() || contentElement.hasSelection()) {
Blink Reformat4c46d092018-04-07 15:32:37380 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34381 }
Sigurd Schneider45f32c32020-10-13 13:32:05382 this._expandTrace && this._expandTrace(stackTraceElement.classList.contains('hidden'));
Blink Reformat4c46d092018-04-07 15:32:37383 event.consume();
Sigurd Schneider45f32c32020-10-13 13:32:05384 };
Blink Reformat4c46d092018-04-07 15:32:37385
Sigurd Schneider45f32c32020-10-13 13:32:05386 clickableElement.addEventListener('click', toggleStackTrace, false);
Tim van der Lippe9b2f8712020-02-12 17:46:22387 if (this._message.type === SDK.ConsoleModel.MessageType.Trace) {
Erik Luo8ef5d0c2018-09-25 21:16:00388 this._expandTrace(true);
Tim van der Lippe1d6e57a2019-09-30 11:55:34389 }
Blink Reformat4c46d092018-04-07 15:32:37390
Sigurd Schneider45f32c32020-10-13 13:32:05391 // @ts-ignore
Erik Luo8ef5d0c2018-09-25 21:16:00392 toggleElement._expandStackTraceForTest = this._expandTrace.bind(this, true);
Blink Reformat4c46d092018-04-07 15:32:37393 return toggleElement;
394 }
395
396 /**
397 * @param {string} url
398 * @param {number} lineNumber
399 * @param {number} columnNumber
Sigurd Schneider53f33522020-10-08 15:00:49400 * @return {?HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37401 */
402 _linkifyLocation(url, lineNumber, columnNumber) {
Sigurd Schneider45f32c32020-10-13 13:32:05403 const runtimeModel = this._message.runtimeModel();
404 if (!runtimeModel) {
Blink Reformat4c46d092018-04-07 15:32:37405 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34406 }
Blink Reformat4c46d092018-04-07 15:32:37407 return this._linkifier.linkifyScriptLocation(
Sigurd Schneider45f32c32020-10-13 13:32:05408 runtimeModel.target(), /* scriptId */ null, url, lineNumber,
409 {columnNumber, className: undefined, tabStop: undefined});
Blink Reformat4c46d092018-04-07 15:32:37410 }
411
412 /**
413 * @param {!Protocol.Runtime.StackTrace} stackTrace
Sigurd Schneider53f33522020-10-08 15:00:49414 * @return {?HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37415 */
416 _linkifyStackTraceTopFrame(stackTrace) {
Sigurd Schneider45f32c32020-10-13 13:32:05417 const runtimeModel = this._message.runtimeModel();
418 if (!runtimeModel) {
Blink Reformat4c46d092018-04-07 15:32:37419 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34420 }
Sigurd Schneider45f32c32020-10-13 13:32:05421 return this._linkifier.linkifyStackTraceTopFrame(runtimeModel.target(), stackTrace);
Blink Reformat4c46d092018-04-07 15:32:37422 }
423
424 /**
425 * @param {string} scriptId
426 * @param {string} url
427 * @param {number} lineNumber
428 * @param {number} columnNumber
Sigurd Schneider53f33522020-10-08 15:00:49429 * @return {?HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37430 */
431 _linkifyScriptId(scriptId, url, lineNumber, columnNumber) {
Sigurd Schneider45f32c32020-10-13 13:32:05432 const runtimeModel = this._message.runtimeModel();
433 if (!runtimeModel) {
Blink Reformat4c46d092018-04-07 15:32:37434 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34435 }
Blink Reformat4c46d092018-04-07 15:32:37436 return this._linkifier.linkifyScriptLocation(
Sigurd Schneider45f32c32020-10-13 13:32:05437 runtimeModel.target(), scriptId, url, lineNumber, {columnNumber, className: undefined, tabStop: undefined});
Blink Reformat4c46d092018-04-07 15:32:37438 }
439
440 /**
Sigurd Schneider45f32c32020-10-13 13:32:05441 * @param {!Array.<!Protocol.Runtime.RemoteObject | !SDK.RemoteObject.RemoteObject | string | undefined>} rawParameters
Sigurd Schneider53f33522020-10-08 15:00:49442 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37443 */
444 _format(rawParameters) {
445 // This node is used like a Builder. Values are continually appended onto it.
Sigurd Schneider53f33522020-10-08 15:00:49446 const formattedResult = /** @type {!HTMLElement} */ (document.createElement('span'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34447 if (this._messagePrefix) {
Pavel Feldman9f0f0a32018-12-18 02:09:13448 formattedResult.createChild('span').textContent = this._messagePrefix;
Tim van der Lippe1d6e57a2019-09-30 11:55:34449 }
450 if (!rawParameters.length) {
Blink Reformat4c46d092018-04-07 15:32:37451 return formattedResult;
Tim van der Lippe1d6e57a2019-09-30 11:55:34452 }
Blink Reformat4c46d092018-04-07 15:32:37453
454 // Formatting code below assumes that parameters are all wrappers whereas frontend console
455 // API allows passing arbitrary values as messages (strings, numbers, etc.). Wrap them here.
456 // FIXME: Only pass runtime wrappers here.
Sigurd Schneider8bfb4212020-10-27 10:27:37457 let parameters = rawParameters.map(parameterToRemoteObject(this._message.runtimeModel()));
Blink Reformat4c46d092018-04-07 15:32:37458
459 // There can be string log and string eval result. We distinguish between them based on message type.
460 const shouldFormatMessage =
Tim van der Lippe9b2f8712020-02-12 17:46:22461 SDK.RemoteObject.RemoteObject.type(
462 (/** @type {!Array.<!SDK.RemoteObject.RemoteObject>} **/ (parameters))[0]) === 'string' &&
463 (this._message.type !== SDK.ConsoleModel.MessageType.Result ||
464 this._message.level === SDK.ConsoleModel.MessageLevel.Error);
Blink Reformat4c46d092018-04-07 15:32:37465
466 // Multiple parameters with the first being a format string. Save unused substitutions.
467 if (shouldFormatMessage) {
468 const result = this._formatWithSubstitutionString(
469 /** @type {string} **/ (parameters[0].description), parameters.slice(1), formattedResult);
Sigurd Schneider45f32c32020-10-13 13:32:05470 parameters = Array.from(result.unusedSubstitutions || []);
Tim van der Lippe1d6e57a2019-09-30 11:55:34471 if (parameters.length) {
Sigurd Schneider23c52972020-10-13 09:31:14472 UI.UIUtils.createTextChild(formattedResult, ' ');
Tim van der Lippe1d6e57a2019-09-30 11:55:34473 }
Blink Reformat4c46d092018-04-07 15:32:37474 }
475
476 // Single parameter, or unused substitutions from above.
477 for (let i = 0; i < parameters.length; ++i) {
478 // Inline strings when formatting.
Tim van der Lippe1d6e57a2019-09-30 11:55:34479 if (shouldFormatMessage && parameters[i].type === 'string') {
Sigurd Schneider45f32c32020-10-13 13:32:05480 formattedResult.appendChild(this._linkifyStringAsFragment(parameters[i].description || ''));
Tim van der Lippe1d6e57a2019-09-30 11:55:34481 } else {
Blink Reformat4c46d092018-04-07 15:32:37482 formattedResult.appendChild(this._formatParameter(parameters[i], false, true));
Tim van der Lippe1d6e57a2019-09-30 11:55:34483 }
484 if (i < parameters.length - 1) {
Sigurd Schneider23c52972020-10-13 09:31:14485 UI.UIUtils.createTextChild(formattedResult, ' ');
Tim van der Lippe1d6e57a2019-09-30 11:55:34486 }
Blink Reformat4c46d092018-04-07 15:32:37487 }
488 return formattedResult;
489 }
490
491 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22492 * @param {!SDK.RemoteObject.RemoteObject} output
Blink Reformat4c46d092018-04-07 15:32:37493 * @param {boolean=} forceObjectFormat
494 * @param {boolean=} includePreview
Sigurd Schneider53f33522020-10-08 15:00:49495 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37496 */
497 _formatParameter(output, forceObjectFormat, includePreview) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34498 if (output.customPreview()) {
Sigurd Schneider53f33522020-10-08 15:00:49499 return /** @type {!HTMLElement} */ ((new ObjectUI.CustomPreviewComponent.CustomPreviewComponent(output)).element);
Tim van der Lippe1d6e57a2019-09-30 11:55:34500 }
Blink Reformat4c46d092018-04-07 15:32:37501
502 const type = forceObjectFormat ? 'object' : (output.subtype || output.type);
503 let element;
504 switch (type) {
505 case 'error':
506 element = this._formatParameterAsError(output);
507 break;
508 case 'function':
509 element = this._formatParameterAsFunction(output, includePreview);
510 break;
511 case 'array':
512 case 'arraybuffer':
513 case 'blob':
514 case 'dataview':
515 case 'generator':
516 case 'iterator':
517 case 'map':
518 case 'object':
519 case 'promise':
520 case 'proxy':
521 case 'set':
522 case 'typedarray':
523 case 'weakmap':
524 case 'weakset':
525 element = this._formatParameterAsObject(output, includePreview);
526 break;
527 case 'node':
528 element = output.isNode() ? this._formatParameterAsNode(output) : this._formatParameterAsObject(output, false);
529 break;
530 case 'string':
531 element = this._formatParameterAsString(output);
532 break;
533 case 'boolean':
534 case 'date':
535 case 'null':
536 case 'number':
537 case 'regexp':
538 case 'symbol':
539 case 'undefined':
540 case 'bigint':
541 element = this._formatParameterAsValue(output);
542 break;
543 default:
544 element = this._formatParameterAsValue(output);
545 console.error('Tried to format remote object of unknown type.');
546 }
547 element.classList.add('object-value-' + type);
548 element.classList.add('source-code');
549 return element;
550 }
551
552 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22553 * @param {!SDK.RemoteObject.RemoteObject} obj
Sigurd Schneider53f33522020-10-08 15:00:49554 * @return {!HTMLElement}
Tim van der Lippeeaacb722020-01-10 12:16:00555 * @suppress {accessControls}
Blink Reformat4c46d092018-04-07 15:32:37556 */
557 _formatParameterAsValue(obj) {
Sigurd Schneider53f33522020-10-08 15:00:49558 const result = /** @type {!HTMLElement} */ (document.createElement('span'));
Blink Reformat4c46d092018-04-07 15:32:37559 const description = obj.description || '';
Sigurd Schneider8f4ac862020-10-13 13:30:11560 if (description.length > getMaxTokenizableStringLength()) {
Tim van der Lippe9b2f8712020-02-12 17:46:22561 const propertyValue = new ObjectUI.ObjectPropertiesSection.ExpandableTextPropertyValue(
Sigurd Schneider8f4ac862020-10-13 13:30:11562 document.createElement('span'), description, getLongStringVisibleLength());
Connor Moody1a5c0d32019-12-19 07:23:36563 result.appendChild(propertyValue.element);
Tim van der Lippe1d6e57a2019-09-30 11:55:34564 } else {
Sigurd Schneider23c52972020-10-13 09:31:14565 UI.UIUtils.createTextChild(result, description);
Tim van der Lippe1d6e57a2019-09-30 11:55:34566 }
567 if (obj.objectId) {
Blink Reformat4c46d092018-04-07 15:32:37568 result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, obj), false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34569 }
Blink Reformat4c46d092018-04-07 15:32:37570 return result;
571 }
572
573 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22574 * @param {!SDK.RemoteObject.RemoteObject} obj
Blink Reformat4c46d092018-04-07 15:32:37575 * @param {boolean=} includePreview
Sigurd Schneider53f33522020-10-08 15:00:49576 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37577 */
578 _formatParameterAsObject(obj, includePreview) {
Sigurd Schneider53f33522020-10-08 15:00:49579 const titleElement = /** @type {!HTMLElement} */ (document.createElement('span'));
Tim van der Lippef49e2322020-05-01 15:03:09580 titleElement.classList.add('console-object');
Blink Reformat4c46d092018-04-07 15:32:37581 if (includePreview && obj.preview) {
582 titleElement.classList.add('console-object-preview');
583 this._previewFormatter.appendObjectPreview(titleElement, obj.preview, false /* isEntry */);
584 } else if (obj.type === 'function') {
585 const functionElement = titleElement.createChild('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22586 ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection.formatObjectAsFunction(obj, functionElement, false);
Blink Reformat4c46d092018-04-07 15:32:37587 titleElement.classList.add('object-value-function');
588 } else {
Sigurd Schneider23c52972020-10-13 09:31:14589 UI.UIUtils.createTextChild(titleElement, obj.description || '');
Blink Reformat4c46d092018-04-07 15:32:37590 }
591
Tim van der Lippe1d6e57a2019-09-30 11:55:34592 if (!obj.hasChildren || obj.customPreview()) {
Blink Reformat4c46d092018-04-07 15:32:37593 return titleElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:34594 }
Blink Reformat4c46d092018-04-07 15:32:37595
596 const note = titleElement.createChild('span', 'object-state-note info-note');
Tim van der Lippe9b2f8712020-02-12 17:46:22597 if (this._message.type === SDK.ConsoleModel.MessageType.QueryObjectResult) {
Blink Reformat4c46d092018-04-07 15:32:37598 note.title = ls`This value will not be collected until console is cleared.`;
Tim van der Lippe1d6e57a2019-09-30 11:55:34599 } else {
Blink Reformat4c46d092018-04-07 15:32:37600 note.title = ls`Value below was evaluated just now.`;
Tim van der Lippe1d6e57a2019-09-30 11:55:34601 }
Blink Reformat4c46d092018-04-07 15:32:37602
Tim van der Lippe9b2f8712020-02-12 17:46:22603 const section = new ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection(obj, titleElement, this._linkifier);
Blink Reformat4c46d092018-04-07 15:32:37604 section.element.classList.add('console-view-object-properties-section');
605 section.enableContextMenu();
Erik Luocc14b812018-11-03 01:33:09606 section.setShowSelectionOnKeyboardFocus(true, true);
Erik Luo383f21d2018-11-07 23:16:37607 this._selectableChildren.push(section);
Erik Luo840be6b2018-12-03 20:54:27608 section.addEventListener(UI.TreeOutline.Events.ElementAttached, this._messageResized);
609 section.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._messageResized);
610 section.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._messageResized);
Blink Reformat4c46d092018-04-07 15:32:37611 return section.element;
612 }
613
614 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22615 * @param {!SDK.RemoteObject.RemoteObject} func
Blink Reformat4c46d092018-04-07 15:32:37616 * @param {boolean=} includePreview
Sigurd Schneider53f33522020-10-08 15:00:49617 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37618 */
619 _formatParameterAsFunction(func, includePreview) {
Sigurd Schneider53f33522020-10-08 15:00:49620 const result = /** @type {!HTMLElement} */ (document.createElement('span'));
Tim van der Lippe9b2f8712020-02-12 17:46:22621 SDK.RemoteObject.RemoteFunction.objectAsFunction(func).targetFunction().then(formatTargetFunction.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37622 return result;
623
624 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22625 * @param {!SDK.RemoteObject.RemoteObject} targetFunction
Tim van der Lippeeaacb722020-01-10 12:16:00626 * @this {ConsoleViewMessage}
Blink Reformat4c46d092018-04-07 15:32:37627 */
628 function formatTargetFunction(targetFunction) {
Sigurd Schneider53f33522020-10-08 15:00:49629 const functionElement = document.createElement('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22630 const promise = ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection.formatObjectAsFunction(
Joey Arhard78a58f2018-12-05 01:59:45631 targetFunction, functionElement, true, includePreview);
Blink Reformat4c46d092018-04-07 15:32:37632 result.appendChild(functionElement);
633 if (targetFunction !== func) {
634 const note = result.createChild('span', 'object-info-state-note');
Tim van der Lippe9b2f8712020-02-12 17:46:22635 note.title = Common.UIString.UIString('Function was resolved from bound function.');
Blink Reformat4c46d092018-04-07 15:32:37636 }
637 result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, targetFunction), false);
Joey Arhard78a58f2018-12-05 01:59:45638 promise.then(() => this._formattedParameterAsFunctionForTest());
Blink Reformat4c46d092018-04-07 15:32:37639 }
640 }
641
Joey Arhard78a58f2018-12-05 01:59:45642 _formattedParameterAsFunctionForTest() {
643 }
644
Blink Reformat4c46d092018-04-07 15:32:37645 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22646 * @param {!SDK.RemoteObject.RemoteObject} obj
Blink Reformat4c46d092018-04-07 15:32:37647 * @param {!Event} event
648 */
649 _contextMenuEventFired(obj, event) {
Tim van der Lippe9b2f8712020-02-12 17:46:22650 const contextMenu = new UI.ContextMenu.ContextMenu(event);
Blink Reformat4c46d092018-04-07 15:32:37651 contextMenu.appendApplicableItems(obj);
652 contextMenu.show();
653 }
654
655 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22656 * @param {?SDK.RemoteObject.RemoteObject} object
Sigurd Schneider45f32c32020-10-13 13:32:05657 * @param {!Protocol.Runtime.PropertyPreview|!{name:(string|symbol), type: !Protocol.Runtime.PropertyPreviewType, value: (string|undefined)}} property
658 * @param {!Array.<!{name:(string|symbol)}>} propertyPath
Sigurd Schneider53f33522020-10-08 15:00:49659 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37660 */
Sigurd Schneider45f32c32020-10-13 13:32:05661 _renderPropertyPreviewOrAccessor(object, property, propertyPath) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34662 if (property.type === 'accessor') {
Sigurd Schneider45f32c32020-10-13 13:32:05663 return this._formatAsAccessorProperty(object, propertyPath.map(property => property.name.toString()), false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34664 }
Blink Reformat4c46d092018-04-07 15:32:37665 return this._previewFormatter.renderPropertyPreview(
Sigurd Schneider45f32c32020-10-13 13:32:05666 property.type, 'subtype' in property ? property.subtype : undefined, property.value);
Blink Reformat4c46d092018-04-07 15:32:37667 }
668
669 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22670 * @param {!SDK.RemoteObject.RemoteObject} remoteObject
Sigurd Schneider53f33522020-10-08 15:00:49671 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37672 */
673 _formatParameterAsNode(remoteObject) {
Sigurd Schneider53f33522020-10-08 15:00:49674 const result = /** @type {!HTMLElement} */ (document.createElement('span'));
Blink Reformat4c46d092018-04-07 15:32:37675
Tim van der Lippe9b2f8712020-02-12 17:46:22676 const domModel = remoteObject.runtimeModel().target().model(SDK.DOMModel.DOMModel);
Tim van der Lippe1d6e57a2019-09-30 11:55:34677 if (!domModel) {
Blink Reformat4c46d092018-04-07 15:32:37678 return result;
Tim van der Lippe1d6e57a2019-09-30 11:55:34679 }
Erik Luo54fdd912018-11-01 17:57:01680 domModel.pushObjectAsNodeToFrontend(remoteObject).then(async node => {
Blink Reformat4c46d092018-04-07 15:32:37681 if (!node) {
682 result.appendChild(this._formatParameterAsObject(remoteObject, false));
683 return;
684 }
Tim van der Lippe9b2f8712020-02-12 17:46:22685 const renderResult = await UI.UIUtils.Renderer.render(/** @type {!Object} */ (node));
Erik Luofc6a6302018-11-02 06:48:52686 if (renderResult) {
Erik Luo840be6b2018-12-03 20:54:27687 if (renderResult.tree) {
Erik Luo383f21d2018-11-07 23:16:37688 this._selectableChildren.push(renderResult.tree);
Erik Luo840be6b2018-12-03 20:54:27689 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementAttached, this._messageResized);
690 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._messageResized);
691 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._messageResized);
692 }
Erik Luofc6a6302018-11-02 06:48:52693 result.appendChild(renderResult.node);
694 } else {
695 result.appendChild(this._formatParameterAsObject(remoteObject, false));
696 }
Erik Luo54fdd912018-11-01 17:57:01697 this._formattedParameterAsNodeForTest();
Blink Reformat4c46d092018-04-07 15:32:37698 });
699
700 return result;
701 }
702
703 _formattedParameterAsNodeForTest() {
704 }
705
706 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22707 * @param {!SDK.RemoteObject.RemoteObject} output
Sigurd Schneider53f33522020-10-08 15:00:49708 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37709 */
710 _formatParameterAsString(output) {
Sigurd Schneider53f33522020-10-08 15:00:49711 const span = /** @type {!HTMLElement} */ (document.createElement('span'));
Erik Luo383f21d2018-11-07 23:16:37712 span.appendChild(this._linkifyStringAsFragment(output.description || ''));
Blink Reformat4c46d092018-04-07 15:32:37713
Sigurd Schneider53f33522020-10-08 15:00:49714 const result = /** @type {!HTMLElement} */ (document.createElement('span'));
Blink Reformat4c46d092018-04-07 15:32:37715 result.createChild('span', 'object-value-string-quote').textContent = '"';
716 result.appendChild(span);
717 result.createChild('span', 'object-value-string-quote').textContent = '"';
718 return result;
719 }
720
721 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22722 * @param {!SDK.RemoteObject.RemoteObject} output
Sigurd Schneider53f33522020-10-08 15:00:49723 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37724 */
725 _formatParameterAsError(output) {
Sigurd Schneider53f33522020-10-08 15:00:49726 const result = /** @type {!HTMLElement} */ (document.createElement('span'));
Blink Reformat4c46d092018-04-07 15:32:37727 const errorSpan = this._tryFormatAsError(output.description || '');
Erik Luo383f21d2018-11-07 23:16:37728 result.appendChild(errorSpan ? errorSpan : this._linkifyStringAsFragment(output.description || ''));
Blink Reformat4c46d092018-04-07 15:32:37729 return result;
730 }
731
732 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22733 * @param {!SDK.RemoteObject.RemoteObject} output
Sigurd Schneider53f33522020-10-08 15:00:49734 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37735 */
736 _formatAsArrayEntry(output) {
737 return this._previewFormatter.renderPropertyPreview(output.type, output.subtype, output.description);
738 }
739
740 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22741 * @param {?SDK.RemoteObject.RemoteObject} object
Blink Reformat4c46d092018-04-07 15:32:37742 * @param {!Array.<string>} propertyPath
743 * @param {boolean} isArrayEntry
Sigurd Schneider53f33522020-10-08 15:00:49744 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37745 */
746 _formatAsAccessorProperty(object, propertyPath, isArrayEntry) {
Tim van der Lippe9b2f8712020-02-12 17:46:22747 const rootElement =
748 ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan(
749 object, propertyPath, onInvokeGetterClick.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37750
751 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22752 * @param {!SDK.RemoteObject.CallFunctionResult} result
Tim van der Lippeeaacb722020-01-10 12:16:00753 * @this {ConsoleViewMessage}
Blink Reformat4c46d092018-04-07 15:32:37754 */
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18755 function onInvokeGetterClick(result) {
756 const wasThrown = result.wasThrown;
757 const object = result.object;
Tim van der Lippe1d6e57a2019-09-30 11:55:34758 if (!object) {
Blink Reformat4c46d092018-04-07 15:32:37759 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34760 }
Blink Reformat4c46d092018-04-07 15:32:37761 rootElement.removeChildren();
762 if (wasThrown) {
763 const element = rootElement.createChild('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22764 element.textContent = Common.UIString.UIString('<exception>');
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18765 element.title = /** @type {string} */ (object.description);
Blink Reformat4c46d092018-04-07 15:32:37766 } else if (isArrayEntry) {
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18767 rootElement.appendChild(this._formatAsArrayEntry(object));
Blink Reformat4c46d092018-04-07 15:32:37768 } else {
769 // Make a PropertyPreview from the RemoteObject similar to the backend logic.
770 const maxLength = 100;
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18771 const type = object.type;
772 const subtype = object.subtype;
Blink Reformat4c46d092018-04-07 15:32:37773 let description = '';
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18774 if (type !== 'function' && object.description) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34775 if (type === 'string' || subtype === 'regexp') {
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18776 description = object.description.trimMiddle(maxLength);
Tim van der Lippe1d6e57a2019-09-30 11:55:34777 } else {
Tim van der Lippeffa78622019-09-16 12:07:12778 description = object.description.trimEndWithMaxLength(maxLength);
Tim van der Lippe1d6e57a2019-09-30 11:55:34779 }
Blink Reformat4c46d092018-04-07 15:32:37780 }
781 rootElement.appendChild(this._previewFormatter.renderPropertyPreview(type, subtype, description));
782 }
783 }
784
785 return rootElement;
786 }
787
788 /**
789 * @param {string} format
Tim van der Lippe9b2f8712020-02-12 17:46:22790 * @param {!Array.<!SDK.RemoteObject.RemoteObject>} parameters
Sigurd Schneider53f33522020-10-08 15:00:49791 * @param {!HTMLElement} formattedResult
Sigurd Schneider45f32c32020-10-13 13:32:05792 * @return {!{formattedResult:!Element, unusedSubstitutions: ?ArrayLike<!SDK.RemoteObject.RemoteObject>}}
Blink Reformat4c46d092018-04-07 15:32:37793 */
794 _formatWithSubstitutionString(format, parameters, formattedResult) {
Blink Reformat4c46d092018-04-07 15:32:37795 /**
796 * @param {boolean} force
797 * @param {boolean} includePreview
Sigurd Schneider45f32c32020-10-13 13:32:05798 * @param {!SDK.RemoteObject.RemoteObject|string|{description:string}|undefined} obj
799 * @return {!HTMLElement|string|undefined}
Tim van der Lippeeaacb722020-01-10 12:16:00800 * @this {ConsoleViewMessage}
Blink Reformat4c46d092018-04-07 15:32:37801 */
802 function parameterFormatter(force, includePreview, obj) {
Sigurd Schneider45f32c32020-10-13 13:32:05803 if (obj instanceof SDK.RemoteObject.RemoteObject) {
804 return this._formatParameter(obj, force, includePreview);
805 }
806 return stringFormatter(obj);
Blink Reformat4c46d092018-04-07 15:32:37807 }
808
Sigurd Schneider45f32c32020-10-13 13:32:05809 /**
810 * @param {!SDK.RemoteObject.RemoteObject|string|{description:string}|undefined} obj
811 */
Blink Reformat4c46d092018-04-07 15:32:37812 function stringFormatter(obj) {
Sigurd Schneider45f32c32020-10-13 13:32:05813 if (obj === undefined) {
814 return undefined;
815 }
816 if (typeof obj === 'string') {
817 return obj;
818 }
Blink Reformat4c46d092018-04-07 15:32:37819 return obj.description;
820 }
821
Sigurd Schneider45f32c32020-10-13 13:32:05822 /**
823 * @param {!SDK.RemoteObject.RemoteObject|string|{description:string}|undefined} obj
824 */
Blink Reformat4c46d092018-04-07 15:32:37825 function floatFormatter(obj) {
Sigurd Schneider45f32c32020-10-13 13:32:05826 if (obj instanceof SDK.RemoteObject.RemoteObject) {
827 if (typeof obj.value !== 'number') {
828 return 'NaN';
829 }
830 return obj.value;
Tim van der Lippe1d6e57a2019-09-30 11:55:34831 }
Sigurd Schneider45f32c32020-10-13 13:32:05832 return undefined;
Blink Reformat4c46d092018-04-07 15:32:37833 }
834
Sigurd Schneider45f32c32020-10-13 13:32:05835 /**
836 * @param {!SDK.RemoteObject.RemoteObject|string|{description:string}|undefined} obj
837 */
Blink Reformat4c46d092018-04-07 15:32:37838 function integerFormatter(obj) {
Sigurd Schneider45f32c32020-10-13 13:32:05839 if (obj instanceof SDK.RemoteObject.RemoteObject) {
840 if (obj.type === 'bigint') {
841 return obj.description;
842 }
843 if (typeof obj.value !== 'number') {
844 return 'NaN';
845 }
846 return Math.floor(obj.value);
Tim van der Lippe1d6e57a2019-09-30 11:55:34847 }
Sigurd Schneider45f32c32020-10-13 13:32:05848 return undefined;
Blink Reformat4c46d092018-04-07 15:32:37849 }
850
Sigurd Schneider45f32c32020-10-13 13:32:05851 /**
852 * @param {!SDK.RemoteObject.RemoteObject|string|{description:string}|undefined} obj
853 */
Blink Reformat4c46d092018-04-07 15:32:37854 function bypassFormatter(obj) {
855 return (obj instanceof Node) ? obj : '';
856 }
857
Sigurd Schneider45f32c32020-10-13 13:32:05858 /** @type {?Map<string, !{value:string, priority:string}>} */
Blink Reformat4c46d092018-04-07 15:32:37859 let currentStyle = null;
Sigurd Schneider45f32c32020-10-13 13:32:05860 /**
861 * @param {!SDK.RemoteObject.RemoteObject|string|{description:string}|undefined} obj
862 */
Blink Reformat4c46d092018-04-07 15:32:37863 function styleFormatter(obj) {
Sigurd Schneider45f32c32020-10-13 13:32:05864 currentStyle = new Map();
Sigurd Schneider53f33522020-10-08 15:00:49865 const buffer = document.createElement('span');
Sigurd Schneider45f32c32020-10-13 13:32:05866 if (obj === undefined) {
867 return;
868 }
869 if (typeof obj === 'string' || !obj.description) {
870 return;
871 }
Blink Reformat4c46d092018-04-07 15:32:37872 buffer.setAttribute('style', obj.description);
Sigurd Schneider45f32c32020-10-13 13:32:05873 for (const property of buffer.style) {
Mathias Bynens5165a7a2020-06-10 05:51:43874 if (isAllowedProperty(property)) {
Sigurd Schneider45f32c32020-10-13 13:32:05875 const info = {
876 value: buffer.style.getPropertyValue(property),
877 priority: buffer.style.getPropertyPriority(property)
878 };
879 currentStyle.set(property, info);
Tim van der Lippe1d6e57a2019-09-30 11:55:34880 }
Blink Reformat4c46d092018-04-07 15:32:37881 }
882 }
883
Sigurd Schneider45f32c32020-10-13 13:32:05884 /**
885 * @param {string} property
886 */
Mathias Bynens5165a7a2020-06-10 05:51:43887 function isAllowedProperty(property) {
Blink Reformat4c46d092018-04-07 15:32:37888 // Make sure that allowed properties do not interfere with link visibility.
889 const prefixes = [
890 'background', 'border', 'color', 'font', 'line', 'margin', 'padding', 'text', '-webkit-background',
891 '-webkit-border', '-webkit-font', '-webkit-margin', '-webkit-padding', '-webkit-text'
892 ];
Sigurd Schneider45f32c32020-10-13 13:32:05893 for (const prefix of prefixes) {
894 if (property.startsWith(prefix)) {
Blink Reformat4c46d092018-04-07 15:32:37895 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:34896 }
Blink Reformat4c46d092018-04-07 15:32:37897 }
898 return false;
899 }
900
Sigurd Schneider45f32c32020-10-13 13:32:05901 /** @type {!Object.<string, function((string|!{description: string}|undefined|!SDK.RemoteObject.RemoteObject), !Platform.StringUtilities.FORMATTER_TOKEN):*>} */
902 const formatters = {};
Blink Reformat4c46d092018-04-07 15:32:37903 // Firebug uses %o for formatting objects.
904 formatters.o = parameterFormatter.bind(this, false /* force */, true /* includePreview */);
905 formatters.s = stringFormatter;
906 formatters.f = floatFormatter;
907 // Firebug allows both %i and %d for formatting integers.
908 formatters.i = integerFormatter;
909 formatters.d = integerFormatter;
910
911 // Firebug uses %c for styling the message.
912 formatters.c = styleFormatter;
913
914 // Support %O to force object formatting, instead of the type-based %o formatting.
915 formatters.O = parameterFormatter.bind(this, true /* force */, false /* includePreview */);
916
917 formatters._ = bypassFormatter;
918
919 /**
Sigurd Schneider53f33522020-10-08 15:00:49920 * @param {!HTMLElement} a
Blink Reformat4c46d092018-04-07 15:32:37921 * @param {*} b
Tim van der Lippeeaacb722020-01-10 12:16:00922 * @this {!ConsoleViewMessage}
Sigurd Schneider53f33522020-10-08 15:00:49923 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37924 */
925 function append(a, b) {
926 if (b instanceof Node) {
927 a.appendChild(b);
Erik Luo17926392018-05-17 22:06:12928 return a;
929 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34930 if (typeof b === 'undefined') {
Erik Luo17926392018-05-17 22:06:12931 return a;
Tim van der Lippe1d6e57a2019-09-30 11:55:34932 }
Erik Luo17926392018-05-17 22:06:12933 if (!currentStyle) {
Erik Luo383f21d2018-11-07 23:16:37934 a.appendChild(this._linkifyStringAsFragment(String(b)));
Erik Luo17926392018-05-17 22:06:12935 return a;
936 }
937 const lines = String(b).split('\n');
938 for (let i = 0; i < lines.length; i++) {
939 const line = lines[i];
Erik Luo383f21d2018-11-07 23:16:37940 const lineFragment = this._linkifyStringAsFragment(line);
Sigurd Schneider53f33522020-10-08 15:00:49941 const wrapper = /** @type {!HTMLElement} */ (document.createElement('span'));
Erik Luo17926392018-05-17 22:06:12942 wrapper.style.setProperty('contain', 'paint');
943 wrapper.style.setProperty('display', 'inline-block');
944 wrapper.style.setProperty('max-width', '100%');
945 wrapper.appendChild(lineFragment);
946 applyCurrentStyle(wrapper);
947 for (const child of wrapper.children) {
Sigurd Schneider53f33522020-10-08 15:00:49948 if (child.classList.contains('devtools-link') && child instanceof HTMLElement) {
Erik Luo17926392018-05-17 22:06:12949 this._applyForcedVisibleStyle(child);
Tim van der Lippe1d6e57a2019-09-30 11:55:34950 }
Blink Reformat4c46d092018-04-07 15:32:37951 }
Erik Luo17926392018-05-17 22:06:12952 a.appendChild(wrapper);
Tim van der Lippe1d6e57a2019-09-30 11:55:34953 if (i < lines.length - 1) {
Sigurd Schneider53f33522020-10-08 15:00:49954 a.appendChild(document.createElement('br'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34955 }
Blink Reformat4c46d092018-04-07 15:32:37956 }
957 return a;
958 }
959
960 /**
Sigurd Schneider53f33522020-10-08 15:00:49961 * @param {!HTMLElement} element
Blink Reformat4c46d092018-04-07 15:32:37962 */
963 function applyCurrentStyle(element) {
Sigurd Schneider45f32c32020-10-13 13:32:05964 if (!currentStyle) {
965 return;
966 }
967 for (const [property, {value, priority}] of currentStyle.entries()) {
968 element.style.setProperty(/** @type {string} */ (property), value, priority);
Tim van der Lippe1d6e57a2019-09-30 11:55:34969 }
Blink Reformat4c46d092018-04-07 15:32:37970 }
971
Tim van der Lippe93b57c32020-02-20 17:38:44972 // Platform.StringUtilities.format does treat formattedResult like a Builder, result is an object.
973 return Platform.StringUtilities.format(format, parameters, formatters, formattedResult, append.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37974 }
975
976 /**
Sigurd Schneider53f33522020-10-08 15:00:49977 * @param {!HTMLElement} element
Blink Reformat4c46d092018-04-07 15:32:37978 */
979 _applyForcedVisibleStyle(element) {
980 element.style.setProperty('-webkit-text-stroke', '0', 'important');
981 element.style.setProperty('text-decoration', 'underline', 'important');
982
Paul Lewisca569a52020-09-09 16:11:51983 const themedColor = ThemeSupport.ThemeSupport.instance().patchColorText(
984 'rgb(33%, 33%, 33%)', ThemeSupport.ThemeSupport.ColorUsage.Foreground);
Blink Reformat4c46d092018-04-07 15:32:37985 element.style.setProperty('color', themedColor, 'important');
986
987 let backgroundColor = 'hsl(0, 0%, 100%)';
Tim van der Lippe9b2f8712020-02-12 17:46:22988 if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Blink Reformat4c46d092018-04-07 15:32:37989 backgroundColor = 'hsl(0, 100%, 97%)';
Tim van der Lippe9b2f8712020-02-12 17:46:22990 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning || this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:37991 backgroundColor = 'hsl(50, 100%, 95%)';
Tim van der Lippe1d6e57a2019-09-30 11:55:34992 }
Paul Lewisca569a52020-09-09 16:11:51993 const themedBackgroundColor = ThemeSupport.ThemeSupport.instance().patchColorText(
994 backgroundColor, ThemeSupport.ThemeSupport.ColorUsage.Background);
Blink Reformat4c46d092018-04-07 15:32:37995 element.style.setProperty('background-color', themedBackgroundColor, 'important');
996 }
997
998 /**
Sigurd Schneider45f32c32020-10-13 13:32:05999 * @param {!RegExp} regexObject
Blink Reformat4c46d092018-04-07 15:32:371000 * @return {boolean}
1001 */
1002 matchesFilterRegex(regexObject) {
1003 regexObject.lastIndex = 0;
Erik Luo5976c8c2018-07-24 02:03:091004 const contentElement = this.contentElement();
1005 const anchorText = this._anchorElement ? this._anchorElement.deepTextContent() : '';
Sigurd Schneider45f32c32020-10-13 13:32:051006 return (!!anchorText && regexObject.test(anchorText.trim())) ||
Erik Luo5976c8c2018-07-24 02:03:091007 regexObject.test(contentElement.deepTextContent().slice(anchorText.length));
Blink Reformat4c46d092018-04-07 15:32:371008 }
1009
1010 /**
1011 * @param {string} filter
1012 * @return {boolean}
1013 */
1014 matchesFilterText(filter) {
1015 const text = this.contentElement().deepTextContent();
1016 return text.toLowerCase().includes(filter.toLowerCase());
1017 }
1018
1019 updateTimestamp() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341020 if (!this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371021 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341022 }
Blink Reformat4c46d092018-04-07 15:32:371023
Paul Lewis2d7d65c2020-03-16 17:26:301024 if (Common.Settings.Settings.instance().moduleSetting('consoleTimestampsEnabled').get()) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341025 if (!this._timestampElement) {
Sigurd Schneider53e98632020-10-26 15:29:501026 this._timestampElement = /** @type {!HTMLElement} */ (document.createElement('span'));
Tim van der Lippef49e2322020-05-01 15:03:091027 this._timestampElement.classList.add('console-timestamp');
Tim van der Lippe1d6e57a2019-09-30 11:55:341028 }
Tim van der Lippe9b2f8712020-02-12 17:46:221029 this._timestampElement.textContent = UI.UIUtils.formatTimestamp(this._message.timestamp, false) + ' ';
1030 this._timestampElement.title = UI.UIUtils.formatTimestamp(this._message.timestamp, true);
Blink Reformat4c46d092018-04-07 15:32:371031 this._contentElement.insertBefore(this._timestampElement, this._contentElement.firstChild);
1032 } else if (this._timestampElement) {
1033 this._timestampElement.remove();
Sigurd Schneider53e98632020-10-26 15:29:501034 this._timestampElement = null;
Blink Reformat4c46d092018-04-07 15:32:371035 }
Blink Reformat4c46d092018-04-07 15:32:371036 }
1037
1038 /**
1039 * @return {number}
1040 */
1041 nestingLevel() {
1042 return this._nestingLevel;
1043 }
1044
1045 /**
1046 * @param {boolean} inSimilarGroup
1047 * @param {boolean=} isLast
1048 */
1049 setInSimilarGroup(inSimilarGroup, isLast) {
1050 this._inSimilarGroup = inSimilarGroup;
1051 this._lastInSimilarGroup = inSimilarGroup && !!isLast;
1052 if (this._similarGroupMarker && !inSimilarGroup) {
1053 this._similarGroupMarker.remove();
1054 this._similarGroupMarker = null;
1055 } else if (this._element && !this._similarGroupMarker && inSimilarGroup) {
Sigurd Schneider53e98632020-10-26 15:29:501056 this._similarGroupMarker = /** @type {!HTMLElement} */ (document.createElement('div'));
Tim van der Lippef49e2322020-05-01 15:03:091057 this._similarGroupMarker.classList.add('nesting-level-marker');
Blink Reformat4c46d092018-04-07 15:32:371058 this._element.insertBefore(this._similarGroupMarker, this._element.firstChild);
1059 this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
1060 }
1061 }
1062
1063 /**
1064 * @return {boolean}
1065 */
1066 isLastInSimilarGroup() {
Sigurd Schneider45f32c32020-10-13 13:32:051067 return !!this._inSimilarGroup && !!this._lastInSimilarGroup;
Blink Reformat4c46d092018-04-07 15:32:371068 }
1069
1070 resetCloseGroupDecorationCount() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341071 if (!this._closeGroupDecorationCount) {
Blink Reformat4c46d092018-04-07 15:32:371072 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341073 }
Blink Reformat4c46d092018-04-07 15:32:371074 this._closeGroupDecorationCount = 0;
1075 this._updateCloseGroupDecorations();
1076 }
1077
1078 incrementCloseGroupDecorationCount() {
1079 ++this._closeGroupDecorationCount;
1080 this._updateCloseGroupDecorations();
1081 }
1082
1083 _updateCloseGroupDecorations() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341084 if (!this._nestingLevelMarkers) {
Blink Reformat4c46d092018-04-07 15:32:371085 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341086 }
Blink Reformat4c46d092018-04-07 15:32:371087 for (let i = 0, n = this._nestingLevelMarkers.length; i < n; ++i) {
1088 const marker = this._nestingLevelMarkers[i];
1089 marker.classList.toggle('group-closed', n - i <= this._closeGroupDecorationCount);
1090 }
1091 }
1092
1093 /**
Erik Luo0b8282e2018-10-08 20:37:461094 * @return {number}
1095 */
1096 _focusedChildIndex() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341097 if (!this._selectableChildren.length) {
Erik Luo0b8282e2018-10-08 20:37:461098 return -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341099 }
Erik Luo383f21d2018-11-07 23:16:371100 return this._selectableChildren.findIndex(child => child.element.hasFocus());
Erik Luo0b8282e2018-10-08 20:37:461101 }
1102
1103 /**
Sigurd Schneider45f32c32020-10-13 13:32:051104 * @param {!KeyboardEvent} event
Erik Luo8ef5d0c2018-09-25 21:16:001105 */
1106 _onKeyDown(event) {
Sigurd Schneider45f32c32020-10-13 13:32:051107 if (UI.UIUtils.isEditing() || !this._element || !this._element.hasFocus() || this._element.hasSelection()) {
Erik Luo8ef5d0c2018-09-25 21:16:001108 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341109 }
1110 if (this.maybeHandleOnKeyDown(event)) {
Erik Luo8ef5d0c2018-09-25 21:16:001111 event.consume(true);
Tim van der Lippe1d6e57a2019-09-30 11:55:341112 }
Erik Luo8ef5d0c2018-09-25 21:16:001113 }
1114
1115 /**
1116 * @protected
Sigurd Schneider45f32c32020-10-13 13:32:051117 * @param {!KeyboardEvent} event
Erik Luo8ef5d0c2018-09-25 21:16:001118 */
1119 maybeHandleOnKeyDown(event) {
1120 // Handle trace expansion.
Erik Luo0b8282e2018-10-08 20:37:461121 const focusedChildIndex = this._focusedChildIndex();
1122 const isWrapperFocused = focusedChildIndex === -1;
1123 if (this._expandTrace && isWrapperFocused) {
Erik Luo8ef5d0c2018-09-25 21:16:001124 if ((event.key === 'ArrowLeft' && this._traceExpanded) || (event.key === 'ArrowRight' && !this._traceExpanded)) {
1125 this._expandTrace(!this._traceExpanded);
1126 return true;
1127 }
1128 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341129 if (!this._selectableChildren.length) {
Erik Luo0b8282e2018-10-08 20:37:461130 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341131 }
Erik Luo0b8282e2018-10-08 20:37:461132
1133 if (event.key === 'ArrowLeft') {
Sigurd Schneider45f32c32020-10-13 13:32:051134 this._element && this._element.focus();
Erik Luo0b8282e2018-10-08 20:37:461135 return true;
1136 }
1137 if (event.key === 'ArrowRight') {
Tim van der Lippe1d6e57a2019-09-30 11:55:341138 if (isWrapperFocused && this._selectNearestVisibleChild(0)) {
Erik Luo0b8282e2018-10-08 20:37:461139 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341140 }
Erik Luo0b8282e2018-10-08 20:37:461141 }
1142 if (event.key === 'ArrowUp') {
Erik Luo182bece2018-11-29 03:15:221143 const firstVisibleChild = this._nearestVisibleChild(0);
1144 if (this._selectableChildren[focusedChildIndex] === firstVisibleChild && firstVisibleChild) {
Sigurd Schneider45f32c32020-10-13 13:32:051145 this._element && this._element.focus();
Erik Luo0b8282e2018-10-08 20:37:461146 return true;
Mathias Bynensf06e8c02020-02-28 13:58:281147 }
1148 if (this._selectNearestVisibleChild(focusedChildIndex - 1, true /* backwards */)) {
Erik Luo0b8282e2018-10-08 20:37:461149 return true;
1150 }
1151 }
1152 if (event.key === 'ArrowDown') {
Tim van der Lippe1d6e57a2019-09-30 11:55:341153 if (isWrapperFocused && this._selectNearestVisibleChild(0)) {
Erik Luo0b8282e2018-10-08 20:37:461154 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341155 }
1156 if (!isWrapperFocused && this._selectNearestVisibleChild(focusedChildIndex + 1)) {
Erik Luo0b8282e2018-10-08 20:37:461157 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341158 }
Erik Luo0b8282e2018-10-08 20:37:461159 }
Erik Luo8ef5d0c2018-09-25 21:16:001160 return false;
1161 }
1162
Erik Luo182bece2018-11-29 03:15:221163 /**
1164 * @param {number} fromIndex
1165 * @param {boolean=} backwards
1166 * @return {boolean}
1167 */
1168 _selectNearestVisibleChild(fromIndex, backwards) {
1169 const nearestChild = this._nearestVisibleChild(fromIndex, backwards);
1170 if (nearestChild) {
Erik Luo31c21f62018-12-13 03:39:391171 nearestChild.forceSelect();
Erik Luo182bece2018-11-29 03:15:221172 return true;
1173 }
1174 return false;
1175 }
1176
1177 /**
1178 * @param {number} fromIndex
1179 * @param {boolean=} backwards
Erik Luo31c21f62018-12-13 03:39:391180 * @return {?{element: !Element, forceSelect: function()}}
Erik Luo182bece2018-11-29 03:15:221181 */
1182 _nearestVisibleChild(fromIndex, backwards) {
1183 const childCount = this._selectableChildren.length;
Tim van der Lippe1d6e57a2019-09-30 11:55:341184 if (fromIndex < 0 || fromIndex >= childCount) {
Erik Luo182bece2018-11-29 03:15:221185 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341186 }
Erik Luo182bece2018-11-29 03:15:221187 const direction = backwards ? -1 : 1;
1188 let index = fromIndex;
1189
1190 while (!this._selectableChildren[index].element.offsetParent) {
1191 index += direction;
Tim van der Lippe1d6e57a2019-09-30 11:55:341192 if (index < 0 || index >= 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 }
1196 return this._selectableChildren[index];
1197 }
1198
Sigurd Schneider53f33522020-10-08 15:00:491199 /**
1200 * @override
1201 */
Erik Luo0b8282e2018-10-08 20:37:461202 focusLastChildOrSelf() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341203 if (this._element && !this._selectNearestVisibleChild(this._selectableChildren.length - 1, true /* backwards */)) {
Erik Luo0b8282e2018-10-08 20:37:461204 this._element.focus();
Tim van der Lippe1d6e57a2019-09-30 11:55:341205 }
Erik Luo0b8282e2018-10-08 20:37:461206 }
1207
1208 /**
Sigurd Schneiderb2953b22020-10-09 09:30:151209 * @protected
1210 * @param {!HTMLElement} element
1211 */
1212 setContentElement(element) {
1213 console.assert(!this._contentElement, 'Cannot set content element twice');
1214 this._contentElement = element;
1215 }
1216
Sigurd Schneiderb2953b22020-10-09 09:30:151217 /**
1218 * @protected
1219 * @return {?HTMLElement}
1220 */
1221 getContentElement() {
1222 return this._contentElement;
1223 }
1224
1225 /**
Sigurd Schneider53f33522020-10-08 15:00:491226 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:371227 */
1228 contentElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341229 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371230 return this._contentElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:341231 }
Blink Reformat4c46d092018-04-07 15:32:371232
Sigurd Schneider53f33522020-10-08 15:00:491233 const contentElement = /** @type {!HTMLElement} */ (document.createElement('div'));
Tim van der Lippef49e2322020-05-01 15:03:091234 contentElement.classList.add('console-message');
Tim van der Lippe1d6e57a2019-09-30 11:55:341235 if (this._messageLevelIcon) {
Blink Reformat4c46d092018-04-07 15:32:371236 contentElement.appendChild(this._messageLevelIcon);
Tim van der Lippe1d6e57a2019-09-30 11:55:341237 }
Blink Reformat4c46d092018-04-07 15:32:371238 this._contentElement = contentElement;
1239
Sigurd Schneider45f32c32020-10-13 13:32:051240 const runtimeModel = this._message.runtimeModel();
Blink Reformat4c46d092018-04-07 15:32:371241 let formattedMessage;
1242 const shouldIncludeTrace = !!this._message.stackTrace &&
Tim van der Lippe9b2f8712020-02-12 17:46:221243 (this._message.source === SDK.ConsoleModel.MessageSource.Network ||
1244 this._message.source === SDK.ConsoleModel.MessageSource.Violation ||
1245 this._message.level === SDK.ConsoleModel.MessageLevel.Error ||
1246 this._message.level === SDK.ConsoleModel.MessageLevel.Warning ||
1247 this._message.type === SDK.ConsoleModel.MessageType.Trace);
Sigurd Schneider45f32c32020-10-13 13:32:051248 if (runtimeModel && shouldIncludeTrace) {
1249 formattedMessage = this._buildMessageWithStackTrace(runtimeModel);
Tim van der Lippe1d6e57a2019-09-30 11:55:341250 } else {
Blink Reformat4c46d092018-04-07 15:32:371251 formattedMessage = this._buildMessage();
Tim van der Lippe1d6e57a2019-09-30 11:55:341252 }
Blink Reformat4c46d092018-04-07 15:32:371253 contentElement.appendChild(formattedMessage);
1254
1255 this.updateTimestamp();
1256 return this._contentElement;
1257 }
1258
1259 /**
Sigurd Schneider53f33522020-10-08 15:00:491260 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:371261 */
1262 toMessageElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341263 if (this._element) {
Blink Reformat4c46d092018-04-07 15:32:371264 return this._element;
Tim van der Lippe1d6e57a2019-09-30 11:55:341265 }
Blink Reformat4c46d092018-04-07 15:32:371266
Sigurd Schneider53f33522020-10-08 15:00:491267 this._element = /** @type {!HTMLElement} */ (document.createElement('div'));
Pavel Feldmandb310912019-01-30 00:31:201268 this._element.tabIndex = -1;
Sigurd Schneider45f32c32020-10-13 13:32:051269 this._element.addEventListener('keydown', /** @type {!EventListener} */ (this._onKeyDown.bind(this)));
Blink Reformat4c46d092018-04-07 15:32:371270 this.updateMessageElement();
1271 return this._element;
1272 }
1273
1274 updateMessageElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341275 if (!this._element) {
Blink Reformat4c46d092018-04-07 15:32:371276 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341277 }
Blink Reformat4c46d092018-04-07 15:32:371278
1279 this._element.className = 'console-message-wrapper';
1280 this._element.removeChildren();
Tim van der Lippe1d6e57a2019-09-30 11:55:341281 if (this._message.isGroupStartMessage()) {
Blink Reformat4c46d092018-04-07 15:32:371282 this._element.classList.add('console-group-title');
Tim van der Lippe1d6e57a2019-09-30 11:55:341283 }
Tim van der Lippe9b2f8712020-02-12 17:46:221284 if (this._message.source === SDK.ConsoleModel.MessageSource.ConsoleAPI) {
Blink Reformat4c46d092018-04-07 15:32:371285 this._element.classList.add('console-from-api');
Tim van der Lippe1d6e57a2019-09-30 11:55:341286 }
Blink Reformat4c46d092018-04-07 15:32:371287 if (this._inSimilarGroup) {
Sigurd Schneider53e98632020-10-26 15:29:501288 this._similarGroupMarker = /** @type {!HTMLElement} */ (this._element.createChild('div', 'nesting-level-marker'));
Blink Reformat4c46d092018-04-07 15:32:371289 this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
1290 }
1291
1292 this._nestingLevelMarkers = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341293 for (let i = 0; i < this._nestingLevel; ++i) {
Blink Reformat4c46d092018-04-07 15:32:371294 this._nestingLevelMarkers.push(this._element.createChild('div', 'nesting-level-marker'));
Tim van der Lippe1d6e57a2019-09-30 11:55:341295 }
Blink Reformat4c46d092018-04-07 15:32:371296 this._updateCloseGroupDecorations();
Sigurd Schneiderca7b4ff2020-10-14 07:45:471297 elementToMessage.set(this._element, this);
Blink Reformat4c46d092018-04-07 15:32:371298
1299 switch (this._message.level) {
Tim van der Lippe9b2f8712020-02-12 17:46:221300 case SDK.ConsoleModel.MessageLevel.Verbose:
Blink Reformat4c46d092018-04-07 15:32:371301 this._element.classList.add('console-verbose-level');
Blink Reformat4c46d092018-04-07 15:32:371302 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221303 case SDK.ConsoleModel.MessageLevel.Info:
Blink Reformat4c46d092018-04-07 15:32:371304 this._element.classList.add('console-info-level');
Tim van der Lippe9b2f8712020-02-12 17:46:221305 if (this._message.type === SDK.ConsoleModel.MessageType.System) {
Blink Reformat4c46d092018-04-07 15:32:371306 this._element.classList.add('console-system-type');
Tim van der Lippe1d6e57a2019-09-30 11:55:341307 }
Blink Reformat4c46d092018-04-07 15:32:371308 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221309 case SDK.ConsoleModel.MessageLevel.Warning:
Blink Reformat4c46d092018-04-07 15:32:371310 this._element.classList.add('console-warning-level');
Blink Reformat4c46d092018-04-07 15:32:371311 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221312 case SDK.ConsoleModel.MessageLevel.Error:
Blink Reformat4c46d092018-04-07 15:32:371313 this._element.classList.add('console-error-level');
Blink Reformat4c46d092018-04-07 15:32:371314 break;
1315 }
Erik Luofd3e7d42018-09-25 02:12:351316 this._updateMessageLevelIcon();
Tim van der Lippe1d6e57a2019-09-30 11:55:341317 if (this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371318 this._element.classList.add('console-warning-level');
Tim van der Lippe1d6e57a2019-09-30 11:55:341319 }
Blink Reformat4c46d092018-04-07 15:32:371320
1321 this._element.appendChild(this.contentElement());
Tim van der Lippe1d6e57a2019-09-30 11:55:341322 if (this._repeatCount > 1) {
Blink Reformat4c46d092018-04-07 15:32:371323 this._showRepeatCountElement();
Tim van der Lippe1d6e57a2019-09-30 11:55:341324 }
Blink Reformat4c46d092018-04-07 15:32:371325 }
1326
1327 /**
1328 * @return {boolean}
1329 */
1330 _shouldRenderAsWarning() {
Tim van der Lippe9b2f8712020-02-12 17:46:221331 return (this._message.level === SDK.ConsoleModel.MessageLevel.Verbose ||
1332 this._message.level === SDK.ConsoleModel.MessageLevel.Info) &&
1333 (this._message.source === SDK.ConsoleModel.MessageSource.Violation ||
1334 this._message.source === SDK.ConsoleModel.MessageSource.Deprecation ||
1335 this._message.source === SDK.ConsoleModel.MessageSource.Intervention ||
1336 this._message.source === SDK.ConsoleModel.MessageSource.Recommendation);
Blink Reformat4c46d092018-04-07 15:32:371337 }
1338
Erik Luofd3e7d42018-09-25 02:12:351339 _updateMessageLevelIcon() {
1340 let iconType = '';
1341 let accessibleName = '';
Tim van der Lippe9b2f8712020-02-12 17:46:221342 if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning) {
Erik Luofd3e7d42018-09-25 02:12:351343 iconType = 'smallicon-warning';
1344 accessibleName = ls`Warning`;
Tim van der Lippe9b2f8712020-02-12 17:46:221345 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Erik Luofd3e7d42018-09-25 02:12:351346 iconType = 'smallicon-error';
1347 accessibleName = ls`Error`;
1348 }
Sigurd Schneider45f32c32020-10-13 13:32:051349 if (!this._messageLevelIcon) {
1350 if (!iconType) {
1351 return;
1352 }
Tim van der Lippe9b2f8712020-02-12 17:46:221353 this._messageLevelIcon = UI.Icon.Icon.create('', 'message-level-icon');
Tim van der Lippe1d6e57a2019-09-30 11:55:341354 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371355 this._contentElement.insertBefore(this._messageLevelIcon, this._contentElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341356 }
Blink Reformat4c46d092018-04-07 15:32:371357 }
1358 this._messageLevelIcon.setIconType(iconType);
Erik Luofd3e7d42018-09-25 02:12:351359 UI.ARIAUtils.setAccessibleName(this._messageLevelIcon, accessibleName);
Blink Reformat4c46d092018-04-07 15:32:371360 }
1361
1362 /**
1363 * @return {number}
1364 */
1365 repeatCount() {
1366 return this._repeatCount || 1;
1367 }
1368
1369 resetIncrementRepeatCount() {
1370 this._repeatCount = 1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341371 if (!this._repeatCountElement) {
Blink Reformat4c46d092018-04-07 15:32:371372 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341373 }
Blink Reformat4c46d092018-04-07 15:32:371374
1375 this._repeatCountElement.remove();
Tim van der Lippe1d6e57a2019-09-30 11:55:341376 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371377 this._contentElement.classList.remove('repeated-message');
Tim van der Lippe1d6e57a2019-09-30 11:55:341378 }
Sigurd Schneider53e98632020-10-26 15:29:501379 this._repeatCountElement = null;
Blink Reformat4c46d092018-04-07 15:32:371380 }
1381
1382 incrementRepeatCount() {
1383 this._repeatCount++;
1384 this._showRepeatCountElement();
1385 }
1386
1387 /**
1388 * @param {number} repeatCount
1389 */
1390 setRepeatCount(repeatCount) {
1391 this._repeatCount = repeatCount;
1392 this._showRepeatCountElement();
1393 }
1394
Tim van der Lippeee954d42020-05-04 10:35:571395 /**
1396 * @suppress {checkTypes}
1397 */
Blink Reformat4c46d092018-04-07 15:32:371398 _showRepeatCountElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341399 if (!this._element) {
Blink Reformat4c46d092018-04-07 15:32:371400 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341401 }
Blink Reformat4c46d092018-04-07 15:32:371402
1403 if (!this._repeatCountElement) {
Sigurd Schneider45f32c32020-10-13 13:32:051404 this._repeatCountElement =
1405 /** @type {!UI.UIUtils.DevToolsSmallBubble} */ (document.createElement('span', {is: 'dt-small-bubble'}));
Tim van der Lippeee954d42020-05-04 10:35:571406 this._repeatCountElement.classList.add('console-message-repeat-count');
Blink Reformat4c46d092018-04-07 15:32:371407 switch (this._message.level) {
Tim van der Lippe9b2f8712020-02-12 17:46:221408 case SDK.ConsoleModel.MessageLevel.Warning:
Blink Reformat4c46d092018-04-07 15:32:371409 this._repeatCountElement.type = 'warning';
1410 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221411 case SDK.ConsoleModel.MessageLevel.Error:
Blink Reformat4c46d092018-04-07 15:32:371412 this._repeatCountElement.type = 'error';
1413 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221414 case SDK.ConsoleModel.MessageLevel.Verbose:
Blink Reformat4c46d092018-04-07 15:32:371415 this._repeatCountElement.type = 'verbose';
1416 break;
1417 default:
1418 this._repeatCountElement.type = 'info';
1419 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341420 if (this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371421 this._repeatCountElement.type = 'warning';
Tim van der Lippe1d6e57a2019-09-30 11:55:341422 }
Blink Reformat4c46d092018-04-07 15:32:371423
1424 this._element.insertBefore(this._repeatCountElement, this._contentElement);
Sigurd Schneider45f32c32020-10-13 13:32:051425 this.contentElement().classList.add('repeated-message');
Blink Reformat4c46d092018-04-07 15:32:371426 }
Sigurd Schneider45f32c32020-10-13 13:32:051427 this._repeatCountElement.textContent = `${this._repeatCount}`;
Erik Luofd3e7d42018-09-25 02:12:351428 let accessibleName = ls`Repeat ${this._repeatCount}`;
Tim van der Lippe9b2f8712020-02-12 17:46:221429 if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning) {
Erik Luofd3e7d42018-09-25 02:12:351430 accessibleName = ls`Warning ${accessibleName}`;
Tim van der Lippe9b2f8712020-02-12 17:46:221431 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Erik Luofd3e7d42018-09-25 02:12:351432 accessibleName = ls`Error ${accessibleName}`;
Tim van der Lippe1d6e57a2019-09-30 11:55:341433 }
Erik Luofd3e7d42018-09-25 02:12:351434 UI.ARIAUtils.setAccessibleName(this._repeatCountElement, accessibleName);
Blink Reformat4c46d092018-04-07 15:32:371435 }
1436
1437 get text() {
1438 return this._message.messageText;
1439 }
1440
1441 /**
1442 * @return {string}
1443 */
1444 toExportString() {
1445 const lines = [];
1446 const nodes = this.contentElement().childTextNodes();
Tim van der Lippe9b2f8712020-02-12 17:46:221447 const messageContent = nodes.map(Components.Linkifier.Linkifier.untruncatedNodeText).join('');
Tim van der Lippe1d6e57a2019-09-30 11:55:341448 for (let i = 0; i < this.repeatCount(); ++i) {
Blink Reformat4c46d092018-04-07 15:32:371449 lines.push(messageContent);
Tim van der Lippe1d6e57a2019-09-30 11:55:341450 }
Blink Reformat4c46d092018-04-07 15:32:371451 return lines.join('\n');
1452 }
1453
1454 /**
1455 * @param {?RegExp} regex
1456 */
1457 setSearchRegex(regex) {
Sigurd Schneidere8e75cf2020-10-13 08:17:521458 if (this._searchHighlightNodeChanges && this._searchHighlightNodeChanges.length) {
1459 UI.UIUtils.revertDomChanges(this._searchHighlightNodeChanges);
Tim van der Lippe1d6e57a2019-09-30 11:55:341460 }
Blink Reformat4c46d092018-04-07 15:32:371461 this._searchRegex = regex;
1462 this._searchHighlightNodes = [];
Sigurd Schneidere8e75cf2020-10-13 08:17:521463 this._searchHighlightNodeChanges = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341464 if (!this._searchRegex) {
Blink Reformat4c46d092018-04-07 15:32:371465 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341466 }
Blink Reformat4c46d092018-04-07 15:32:371467
1468 const text = this.contentElement().deepTextContent();
1469 let match;
1470 this._searchRegex.lastIndex = 0;
1471 const sourceRanges = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341472 while ((match = this._searchRegex.exec(text)) && match[0]) {
Tim van der Lippe9b2f8712020-02-12 17:46:221473 sourceRanges.push(new TextUtils.TextRange.SourceRange(match.index, match[0].length));
Tim van der Lippe1d6e57a2019-09-30 11:55:341474 }
Blink Reformat4c46d092018-04-07 15:32:371475
1476 if (sourceRanges.length) {
1477 this._searchHighlightNodes =
Sigurd Schneidere8e75cf2020-10-13 08:17:521478 UI.UIUtils.highlightSearchResults(this.contentElement(), sourceRanges, this._searchHighlightNodeChanges);
Blink Reformat4c46d092018-04-07 15:32:371479 }
1480 }
1481
1482 /**
1483 * @return {?RegExp}
1484 */
1485 searchRegex() {
1486 return this._searchRegex;
1487 }
1488
1489 /**
1490 * @return {number}
1491 */
1492 searchCount() {
1493 return this._searchHighlightNodes.length;
1494 }
1495
1496 /**
Sigurd Schneider45f32c32020-10-13 13:32:051497 * @param {number} index
1498 * @return {!Element}
Blink Reformat4c46d092018-04-07 15:32:371499 */
1500 searchHighlightNode(index) {
1501 return this._searchHighlightNodes[index];
1502 }
1503
1504 /**
1505 * @param {string} string
Sigurd Schneider53f33522020-10-08 15:00:491506 * @return {?HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:371507 */
1508 _tryFormatAsError(string) {
1509 /**
1510 * @param {string} prefix
1511 */
1512 function startsWith(prefix) {
1513 return string.startsWith(prefix);
1514 }
1515
Sigurd Schneider45f32c32020-10-13 13:32:051516 const runtimeModel = this._message.runtimeModel();
Blink Reformat4c46d092018-04-07 15:32:371517 const errorPrefixes =
1518 ['EvalError', 'ReferenceError', 'SyntaxError', 'TypeError', 'RangeError', 'Error', 'URIError'];
Sigurd Schneider45f32c32020-10-13 13:32:051519 if (!runtimeModel || !errorPrefixes.some(startsWith)) {
Blink Reformat4c46d092018-04-07 15:32:371520 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341521 }
Sigurd Schneider45f32c32020-10-13 13:32:051522 const debuggerModel = runtimeModel.debuggerModel();
1523 const baseURL = runtimeModel.target().inspectedURL();
Blink Reformat4c46d092018-04-07 15:32:371524
1525 const lines = string.split('\n');
1526 const links = [];
1527 let position = 0;
1528 for (let i = 0; i < lines.length; ++i) {
1529 position += i > 0 ? lines[i - 1].length + 1 : 0;
1530 const isCallFrameLine = /^\s*at\s/.test(lines[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:341531 if (!isCallFrameLine && links.length) {
Blink Reformat4c46d092018-04-07 15:32:371532 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341533 }
Blink Reformat4c46d092018-04-07 15:32:371534
Tim van der Lippe1d6e57a2019-09-30 11:55:341535 if (!isCallFrameLine) {
Blink Reformat4c46d092018-04-07 15:32:371536 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341537 }
Blink Reformat4c46d092018-04-07 15:32:371538
1539 let openBracketIndex = -1;
1540 let closeBracketIndex = -1;
Yang Guo39256bd2019-07-18 06:02:251541 const inBracketsWithLineAndColumn = /\([^\)\(]+:\d+:\d+\)/g;
1542 const inBrackets = /\([^\)\(]+\)/g;
1543 let lastMatch = null;
1544 let currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341545 while ((currentMatch = inBracketsWithLineAndColumn.exec(lines[i]))) {
Yang Guo39256bd2019-07-18 06:02:251546 lastMatch = currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341547 }
Yang Guo39256bd2019-07-18 06:02:251548 if (!lastMatch) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341549 while ((currentMatch = inBrackets.exec(lines[i]))) {
Yang Guo39256bd2019-07-18 06:02:251550 lastMatch = currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341551 }
Yang Guo39256bd2019-07-18 06:02:251552 }
1553 if (lastMatch) {
1554 openBracketIndex = lastMatch.index;
1555 closeBracketIndex = lastMatch.index + lastMatch[0].length - 1;
Blink Reformat4c46d092018-04-07 15:32:371556 }
1557 const hasOpenBracket = openBracketIndex !== -1;
1558 const left = hasOpenBracket ? openBracketIndex + 1 : lines[i].indexOf('at') + 3;
1559 const right = hasOpenBracket ? closeBracketIndex : lines[i].length;
1560 const linkCandidate = lines[i].substring(left, right);
Tim van der Lippe9b2f8712020-02-12 17:46:221561 const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(linkCandidate);
Tim van der Lippe1d6e57a2019-09-30 11:55:341562 if (!splitResult) {
Blink Reformat4c46d092018-04-07 15:32:371563 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341564 }
Blink Reformat4c46d092018-04-07 15:32:371565
Tim van der Lippe1d6e57a2019-09-30 11:55:341566 if (splitResult.url === '<anonymous>') {
Blink Reformat4c46d092018-04-07 15:32:371567 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341568 }
Blink Reformat4c46d092018-04-07 15:32:371569 let url = parseOrScriptMatch(splitResult.url);
Tim van der Lippe9b2f8712020-02-12 17:46:221570 if (!url && Common.ParsedURL.ParsedURL.isRelativeURL(splitResult.url)) {
1571 url = parseOrScriptMatch(Common.ParsedURL.ParsedURL.completeURL(baseURL, splitResult.url));
Tim van der Lippe1d6e57a2019-09-30 11:55:341572 }
1573 if (!url) {
Blink Reformat4c46d092018-04-07 15:32:371574 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341575 }
Blink Reformat4c46d092018-04-07 15:32:371576
1577 links.push({
1578 url: url,
1579 positionLeft: position + left,
1580 positionRight: position + right,
1581 lineNumber: splitResult.lineNumber,
1582 columnNumber: splitResult.columnNumber
1583 });
1584 }
1585
Tim van der Lippe1d6e57a2019-09-30 11:55:341586 if (!links.length) {
Blink Reformat4c46d092018-04-07 15:32:371587 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341588 }
Blink Reformat4c46d092018-04-07 15:32:371589
Sigurd Schneider53f33522020-10-08 15:00:491590 const formattedResult = /** @type {!HTMLElement} */ (document.createElement('span'));
Blink Reformat4c46d092018-04-07 15:32:371591 let start = 0;
1592 for (let i = 0; i < links.length; ++i) {
Erik Luo383f21d2018-11-07 23:16:371593 formattedResult.appendChild(this._linkifyStringAsFragment(string.substring(start, links[i].positionLeft)));
Erik Luo182bece2018-11-29 03:15:221594 const scriptLocationLink = this._linkifier.linkifyScriptLocation(
Sigurd Schneider45f32c32020-10-13 13:32:051595 debuggerModel.target(), null, links[i].url, links[i].lineNumber,
1596 {columnNumber: links[i].columnNumber, className: undefined, tabStop: undefined});
Erik Luo182bece2018-11-29 03:15:221597 scriptLocationLink.tabIndex = -1;
Erik Luo31c21f62018-12-13 03:39:391598 this._selectableChildren.push({element: scriptLocationLink, forceSelect: () => scriptLocationLink.focus()});
Erik Luo182bece2018-11-29 03:15:221599 formattedResult.appendChild(scriptLocationLink);
Blink Reformat4c46d092018-04-07 15:32:371600 start = links[i].positionRight;
1601 }
1602
Tim van der Lippe1d6e57a2019-09-30 11:55:341603 if (start !== string.length) {
Erik Luo383f21d2018-11-07 23:16:371604 formattedResult.appendChild(this._linkifyStringAsFragment(string.substring(start)));
Tim van der Lippe1d6e57a2019-09-30 11:55:341605 }
Blink Reformat4c46d092018-04-07 15:32:371606
1607 return formattedResult;
1608
1609 /**
1610 * @param {?string} url
1611 * @return {?string}
1612 */
1613 function parseOrScriptMatch(url) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341614 if (!url) {
Blink Reformat4c46d092018-04-07 15:32:371615 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341616 }
Tim van der Lippe9b2f8712020-02-12 17:46:221617 const parsedURL = Common.ParsedURL.ParsedURL.fromString(url);
Tim van der Lippe1d6e57a2019-09-30 11:55:341618 if (parsedURL) {
Blink Reformat4c46d092018-04-07 15:32:371619 return parsedURL.url;
Tim van der Lippe1d6e57a2019-09-30 11:55:341620 }
1621 if (debuggerModel.scriptsForSourceURL(url).length) {
Blink Reformat4c46d092018-04-07 15:32:371622 return url;
Tim van der Lippe1d6e57a2019-09-30 11:55:341623 }
Blink Reformat4c46d092018-04-07 15:32:371624 return null;
1625 }
1626 }
1627
1628 /**
1629 * @param {string} string
1630 * @param {function(string,string,number=,number=):!Node} linkifier
1631 * @return {!DocumentFragment}
Tim van der Lippeeaacb722020-01-10 12:16:001632 * @suppress {accessControls}
Blink Reformat4c46d092018-04-07 15:32:371633 */
Erik Luofc2214f2018-11-21 19:54:581634 _linkifyWithCustomLinkifier(string, linkifier) {
Sigurd Schneider8f4ac862020-10-13 13:30:111635 if (string.length > getMaxTokenizableStringLength()) {
Tim van der Lippe9b2f8712020-02-12 17:46:221636 const propertyValue = new ObjectUI.ObjectPropertiesSection.ExpandableTextPropertyValue(
Sigurd Schneider8f4ac862020-10-13 13:30:111637 document.createElement('span'), string, getLongStringVisibleLength());
Sigurd Schneider45f32c32020-10-13 13:32:051638 const fragment = document.createDocumentFragment();
Connor Moody1a5c0d32019-12-19 07:23:361639 fragment.appendChild(propertyValue.element);
1640 return fragment;
Tim van der Lippe1d6e57a2019-09-30 11:55:341641 }
Sigurd Schneider45f32c32020-10-13 13:32:051642 const container = document.createDocumentFragment();
Tim van der Lippeeaacb722020-01-10 12:16:001643 const tokens = ConsoleViewMessage._tokenizeMessageText(string);
Blink Reformat4c46d092018-04-07 15:32:371644 for (const token of tokens) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341645 if (!token.text) {
Erik Luofc2214f2018-11-21 19:54:581646 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341647 }
Blink Reformat4c46d092018-04-07 15:32:371648 switch (token.type) {
1649 case 'url': {
1650 const realURL = (token.text.startsWith('www.') ? 'http://' + token.text : token.text);
Tim van der Lippe9b2f8712020-02-12 17:46:221651 const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(realURL);
Kim-Anh Tran9e49a452020-02-17 09:46:101652 const sourceURL = Common.ParsedURL.ParsedURL.removeWasmFunctionInfoFromURL(splitResult.url);
Blink Reformat4c46d092018-04-07 15:32:371653 let linkNode;
Tim van der Lippe1d6e57a2019-09-30 11:55:341654 if (splitResult) {
Kim-Anh Tran9e49a452020-02-17 09:46:101655 linkNode = linkifier(token.text, sourceURL, splitResult.lineNumber, splitResult.columnNumber);
Tim van der Lippe1d6e57a2019-09-30 11:55:341656 } else {
Sigurd Schneider45f32c32020-10-13 13:32:051657 linkNode = linkifier(token.text, '');
Tim van der Lippe1d6e57a2019-09-30 11:55:341658 }
Blink Reformat4c46d092018-04-07 15:32:371659 container.appendChild(linkNode);
1660 break;
1661 }
1662 default:
Sigurd Schneider45f32c32020-10-13 13:32:051663 container.appendChild(document.createTextNode(token.text));
Blink Reformat4c46d092018-04-07 15:32:371664 break;
1665 }
1666 }
1667 return container;
1668 }
1669
1670 /**
Blink Reformat4c46d092018-04-07 15:32:371671 * @param {string} string
1672 * @return {!DocumentFragment}
1673 */
Erik Luo383f21d2018-11-07 23:16:371674 _linkifyStringAsFragment(string) {
Erik Luofc2214f2018-11-21 19:54:581675 return this._linkifyWithCustomLinkifier(string, (text, url, lineNumber, columnNumber) => {
Sigurd Schneider45f32c32020-10-13 13:32:051676 const options = {text, lineNumber, columnNumber};
1677 const linkElement = Components.Linkifier.Linkifier.linkifyURL(
1678 url, /** @type {!Components.Linkifier.LinkifyURLOptions} */ (options));
Erik Luo383f21d2018-11-07 23:16:371679 linkElement.tabIndex = -1;
Erik Luo31c21f62018-12-13 03:39:391680 this._selectableChildren.push({element: linkElement, forceSelect: () => linkElement.focus()});
Erik Luo383f21d2018-11-07 23:16:371681 return linkElement;
Blink Reformat4c46d092018-04-07 15:32:371682 });
1683 }
1684
1685 /**
1686 * @param {string} string
Sigurd Schneider30ac3dd2020-10-13 09:06:391687 * @return {!Array<{type: (string|undefined), text: string}>}
Tim van der Lippeeaacb722020-01-10 12:16:001688 * @suppress {accessControls}
Blink Reformat4c46d092018-04-07 15:32:371689 */
1690 static _tokenizeMessageText(string) {
Sigurd Schneider30ac3dd2020-10-13 09:06:391691 const {tokenizerRegexes, tokenizerTypes} = getOrCreateTokenizers();
Sigurd Schneider8f4ac862020-10-13 13:30:111692 if (string.length > getMaxTokenizableStringLength()) {
Blink Reformat4c46d092018-04-07 15:32:371693 return [{text: string, type: undefined}];
Tim van der Lippe1d6e57a2019-09-30 11:55:341694 }
Sigurd Schneider30ac3dd2020-10-13 09:06:391695 const results = TextUtils.TextUtils.Utils.splitStringByRegexes(string, tokenizerRegexes);
1696 return results.map(result => ({text: result.value, type: tokenizerTypes[result.regexIndex]}));
Blink Reformat4c46d092018-04-07 15:32:371697 }
1698
1699 /**
1700 * @return {string}
1701 */
1702 groupKey() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341703 if (!this._groupKey) {
Blink Reformat4c46d092018-04-07 15:32:371704 this._groupKey = this._message.groupCategoryKey() + ':' + this.groupTitle();
Tim van der Lippe1d6e57a2019-09-30 11:55:341705 }
Blink Reformat4c46d092018-04-07 15:32:371706 return this._groupKey;
1707 }
1708
1709 /**
1710 * @return {string}
1711 */
1712 groupTitle() {
Tim van der Lippeeaacb722020-01-10 12:16:001713 const tokens = ConsoleViewMessage._tokenizeMessageText(this._message.messageText);
Blink Reformat4c46d092018-04-07 15:32:371714 const result = tokens.reduce((acc, token) => {
1715 let text = token.text;
Tim van der Lippe1d6e57a2019-09-30 11:55:341716 if (token.type === 'url') {
Tim van der Lippe9b2f8712020-02-12 17:46:221717 text = Common.UIString.UIString('<URL>');
Tim van der Lippe1d6e57a2019-09-30 11:55:341718 } else if (token.type === 'time') {
Tim van der Lippe9b2f8712020-02-12 17:46:221719 text = Common.UIString.UIString('took <N>ms');
Tim van der Lippe1d6e57a2019-09-30 11:55:341720 } else if (token.type === 'event') {
Tim van der Lippe9b2f8712020-02-12 17:46:221721 text = Common.UIString.UIString('<some> event');
Tim van der Lippe1d6e57a2019-09-30 11:55:341722 } else if (token.type === 'milestone') {
Tim van der Lippe9b2f8712020-02-12 17:46:221723 text = Common.UIString.UIString(' M<XX>');
Tim van der Lippe1d6e57a2019-09-30 11:55:341724 } else if (token.type === 'autofill') {
Tim van der Lippe9b2f8712020-02-12 17:46:221725 text = Common.UIString.UIString('<attribute>');
Tim van der Lippe1d6e57a2019-09-30 11:55:341726 }
Blink Reformat4c46d092018-04-07 15:32:371727 return acc + text;
1728 }, '');
1729 return result.replace(/[%]o/g, '');
1730 }
Paul Lewisbf7aa3c2019-11-20 17:03:381731}
Blink Reformat4c46d092018-04-07 15:32:371732
Sigurd Schneider30ac3dd2020-10-13 09:06:391733/** @type {?Array<!RegExp>} */
1734let tokenizerRegexes = null;
1735/** @type {?Array<string>} */
1736let tokenizerTypes = null;
1737
1738/**
1739 * @return {!{tokenizerRegexes:!Array<!RegExp>, tokenizerTypes:Array<string>}}
1740 */
1741function getOrCreateTokenizers() {
1742 if (!tokenizerRegexes || !tokenizerTypes) {
1743 const controlCodes = '\\u0000-\\u0020\\u007f-\\u009f';
1744 const linkStringRegex = new RegExp(
1745 '(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\\/\\/|data:|www\\.)[^\\s' + controlCodes + '"]{2,}[^\\s' + controlCodes +
1746 '"\')}\\],:;.!?]',
1747 'u');
1748 const pathLineRegex = /(?:\/[\w\.-]*)+\:[\d]+/;
1749 const timeRegex = /took [\d]+ms/;
1750 const eventRegex = /'\w+' event/;
1751 const milestoneRegex = /\sM[6-7]\d/;
1752 const autofillRegex = /\(suggested: \"[\w-]+\"\)/;
1753 /** @type {!Map<!RegExp, string>} */
1754 const handlers = new Map();
1755 handlers.set(linkStringRegex, 'url');
1756 handlers.set(pathLineRegex, 'url');
1757 handlers.set(timeRegex, 'time');
1758 handlers.set(eventRegex, 'event');
1759 handlers.set(milestoneRegex, 'milestone');
1760 handlers.set(autofillRegex, 'autofill');
1761 tokenizerRegexes = Array.from(handlers.keys());
1762 tokenizerTypes = Array.from(handlers.values());
1763 return {tokenizerRegexes, tokenizerTypes};
1764 }
1765 return {tokenizerRegexes, tokenizerTypes};
1766}
1767
Paul Lewisbf7aa3c2019-11-20 17:03:381768export class ConsoleGroupViewMessage extends ConsoleViewMessage {
Blink Reformat4c46d092018-04-07 15:32:371769 /**
Tim van der Lippe9b2f8712020-02-12 17:46:221770 * @param {!SDK.ConsoleModel.ConsoleMessage} consoleMessage
1771 * @param {!Components.Linkifier.Linkifier} linkifier
Blink Reformat4c46d092018-04-07 15:32:371772 * @param {number} nestingLevel
Sigurd Schneider45f32c32020-10-13 13:32:051773 * @param {function(): void} onToggle
1774 * @param {function(!Common.EventTarget.EventTargetEvent): void} onResize
Blink Reformat4c46d092018-04-07 15:32:371775 */
Tim van der Lippeb45d9a02019-11-05 17:24:411776 constructor(consoleMessage, linkifier, nestingLevel, onToggle, onResize) {
Blink Reformat4c46d092018-04-07 15:32:371777 console.assert(consoleMessage.isGroupStartMessage());
Tim van der Lippeb45d9a02019-11-05 17:24:411778 super(consoleMessage, linkifier, nestingLevel, onResize);
Tim van der Lippe9b2f8712020-02-12 17:46:221779 this._collapsed = consoleMessage.type === SDK.ConsoleModel.MessageType.StartGroupCollapsed;
1780 /** @type {?UI.Icon.Icon} */
Blink Reformat4c46d092018-04-07 15:32:371781 this._expandGroupIcon = null;
Erik Luo8ef5d0c2018-09-25 21:16:001782 this._onToggle = onToggle;
Blink Reformat4c46d092018-04-07 15:32:371783 }
1784
1785 /**
1786 * @param {boolean} collapsed
1787 */
Erik Luo8ef5d0c2018-09-25 21:16:001788 _setCollapsed(collapsed) {
Blink Reformat4c46d092018-04-07 15:32:371789 this._collapsed = collapsed;
Tim van der Lippe1d6e57a2019-09-30 11:55:341790 if (this._expandGroupIcon) {
Blink Reformat4c46d092018-04-07 15:32:371791 this._expandGroupIcon.setIconType(this._collapsed ? 'smallicon-triangle-right' : 'smallicon-triangle-down');
Tim van der Lippe1d6e57a2019-09-30 11:55:341792 }
Erik Luo8ef5d0c2018-09-25 21:16:001793 this._onToggle.call(null);
Blink Reformat4c46d092018-04-07 15:32:371794 }
1795
1796 /**
1797 * @return {boolean}
1798 */
1799 collapsed() {
1800 return this._collapsed;
1801 }
1802
1803 /**
1804 * @override
Sigurd Schneider45f32c32020-10-13 13:32:051805 * @param {!KeyboardEvent} event
Erik Luo8ef5d0c2018-09-25 21:16:001806 */
1807 maybeHandleOnKeyDown(event) {
Erik Luo0b8282e2018-10-08 20:37:461808 const focusedChildIndex = this._focusedChildIndex();
1809 if (focusedChildIndex === -1) {
1810 if ((event.key === 'ArrowLeft' && !this._collapsed) || (event.key === 'ArrowRight' && this._collapsed)) {
1811 this._setCollapsed(!this._collapsed);
1812 return true;
1813 }
Erik Luo8ef5d0c2018-09-25 21:16:001814 }
1815 return super.maybeHandleOnKeyDown(event);
1816 }
1817
1818 /**
1819 * @override
Sigurd Schneider53f33522020-10-08 15:00:491820 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:371821 */
1822 toMessageElement() {
Sigurd Schneider45f32c32020-10-13 13:32:051823 /** @type {?HTMLElement} */
1824 let element = this._element || null;
1825 if (!element) {
1826 element = super.toMessageElement();
Erik Luo8ef5d0c2018-09-25 21:16:001827 const iconType = this._collapsed ? 'smallicon-triangle-right' : 'smallicon-triangle-down';
Tim van der Lippe9b2f8712020-02-12 17:46:221828 this._expandGroupIcon = UI.Icon.Icon.create(iconType, 'expand-group-icon');
Erik Luob5bfff42018-09-20 02:52:391829 // Intercept focus to avoid highlight on click.
Sigurd Schneider45f32c32020-10-13 13:32:051830 this.contentElement().tabIndex = -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341831 if (this._repeatCountElement) {
Blink Reformat4c46d092018-04-07 15:32:371832 this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341833 } else {
Sigurd Schneider45f32c32020-10-13 13:32:051834 element.insertBefore(this._expandGroupIcon, this._contentElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:341835 }
Sigurd Schneider45f32c32020-10-13 13:32:051836 element.addEventListener('click', () => this._setCollapsed(!this._collapsed));
Blink Reformat4c46d092018-04-07 15:32:371837 }
Sigurd Schneider45f32c32020-10-13 13:32:051838 return element;
Blink Reformat4c46d092018-04-07 15:32:371839 }
1840
1841 /**
1842 * @override
1843 */
1844 _showRepeatCountElement() {
1845 super._showRepeatCountElement();
Tim van der Lippe1d6e57a2019-09-30 11:55:341846 if (this._repeatCountElement && this._expandGroupIcon) {
Blink Reformat4c46d092018-04-07 15:32:371847 this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341848 }
Blink Reformat4c46d092018-04-07 15:32:371849 }
Paul Lewisbf7aa3c2019-11-20 17:03:381850}
Blink Reformat4c46d092018-04-07 15:32:371851
Sigurd Schneiderca7b4ff2020-10-14 07:45:471852export class ConsoleCommand extends ConsoleViewMessage {
1853 /**
1854 * @param {!SDK.ConsoleModel.ConsoleMessage} consoleMessage
1855 * @param {!Components.Linkifier.Linkifier} linkifier
1856 * @param {number} nestingLevel
1857 * @param {function(!Common.EventTarget.EventTargetEvent):void} onResize
1858 */
1859 constructor(consoleMessage, linkifier, nestingLevel, onResize) {
1860 super(consoleMessage, linkifier, nestingLevel, onResize);
1861 /** @type {?HTMLElement} */
1862 this._formattedCommand = null;
1863 }
1864
1865 /**
1866 * @override
1867 * @return {!HTMLElement}
1868 */
1869 contentElement() {
1870 const contentElement = this.getContentElement();
1871 if (contentElement) {
1872 return contentElement;
1873 }
1874 const newContentElement = /** @type {!HTMLElement} */ (document.createElement('div'));
1875 this.setContentElement(newContentElement);
1876 newContentElement.classList.add('console-user-command');
1877 const icon = UI.Icon.Icon.create('smallicon-user-command', 'command-result-icon');
1878 newContentElement.appendChild(icon);
1879
1880 elementToMessage.set(newContentElement, this);
1881
1882 this._formattedCommand = /** @type {!HTMLElement} */ (document.createElement('span'));
1883 this._formattedCommand.classList.add('source-code');
1884 this._formattedCommand.textContent = Platform.StringUtilities.replaceControlCharacters(this.text);
1885 newContentElement.appendChild(this._formattedCommand);
1886
1887 if (this._formattedCommand.textContent.length < MaxLengthToIgnoreHighlighter) {
1888 const javascriptSyntaxHighlighter = new UI.SyntaxHighlighter.SyntaxHighlighter('text/javascript', true);
1889 javascriptSyntaxHighlighter.syntaxHighlightNode(this._formattedCommand).then(this._updateSearch.bind(this));
1890 } else {
1891 this._updateSearch();
1892 }
1893
1894 this.updateTimestamp();
1895 return newContentElement;
1896 }
1897
1898 _updateSearch() {
1899 this.setSearchRegex(this.searchRegex());
1900 }
1901}
1902
1903export class ConsoleCommandResult extends ConsoleViewMessage {
1904 /**
1905 * @override
1906 * @return {!HTMLElement}
1907 */
1908 contentElement() {
1909 const element = super.contentElement();
1910 if (!element.classList.contains('console-user-command-result')) {
1911 element.classList.add('console-user-command-result');
1912 if (this.consoleMessage().level === SDK.ConsoleModel.MessageLevel.Info) {
1913 const icon = UI.Icon.Icon.create('smallicon-command-result', 'command-result-icon');
1914 element.insertBefore(icon, element.firstChild);
1915 }
1916 }
1917 return element;
1918 }
1919}
1920
Sigurd Schneider8bfb4212020-10-27 10:27:371921export class ConsoleTableMessageView extends ConsoleViewMessage {
1922 /**
1923 * @param {!SDK.ConsoleModel.ConsoleMessage} consoleMessage
1924 * @param {!Components.Linkifier.Linkifier} linkifier
1925 * @param {number} nestingLevel
1926 * @param {function(!Common.EventTarget.EventTargetEvent): void} onResize
1927 */
1928 constructor(consoleMessage, linkifier, nestingLevel, onResize) {
1929 super(consoleMessage, linkifier, nestingLevel, onResize);
1930 console.assert(consoleMessage.type === SDK.ConsoleModel.MessageType.Table);
1931 /** @type {?DataGrid.SortableDataGrid.SortableDataGrid<?>} */
1932 this._dataGrid = null;
1933 }
1934
1935 /**
1936 * @override
1937 */
1938 wasShown() {
1939 if (this._dataGrid) {
1940 this._dataGrid.updateWidths();
1941 }
1942 super.wasShown();
1943 }
1944
1945 /**
1946 * @override
1947 */
1948 onResize() {
1949 if (!this.isVisible()) {
1950 return;
1951 }
1952 if (this._dataGrid) {
1953 this._dataGrid.onResize();
1954 }
1955 }
1956
1957 /**
1958 * @override
1959 * @return {!HTMLElement}
1960 */
1961 contentElement() {
1962 const contentElement = this.getContentElement();
1963 if (contentElement) {
1964 return contentElement;
1965 }
1966
1967 const newContentElement = /** @type {!HTMLElement} */ (document.createElement('div'));
1968 newContentElement.classList.add('console-message');
1969 if (this._messageLevelIcon) {
1970 newContentElement.appendChild(this._messageLevelIcon);
1971 }
1972 this.setContentElement(newContentElement);
1973
1974 newContentElement.appendChild(this._buildTableMessage());
1975 this.updateTimestamp();
1976 return newContentElement;
1977 }
1978
1979 /**
1980 * @return {!HTMLElement}
1981 */
1982 _buildTableMessage() {
1983 const formattedMessage = /** @type {!HTMLElement} */ (document.createElement('span'));
1984 formattedMessage.classList.add('source-code');
1985 this._anchorElement = this._buildMessageAnchor();
1986 if (this._anchorElement) {
1987 formattedMessage.appendChild(this._anchorElement);
1988 }
1989
1990 const table = this._message.parameters && this._message.parameters.length ? this._message.parameters[0] : null;
1991 if (!table) {
1992 return this._buildMessage();
1993 }
1994 const actualTable = parameterToRemoteObject(this._message.runtimeModel())(table);
1995 if (!actualTable || !actualTable.preview) {
1996 return this._buildMessage();
1997 }
1998
1999 const rawValueColumnSymbol = Symbol('rawValueColumn');
2000 /** @type {!Array<string|symbol>} */
2001 const columnNames = [];
2002 const preview = actualTable.preview;
2003 const rows = [];
2004 for (let i = 0; i < preview.properties.length; ++i) {
2005 const rowProperty = preview.properties[i];
2006 /** @type {!Array<!Protocol.Runtime.PropertyPreview|!{name:(string|symbol), type: !Protocol.Runtime.PropertyPreviewType, value: (string|undefined)}>} */
2007 let rowSubProperties;
2008 if (rowProperty.valuePreview) {
2009 rowSubProperties = rowProperty.valuePreview.properties;
2010 } else if (rowProperty.value) {
2011 rowSubProperties = [{name: rawValueColumnSymbol, type: rowProperty.type, value: rowProperty.value}];
2012 } else {
2013 continue;
2014 }
2015
2016 /** @type {!Map<string|symbol, !HTMLElement>} */
2017 const rowValue = new Map();
2018 const maxColumnsToRender = 20;
2019 for (let j = 0; j < rowSubProperties.length; ++j) {
2020 const cellProperty = rowSubProperties[j];
2021 let columnRendered = columnNames.indexOf(cellProperty.name) !== -1;
2022 if (!columnRendered) {
2023 if (columnNames.length === maxColumnsToRender) {
2024 continue;
2025 }
2026 columnRendered = true;
2027 columnNames.push(cellProperty.name);
2028 }
2029
2030 if (columnRendered) {
2031 const cellElement =
2032 this._renderPropertyPreviewOrAccessor(actualTable, cellProperty, [rowProperty, cellProperty]);
2033 cellElement.classList.add('console-message-nowrap-below');
2034 rowValue.set(cellProperty.name, cellElement);
2035 }
2036 }
2037 rows.push({rowName: rowProperty.name, rowValue});
2038 }
2039
2040 const flatValues = [];
2041 for (const {rowName, rowValue} of rows) {
2042 flatValues.push(rowName);
2043 for (let j = 0; j < columnNames.length; ++j) {
2044 flatValues.push(rowValue.get(columnNames[j]));
2045 }
2046 }
2047 columnNames.unshift(Common.UIString.UIString('(index)'));
2048 const columnDisplayNames =
2049 columnNames.map(name => name === rawValueColumnSymbol ? Common.UIString.UIString('Value') : name.toString());
2050
2051 if (flatValues.length) {
2052 this._dataGrid = DataGrid.SortableDataGrid.SortableDataGrid.create(columnDisplayNames, flatValues, ls`Console`);
2053 if (this._dataGrid) {
2054 this._dataGrid.setStriped(true);
2055 this._dataGrid.setFocusable(false);
2056
2057 const formattedResult = document.createElement('span');
2058 formattedResult.classList.add('console-message-text');
2059 const tableElement = formattedResult.createChild('div', 'console-message-formatted-table');
2060 const dataGridContainer = tableElement.createChild('span');
2061 tableElement.appendChild(this._formatParameter(actualTable, true, false));
2062 dataGridContainer.appendChild(this._dataGrid.element);
2063 formattedMessage.appendChild(formattedResult);
2064 this._dataGrid.renderInline();
2065 }
2066 }
2067 return formattedMessage;
2068 }
2069
2070 /**
2071 * @override
2072 * @return {number}
2073 */
2074 approximateFastHeight() {
2075 const table = this._message.parameters && this._message.parameters[0];
2076 if (table && typeof table !== 'string' && table.preview) {
2077 return defaultConsoleRowHeight * table.preview.properties.length;
2078 }
2079 return defaultConsoleRowHeight;
2080 }
2081}
2082
Sigurd Schneiderca7b4ff2020-10-14 07:45:472083/**
2084 * The maximum length before strings are considered too long for syntax highlighting.
2085 * @const
2086 * @type {number}
2087 */
2088const MaxLengthToIgnoreHighlighter = 10000;
2089
Blink Reformat4c46d092018-04-07 15:32:372090/**
2091 * @const
2092 * @type {number}
2093 */
Paul Lewisbf7aa3c2019-11-20 17:03:382094export const MaxLengthForLinks = 40;
Blink Reformat4c46d092018-04-07 15:32:372095
Sigurd Schneider8f4ac862020-10-13 13:30:112096let _MaxTokenizableStringLength = 10000;
2097let _LongStringVisibleLength = 5000;
2098
2099export const getMaxTokenizableStringLength = () => {
2100 return _MaxTokenizableStringLength;
2101};
2102
2103/**
2104 * @param {number} length
2105 */
2106export const setMaxTokenizableStringLength = length => {
2107 _MaxTokenizableStringLength = length;
2108};
2109
2110export const getLongStringVisibleLength = () => {
2111 return _LongStringVisibleLength;
2112};
2113
2114/**
2115 * @param {number} length
2116 */
2117export const setLongStringVisibleLength = length => {
2118 _LongStringVisibleLength = length;
2119};