blob: 96e01ff9165a76f4d2ffa277fd91e1d08e2de8d0 [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371/*
2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
4 * Copyright (C) 2009 Joseph Pecoraro
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
Tim van der Lippe9b2f8712020-02-12 17:46:2230
31import * as Common from '../common/common.js';
32import * as Components from '../components/components.js';
33import * as DataGrid from '../data_grid/data_grid.js';
34import * as ObjectUI from '../object_ui/object_ui.js';
Tim van der Lippe93b57c32020-02-20 17:38:4435import * as Platform from '../platform/platform.js';
Tim van der Lippe9b2f8712020-02-12 17:46:2236import * as SDK from '../sdk/sdk.js';
37import * as TextUtils from '../text_utils/text_utils.js';
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
Alfonso Castaño20d22cd2020-10-28 16:23:58502 const outputType = forceObjectFormat ? 'object' : (output.subtype || output.type);
Blink Reformat4c46d092018-04-07 15:32:37503 let element;
Alfonso Castaño20d22cd2020-10-28 16:23:58504 switch (outputType) {
Blink Reformat4c46d092018-04-07 15:32:37505 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;
Alfonso Castaño20d22cd2020-10-28 16:23:58530 case 'trustedtype':
531 element = this._formatParameterAsObject(output, false);
532 break;
Blink Reformat4c46d092018-04-07 15:32:37533 case 'string':
534 element = this._formatParameterAsString(output);
535 break;
536 case 'boolean':
537 case 'date':
538 case 'null':
539 case 'number':
540 case 'regexp':
541 case 'symbol':
542 case 'undefined':
543 case 'bigint':
544 element = this._formatParameterAsValue(output);
545 break;
546 default:
547 element = this._formatParameterAsValue(output);
Alfonso Castaño20d22cd2020-10-28 16:23:58548 console.error(`Tried to format remote object of unknown type ${outputType}.`);
Blink Reformat4c46d092018-04-07 15:32:37549 }
Alfonso Castaño20d22cd2020-10-28 16:23:58550 element.classList.add(`object-value-${outputType}`);
Blink Reformat4c46d092018-04-07 15:32:37551 element.classList.add('source-code');
552 return element;
553 }
554
555 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22556 * @param {!SDK.RemoteObject.RemoteObject} obj
Sigurd Schneider53f33522020-10-08 15:00:49557 * @return {!HTMLElement}
Tim van der Lippeeaacb722020-01-10 12:16:00558 * @suppress {accessControls}
Blink Reformat4c46d092018-04-07 15:32:37559 */
560 _formatParameterAsValue(obj) {
Sigurd Schneider53f33522020-10-08 15:00:49561 const result = /** @type {!HTMLElement} */ (document.createElement('span'));
Blink Reformat4c46d092018-04-07 15:32:37562 const description = obj.description || '';
Sigurd Schneider8f4ac862020-10-13 13:30:11563 if (description.length > getMaxTokenizableStringLength()) {
Tim van der Lippe9b2f8712020-02-12 17:46:22564 const propertyValue = new ObjectUI.ObjectPropertiesSection.ExpandableTextPropertyValue(
Sigurd Schneider8f4ac862020-10-13 13:30:11565 document.createElement('span'), description, getLongStringVisibleLength());
Connor Moody1a5c0d32019-12-19 07:23:36566 result.appendChild(propertyValue.element);
Tim van der Lippe1d6e57a2019-09-30 11:55:34567 } else {
Sigurd Schneider23c52972020-10-13 09:31:14568 UI.UIUtils.createTextChild(result, description);
Tim van der Lippe1d6e57a2019-09-30 11:55:34569 }
570 if (obj.objectId) {
Blink Reformat4c46d092018-04-07 15:32:37571 result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, obj), false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34572 }
Blink Reformat4c46d092018-04-07 15:32:37573 return result;
574 }
575
576 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22577 * @param {!SDK.RemoteObject.RemoteObject} obj
Alfonso Castaño20d22cd2020-10-28 16:23:58578 * @return {!HTMLElement}
579 * @suppress {accessControls}
580 */
581 _formatParameterAsTrustedType(obj) {
582 const result = /** @type {!HTMLElement} */ (document.createElement('span'));
583 const trustedContentSpan = document.createElement('span');
584 trustedContentSpan.appendChild(this._formatParameterAsString(obj));
585 trustedContentSpan.classList.add('object-value-string');
Alfonso Castañodfe8ca32020-10-29 13:03:09586 UI.UIUtils.createTextChild(result, `${obj.className} `);
Alfonso Castaño20d22cd2020-10-28 16:23:58587 result.appendChild(trustedContentSpan);
Alfonso Castaño20d22cd2020-10-28 16:23:58588 return result;
589 }
590
591 /**
592 * @param {!SDK.RemoteObject.RemoteObject} obj
Blink Reformat4c46d092018-04-07 15:32:37593 * @param {boolean=} includePreview
Sigurd Schneider53f33522020-10-08 15:00:49594 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37595 */
596 _formatParameterAsObject(obj, includePreview) {
Sigurd Schneider53f33522020-10-08 15:00:49597 const titleElement = /** @type {!HTMLElement} */ (document.createElement('span'));
Tim van der Lippef49e2322020-05-01 15:03:09598 titleElement.classList.add('console-object');
Blink Reformat4c46d092018-04-07 15:32:37599 if (includePreview && obj.preview) {
600 titleElement.classList.add('console-object-preview');
601 this._previewFormatter.appendObjectPreview(titleElement, obj.preview, false /* isEntry */);
602 } else if (obj.type === 'function') {
603 const functionElement = titleElement.createChild('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22604 ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection.formatObjectAsFunction(obj, functionElement, false);
Blink Reformat4c46d092018-04-07 15:32:37605 titleElement.classList.add('object-value-function');
Alfonso Castaño20d22cd2020-10-28 16:23:58606 } else if (obj.subtype === 'trustedtype') {
607 titleElement.appendChild(this._formatParameterAsTrustedType(obj));
Blink Reformat4c46d092018-04-07 15:32:37608 } else {
Sigurd Schneider23c52972020-10-13 09:31:14609 UI.UIUtils.createTextChild(titleElement, obj.description || '');
Blink Reformat4c46d092018-04-07 15:32:37610 }
611
Tim van der Lippe1d6e57a2019-09-30 11:55:34612 if (!obj.hasChildren || obj.customPreview()) {
Blink Reformat4c46d092018-04-07 15:32:37613 return titleElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:34614 }
Blink Reformat4c46d092018-04-07 15:32:37615
616 const note = titleElement.createChild('span', 'object-state-note info-note');
Tim van der Lippe9b2f8712020-02-12 17:46:22617 if (this._message.type === SDK.ConsoleModel.MessageType.QueryObjectResult) {
Blink Reformat4c46d092018-04-07 15:32:37618 note.title = ls`This value will not be collected until console is cleared.`;
Tim van der Lippe1d6e57a2019-09-30 11:55:34619 } else {
Yang Guo40091c32020-10-29 08:51:32620 note.title = ls`This value was evaluated just now and may have changed since output to console.`;
Tim van der Lippe1d6e57a2019-09-30 11:55:34621 }
Blink Reformat4c46d092018-04-07 15:32:37622
Tim van der Lippe9b2f8712020-02-12 17:46:22623 const section = new ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection(obj, titleElement, this._linkifier);
Blink Reformat4c46d092018-04-07 15:32:37624 section.element.classList.add('console-view-object-properties-section');
625 section.enableContextMenu();
Erik Luocc14b812018-11-03 01:33:09626 section.setShowSelectionOnKeyboardFocus(true, true);
Erik Luo383f21d2018-11-07 23:16:37627 this._selectableChildren.push(section);
Erik Luo840be6b2018-12-03 20:54:27628 section.addEventListener(UI.TreeOutline.Events.ElementAttached, this._messageResized);
629 section.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._messageResized);
630 section.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._messageResized);
Blink Reformat4c46d092018-04-07 15:32:37631 return section.element;
632 }
633
634 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22635 * @param {!SDK.RemoteObject.RemoteObject} func
Blink Reformat4c46d092018-04-07 15:32:37636 * @param {boolean=} includePreview
Sigurd Schneider53f33522020-10-08 15:00:49637 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37638 */
639 _formatParameterAsFunction(func, includePreview) {
Sigurd Schneider53f33522020-10-08 15:00:49640 const result = /** @type {!HTMLElement} */ (document.createElement('span'));
Tim van der Lippe9b2f8712020-02-12 17:46:22641 SDK.RemoteObject.RemoteFunction.objectAsFunction(func).targetFunction().then(formatTargetFunction.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37642 return result;
643
644 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22645 * @param {!SDK.RemoteObject.RemoteObject} targetFunction
Tim van der Lippeeaacb722020-01-10 12:16:00646 * @this {ConsoleViewMessage}
Blink Reformat4c46d092018-04-07 15:32:37647 */
648 function formatTargetFunction(targetFunction) {
Sigurd Schneider53f33522020-10-08 15:00:49649 const functionElement = document.createElement('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22650 const promise = ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection.formatObjectAsFunction(
Joey Arhard78a58f2018-12-05 01:59:45651 targetFunction, functionElement, true, includePreview);
Blink Reformat4c46d092018-04-07 15:32:37652 result.appendChild(functionElement);
653 if (targetFunction !== func) {
654 const note = result.createChild('span', 'object-info-state-note');
Tim van der Lippe9b2f8712020-02-12 17:46:22655 note.title = Common.UIString.UIString('Function was resolved from bound function.');
Blink Reformat4c46d092018-04-07 15:32:37656 }
657 result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, targetFunction), false);
Joey Arhard78a58f2018-12-05 01:59:45658 promise.then(() => this._formattedParameterAsFunctionForTest());
Blink Reformat4c46d092018-04-07 15:32:37659 }
660 }
661
Joey Arhard78a58f2018-12-05 01:59:45662 _formattedParameterAsFunctionForTest() {
663 }
664
Blink Reformat4c46d092018-04-07 15:32:37665 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22666 * @param {!SDK.RemoteObject.RemoteObject} obj
Blink Reformat4c46d092018-04-07 15:32:37667 * @param {!Event} event
668 */
669 _contextMenuEventFired(obj, event) {
Tim van der Lippe9b2f8712020-02-12 17:46:22670 const contextMenu = new UI.ContextMenu.ContextMenu(event);
Blink Reformat4c46d092018-04-07 15:32:37671 contextMenu.appendApplicableItems(obj);
672 contextMenu.show();
673 }
674
675 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22676 * @param {?SDK.RemoteObject.RemoteObject} object
Sigurd Schneider45f32c32020-10-13 13:32:05677 * @param {!Protocol.Runtime.PropertyPreview|!{name:(string|symbol), type: !Protocol.Runtime.PropertyPreviewType, value: (string|undefined)}} property
678 * @param {!Array.<!{name:(string|symbol)}>} propertyPath
Sigurd Schneider53f33522020-10-08 15:00:49679 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37680 */
Sigurd Schneider45f32c32020-10-13 13:32:05681 _renderPropertyPreviewOrAccessor(object, property, propertyPath) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34682 if (property.type === 'accessor') {
Sigurd Schneider45f32c32020-10-13 13:32:05683 return this._formatAsAccessorProperty(object, propertyPath.map(property => property.name.toString()), false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34684 }
Blink Reformat4c46d092018-04-07 15:32:37685 return this._previewFormatter.renderPropertyPreview(
Alfonso Castaño20d22cd2020-10-28 16:23:58686 property.type, 'subtype' in property ? property.subtype : undefined, null, property.value);
Blink Reformat4c46d092018-04-07 15:32:37687 }
688
689 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22690 * @param {!SDK.RemoteObject.RemoteObject} remoteObject
Sigurd Schneider53f33522020-10-08 15:00:49691 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37692 */
693 _formatParameterAsNode(remoteObject) {
Sigurd Schneider53f33522020-10-08 15:00:49694 const result = /** @type {!HTMLElement} */ (document.createElement('span'));
Blink Reformat4c46d092018-04-07 15:32:37695
Tim van der Lippe9b2f8712020-02-12 17:46:22696 const domModel = remoteObject.runtimeModel().target().model(SDK.DOMModel.DOMModel);
Tim van der Lippe1d6e57a2019-09-30 11:55:34697 if (!domModel) {
Blink Reformat4c46d092018-04-07 15:32:37698 return result;
Tim van der Lippe1d6e57a2019-09-30 11:55:34699 }
Erik Luo54fdd912018-11-01 17:57:01700 domModel.pushObjectAsNodeToFrontend(remoteObject).then(async node => {
Blink Reformat4c46d092018-04-07 15:32:37701 if (!node) {
702 result.appendChild(this._formatParameterAsObject(remoteObject, false));
703 return;
704 }
Tim van der Lippe9b2f8712020-02-12 17:46:22705 const renderResult = await UI.UIUtils.Renderer.render(/** @type {!Object} */ (node));
Erik Luofc6a6302018-11-02 06:48:52706 if (renderResult) {
Erik Luo840be6b2018-12-03 20:54:27707 if (renderResult.tree) {
Erik Luo383f21d2018-11-07 23:16:37708 this._selectableChildren.push(renderResult.tree);
Erik Luo840be6b2018-12-03 20:54:27709 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementAttached, this._messageResized);
710 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._messageResized);
711 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._messageResized);
712 }
Erik Luofc6a6302018-11-02 06:48:52713 result.appendChild(renderResult.node);
714 } else {
715 result.appendChild(this._formatParameterAsObject(remoteObject, false));
716 }
Erik Luo54fdd912018-11-01 17:57:01717 this._formattedParameterAsNodeForTest();
Blink Reformat4c46d092018-04-07 15:32:37718 });
719
720 return result;
721 }
722
723 _formattedParameterAsNodeForTest() {
724 }
725
726 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22727 * @param {!SDK.RemoteObject.RemoteObject} output
Sigurd Schneider53f33522020-10-08 15:00:49728 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37729 */
730 _formatParameterAsString(output) {
Sigurd Schneider53f33522020-10-08 15:00:49731 const span = /** @type {!HTMLElement} */ (document.createElement('span'));
Erik Luo383f21d2018-11-07 23:16:37732 span.appendChild(this._linkifyStringAsFragment(output.description || ''));
Blink Reformat4c46d092018-04-07 15:32:37733
Sigurd Schneider53f33522020-10-08 15:00:49734 const result = /** @type {!HTMLElement} */ (document.createElement('span'));
Blink Reformat4c46d092018-04-07 15:32:37735 result.createChild('span', 'object-value-string-quote').textContent = '"';
736 result.appendChild(span);
737 result.createChild('span', 'object-value-string-quote').textContent = '"';
738 return result;
739 }
740
741 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22742 * @param {!SDK.RemoteObject.RemoteObject} output
Sigurd Schneider53f33522020-10-08 15:00:49743 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37744 */
745 _formatParameterAsError(output) {
Sigurd Schneider53f33522020-10-08 15:00:49746 const result = /** @type {!HTMLElement} */ (document.createElement('span'));
Blink Reformat4c46d092018-04-07 15:32:37747 const errorSpan = this._tryFormatAsError(output.description || '');
Erik Luo383f21d2018-11-07 23:16:37748 result.appendChild(errorSpan ? errorSpan : this._linkifyStringAsFragment(output.description || ''));
Blink Reformat4c46d092018-04-07 15:32:37749 return result;
750 }
751
752 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22753 * @param {!SDK.RemoteObject.RemoteObject} output
Sigurd Schneider53f33522020-10-08 15:00:49754 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37755 */
756 _formatAsArrayEntry(output) {
Alfonso Castaño20d22cd2020-10-28 16:23:58757 return this._previewFormatter.renderPropertyPreview(
758 output.type, output.subtype, output.className, output.description);
Blink Reformat4c46d092018-04-07 15:32:37759 }
760
761 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22762 * @param {?SDK.RemoteObject.RemoteObject} object
Blink Reformat4c46d092018-04-07 15:32:37763 * @param {!Array.<string>} propertyPath
764 * @param {boolean} isArrayEntry
Sigurd Schneider53f33522020-10-08 15:00:49765 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37766 */
767 _formatAsAccessorProperty(object, propertyPath, isArrayEntry) {
Tim van der Lippe9b2f8712020-02-12 17:46:22768 const rootElement =
769 ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan(
770 object, propertyPath, onInvokeGetterClick.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37771
772 /**
Tim van der Lippe9b2f8712020-02-12 17:46:22773 * @param {!SDK.RemoteObject.CallFunctionResult} result
Tim van der Lippeeaacb722020-01-10 12:16:00774 * @this {ConsoleViewMessage}
Blink Reformat4c46d092018-04-07 15:32:37775 */
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18776 function onInvokeGetterClick(result) {
777 const wasThrown = result.wasThrown;
778 const object = result.object;
Tim van der Lippe1d6e57a2019-09-30 11:55:34779 if (!object) {
Blink Reformat4c46d092018-04-07 15:32:37780 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34781 }
Blink Reformat4c46d092018-04-07 15:32:37782 rootElement.removeChildren();
783 if (wasThrown) {
784 const element = rootElement.createChild('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22785 element.textContent = Common.UIString.UIString('<exception>');
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18786 element.title = /** @type {string} */ (object.description);
Blink Reformat4c46d092018-04-07 15:32:37787 } else if (isArrayEntry) {
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18788 rootElement.appendChild(this._formatAsArrayEntry(object));
Blink Reformat4c46d092018-04-07 15:32:37789 } else {
790 // Make a PropertyPreview from the RemoteObject similar to the backend logic.
791 const maxLength = 100;
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18792 const type = object.type;
793 const subtype = object.subtype;
Blink Reformat4c46d092018-04-07 15:32:37794 let description = '';
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18795 if (type !== 'function' && object.description) {
Alfonso Castaño20d22cd2020-10-28 16:23:58796 if (type === 'string' || subtype === 'regexp' || subtype === 'trustedtype') {
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18797 description = object.description.trimMiddle(maxLength);
Tim van der Lippe1d6e57a2019-09-30 11:55:34798 } else {
Tim van der Lippeffa78622019-09-16 12:07:12799 description = object.description.trimEndWithMaxLength(maxLength);
Tim van der Lippe1d6e57a2019-09-30 11:55:34800 }
Blink Reformat4c46d092018-04-07 15:32:37801 }
Alfonso Castaño20d22cd2020-10-28 16:23:58802 rootElement.appendChild(
803 this._previewFormatter.renderPropertyPreview(type, subtype, object.className, description));
Blink Reformat4c46d092018-04-07 15:32:37804 }
805 }
806
807 return rootElement;
808 }
809
810 /**
811 * @param {string} format
Tim van der Lippe9b2f8712020-02-12 17:46:22812 * @param {!Array.<!SDK.RemoteObject.RemoteObject>} parameters
Sigurd Schneider53f33522020-10-08 15:00:49813 * @param {!HTMLElement} formattedResult
Sigurd Schneider45f32c32020-10-13 13:32:05814 * @return {!{formattedResult:!Element, unusedSubstitutions: ?ArrayLike<!SDK.RemoteObject.RemoteObject>}}
Blink Reformat4c46d092018-04-07 15:32:37815 */
816 _formatWithSubstitutionString(format, parameters, formattedResult) {
Blink Reformat4c46d092018-04-07 15:32:37817 /**
818 * @param {boolean} force
819 * @param {boolean} includePreview
Sigurd Schneider45f32c32020-10-13 13:32:05820 * @param {!SDK.RemoteObject.RemoteObject|string|{description:string}|undefined} obj
821 * @return {!HTMLElement|string|undefined}
Tim van der Lippeeaacb722020-01-10 12:16:00822 * @this {ConsoleViewMessage}
Blink Reformat4c46d092018-04-07 15:32:37823 */
824 function parameterFormatter(force, includePreview, obj) {
Sigurd Schneider45f32c32020-10-13 13:32:05825 if (obj instanceof SDK.RemoteObject.RemoteObject) {
826 return this._formatParameter(obj, force, includePreview);
827 }
828 return stringFormatter(obj);
Blink Reformat4c46d092018-04-07 15:32:37829 }
830
Sigurd Schneider45f32c32020-10-13 13:32:05831 /**
832 * @param {!SDK.RemoteObject.RemoteObject|string|{description:string}|undefined} obj
833 */
Blink Reformat4c46d092018-04-07 15:32:37834 function stringFormatter(obj) {
Sigurd Schneider45f32c32020-10-13 13:32:05835 if (obj === undefined) {
836 return undefined;
837 }
838 if (typeof obj === 'string') {
839 return obj;
840 }
Blink Reformat4c46d092018-04-07 15:32:37841 return obj.description;
842 }
843
Sigurd Schneider45f32c32020-10-13 13:32:05844 /**
845 * @param {!SDK.RemoteObject.RemoteObject|string|{description:string}|undefined} obj
846 */
Blink Reformat4c46d092018-04-07 15:32:37847 function floatFormatter(obj) {
Sigurd Schneider45f32c32020-10-13 13:32:05848 if (obj instanceof SDK.RemoteObject.RemoteObject) {
849 if (typeof obj.value !== 'number') {
850 return 'NaN';
851 }
852 return obj.value;
Tim van der Lippe1d6e57a2019-09-30 11:55:34853 }
Sigurd Schneider45f32c32020-10-13 13:32:05854 return undefined;
Blink Reformat4c46d092018-04-07 15:32:37855 }
856
Sigurd Schneider45f32c32020-10-13 13:32:05857 /**
858 * @param {!SDK.RemoteObject.RemoteObject|string|{description:string}|undefined} obj
859 */
Blink Reformat4c46d092018-04-07 15:32:37860 function integerFormatter(obj) {
Sigurd Schneider45f32c32020-10-13 13:32:05861 if (obj instanceof SDK.RemoteObject.RemoteObject) {
862 if (obj.type === 'bigint') {
863 return obj.description;
864 }
865 if (typeof obj.value !== 'number') {
866 return 'NaN';
867 }
868 return Math.floor(obj.value);
Tim van der Lippe1d6e57a2019-09-30 11:55:34869 }
Sigurd Schneider45f32c32020-10-13 13:32:05870 return undefined;
Blink Reformat4c46d092018-04-07 15:32:37871 }
872
Sigurd Schneider45f32c32020-10-13 13:32:05873 /**
874 * @param {!SDK.RemoteObject.RemoteObject|string|{description:string}|undefined} obj
875 */
Blink Reformat4c46d092018-04-07 15:32:37876 function bypassFormatter(obj) {
877 return (obj instanceof Node) ? obj : '';
878 }
879
Sigurd Schneider45f32c32020-10-13 13:32:05880 /** @type {?Map<string, !{value:string, priority:string}>} */
Blink Reformat4c46d092018-04-07 15:32:37881 let currentStyle = null;
Sigurd Schneider45f32c32020-10-13 13:32:05882 /**
883 * @param {!SDK.RemoteObject.RemoteObject|string|{description:string}|undefined} obj
884 */
Blink Reformat4c46d092018-04-07 15:32:37885 function styleFormatter(obj) {
Sigurd Schneider45f32c32020-10-13 13:32:05886 currentStyle = new Map();
Sigurd Schneider53f33522020-10-08 15:00:49887 const buffer = document.createElement('span');
Sigurd Schneider45f32c32020-10-13 13:32:05888 if (obj === undefined) {
889 return;
890 }
891 if (typeof obj === 'string' || !obj.description) {
892 return;
893 }
Blink Reformat4c46d092018-04-07 15:32:37894 buffer.setAttribute('style', obj.description);
Sigurd Schneider45f32c32020-10-13 13:32:05895 for (const property of buffer.style) {
Mathias Bynens5165a7a2020-06-10 05:51:43896 if (isAllowedProperty(property)) {
Sigurd Schneider45f32c32020-10-13 13:32:05897 const info = {
898 value: buffer.style.getPropertyValue(property),
899 priority: buffer.style.getPropertyPriority(property)
900 };
901 currentStyle.set(property, info);
Tim van der Lippe1d6e57a2019-09-30 11:55:34902 }
Blink Reformat4c46d092018-04-07 15:32:37903 }
904 }
905
Sigurd Schneider45f32c32020-10-13 13:32:05906 /**
907 * @param {string} property
908 */
Mathias Bynens5165a7a2020-06-10 05:51:43909 function isAllowedProperty(property) {
Blink Reformat4c46d092018-04-07 15:32:37910 // Make sure that allowed properties do not interfere with link visibility.
911 const prefixes = [
912 'background', 'border', 'color', 'font', 'line', 'margin', 'padding', 'text', '-webkit-background',
913 '-webkit-border', '-webkit-font', '-webkit-margin', '-webkit-padding', '-webkit-text'
914 ];
Sigurd Schneider45f32c32020-10-13 13:32:05915 for (const prefix of prefixes) {
916 if (property.startsWith(prefix)) {
Blink Reformat4c46d092018-04-07 15:32:37917 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:34918 }
Blink Reformat4c46d092018-04-07 15:32:37919 }
920 return false;
921 }
922
Sigurd Schneider45f32c32020-10-13 13:32:05923 /** @type {!Object.<string, function((string|!{description: string}|undefined|!SDK.RemoteObject.RemoteObject), !Platform.StringUtilities.FORMATTER_TOKEN):*>} */
924 const formatters = {};
Blink Reformat4c46d092018-04-07 15:32:37925 // Firebug uses %o for formatting objects.
926 formatters.o = parameterFormatter.bind(this, false /* force */, true /* includePreview */);
927 formatters.s = stringFormatter;
928 formatters.f = floatFormatter;
929 // Firebug allows both %i and %d for formatting integers.
930 formatters.i = integerFormatter;
931 formatters.d = integerFormatter;
932
933 // Firebug uses %c for styling the message.
934 formatters.c = styleFormatter;
935
936 // Support %O to force object formatting, instead of the type-based %o formatting.
937 formatters.O = parameterFormatter.bind(this, true /* force */, false /* includePreview */);
938
939 formatters._ = bypassFormatter;
940
941 /**
Sigurd Schneider53f33522020-10-08 15:00:49942 * @param {!HTMLElement} a
Blink Reformat4c46d092018-04-07 15:32:37943 * @param {*} b
Tim van der Lippeeaacb722020-01-10 12:16:00944 * @this {!ConsoleViewMessage}
Sigurd Schneider53f33522020-10-08 15:00:49945 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:37946 */
947 function append(a, b) {
948 if (b instanceof Node) {
949 a.appendChild(b);
Erik Luo17926392018-05-17 22:06:12950 return a;
951 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34952 if (typeof b === 'undefined') {
Erik Luo17926392018-05-17 22:06:12953 return a;
Tim van der Lippe1d6e57a2019-09-30 11:55:34954 }
Erik Luo17926392018-05-17 22:06:12955 if (!currentStyle) {
Erik Luo383f21d2018-11-07 23:16:37956 a.appendChild(this._linkifyStringAsFragment(String(b)));
Erik Luo17926392018-05-17 22:06:12957 return a;
958 }
959 const lines = String(b).split('\n');
960 for (let i = 0; i < lines.length; i++) {
961 const line = lines[i];
Erik Luo383f21d2018-11-07 23:16:37962 const lineFragment = this._linkifyStringAsFragment(line);
Sigurd Schneider53f33522020-10-08 15:00:49963 const wrapper = /** @type {!HTMLElement} */ (document.createElement('span'));
Erik Luo17926392018-05-17 22:06:12964 wrapper.style.setProperty('contain', 'paint');
965 wrapper.style.setProperty('display', 'inline-block');
966 wrapper.style.setProperty('max-width', '100%');
967 wrapper.appendChild(lineFragment);
968 applyCurrentStyle(wrapper);
969 for (const child of wrapper.children) {
Sigurd Schneider53f33522020-10-08 15:00:49970 if (child.classList.contains('devtools-link') && child instanceof HTMLElement) {
Erik Luo17926392018-05-17 22:06:12971 this._applyForcedVisibleStyle(child);
Tim van der Lippe1d6e57a2019-09-30 11:55:34972 }
Blink Reformat4c46d092018-04-07 15:32:37973 }
Erik Luo17926392018-05-17 22:06:12974 a.appendChild(wrapper);
Tim van der Lippe1d6e57a2019-09-30 11:55:34975 if (i < lines.length - 1) {
Sigurd Schneider53f33522020-10-08 15:00:49976 a.appendChild(document.createElement('br'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34977 }
Blink Reformat4c46d092018-04-07 15:32:37978 }
979 return a;
980 }
981
982 /**
Sigurd Schneider53f33522020-10-08 15:00:49983 * @param {!HTMLElement} element
Blink Reformat4c46d092018-04-07 15:32:37984 */
985 function applyCurrentStyle(element) {
Sigurd Schneider45f32c32020-10-13 13:32:05986 if (!currentStyle) {
987 return;
988 }
989 for (const [property, {value, priority}] of currentStyle.entries()) {
990 element.style.setProperty(/** @type {string} */ (property), value, priority);
Tim van der Lippe1d6e57a2019-09-30 11:55:34991 }
Blink Reformat4c46d092018-04-07 15:32:37992 }
993
Tim van der Lippe93b57c32020-02-20 17:38:44994 // Platform.StringUtilities.format does treat formattedResult like a Builder, result is an object.
995 return Platform.StringUtilities.format(format, parameters, formatters, formattedResult, append.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37996 }
997
998 /**
Sigurd Schneider53f33522020-10-08 15:00:49999 * @param {!HTMLElement} element
Blink Reformat4c46d092018-04-07 15:32:371000 */
1001 _applyForcedVisibleStyle(element) {
1002 element.style.setProperty('-webkit-text-stroke', '0', 'important');
1003 element.style.setProperty('text-decoration', 'underline', 'important');
1004
Paul Lewisca569a52020-09-09 16:11:511005 const themedColor = ThemeSupport.ThemeSupport.instance().patchColorText(
1006 'rgb(33%, 33%, 33%)', ThemeSupport.ThemeSupport.ColorUsage.Foreground);
Blink Reformat4c46d092018-04-07 15:32:371007 element.style.setProperty('color', themedColor, 'important');
1008
1009 let backgroundColor = 'hsl(0, 0%, 100%)';
Tim van der Lippe9b2f8712020-02-12 17:46:221010 if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Blink Reformat4c46d092018-04-07 15:32:371011 backgroundColor = 'hsl(0, 100%, 97%)';
Tim van der Lippe9b2f8712020-02-12 17:46:221012 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning || this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371013 backgroundColor = 'hsl(50, 100%, 95%)';
Tim van der Lippe1d6e57a2019-09-30 11:55:341014 }
Paul Lewisca569a52020-09-09 16:11:511015 const themedBackgroundColor = ThemeSupport.ThemeSupport.instance().patchColorText(
1016 backgroundColor, ThemeSupport.ThemeSupport.ColorUsage.Background);
Blink Reformat4c46d092018-04-07 15:32:371017 element.style.setProperty('background-color', themedBackgroundColor, 'important');
1018 }
1019
1020 /**
Sigurd Schneider45f32c32020-10-13 13:32:051021 * @param {!RegExp} regexObject
Blink Reformat4c46d092018-04-07 15:32:371022 * @return {boolean}
1023 */
1024 matchesFilterRegex(regexObject) {
1025 regexObject.lastIndex = 0;
Erik Luo5976c8c2018-07-24 02:03:091026 const contentElement = this.contentElement();
1027 const anchorText = this._anchorElement ? this._anchorElement.deepTextContent() : '';
Sigurd Schneider45f32c32020-10-13 13:32:051028 return (!!anchorText && regexObject.test(anchorText.trim())) ||
Erik Luo5976c8c2018-07-24 02:03:091029 regexObject.test(contentElement.deepTextContent().slice(anchorText.length));
Blink Reformat4c46d092018-04-07 15:32:371030 }
1031
1032 /**
1033 * @param {string} filter
1034 * @return {boolean}
1035 */
1036 matchesFilterText(filter) {
1037 const text = this.contentElement().deepTextContent();
1038 return text.toLowerCase().includes(filter.toLowerCase());
1039 }
1040
1041 updateTimestamp() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341042 if (!this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371043 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341044 }
Blink Reformat4c46d092018-04-07 15:32:371045
Paul Lewis2d7d65c2020-03-16 17:26:301046 if (Common.Settings.Settings.instance().moduleSetting('consoleTimestampsEnabled').get()) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341047 if (!this._timestampElement) {
Sigurd Schneider53e98632020-10-26 15:29:501048 this._timestampElement = /** @type {!HTMLElement} */ (document.createElement('span'));
Tim van der Lippef49e2322020-05-01 15:03:091049 this._timestampElement.classList.add('console-timestamp');
Tim van der Lippe1d6e57a2019-09-30 11:55:341050 }
Tim van der Lippe9b2f8712020-02-12 17:46:221051 this._timestampElement.textContent = UI.UIUtils.formatTimestamp(this._message.timestamp, false) + ' ';
1052 this._timestampElement.title = UI.UIUtils.formatTimestamp(this._message.timestamp, true);
Blink Reformat4c46d092018-04-07 15:32:371053 this._contentElement.insertBefore(this._timestampElement, this._contentElement.firstChild);
1054 } else if (this._timestampElement) {
1055 this._timestampElement.remove();
Sigurd Schneider53e98632020-10-26 15:29:501056 this._timestampElement = null;
Blink Reformat4c46d092018-04-07 15:32:371057 }
Blink Reformat4c46d092018-04-07 15:32:371058 }
1059
1060 /**
1061 * @return {number}
1062 */
1063 nestingLevel() {
1064 return this._nestingLevel;
1065 }
1066
1067 /**
1068 * @param {boolean} inSimilarGroup
1069 * @param {boolean=} isLast
1070 */
1071 setInSimilarGroup(inSimilarGroup, isLast) {
1072 this._inSimilarGroup = inSimilarGroup;
1073 this._lastInSimilarGroup = inSimilarGroup && !!isLast;
1074 if (this._similarGroupMarker && !inSimilarGroup) {
1075 this._similarGroupMarker.remove();
1076 this._similarGroupMarker = null;
1077 } else if (this._element && !this._similarGroupMarker && inSimilarGroup) {
Sigurd Schneider53e98632020-10-26 15:29:501078 this._similarGroupMarker = /** @type {!HTMLElement} */ (document.createElement('div'));
Tim van der Lippef49e2322020-05-01 15:03:091079 this._similarGroupMarker.classList.add('nesting-level-marker');
Blink Reformat4c46d092018-04-07 15:32:371080 this._element.insertBefore(this._similarGroupMarker, this._element.firstChild);
1081 this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
1082 }
1083 }
1084
1085 /**
1086 * @return {boolean}
1087 */
1088 isLastInSimilarGroup() {
Sigurd Schneider45f32c32020-10-13 13:32:051089 return !!this._inSimilarGroup && !!this._lastInSimilarGroup;
Blink Reformat4c46d092018-04-07 15:32:371090 }
1091
1092 resetCloseGroupDecorationCount() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341093 if (!this._closeGroupDecorationCount) {
Blink Reformat4c46d092018-04-07 15:32:371094 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341095 }
Blink Reformat4c46d092018-04-07 15:32:371096 this._closeGroupDecorationCount = 0;
1097 this._updateCloseGroupDecorations();
1098 }
1099
1100 incrementCloseGroupDecorationCount() {
1101 ++this._closeGroupDecorationCount;
1102 this._updateCloseGroupDecorations();
1103 }
1104
1105 _updateCloseGroupDecorations() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341106 if (!this._nestingLevelMarkers) {
Blink Reformat4c46d092018-04-07 15:32:371107 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341108 }
Blink Reformat4c46d092018-04-07 15:32:371109 for (let i = 0, n = this._nestingLevelMarkers.length; i < n; ++i) {
1110 const marker = this._nestingLevelMarkers[i];
1111 marker.classList.toggle('group-closed', n - i <= this._closeGroupDecorationCount);
1112 }
1113 }
1114
1115 /**
Erik Luo0b8282e2018-10-08 20:37:461116 * @return {number}
1117 */
1118 _focusedChildIndex() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341119 if (!this._selectableChildren.length) {
Erik Luo0b8282e2018-10-08 20:37:461120 return -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341121 }
Erik Luo383f21d2018-11-07 23:16:371122 return this._selectableChildren.findIndex(child => child.element.hasFocus());
Erik Luo0b8282e2018-10-08 20:37:461123 }
1124
1125 /**
Sigurd Schneider45f32c32020-10-13 13:32:051126 * @param {!KeyboardEvent} event
Erik Luo8ef5d0c2018-09-25 21:16:001127 */
1128 _onKeyDown(event) {
Sigurd Schneider45f32c32020-10-13 13:32:051129 if (UI.UIUtils.isEditing() || !this._element || !this._element.hasFocus() || this._element.hasSelection()) {
Erik Luo8ef5d0c2018-09-25 21:16:001130 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341131 }
1132 if (this.maybeHandleOnKeyDown(event)) {
Erik Luo8ef5d0c2018-09-25 21:16:001133 event.consume(true);
Tim van der Lippe1d6e57a2019-09-30 11:55:341134 }
Erik Luo8ef5d0c2018-09-25 21:16:001135 }
1136
1137 /**
1138 * @protected
Sigurd Schneider45f32c32020-10-13 13:32:051139 * @param {!KeyboardEvent} event
Erik Luo8ef5d0c2018-09-25 21:16:001140 */
1141 maybeHandleOnKeyDown(event) {
1142 // Handle trace expansion.
Erik Luo0b8282e2018-10-08 20:37:461143 const focusedChildIndex = this._focusedChildIndex();
1144 const isWrapperFocused = focusedChildIndex === -1;
1145 if (this._expandTrace && isWrapperFocused) {
Erik Luo8ef5d0c2018-09-25 21:16:001146 if ((event.key === 'ArrowLeft' && this._traceExpanded) || (event.key === 'ArrowRight' && !this._traceExpanded)) {
1147 this._expandTrace(!this._traceExpanded);
1148 return true;
1149 }
1150 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341151 if (!this._selectableChildren.length) {
Erik Luo0b8282e2018-10-08 20:37:461152 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341153 }
Erik Luo0b8282e2018-10-08 20:37:461154
1155 if (event.key === 'ArrowLeft') {
Sigurd Schneider45f32c32020-10-13 13:32:051156 this._element && this._element.focus();
Erik Luo0b8282e2018-10-08 20:37:461157 return true;
1158 }
1159 if (event.key === 'ArrowRight') {
Tim van der Lippe1d6e57a2019-09-30 11:55:341160 if (isWrapperFocused && this._selectNearestVisibleChild(0)) {
Erik Luo0b8282e2018-10-08 20:37:461161 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341162 }
Erik Luo0b8282e2018-10-08 20:37:461163 }
1164 if (event.key === 'ArrowUp') {
Erik Luo182bece2018-11-29 03:15:221165 const firstVisibleChild = this._nearestVisibleChild(0);
1166 if (this._selectableChildren[focusedChildIndex] === firstVisibleChild && firstVisibleChild) {
Sigurd Schneider45f32c32020-10-13 13:32:051167 this._element && this._element.focus();
Erik Luo0b8282e2018-10-08 20:37:461168 return true;
Mathias Bynensf06e8c02020-02-28 13:58:281169 }
1170 if (this._selectNearestVisibleChild(focusedChildIndex - 1, true /* backwards */)) {
Erik Luo0b8282e2018-10-08 20:37:461171 return true;
1172 }
1173 }
1174 if (event.key === 'ArrowDown') {
Tim van der Lippe1d6e57a2019-09-30 11:55:341175 if (isWrapperFocused && this._selectNearestVisibleChild(0)) {
Erik Luo0b8282e2018-10-08 20:37:461176 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341177 }
1178 if (!isWrapperFocused && this._selectNearestVisibleChild(focusedChildIndex + 1)) {
Erik Luo0b8282e2018-10-08 20:37:461179 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341180 }
Erik Luo0b8282e2018-10-08 20:37:461181 }
Erik Luo8ef5d0c2018-09-25 21:16:001182 return false;
1183 }
1184
Erik Luo182bece2018-11-29 03:15:221185 /**
1186 * @param {number} fromIndex
1187 * @param {boolean=} backwards
1188 * @return {boolean}
1189 */
1190 _selectNearestVisibleChild(fromIndex, backwards) {
1191 const nearestChild = this._nearestVisibleChild(fromIndex, backwards);
1192 if (nearestChild) {
Erik Luo31c21f62018-12-13 03:39:391193 nearestChild.forceSelect();
Erik Luo182bece2018-11-29 03:15:221194 return true;
1195 }
1196 return false;
1197 }
1198
1199 /**
1200 * @param {number} fromIndex
1201 * @param {boolean=} backwards
Erik Luo31c21f62018-12-13 03:39:391202 * @return {?{element: !Element, forceSelect: function()}}
Erik Luo182bece2018-11-29 03:15:221203 */
1204 _nearestVisibleChild(fromIndex, backwards) {
1205 const childCount = this._selectableChildren.length;
Tim van der Lippe1d6e57a2019-09-30 11:55:341206 if (fromIndex < 0 || fromIndex >= childCount) {
Erik Luo182bece2018-11-29 03:15:221207 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341208 }
Erik Luo182bece2018-11-29 03:15:221209 const direction = backwards ? -1 : 1;
1210 let index = fromIndex;
1211
1212 while (!this._selectableChildren[index].element.offsetParent) {
1213 index += direction;
Tim van der Lippe1d6e57a2019-09-30 11:55:341214 if (index < 0 || index >= childCount) {
Erik Luo182bece2018-11-29 03:15:221215 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341216 }
Erik Luo182bece2018-11-29 03:15:221217 }
1218 return this._selectableChildren[index];
1219 }
1220
Sigurd Schneider53f33522020-10-08 15:00:491221 /**
1222 * @override
1223 */
Erik Luo0b8282e2018-10-08 20:37:461224 focusLastChildOrSelf() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341225 if (this._element && !this._selectNearestVisibleChild(this._selectableChildren.length - 1, true /* backwards */)) {
Erik Luo0b8282e2018-10-08 20:37:461226 this._element.focus();
Tim van der Lippe1d6e57a2019-09-30 11:55:341227 }
Erik Luo0b8282e2018-10-08 20:37:461228 }
1229
1230 /**
Sigurd Schneiderb2953b22020-10-09 09:30:151231 * @protected
1232 * @param {!HTMLElement} element
1233 */
1234 setContentElement(element) {
1235 console.assert(!this._contentElement, 'Cannot set content element twice');
1236 this._contentElement = element;
1237 }
1238
Sigurd Schneiderb2953b22020-10-09 09:30:151239 /**
1240 * @protected
1241 * @return {?HTMLElement}
1242 */
1243 getContentElement() {
1244 return this._contentElement;
1245 }
1246
1247 /**
Sigurd Schneider53f33522020-10-08 15:00:491248 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:371249 */
1250 contentElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341251 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371252 return this._contentElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:341253 }
Blink Reformat4c46d092018-04-07 15:32:371254
Sigurd Schneider53f33522020-10-08 15:00:491255 const contentElement = /** @type {!HTMLElement} */ (document.createElement('div'));
Tim van der Lippef49e2322020-05-01 15:03:091256 contentElement.classList.add('console-message');
Tim van der Lippe1d6e57a2019-09-30 11:55:341257 if (this._messageLevelIcon) {
Blink Reformat4c46d092018-04-07 15:32:371258 contentElement.appendChild(this._messageLevelIcon);
Tim van der Lippe1d6e57a2019-09-30 11:55:341259 }
Blink Reformat4c46d092018-04-07 15:32:371260 this._contentElement = contentElement;
1261
Sigurd Schneider45f32c32020-10-13 13:32:051262 const runtimeModel = this._message.runtimeModel();
Blink Reformat4c46d092018-04-07 15:32:371263 let formattedMessage;
1264 const shouldIncludeTrace = !!this._message.stackTrace &&
Tim van der Lippe9b2f8712020-02-12 17:46:221265 (this._message.source === SDK.ConsoleModel.MessageSource.Network ||
1266 this._message.source === SDK.ConsoleModel.MessageSource.Violation ||
1267 this._message.level === SDK.ConsoleModel.MessageLevel.Error ||
1268 this._message.level === SDK.ConsoleModel.MessageLevel.Warning ||
1269 this._message.type === SDK.ConsoleModel.MessageType.Trace);
Sigurd Schneider45f32c32020-10-13 13:32:051270 if (runtimeModel && shouldIncludeTrace) {
1271 formattedMessage = this._buildMessageWithStackTrace(runtimeModel);
Tim van der Lippe1d6e57a2019-09-30 11:55:341272 } else {
Blink Reformat4c46d092018-04-07 15:32:371273 formattedMessage = this._buildMessage();
Tim van der Lippe1d6e57a2019-09-30 11:55:341274 }
Blink Reformat4c46d092018-04-07 15:32:371275 contentElement.appendChild(formattedMessage);
1276
1277 this.updateTimestamp();
1278 return this._contentElement;
1279 }
1280
1281 /**
Sigurd Schneider53f33522020-10-08 15:00:491282 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:371283 */
1284 toMessageElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341285 if (this._element) {
Blink Reformat4c46d092018-04-07 15:32:371286 return this._element;
Tim van der Lippe1d6e57a2019-09-30 11:55:341287 }
Blink Reformat4c46d092018-04-07 15:32:371288
Sigurd Schneider53f33522020-10-08 15:00:491289 this._element = /** @type {!HTMLElement} */ (document.createElement('div'));
Pavel Feldmandb310912019-01-30 00:31:201290 this._element.tabIndex = -1;
Sigurd Schneider45f32c32020-10-13 13:32:051291 this._element.addEventListener('keydown', /** @type {!EventListener} */ (this._onKeyDown.bind(this)));
Blink Reformat4c46d092018-04-07 15:32:371292 this.updateMessageElement();
1293 return this._element;
1294 }
1295
1296 updateMessageElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341297 if (!this._element) {
Blink Reformat4c46d092018-04-07 15:32:371298 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341299 }
Blink Reformat4c46d092018-04-07 15:32:371300
1301 this._element.className = 'console-message-wrapper';
1302 this._element.removeChildren();
Tim van der Lippe1d6e57a2019-09-30 11:55:341303 if (this._message.isGroupStartMessage()) {
Blink Reformat4c46d092018-04-07 15:32:371304 this._element.classList.add('console-group-title');
Tim van der Lippe1d6e57a2019-09-30 11:55:341305 }
Tim van der Lippe9b2f8712020-02-12 17:46:221306 if (this._message.source === SDK.ConsoleModel.MessageSource.ConsoleAPI) {
Blink Reformat4c46d092018-04-07 15:32:371307 this._element.classList.add('console-from-api');
Tim van der Lippe1d6e57a2019-09-30 11:55:341308 }
Blink Reformat4c46d092018-04-07 15:32:371309 if (this._inSimilarGroup) {
Sigurd Schneider53e98632020-10-26 15:29:501310 this._similarGroupMarker = /** @type {!HTMLElement} */ (this._element.createChild('div', 'nesting-level-marker'));
Blink Reformat4c46d092018-04-07 15:32:371311 this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
1312 }
1313
1314 this._nestingLevelMarkers = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341315 for (let i = 0; i < this._nestingLevel; ++i) {
Blink Reformat4c46d092018-04-07 15:32:371316 this._nestingLevelMarkers.push(this._element.createChild('div', 'nesting-level-marker'));
Tim van der Lippe1d6e57a2019-09-30 11:55:341317 }
Blink Reformat4c46d092018-04-07 15:32:371318 this._updateCloseGroupDecorations();
Sigurd Schneiderca7b4ff2020-10-14 07:45:471319 elementToMessage.set(this._element, this);
Blink Reformat4c46d092018-04-07 15:32:371320
1321 switch (this._message.level) {
Tim van der Lippe9b2f8712020-02-12 17:46:221322 case SDK.ConsoleModel.MessageLevel.Verbose:
Blink Reformat4c46d092018-04-07 15:32:371323 this._element.classList.add('console-verbose-level');
Blink Reformat4c46d092018-04-07 15:32:371324 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221325 case SDK.ConsoleModel.MessageLevel.Info:
Blink Reformat4c46d092018-04-07 15:32:371326 this._element.classList.add('console-info-level');
Tim van der Lippe9b2f8712020-02-12 17:46:221327 if (this._message.type === SDK.ConsoleModel.MessageType.System) {
Blink Reformat4c46d092018-04-07 15:32:371328 this._element.classList.add('console-system-type');
Tim van der Lippe1d6e57a2019-09-30 11:55:341329 }
Blink Reformat4c46d092018-04-07 15:32:371330 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221331 case SDK.ConsoleModel.MessageLevel.Warning:
Blink Reformat4c46d092018-04-07 15:32:371332 this._element.classList.add('console-warning-level');
Blink Reformat4c46d092018-04-07 15:32:371333 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221334 case SDK.ConsoleModel.MessageLevel.Error:
Blink Reformat4c46d092018-04-07 15:32:371335 this._element.classList.add('console-error-level');
Blink Reformat4c46d092018-04-07 15:32:371336 break;
1337 }
Erik Luofd3e7d42018-09-25 02:12:351338 this._updateMessageLevelIcon();
Tim van der Lippe1d6e57a2019-09-30 11:55:341339 if (this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371340 this._element.classList.add('console-warning-level');
Tim van der Lippe1d6e57a2019-09-30 11:55:341341 }
Blink Reformat4c46d092018-04-07 15:32:371342
1343 this._element.appendChild(this.contentElement());
Tim van der Lippe1d6e57a2019-09-30 11:55:341344 if (this._repeatCount > 1) {
Blink Reformat4c46d092018-04-07 15:32:371345 this._showRepeatCountElement();
Tim van der Lippe1d6e57a2019-09-30 11:55:341346 }
Blink Reformat4c46d092018-04-07 15:32:371347 }
1348
1349 /**
1350 * @return {boolean}
1351 */
1352 _shouldRenderAsWarning() {
Tim van der Lippe9b2f8712020-02-12 17:46:221353 return (this._message.level === SDK.ConsoleModel.MessageLevel.Verbose ||
1354 this._message.level === SDK.ConsoleModel.MessageLevel.Info) &&
1355 (this._message.source === SDK.ConsoleModel.MessageSource.Violation ||
1356 this._message.source === SDK.ConsoleModel.MessageSource.Deprecation ||
1357 this._message.source === SDK.ConsoleModel.MessageSource.Intervention ||
1358 this._message.source === SDK.ConsoleModel.MessageSource.Recommendation);
Blink Reformat4c46d092018-04-07 15:32:371359 }
1360
Erik Luofd3e7d42018-09-25 02:12:351361 _updateMessageLevelIcon() {
1362 let iconType = '';
1363 let accessibleName = '';
Tim van der Lippe9b2f8712020-02-12 17:46:221364 if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning) {
Erik Luofd3e7d42018-09-25 02:12:351365 iconType = 'smallicon-warning';
1366 accessibleName = ls`Warning`;
Tim van der Lippe9b2f8712020-02-12 17:46:221367 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Erik Luofd3e7d42018-09-25 02:12:351368 iconType = 'smallicon-error';
1369 accessibleName = ls`Error`;
1370 }
Sigurd Schneider45f32c32020-10-13 13:32:051371 if (!this._messageLevelIcon) {
1372 if (!iconType) {
1373 return;
1374 }
Tim van der Lippe9b2f8712020-02-12 17:46:221375 this._messageLevelIcon = UI.Icon.Icon.create('', 'message-level-icon');
Tim van der Lippe1d6e57a2019-09-30 11:55:341376 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371377 this._contentElement.insertBefore(this._messageLevelIcon, this._contentElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341378 }
Blink Reformat4c46d092018-04-07 15:32:371379 }
1380 this._messageLevelIcon.setIconType(iconType);
Erik Luofd3e7d42018-09-25 02:12:351381 UI.ARIAUtils.setAccessibleName(this._messageLevelIcon, accessibleName);
Blink Reformat4c46d092018-04-07 15:32:371382 }
1383
1384 /**
1385 * @return {number}
1386 */
1387 repeatCount() {
1388 return this._repeatCount || 1;
1389 }
1390
1391 resetIncrementRepeatCount() {
1392 this._repeatCount = 1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341393 if (!this._repeatCountElement) {
Blink Reformat4c46d092018-04-07 15:32:371394 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341395 }
Blink Reformat4c46d092018-04-07 15:32:371396
1397 this._repeatCountElement.remove();
Tim van der Lippe1d6e57a2019-09-30 11:55:341398 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371399 this._contentElement.classList.remove('repeated-message');
Tim van der Lippe1d6e57a2019-09-30 11:55:341400 }
Sigurd Schneider53e98632020-10-26 15:29:501401 this._repeatCountElement = null;
Blink Reformat4c46d092018-04-07 15:32:371402 }
1403
1404 incrementRepeatCount() {
1405 this._repeatCount++;
1406 this._showRepeatCountElement();
1407 }
1408
1409 /**
1410 * @param {number} repeatCount
1411 */
1412 setRepeatCount(repeatCount) {
1413 this._repeatCount = repeatCount;
1414 this._showRepeatCountElement();
1415 }
1416
Tim van der Lippeee954d42020-05-04 10:35:571417 /**
1418 * @suppress {checkTypes}
1419 */
Blink Reformat4c46d092018-04-07 15:32:371420 _showRepeatCountElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341421 if (!this._element) {
Blink Reformat4c46d092018-04-07 15:32:371422 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341423 }
Blink Reformat4c46d092018-04-07 15:32:371424
1425 if (!this._repeatCountElement) {
Sigurd Schneider45f32c32020-10-13 13:32:051426 this._repeatCountElement =
1427 /** @type {!UI.UIUtils.DevToolsSmallBubble} */ (document.createElement('span', {is: 'dt-small-bubble'}));
Tim van der Lippeee954d42020-05-04 10:35:571428 this._repeatCountElement.classList.add('console-message-repeat-count');
Blink Reformat4c46d092018-04-07 15:32:371429 switch (this._message.level) {
Tim van der Lippe9b2f8712020-02-12 17:46:221430 case SDK.ConsoleModel.MessageLevel.Warning:
Blink Reformat4c46d092018-04-07 15:32:371431 this._repeatCountElement.type = 'warning';
1432 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221433 case SDK.ConsoleModel.MessageLevel.Error:
Blink Reformat4c46d092018-04-07 15:32:371434 this._repeatCountElement.type = 'error';
1435 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221436 case SDK.ConsoleModel.MessageLevel.Verbose:
Blink Reformat4c46d092018-04-07 15:32:371437 this._repeatCountElement.type = 'verbose';
1438 break;
1439 default:
1440 this._repeatCountElement.type = 'info';
1441 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341442 if (this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371443 this._repeatCountElement.type = 'warning';
Tim van der Lippe1d6e57a2019-09-30 11:55:341444 }
Blink Reformat4c46d092018-04-07 15:32:371445
1446 this._element.insertBefore(this._repeatCountElement, this._contentElement);
Sigurd Schneider45f32c32020-10-13 13:32:051447 this.contentElement().classList.add('repeated-message');
Blink Reformat4c46d092018-04-07 15:32:371448 }
Sigurd Schneider45f32c32020-10-13 13:32:051449 this._repeatCountElement.textContent = `${this._repeatCount}`;
Erik Luofd3e7d42018-09-25 02:12:351450 let accessibleName = ls`Repeat ${this._repeatCount}`;
Tim van der Lippe9b2f8712020-02-12 17:46:221451 if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning) {
Erik Luofd3e7d42018-09-25 02:12:351452 accessibleName = ls`Warning ${accessibleName}`;
Tim van der Lippe9b2f8712020-02-12 17:46:221453 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Erik Luofd3e7d42018-09-25 02:12:351454 accessibleName = ls`Error ${accessibleName}`;
Tim van der Lippe1d6e57a2019-09-30 11:55:341455 }
Erik Luofd3e7d42018-09-25 02:12:351456 UI.ARIAUtils.setAccessibleName(this._repeatCountElement, accessibleName);
Blink Reformat4c46d092018-04-07 15:32:371457 }
1458
1459 get text() {
1460 return this._message.messageText;
1461 }
1462
1463 /**
1464 * @return {string}
1465 */
1466 toExportString() {
1467 const lines = [];
1468 const nodes = this.contentElement().childTextNodes();
Tim van der Lippe9b2f8712020-02-12 17:46:221469 const messageContent = nodes.map(Components.Linkifier.Linkifier.untruncatedNodeText).join('');
Tim van der Lippe1d6e57a2019-09-30 11:55:341470 for (let i = 0; i < this.repeatCount(); ++i) {
Blink Reformat4c46d092018-04-07 15:32:371471 lines.push(messageContent);
Tim van der Lippe1d6e57a2019-09-30 11:55:341472 }
Blink Reformat4c46d092018-04-07 15:32:371473 return lines.join('\n');
1474 }
1475
1476 /**
1477 * @param {?RegExp} regex
1478 */
1479 setSearchRegex(regex) {
Sigurd Schneidere8e75cf2020-10-13 08:17:521480 if (this._searchHighlightNodeChanges && this._searchHighlightNodeChanges.length) {
1481 UI.UIUtils.revertDomChanges(this._searchHighlightNodeChanges);
Tim van der Lippe1d6e57a2019-09-30 11:55:341482 }
Blink Reformat4c46d092018-04-07 15:32:371483 this._searchRegex = regex;
1484 this._searchHighlightNodes = [];
Sigurd Schneidere8e75cf2020-10-13 08:17:521485 this._searchHighlightNodeChanges = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341486 if (!this._searchRegex) {
Blink Reformat4c46d092018-04-07 15:32:371487 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341488 }
Blink Reformat4c46d092018-04-07 15:32:371489
1490 const text = this.contentElement().deepTextContent();
1491 let match;
1492 this._searchRegex.lastIndex = 0;
1493 const sourceRanges = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341494 while ((match = this._searchRegex.exec(text)) && match[0]) {
Tim van der Lippe9b2f8712020-02-12 17:46:221495 sourceRanges.push(new TextUtils.TextRange.SourceRange(match.index, match[0].length));
Tim van der Lippe1d6e57a2019-09-30 11:55:341496 }
Blink Reformat4c46d092018-04-07 15:32:371497
1498 if (sourceRanges.length) {
1499 this._searchHighlightNodes =
Sigurd Schneidere8e75cf2020-10-13 08:17:521500 UI.UIUtils.highlightSearchResults(this.contentElement(), sourceRanges, this._searchHighlightNodeChanges);
Blink Reformat4c46d092018-04-07 15:32:371501 }
1502 }
1503
1504 /**
1505 * @return {?RegExp}
1506 */
1507 searchRegex() {
1508 return this._searchRegex;
1509 }
1510
1511 /**
1512 * @return {number}
1513 */
1514 searchCount() {
1515 return this._searchHighlightNodes.length;
1516 }
1517
1518 /**
Sigurd Schneider45f32c32020-10-13 13:32:051519 * @param {number} index
1520 * @return {!Element}
Blink Reformat4c46d092018-04-07 15:32:371521 */
1522 searchHighlightNode(index) {
1523 return this._searchHighlightNodes[index];
1524 }
1525
1526 /**
1527 * @param {string} string
Sigurd Schneider53f33522020-10-08 15:00:491528 * @return {?HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:371529 */
1530 _tryFormatAsError(string) {
1531 /**
1532 * @param {string} prefix
1533 */
1534 function startsWith(prefix) {
1535 return string.startsWith(prefix);
1536 }
1537
Sigurd Schneider45f32c32020-10-13 13:32:051538 const runtimeModel = this._message.runtimeModel();
Blink Reformat4c46d092018-04-07 15:32:371539 const errorPrefixes =
1540 ['EvalError', 'ReferenceError', 'SyntaxError', 'TypeError', 'RangeError', 'Error', 'URIError'];
Sigurd Schneider45f32c32020-10-13 13:32:051541 if (!runtimeModel || !errorPrefixes.some(startsWith)) {
Blink Reformat4c46d092018-04-07 15:32:371542 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341543 }
Sigurd Schneider45f32c32020-10-13 13:32:051544 const debuggerModel = runtimeModel.debuggerModel();
1545 const baseURL = runtimeModel.target().inspectedURL();
Blink Reformat4c46d092018-04-07 15:32:371546
1547 const lines = string.split('\n');
1548 const links = [];
1549 let position = 0;
1550 for (let i = 0; i < lines.length; ++i) {
1551 position += i > 0 ? lines[i - 1].length + 1 : 0;
1552 const isCallFrameLine = /^\s*at\s/.test(lines[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:341553 if (!isCallFrameLine && links.length) {
Blink Reformat4c46d092018-04-07 15:32:371554 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341555 }
Blink Reformat4c46d092018-04-07 15:32:371556
Tim van der Lippe1d6e57a2019-09-30 11:55:341557 if (!isCallFrameLine) {
Blink Reformat4c46d092018-04-07 15:32:371558 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341559 }
Blink Reformat4c46d092018-04-07 15:32:371560
1561 let openBracketIndex = -1;
1562 let closeBracketIndex = -1;
Yang Guo39256bd2019-07-18 06:02:251563 const inBracketsWithLineAndColumn = /\([^\)\(]+:\d+:\d+\)/g;
1564 const inBrackets = /\([^\)\(]+\)/g;
1565 let lastMatch = null;
1566 let currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341567 while ((currentMatch = inBracketsWithLineAndColumn.exec(lines[i]))) {
Yang Guo39256bd2019-07-18 06:02:251568 lastMatch = currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341569 }
Yang Guo39256bd2019-07-18 06:02:251570 if (!lastMatch) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341571 while ((currentMatch = inBrackets.exec(lines[i]))) {
Yang Guo39256bd2019-07-18 06:02:251572 lastMatch = currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341573 }
Yang Guo39256bd2019-07-18 06:02:251574 }
1575 if (lastMatch) {
1576 openBracketIndex = lastMatch.index;
1577 closeBracketIndex = lastMatch.index + lastMatch[0].length - 1;
Blink Reformat4c46d092018-04-07 15:32:371578 }
1579 const hasOpenBracket = openBracketIndex !== -1;
1580 const left = hasOpenBracket ? openBracketIndex + 1 : lines[i].indexOf('at') + 3;
1581 const right = hasOpenBracket ? closeBracketIndex : lines[i].length;
1582 const linkCandidate = lines[i].substring(left, right);
Tim van der Lippe9b2f8712020-02-12 17:46:221583 const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(linkCandidate);
Tim van der Lippe1d6e57a2019-09-30 11:55:341584 if (!splitResult) {
Blink Reformat4c46d092018-04-07 15:32:371585 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341586 }
Blink Reformat4c46d092018-04-07 15:32:371587
Tim van der Lippe1d6e57a2019-09-30 11:55:341588 if (splitResult.url === '<anonymous>') {
Blink Reformat4c46d092018-04-07 15:32:371589 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341590 }
Blink Reformat4c46d092018-04-07 15:32:371591 let url = parseOrScriptMatch(splitResult.url);
Tim van der Lippe9b2f8712020-02-12 17:46:221592 if (!url && Common.ParsedURL.ParsedURL.isRelativeURL(splitResult.url)) {
1593 url = parseOrScriptMatch(Common.ParsedURL.ParsedURL.completeURL(baseURL, splitResult.url));
Tim van der Lippe1d6e57a2019-09-30 11:55:341594 }
1595 if (!url) {
Blink Reformat4c46d092018-04-07 15:32:371596 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341597 }
Blink Reformat4c46d092018-04-07 15:32:371598
1599 links.push({
1600 url: url,
1601 positionLeft: position + left,
1602 positionRight: position + right,
1603 lineNumber: splitResult.lineNumber,
1604 columnNumber: splitResult.columnNumber
1605 });
1606 }
1607
Tim van der Lippe1d6e57a2019-09-30 11:55:341608 if (!links.length) {
Blink Reformat4c46d092018-04-07 15:32:371609 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341610 }
Blink Reformat4c46d092018-04-07 15:32:371611
Sigurd Schneider53f33522020-10-08 15:00:491612 const formattedResult = /** @type {!HTMLElement} */ (document.createElement('span'));
Blink Reformat4c46d092018-04-07 15:32:371613 let start = 0;
1614 for (let i = 0; i < links.length; ++i) {
Erik Luo383f21d2018-11-07 23:16:371615 formattedResult.appendChild(this._linkifyStringAsFragment(string.substring(start, links[i].positionLeft)));
Erik Luo182bece2018-11-29 03:15:221616 const scriptLocationLink = this._linkifier.linkifyScriptLocation(
Sigurd Schneider45f32c32020-10-13 13:32:051617 debuggerModel.target(), null, links[i].url, links[i].lineNumber,
1618 {columnNumber: links[i].columnNumber, className: undefined, tabStop: undefined});
Erik Luo182bece2018-11-29 03:15:221619 scriptLocationLink.tabIndex = -1;
Erik Luo31c21f62018-12-13 03:39:391620 this._selectableChildren.push({element: scriptLocationLink, forceSelect: () => scriptLocationLink.focus()});
Erik Luo182bece2018-11-29 03:15:221621 formattedResult.appendChild(scriptLocationLink);
Blink Reformat4c46d092018-04-07 15:32:371622 start = links[i].positionRight;
1623 }
1624
Tim van der Lippe1d6e57a2019-09-30 11:55:341625 if (start !== string.length) {
Erik Luo383f21d2018-11-07 23:16:371626 formattedResult.appendChild(this._linkifyStringAsFragment(string.substring(start)));
Tim van der Lippe1d6e57a2019-09-30 11:55:341627 }
Blink Reformat4c46d092018-04-07 15:32:371628
1629 return formattedResult;
1630
1631 /**
1632 * @param {?string} url
1633 * @return {?string}
1634 */
1635 function parseOrScriptMatch(url) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341636 if (!url) {
Blink Reformat4c46d092018-04-07 15:32:371637 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341638 }
Tim van der Lippe9b2f8712020-02-12 17:46:221639 const parsedURL = Common.ParsedURL.ParsedURL.fromString(url);
Tim van der Lippe1d6e57a2019-09-30 11:55:341640 if (parsedURL) {
Blink Reformat4c46d092018-04-07 15:32:371641 return parsedURL.url;
Tim van der Lippe1d6e57a2019-09-30 11:55:341642 }
1643 if (debuggerModel.scriptsForSourceURL(url).length) {
Blink Reformat4c46d092018-04-07 15:32:371644 return url;
Tim van der Lippe1d6e57a2019-09-30 11:55:341645 }
Blink Reformat4c46d092018-04-07 15:32:371646 return null;
1647 }
1648 }
1649
1650 /**
1651 * @param {string} string
1652 * @param {function(string,string,number=,number=):!Node} linkifier
1653 * @return {!DocumentFragment}
Tim van der Lippeeaacb722020-01-10 12:16:001654 * @suppress {accessControls}
Blink Reformat4c46d092018-04-07 15:32:371655 */
Erik Luofc2214f2018-11-21 19:54:581656 _linkifyWithCustomLinkifier(string, linkifier) {
Sigurd Schneider8f4ac862020-10-13 13:30:111657 if (string.length > getMaxTokenizableStringLength()) {
Tim van der Lippe9b2f8712020-02-12 17:46:221658 const propertyValue = new ObjectUI.ObjectPropertiesSection.ExpandableTextPropertyValue(
Sigurd Schneider8f4ac862020-10-13 13:30:111659 document.createElement('span'), string, getLongStringVisibleLength());
Sigurd Schneider45f32c32020-10-13 13:32:051660 const fragment = document.createDocumentFragment();
Connor Moody1a5c0d32019-12-19 07:23:361661 fragment.appendChild(propertyValue.element);
1662 return fragment;
Tim van der Lippe1d6e57a2019-09-30 11:55:341663 }
Sigurd Schneider45f32c32020-10-13 13:32:051664 const container = document.createDocumentFragment();
Tim van der Lippeeaacb722020-01-10 12:16:001665 const tokens = ConsoleViewMessage._tokenizeMessageText(string);
Blink Reformat4c46d092018-04-07 15:32:371666 for (const token of tokens) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341667 if (!token.text) {
Erik Luofc2214f2018-11-21 19:54:581668 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341669 }
Blink Reformat4c46d092018-04-07 15:32:371670 switch (token.type) {
1671 case 'url': {
1672 const realURL = (token.text.startsWith('www.') ? 'http://' + token.text : token.text);
Tim van der Lippe9b2f8712020-02-12 17:46:221673 const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(realURL);
Kim-Anh Tran9e49a452020-02-17 09:46:101674 const sourceURL = Common.ParsedURL.ParsedURL.removeWasmFunctionInfoFromURL(splitResult.url);
Blink Reformat4c46d092018-04-07 15:32:371675 let linkNode;
Tim van der Lippe1d6e57a2019-09-30 11:55:341676 if (splitResult) {
Kim-Anh Tran9e49a452020-02-17 09:46:101677 linkNode = linkifier(token.text, sourceURL, splitResult.lineNumber, splitResult.columnNumber);
Tim van der Lippe1d6e57a2019-09-30 11:55:341678 } else {
Sigurd Schneider45f32c32020-10-13 13:32:051679 linkNode = linkifier(token.text, '');
Tim van der Lippe1d6e57a2019-09-30 11:55:341680 }
Blink Reformat4c46d092018-04-07 15:32:371681 container.appendChild(linkNode);
1682 break;
1683 }
1684 default:
Sigurd Schneider45f32c32020-10-13 13:32:051685 container.appendChild(document.createTextNode(token.text));
Blink Reformat4c46d092018-04-07 15:32:371686 break;
1687 }
1688 }
1689 return container;
1690 }
1691
1692 /**
Blink Reformat4c46d092018-04-07 15:32:371693 * @param {string} string
1694 * @return {!DocumentFragment}
1695 */
Erik Luo383f21d2018-11-07 23:16:371696 _linkifyStringAsFragment(string) {
Erik Luofc2214f2018-11-21 19:54:581697 return this._linkifyWithCustomLinkifier(string, (text, url, lineNumber, columnNumber) => {
Sigurd Schneider45f32c32020-10-13 13:32:051698 const options = {text, lineNumber, columnNumber};
1699 const linkElement = Components.Linkifier.Linkifier.linkifyURL(
1700 url, /** @type {!Components.Linkifier.LinkifyURLOptions} */ (options));
Erik Luo383f21d2018-11-07 23:16:371701 linkElement.tabIndex = -1;
Erik Luo31c21f62018-12-13 03:39:391702 this._selectableChildren.push({element: linkElement, forceSelect: () => linkElement.focus()});
Erik Luo383f21d2018-11-07 23:16:371703 return linkElement;
Blink Reformat4c46d092018-04-07 15:32:371704 });
1705 }
1706
1707 /**
1708 * @param {string} string
Sigurd Schneider30ac3dd2020-10-13 09:06:391709 * @return {!Array<{type: (string|undefined), text: string}>}
Tim van der Lippeeaacb722020-01-10 12:16:001710 * @suppress {accessControls}
Blink Reformat4c46d092018-04-07 15:32:371711 */
1712 static _tokenizeMessageText(string) {
Sigurd Schneider30ac3dd2020-10-13 09:06:391713 const {tokenizerRegexes, tokenizerTypes} = getOrCreateTokenizers();
Sigurd Schneider8f4ac862020-10-13 13:30:111714 if (string.length > getMaxTokenizableStringLength()) {
Blink Reformat4c46d092018-04-07 15:32:371715 return [{text: string, type: undefined}];
Tim van der Lippe1d6e57a2019-09-30 11:55:341716 }
Sigurd Schneider30ac3dd2020-10-13 09:06:391717 const results = TextUtils.TextUtils.Utils.splitStringByRegexes(string, tokenizerRegexes);
1718 return results.map(result => ({text: result.value, type: tokenizerTypes[result.regexIndex]}));
Blink Reformat4c46d092018-04-07 15:32:371719 }
1720
1721 /**
1722 * @return {string}
1723 */
1724 groupKey() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341725 if (!this._groupKey) {
Blink Reformat4c46d092018-04-07 15:32:371726 this._groupKey = this._message.groupCategoryKey() + ':' + this.groupTitle();
Tim van der Lippe1d6e57a2019-09-30 11:55:341727 }
Blink Reformat4c46d092018-04-07 15:32:371728 return this._groupKey;
1729 }
1730
1731 /**
1732 * @return {string}
1733 */
1734 groupTitle() {
Tim van der Lippeeaacb722020-01-10 12:16:001735 const tokens = ConsoleViewMessage._tokenizeMessageText(this._message.messageText);
Blink Reformat4c46d092018-04-07 15:32:371736 const result = tokens.reduce((acc, token) => {
1737 let text = token.text;
Tim van der Lippe1d6e57a2019-09-30 11:55:341738 if (token.type === 'url') {
Tim van der Lippe9b2f8712020-02-12 17:46:221739 text = Common.UIString.UIString('<URL>');
Tim van der Lippe1d6e57a2019-09-30 11:55:341740 } else if (token.type === 'time') {
Tim van der Lippe9b2f8712020-02-12 17:46:221741 text = Common.UIString.UIString('took <N>ms');
Tim van der Lippe1d6e57a2019-09-30 11:55:341742 } else if (token.type === 'event') {
Tim van der Lippe9b2f8712020-02-12 17:46:221743 text = Common.UIString.UIString('<some> event');
Tim van der Lippe1d6e57a2019-09-30 11:55:341744 } else if (token.type === 'milestone') {
Tim van der Lippe9b2f8712020-02-12 17:46:221745 text = Common.UIString.UIString(' M<XX>');
Tim van der Lippe1d6e57a2019-09-30 11:55:341746 } else if (token.type === 'autofill') {
Tim van der Lippe9b2f8712020-02-12 17:46:221747 text = Common.UIString.UIString('<attribute>');
Tim van der Lippe1d6e57a2019-09-30 11:55:341748 }
Blink Reformat4c46d092018-04-07 15:32:371749 return acc + text;
1750 }, '');
1751 return result.replace(/[%]o/g, '');
1752 }
Paul Lewisbf7aa3c2019-11-20 17:03:381753}
Blink Reformat4c46d092018-04-07 15:32:371754
Sigurd Schneider30ac3dd2020-10-13 09:06:391755/** @type {?Array<!RegExp>} */
1756let tokenizerRegexes = null;
1757/** @type {?Array<string>} */
1758let tokenizerTypes = null;
1759
1760/**
1761 * @return {!{tokenizerRegexes:!Array<!RegExp>, tokenizerTypes:Array<string>}}
1762 */
1763function getOrCreateTokenizers() {
1764 if (!tokenizerRegexes || !tokenizerTypes) {
1765 const controlCodes = '\\u0000-\\u0020\\u007f-\\u009f';
1766 const linkStringRegex = new RegExp(
1767 '(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\\/\\/|data:|www\\.)[^\\s' + controlCodes + '"]{2,}[^\\s' + controlCodes +
1768 '"\')}\\],:;.!?]',
1769 'u');
1770 const pathLineRegex = /(?:\/[\w\.-]*)+\:[\d]+/;
1771 const timeRegex = /took [\d]+ms/;
1772 const eventRegex = /'\w+' event/;
1773 const milestoneRegex = /\sM[6-7]\d/;
1774 const autofillRegex = /\(suggested: \"[\w-]+\"\)/;
1775 /** @type {!Map<!RegExp, string>} */
1776 const handlers = new Map();
1777 handlers.set(linkStringRegex, 'url');
1778 handlers.set(pathLineRegex, 'url');
1779 handlers.set(timeRegex, 'time');
1780 handlers.set(eventRegex, 'event');
1781 handlers.set(milestoneRegex, 'milestone');
1782 handlers.set(autofillRegex, 'autofill');
1783 tokenizerRegexes = Array.from(handlers.keys());
1784 tokenizerTypes = Array.from(handlers.values());
1785 return {tokenizerRegexes, tokenizerTypes};
1786 }
1787 return {tokenizerRegexes, tokenizerTypes};
1788}
1789
Paul Lewisbf7aa3c2019-11-20 17:03:381790export class ConsoleGroupViewMessage extends ConsoleViewMessage {
Blink Reformat4c46d092018-04-07 15:32:371791 /**
Tim van der Lippe9b2f8712020-02-12 17:46:221792 * @param {!SDK.ConsoleModel.ConsoleMessage} consoleMessage
1793 * @param {!Components.Linkifier.Linkifier} linkifier
Blink Reformat4c46d092018-04-07 15:32:371794 * @param {number} nestingLevel
Sigurd Schneider45f32c32020-10-13 13:32:051795 * @param {function(): void} onToggle
1796 * @param {function(!Common.EventTarget.EventTargetEvent): void} onResize
Blink Reformat4c46d092018-04-07 15:32:371797 */
Tim van der Lippeb45d9a02019-11-05 17:24:411798 constructor(consoleMessage, linkifier, nestingLevel, onToggle, onResize) {
Blink Reformat4c46d092018-04-07 15:32:371799 console.assert(consoleMessage.isGroupStartMessage());
Tim van der Lippeb45d9a02019-11-05 17:24:411800 super(consoleMessage, linkifier, nestingLevel, onResize);
Tim van der Lippe9b2f8712020-02-12 17:46:221801 this._collapsed = consoleMessage.type === SDK.ConsoleModel.MessageType.StartGroupCollapsed;
1802 /** @type {?UI.Icon.Icon} */
Blink Reformat4c46d092018-04-07 15:32:371803 this._expandGroupIcon = null;
Erik Luo8ef5d0c2018-09-25 21:16:001804 this._onToggle = onToggle;
Blink Reformat4c46d092018-04-07 15:32:371805 }
1806
1807 /**
1808 * @param {boolean} collapsed
1809 */
Erik Luo8ef5d0c2018-09-25 21:16:001810 _setCollapsed(collapsed) {
Blink Reformat4c46d092018-04-07 15:32:371811 this._collapsed = collapsed;
Tim van der Lippe1d6e57a2019-09-30 11:55:341812 if (this._expandGroupIcon) {
Blink Reformat4c46d092018-04-07 15:32:371813 this._expandGroupIcon.setIconType(this._collapsed ? 'smallicon-triangle-right' : 'smallicon-triangle-down');
Tim van der Lippe1d6e57a2019-09-30 11:55:341814 }
Erik Luo8ef5d0c2018-09-25 21:16:001815 this._onToggle.call(null);
Blink Reformat4c46d092018-04-07 15:32:371816 }
1817
1818 /**
1819 * @return {boolean}
1820 */
1821 collapsed() {
1822 return this._collapsed;
1823 }
1824
1825 /**
1826 * @override
Sigurd Schneider45f32c32020-10-13 13:32:051827 * @param {!KeyboardEvent} event
Erik Luo8ef5d0c2018-09-25 21:16:001828 */
1829 maybeHandleOnKeyDown(event) {
Erik Luo0b8282e2018-10-08 20:37:461830 const focusedChildIndex = this._focusedChildIndex();
1831 if (focusedChildIndex === -1) {
1832 if ((event.key === 'ArrowLeft' && !this._collapsed) || (event.key === 'ArrowRight' && this._collapsed)) {
1833 this._setCollapsed(!this._collapsed);
1834 return true;
1835 }
Erik Luo8ef5d0c2018-09-25 21:16:001836 }
1837 return super.maybeHandleOnKeyDown(event);
1838 }
1839
1840 /**
1841 * @override
Sigurd Schneider53f33522020-10-08 15:00:491842 * @return {!HTMLElement}
Blink Reformat4c46d092018-04-07 15:32:371843 */
1844 toMessageElement() {
Sigurd Schneider45f32c32020-10-13 13:32:051845 /** @type {?HTMLElement} */
1846 let element = this._element || null;
1847 if (!element) {
1848 element = super.toMessageElement();
Erik Luo8ef5d0c2018-09-25 21:16:001849 const iconType = this._collapsed ? 'smallicon-triangle-right' : 'smallicon-triangle-down';
Tim van der Lippe9b2f8712020-02-12 17:46:221850 this._expandGroupIcon = UI.Icon.Icon.create(iconType, 'expand-group-icon');
Erik Luob5bfff42018-09-20 02:52:391851 // Intercept focus to avoid highlight on click.
Sigurd Schneider45f32c32020-10-13 13:32:051852 this.contentElement().tabIndex = -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341853 if (this._repeatCountElement) {
Blink Reformat4c46d092018-04-07 15:32:371854 this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341855 } else {
Sigurd Schneider45f32c32020-10-13 13:32:051856 element.insertBefore(this._expandGroupIcon, this._contentElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:341857 }
Sigurd Schneider45f32c32020-10-13 13:32:051858 element.addEventListener('click', () => this._setCollapsed(!this._collapsed));
Blink Reformat4c46d092018-04-07 15:32:371859 }
Sigurd Schneider45f32c32020-10-13 13:32:051860 return element;
Blink Reformat4c46d092018-04-07 15:32:371861 }
1862
1863 /**
1864 * @override
1865 */
1866 _showRepeatCountElement() {
1867 super._showRepeatCountElement();
Tim van der Lippe1d6e57a2019-09-30 11:55:341868 if (this._repeatCountElement && this._expandGroupIcon) {
Blink Reformat4c46d092018-04-07 15:32:371869 this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341870 }
Blink Reformat4c46d092018-04-07 15:32:371871 }
Paul Lewisbf7aa3c2019-11-20 17:03:381872}
Blink Reformat4c46d092018-04-07 15:32:371873
Sigurd Schneiderca7b4ff2020-10-14 07:45:471874export class ConsoleCommand extends ConsoleViewMessage {
1875 /**
1876 * @param {!SDK.ConsoleModel.ConsoleMessage} consoleMessage
1877 * @param {!Components.Linkifier.Linkifier} linkifier
1878 * @param {number} nestingLevel
1879 * @param {function(!Common.EventTarget.EventTargetEvent):void} onResize
1880 */
1881 constructor(consoleMessage, linkifier, nestingLevel, onResize) {
1882 super(consoleMessage, linkifier, nestingLevel, onResize);
1883 /** @type {?HTMLElement} */
1884 this._formattedCommand = null;
1885 }
1886
1887 /**
1888 * @override
1889 * @return {!HTMLElement}
1890 */
1891 contentElement() {
1892 const contentElement = this.getContentElement();
1893 if (contentElement) {
1894 return contentElement;
1895 }
1896 const newContentElement = /** @type {!HTMLElement} */ (document.createElement('div'));
1897 this.setContentElement(newContentElement);
1898 newContentElement.classList.add('console-user-command');
1899 const icon = UI.Icon.Icon.create('smallicon-user-command', 'command-result-icon');
1900 newContentElement.appendChild(icon);
1901
1902 elementToMessage.set(newContentElement, this);
1903
1904 this._formattedCommand = /** @type {!HTMLElement} */ (document.createElement('span'));
1905 this._formattedCommand.classList.add('source-code');
1906 this._formattedCommand.textContent = Platform.StringUtilities.replaceControlCharacters(this.text);
1907 newContentElement.appendChild(this._formattedCommand);
1908
1909 if (this._formattedCommand.textContent.length < MaxLengthToIgnoreHighlighter) {
1910 const javascriptSyntaxHighlighter = new UI.SyntaxHighlighter.SyntaxHighlighter('text/javascript', true);
1911 javascriptSyntaxHighlighter.syntaxHighlightNode(this._formattedCommand).then(this._updateSearch.bind(this));
1912 } else {
1913 this._updateSearch();
1914 }
1915
1916 this.updateTimestamp();
1917 return newContentElement;
1918 }
1919
1920 _updateSearch() {
1921 this.setSearchRegex(this.searchRegex());
1922 }
1923}
1924
1925export class ConsoleCommandResult extends ConsoleViewMessage {
1926 /**
1927 * @override
1928 * @return {!HTMLElement}
1929 */
1930 contentElement() {
1931 const element = super.contentElement();
1932 if (!element.classList.contains('console-user-command-result')) {
1933 element.classList.add('console-user-command-result');
1934 if (this.consoleMessage().level === SDK.ConsoleModel.MessageLevel.Info) {
1935 const icon = UI.Icon.Icon.create('smallicon-command-result', 'command-result-icon');
1936 element.insertBefore(icon, element.firstChild);
1937 }
1938 }
1939 return element;
1940 }
1941}
1942
Sigurd Schneider8bfb4212020-10-27 10:27:371943export class ConsoleTableMessageView extends ConsoleViewMessage {
1944 /**
1945 * @param {!SDK.ConsoleModel.ConsoleMessage} consoleMessage
1946 * @param {!Components.Linkifier.Linkifier} linkifier
1947 * @param {number} nestingLevel
1948 * @param {function(!Common.EventTarget.EventTargetEvent): void} onResize
1949 */
1950 constructor(consoleMessage, linkifier, nestingLevel, onResize) {
1951 super(consoleMessage, linkifier, nestingLevel, onResize);
1952 console.assert(consoleMessage.type === SDK.ConsoleModel.MessageType.Table);
1953 /** @type {?DataGrid.SortableDataGrid.SortableDataGrid<?>} */
1954 this._dataGrid = null;
1955 }
1956
1957 /**
1958 * @override
1959 */
1960 wasShown() {
1961 if (this._dataGrid) {
1962 this._dataGrid.updateWidths();
1963 }
1964 super.wasShown();
1965 }
1966
1967 /**
1968 * @override
1969 */
1970 onResize() {
1971 if (!this.isVisible()) {
1972 return;
1973 }
1974 if (this._dataGrid) {
1975 this._dataGrid.onResize();
1976 }
1977 }
1978
1979 /**
1980 * @override
1981 * @return {!HTMLElement}
1982 */
1983 contentElement() {
1984 const contentElement = this.getContentElement();
1985 if (contentElement) {
1986 return contentElement;
1987 }
1988
1989 const newContentElement = /** @type {!HTMLElement} */ (document.createElement('div'));
1990 newContentElement.classList.add('console-message');
1991 if (this._messageLevelIcon) {
1992 newContentElement.appendChild(this._messageLevelIcon);
1993 }
1994 this.setContentElement(newContentElement);
1995
1996 newContentElement.appendChild(this._buildTableMessage());
1997 this.updateTimestamp();
1998 return newContentElement;
1999 }
2000
2001 /**
2002 * @return {!HTMLElement}
2003 */
2004 _buildTableMessage() {
2005 const formattedMessage = /** @type {!HTMLElement} */ (document.createElement('span'));
2006 formattedMessage.classList.add('source-code');
2007 this._anchorElement = this._buildMessageAnchor();
2008 if (this._anchorElement) {
2009 formattedMessage.appendChild(this._anchorElement);
2010 }
2011
2012 const table = this._message.parameters && this._message.parameters.length ? this._message.parameters[0] : null;
2013 if (!table) {
2014 return this._buildMessage();
2015 }
2016 const actualTable = parameterToRemoteObject(this._message.runtimeModel())(table);
2017 if (!actualTable || !actualTable.preview) {
2018 return this._buildMessage();
2019 }
2020
2021 const rawValueColumnSymbol = Symbol('rawValueColumn');
2022 /** @type {!Array<string|symbol>} */
2023 const columnNames = [];
2024 const preview = actualTable.preview;
2025 const rows = [];
2026 for (let i = 0; i < preview.properties.length; ++i) {
2027 const rowProperty = preview.properties[i];
2028 /** @type {!Array<!Protocol.Runtime.PropertyPreview|!{name:(string|symbol), type: !Protocol.Runtime.PropertyPreviewType, value: (string|undefined)}>} */
2029 let rowSubProperties;
2030 if (rowProperty.valuePreview) {
2031 rowSubProperties = rowProperty.valuePreview.properties;
2032 } else if (rowProperty.value) {
2033 rowSubProperties = [{name: rawValueColumnSymbol, type: rowProperty.type, value: rowProperty.value}];
2034 } else {
2035 continue;
2036 }
2037
2038 /** @type {!Map<string|symbol, !HTMLElement>} */
2039 const rowValue = new Map();
2040 const maxColumnsToRender = 20;
2041 for (let j = 0; j < rowSubProperties.length; ++j) {
2042 const cellProperty = rowSubProperties[j];
2043 let columnRendered = columnNames.indexOf(cellProperty.name) !== -1;
2044 if (!columnRendered) {
2045 if (columnNames.length === maxColumnsToRender) {
2046 continue;
2047 }
2048 columnRendered = true;
2049 columnNames.push(cellProperty.name);
2050 }
2051
2052 if (columnRendered) {
2053 const cellElement =
2054 this._renderPropertyPreviewOrAccessor(actualTable, cellProperty, [rowProperty, cellProperty]);
2055 cellElement.classList.add('console-message-nowrap-below');
2056 rowValue.set(cellProperty.name, cellElement);
2057 }
2058 }
2059 rows.push({rowName: rowProperty.name, rowValue});
2060 }
2061
2062 const flatValues = [];
2063 for (const {rowName, rowValue} of rows) {
2064 flatValues.push(rowName);
2065 for (let j = 0; j < columnNames.length; ++j) {
2066 flatValues.push(rowValue.get(columnNames[j]));
2067 }
2068 }
2069 columnNames.unshift(Common.UIString.UIString('(index)'));
2070 const columnDisplayNames =
2071 columnNames.map(name => name === rawValueColumnSymbol ? Common.UIString.UIString('Value') : name.toString());
2072
2073 if (flatValues.length) {
2074 this._dataGrid = DataGrid.SortableDataGrid.SortableDataGrid.create(columnDisplayNames, flatValues, ls`Console`);
2075 if (this._dataGrid) {
2076 this._dataGrid.setStriped(true);
2077 this._dataGrid.setFocusable(false);
2078
2079 const formattedResult = document.createElement('span');
2080 formattedResult.classList.add('console-message-text');
2081 const tableElement = formattedResult.createChild('div', 'console-message-formatted-table');
2082 const dataGridContainer = tableElement.createChild('span');
2083 tableElement.appendChild(this._formatParameter(actualTable, true, false));
2084 dataGridContainer.appendChild(this._dataGrid.element);
2085 formattedMessage.appendChild(formattedResult);
2086 this._dataGrid.renderInline();
2087 }
2088 }
2089 return formattedMessage;
2090 }
2091
2092 /**
2093 * @override
2094 * @return {number}
2095 */
2096 approximateFastHeight() {
2097 const table = this._message.parameters && this._message.parameters[0];
2098 if (table && typeof table !== 'string' && table.preview) {
2099 return defaultConsoleRowHeight * table.preview.properties.length;
2100 }
2101 return defaultConsoleRowHeight;
2102 }
2103}
2104
Sigurd Schneiderca7b4ff2020-10-14 07:45:472105/**
2106 * The maximum length before strings are considered too long for syntax highlighting.
2107 * @const
2108 * @type {number}
2109 */
2110const MaxLengthToIgnoreHighlighter = 10000;
2111
Blink Reformat4c46d092018-04-07 15:32:372112/**
2113 * @const
2114 * @type {number}
2115 */
Paul Lewisbf7aa3c2019-11-20 17:03:382116export const MaxLengthForLinks = 40;
Blink Reformat4c46d092018-04-07 15:32:372117
Sigurd Schneider8f4ac862020-10-13 13:30:112118let _MaxTokenizableStringLength = 10000;
2119let _LongStringVisibleLength = 5000;
2120
2121export const getMaxTokenizableStringLength = () => {
2122 return _MaxTokenizableStringLength;
2123};
2124
2125/**
2126 * @param {number} length
2127 */
2128export const setMaxTokenizableStringLength = length => {
2129 _MaxTokenizableStringLength = length;
2130};
2131
2132export const getLongStringVisibleLength = () => {
2133 return _LongStringVisibleLength;
2134};
2135
2136/**
2137 * @param {number} length
2138 */
2139export const setLongStringVisibleLength = length => {
2140 _LongStringVisibleLength = length;
2141};