blob: 1eca0ec5730fcd0e7cc8c526c580e24bcdab4070 [file] [log] [blame]
Jan Scheffler19cd7ec2021-02-12 14:16:301// Copyright 2020 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Blink Reformat4c46d092018-04-07 15:32:375/*
6 * Copyright (C) 2011 Google Inc. All rights reserved.
7 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
8 * Copyright (C) 2009 Joseph Pecoraro
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
20 * its contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
Tim van der Lippe9b2f8712020-02-12 17:46:2234
Jan Scheffler19cd7ec2021-02-12 14:16:3035/* eslint-disable rulesdir/no_underscored_properties */
36
Tim van der Lippe76961572021-04-06 10:48:0737import * as Common from '../../core/common/common.js';
Tim van der Lippebb352e62021-04-01 17:57:2838import * as i18n from '../../core/i18n/i18n.js';
Tim van der Lippeaa1ed7a2021-03-31 14:38:2739import * as Platform from '../../core/platform/platform.js';
Tim van der Lippee00b92f2021-03-31 16:52:1740import * as SDK from '../../core/sdk/sdk.js';
Tim van der Lippe229a54f2021-05-14 16:59:0541import * as Protocol from '../../generated/protocol.js';
Tim van der Lippe959b6f02021-04-07 09:07:5942import * as Bindings from '../../models/bindings/bindings.js';
Sigurd Schneidercf5b8302021-04-23 07:52:2743import * as Logs from '../../models/logs/logs.js';
Tim van der Lippefca98ed2021-04-08 14:10:1444import * as TextUtils from '../../models/text_utils/text_utils.js';
Tim van der Lippe99aeaf32021-04-09 10:33:3445import * as Workspace from '../../models/workspace/workspace.js';
Tim van der Lippe8499fe22021-04-12 16:42:4746import * as DataGrid from '../../ui/legacy/components/data_grid/data_grid.js';
Tim van der Lippe0dd7a052021-04-12 16:44:2347import * as ObjectUI from '../../ui/legacy/components/object_ui/object_ui.js';
Tim van der Lippe9a1c9732021-04-14 14:14:0748import * as TextEditor from '../../ui/legacy/components/text_editor/text_editor.js';
Tim van der Lippe339ad262021-04-21 12:23:3649import * as Components from '../../ui/legacy/components/utils/utils.js';
Tim van der Lippeaa61faf2021-04-07 15:32:0750import * as UI from '../../ui/legacy/legacy.js';
Tim van der Lippefddcf402021-04-19 13:00:2951import * as ThemeSupport from '../../ui/legacy/theme_support/theme_support.js';
Tim van der Lippe9b2f8712020-02-12 17:46:2252
Tim van der Lippebfbb58f2021-02-25 17:34:1953import type {ConsoleViewportElement} from './ConsoleViewport.js';
Tim van der Lippeeaacb722020-01-10 12:16:0054
Simon Zündfbfd1072021-03-01 07:38:5355const UIStrings = {
Christy Chen9c6d8982021-02-08 02:28:3156 /**
Peter Marshallf295a4b2021-02-26 09:48:0357 * @description Message element text content in Console View Message of the Console panel. Shown
58 * when the user tried to run console.clear() but the 'Preserve log' option is enabled, which stops
59 * the log from being cleared.
Christy Chen9c6d8982021-02-08 02:28:3160 */
61 consoleclearWasPreventedDueTo: '`console.clear()` was prevented due to \'Preserve log\'',
62 /**
Peter Marshallb8bd00f2021-02-24 08:25:1863 * @description Text shown in the Console panel after the user has cleared the console, which
64 * removes all messages from the console so that it is empty.
Christy Chen9c6d8982021-02-08 02:28:3165 */
66 consoleWasCleared: 'Console was cleared',
67 /**
68 *@description Message element title in Console View Message of the Console panel
69 *@example {Ctrl+L} PH1
70 */
71 clearAllMessagesWithS: 'Clear all messages with {PH1}',
72 /**
73 *@description Message prefix in Console View Message of the Console panel
74 */
75 assertionFailed: 'Assertion failed: ',
76 /**
77 *@description Message text in Console View Message of the Console panel
78 *@example {console.log(1)} PH1
79 */
Peter Marshall40dd7d92021-02-19 11:07:3780 violationS: '`[Violation]` {PH1}',
Christy Chen9c6d8982021-02-08 02:28:3181 /**
82 *@description Message text in Console View Message of the Console panel
83 *@example {console.log(1)} PH1
84 */
Peter Marshall40dd7d92021-02-19 11:07:3785 interventionS: '`[Intervention]` {PH1}',
Christy Chen9c6d8982021-02-08 02:28:3186 /**
87 *@description Message text in Console View Message of the Console panel
88 *@example {console.log(1)} PH1
89 */
Peter Marshall40dd7d92021-02-19 11:07:3790 deprecationS: '`[Deprecation]` {PH1}',
Christy Chen9c6d8982021-02-08 02:28:3191 /**
92 *@description Note title in Console View Message of the Console panel
93 */
94 thisValueWillNotBeCollectedUntil: 'This value will not be collected until console is cleared.',
95 /**
96 *@description Note title in Console View Message of the Console panel
97 */
98 thisValueWasEvaluatedUponFirst: 'This value was evaluated upon first expanding. It may have changed since then.',
99 /**
100 *@description Note title in Console View Message of the Console panel
101 */
102 functionWasResolvedFromBound: 'Function was resolved from bound function.',
103 /**
Peter Marshallf625dc82021-03-02 08:10:57104 * @description Shown in the Console panel when an exception is thrown when trying to access a
105 * property on an object. Should be translated.
Christy Chen9c6d8982021-02-08 02:28:31106 */
107 exception: '<exception>',
108 /**
109 *@description Text to indicate an item is a warning
110 */
111 warning: 'Warning',
112 /**
113 *@description Text for errors
114 */
115 error: 'Error',
116 /**
Peter Marshall2bdcc642021-03-03 10:02:09117 * @description Announced by the screen reader to indicate how many times a particular message in
118 * the console was repeated.
Christy Chen9c6d8982021-02-08 02:28:31119 */
Peter Marshall2bdcc642021-03-03 10:02:09120 repeatS: '{n, plural, =1 {Repeated # time} other {Repeated # times}}',
Christy Chen9c6d8982021-02-08 02:28:31121 /**
Peter Marshall2bdcc642021-03-03 10:02:09122 * @description Announced by the screen reader to indicate how many times a particular warning
123 * message in the console was repeated.
Christy Chen9c6d8982021-02-08 02:28:31124 */
Peter Marshall2bdcc642021-03-03 10:02:09125 warningS: '{n, plural, =1 {Warning, Repeated # time} other {Warning, Repeated # times}}',
Christy Chen9c6d8982021-02-08 02:28:31126 /**
Peter Marshall2bdcc642021-03-03 10:02:09127 * @description Announced by the screen reader to indicate how many times a particular error
128 * message in the console was repeated.
Christy Chen9c6d8982021-02-08 02:28:31129 */
Peter Marshall2bdcc642021-03-03 10:02:09130 errorS: '{n, plural, =1 {Error, Repeated # time} other {Error, Repeated # times}}',
Christy Chen9c6d8982021-02-08 02:28:31131 /**
Tim van der Lippee4b96c62021-02-17 12:43:16132 *@description Text appended to grouped console messages that are related to URL requests
Christy Chen9c6d8982021-02-08 02:28:31133 */
134 url: '<URL>',
135 /**
Tim van der Lippee4b96c62021-02-17 12:43:16136 *@description Text appended to grouped console messages about tasks that took longer than N ms
Christy Chen9c6d8982021-02-08 02:28:31137 */
138 tookNms: 'took <N>ms',
139 /**
Tim van der Lippee4b96c62021-02-17 12:43:16140 *@description Text appended to grouped console messages about tasks that are related to some DOM event
Christy Chen9c6d8982021-02-08 02:28:31141 */
142 someEvent: '<some> event',
143 /**
Tim van der Lippee4b96c62021-02-17 12:43:16144 *@description Text appended to grouped console messages about tasks that are related to a particular milestone
Christy Chen9c6d8982021-02-08 02:28:31145 */
146 Mxx: ' M<XX>',
147 /**
Tim van der Lippee4b96c62021-02-17 12:43:16148 *@description Text appended to grouped console messages about tasks that are related to autofill completions
Christy Chen9c6d8982021-02-08 02:28:31149 */
150 attribute: '<attribute>',
151 /**
152 *@description Text for the index of something
153 */
154 index: '(index)',
155 /**
156 *@description Text for the value of something
157 */
158 value: 'Value',
159 /**
160 *@description Title of the Console tool
161 */
162 console: 'Console',
163};
Tim van der Lippe586c8022021-03-18 15:18:20164const str_ = i18n.i18n.registerUIStrings('panels/console/ConsoleViewMessage.ts', UIStrings);
Christy Chen9c6d8982021-02-08 02:28:31165const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
Jan Scheffler19cd7ec2021-02-12 14:16:30166const elementToMessage = new WeakMap<Element, ConsoleViewMessage>();
Sigurd Schneiderca7b4ff2020-10-14 07:45:47167
Jan Scheffler19cd7ec2021-02-12 14:16:30168export const getMessageForElement = (element: Element): ConsoleViewMessage|undefined => {
Sigurd Schneiderca7b4ff2020-10-14 07:45:47169 return elementToMessage.get(element);
170};
171
Sigurd Schneider8bfb4212020-10-27 10:27:37172// This value reflects the 18px min-height of .console-message, plus the
173// 1px border of .console-message-wrapper. Keep in sync with consoleView.css.
174const defaultConsoleRowHeight = 19;
175
Jan Scheffler19cd7ec2021-02-12 14:16:30176const parameterToRemoteObject = (runtimeModel: SDK.RuntimeModel.RuntimeModel|null): (
177 parameter?: SDK.RemoteObject.RemoteObject|Protocol.Runtime.RemoteObject|string) => SDK.RemoteObject.RemoteObject =>
178 (parameter?: string|SDK.RemoteObject.RemoteObject|Protocol.Runtime.RemoteObject): SDK.RemoteObject.RemoteObject => {
Sigurd Schneider8bfb4212020-10-27 10:27:37179 if (parameter instanceof SDK.RemoteObject.RemoteObject) {
180 return parameter;
181 }
182 if (!runtimeModel) {
183 return SDK.RemoteObject.RemoteObject.fromLocalObject(parameter);
184 }
185 if (typeof parameter === 'object') {
186 return runtimeModel.createRemoteObject(parameter);
187 }
188 return runtimeModel.createRemoteObjectFromPrimitiveValue(parameter);
189 };
190
Jan Scheffler19cd7ec2021-02-12 14:16:30191export class ConsoleViewMessage implements ConsoleViewportElement {
192 _message: SDK.ConsoleModel.ConsoleMessage;
193 _linkifier: Components.Linkifier.Linkifier;
194 _repeatCount: number;
195 _closeGroupDecorationCount: number;
196 _nestingLevel: number;
197 _selectableChildren: {
198 element: HTMLElement,
199 forceSelect: () => void,
200 }[];
201 _messageResized: (arg0: Common.EventTarget.EventTargetEvent) => void;
202 _element: HTMLElement|null;
203 _previewFormatter: ObjectUI.RemoteObjectPreviewFormatter.RemoteObjectPreviewFormatter;
204 _searchRegex: RegExp|null;
205 _messageLevelIcon: UI.Icon.Icon|null;
206 _traceExpanded: boolean;
207 _expandTrace: ((arg0: boolean) => void)|null;
208 _anchorElement: HTMLElement|null;
209 _contentElement: HTMLElement|null;
210 _nestingLevelMarkers: HTMLElement[]|null;
211 _searchHighlightNodes: Element[];
212 _searchHighlightNodeChanges: UI.UIUtils.HighlightChange[];
213 _isVisible: boolean;
214 _cachedHeight: number;
215 _messagePrefix: string;
216 _timestampElement: HTMLElement|null;
217 _inSimilarGroup: boolean;
218 _similarGroupMarker: HTMLElement|null;
219 _lastInSimilarGroup: boolean;
220 _groupKey: string;
221 _repeatCountElement: UI.UIUtils.DevToolsSmallBubble|null;
222
223 constructor(
224 consoleMessage: SDK.ConsoleModel.ConsoleMessage, linkifier: Components.Linkifier.Linkifier, nestingLevel: number,
225 onResize: (arg0: Common.EventTarget.EventTargetEvent) => void) {
Blink Reformat4c46d092018-04-07 15:32:37226 this._message = consoleMessage;
227 this._linkifier = linkifier;
Blink Reformat4c46d092018-04-07 15:32:37228 this._repeatCount = 1;
229 this._closeGroupDecorationCount = 0;
230 this._nestingLevel = nestingLevel;
Erik Luo383f21d2018-11-07 23:16:37231 this._selectableChildren = [];
Erik Luo840be6b2018-12-03 20:54:27232 this._messageResized = onResize;
Sigurd Schneider53e98632020-10-26 15:29:50233 this._element = null;
Blink Reformat4c46d092018-04-07 15:32:37234
Tim van der Lippe9b2f8712020-02-12 17:46:22235 this._previewFormatter = new ObjectUI.RemoteObjectPreviewFormatter.RemoteObjectPreviewFormatter();
Blink Reformat4c46d092018-04-07 15:32:37236 this._searchRegex = null;
Blink Reformat4c46d092018-04-07 15:32:37237 this._messageLevelIcon = null;
Erik Luo8ef5d0c2018-09-25 21:16:00238 this._traceExpanded = false;
Erik Luo8ef5d0c2018-09-25 21:16:00239 this._expandTrace = null;
John Emaubb2897a2019-10-04 17:37:32240 this._anchorElement = null;
Sigurd Schneider45f32c32020-10-13 13:32:05241 this._contentElement = null;
Sigurd Schneider45f32c32020-10-13 13:32:05242 this._nestingLevelMarkers = null;
Sigurd Schneider45f32c32020-10-13 13:32:05243 this._searchHighlightNodes = [];
Sigurd Schneidere8e75cf2020-10-13 08:17:52244 this._searchHighlightNodeChanges = [];
Sigurd Schneider53e98632020-10-26 15:29:50245 this._isVisible = false;
246 this._cachedHeight = 0;
247 this._messagePrefix = '';
Sigurd Schneider53e98632020-10-26 15:29:50248 this._timestampElement = null;
249 this._inSimilarGroup = false;
Sigurd Schneider53e98632020-10-26 15:29:50250 this._similarGroupMarker = null;
251 this._lastInSimilarGroup = false;
252 this._groupKey = '';
Sigurd Schneider53e98632020-10-26 15:29:50253 this._repeatCountElement = null;
Blink Reformat4c46d092018-04-07 15:32:37254 }
255
Jan Scheffler19cd7ec2021-02-12 14:16:30256 element(): HTMLElement {
Blink Reformat4c46d092018-04-07 15:32:37257 return this.toMessageElement();
258 }
259
Jan Scheffler19cd7ec2021-02-12 14:16:30260 wasShown(): void {
Blink Reformat4c46d092018-04-07 15:32:37261 this._isVisible = true;
262 }
263
Jan Scheffler19cd7ec2021-02-12 14:16:30264 onResize(): void {
Blink Reformat4c46d092018-04-07 15:32:37265 }
266
Jan Scheffler19cd7ec2021-02-12 14:16:30267 willHide(): void {
Blink Reformat4c46d092018-04-07 15:32:37268 this._isVisible = false;
Erik Luo4b002322018-07-30 21:23:31269 this._cachedHeight = this.element().offsetHeight;
Blink Reformat4c46d092018-04-07 15:32:37270 }
271
Jan Scheffler19cd7ec2021-02-12 14:16:30272 isVisible(): boolean {
Sigurd Schneider8bfb4212020-10-27 10:27:37273 return this._isVisible;
274 }
275
Jan Scheffler19cd7ec2021-02-12 14:16:30276 fastHeight(): number {
Tim van der Lippe1d6e57a2019-09-30 11:55:34277 if (this._cachedHeight) {
Blink Reformat4c46d092018-04-07 15:32:37278 return this._cachedHeight;
Tim van der Lippe1d6e57a2019-09-30 11:55:34279 }
Sigurd Schneider8bfb4212020-10-27 10:27:37280 return this.approximateFastHeight();
281 }
282
Jan Scheffler19cd7ec2021-02-12 14:16:30283 approximateFastHeight(): number {
Blink Reformat4c46d092018-04-07 15:32:37284 return defaultConsoleRowHeight;
285 }
286
Jan Scheffler19cd7ec2021-02-12 14:16:30287 consoleMessage(): SDK.ConsoleModel.ConsoleMessage {
Blink Reformat4c46d092018-04-07 15:32:37288 return this._message;
289 }
290
Jan Scheffler19cd7ec2021-02-12 14:16:30291 _buildMessage(): HTMLElement {
Blink Reformat4c46d092018-04-07 15:32:37292 let messageElement;
Jan Scheffler19cd7ec2021-02-12 14:16:30293 let messageText: Common.UIString.LocalizedString|string = this._message.messageText;
Tim van der Lippeeb876c62021-05-14 15:02:11294 if (this._message.source === SDK.ConsoleModel.FrontendMessageSource.ConsoleAPI) {
Blink Reformat4c46d092018-04-07 15:32:37295 switch (this._message.type) {
Tim van der Lippeeb876c62021-05-14 15:02:11296 case Protocol.Runtime.ConsoleAPICalledEventType.Trace:
Blink Reformat4c46d092018-04-07 15:32:37297 messageElement = this._format(this._message.parameters || ['console.trace']);
298 break;
Tim van der Lippeeb876c62021-05-14 15:02:11299 case Protocol.Runtime.ConsoleAPICalledEventType.Clear:
Tim van der Lippef49e2322020-05-01 15:03:09300 messageElement = document.createElement('span');
301 messageElement.classList.add('console-info');
Paul Lewis2d7d65c2020-03-16 17:26:30302 if (Common.Settings.Settings.instance().moduleSetting('preserveConsoleLog').get()) {
Christy Chen9c6d8982021-02-08 02:28:31303 messageElement.textContent = i18nString(UIStrings.consoleclearWasPreventedDueTo);
Tim van der Lippe1d6e57a2019-09-30 11:55:34304 } else {
Christy Chen9c6d8982021-02-08 02:28:31305 messageElement.textContent = i18nString(UIStrings.consoleWasCleared);
Tim van der Lippe1d6e57a2019-09-30 11:55:34306 }
Tim van der Lippe420e5e32020-11-23 16:58:46307 UI.Tooltip.Tooltip.install(
Christy Chen9c6d8982021-02-08 02:28:31308 messageElement, i18nString(UIStrings.clearAllMessagesWithS, {
Jan Scheffler19cd7ec2021-02-12 14:16:30309 PH1: UI.ShortcutRegistry.ShortcutRegistry.instance().shortcutTitleForAction('console.clear'),
Christy Chen9c6d8982021-02-08 02:28:31310 }));
Blink Reformat4c46d092018-04-07 15:32:37311 break;
Tim van der Lippeeb876c62021-05-14 15:02:11312 case Protocol.Runtime.ConsoleAPICalledEventType.Dir: {
Blink Reformat4c46d092018-04-07 15:32:37313 const obj = this._message.parameters ? this._message.parameters[0] : undefined;
314 const args = ['%O', obj];
315 messageElement = this._format(args);
316 break;
317 }
Tim van der Lippeeb876c62021-05-14 15:02:11318 case Protocol.Runtime.ConsoleAPICalledEventType.Profile:
319 case Protocol.Runtime.ConsoleAPICalledEventType.ProfileEnd:
Blink Reformat4c46d092018-04-07 15:32:37320 messageElement = this._format([messageText]);
321 break;
322 default: {
Tim van der Lippeeb876c62021-05-14 15:02:11323 if (this._message.type === Protocol.Runtime.ConsoleAPICalledEventType.Assert) {
Christy Chen9c6d8982021-02-08 02:28:31324 this._messagePrefix = i18nString(UIStrings.assertionFailed);
Sigurd Schneider45f32c32020-10-13 13:32:05325 }
326 if (this._message.parameters && this._message.parameters.length === 1) {
327 const parameter = this._message.parameters[0];
328 if (typeof parameter !== 'string' && parameter.type === 'string') {
Jan Scheffler19cd7ec2021-02-12 14:16:30329 messageElement = this._tryFormatAsError((parameter.value as string));
Sigurd Schneider45f32c32020-10-13 13:32:05330 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34331 }
Blink Reformat4c46d092018-04-07 15:32:37332 const args = this._message.parameters || [messageText];
333 messageElement = messageElement || this._format(args);
334 }
335 }
336 } else {
Tim van der Lippeeb876c62021-05-14 15:02:11337 if (this._message.source === Protocol.Log.LogEntrySource.Network) {
Erik Luofc2214f2018-11-21 19:54:58338 messageElement = this._formatAsNetworkRequest() || this._format([messageText]);
339 } else {
Jan Scheffler19cd7ec2021-02-12 14:16:30340 const messageInParameters = this._message.parameters && messageText === (this._message.parameters[0] as string);
Peter Marshall40dd7d92021-02-19 11:07:37341 // These terms are locked because the console message will not be translated anyway.
Tim van der Lippeeb876c62021-05-14 15:02:11342 if (this._message.source === Protocol.Log.LogEntrySource.Violation) {
Christy Chen9c6d8982021-02-08 02:28:31343 messageText = i18nString(UIStrings.violationS, {PH1: messageText});
Tim van der Lippeeb876c62021-05-14 15:02:11344 } else if (this._message.source === Protocol.Log.LogEntrySource.Intervention) {
Christy Chen9c6d8982021-02-08 02:28:31345 messageText = i18nString(UIStrings.interventionS, {PH1: messageText});
Tim van der Lippeeb876c62021-05-14 15:02:11346 } else if (this._message.source === Protocol.Log.LogEntrySource.Deprecation) {
Christy Chen9c6d8982021-02-08 02:28:31347 messageText = i18nString(UIStrings.deprecationS, {PH1: messageText});
Tim van der Lippe1d6e57a2019-09-30 11:55:34348 }
Blink Reformat4c46d092018-04-07 15:32:37349 const args = this._message.parameters || [messageText];
Tim van der Lippe1d6e57a2019-09-30 11:55:34350 if (messageInParameters) {
Blink Reformat4c46d092018-04-07 15:32:37351 args[0] = messageText;
Tim van der Lippe1d6e57a2019-09-30 11:55:34352 }
Blink Reformat4c46d092018-04-07 15:32:37353 messageElement = this._format(args);
354 }
355 }
356 messageElement.classList.add('console-message-text');
357
Jan Scheffler19cd7ec2021-02-12 14:16:30358 const formattedMessage = (document.createElement('span') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:09359 formattedMessage.classList.add('source-code');
Erik Luo5976c8c2018-07-24 02:03:09360 this._anchorElement = this._buildMessageAnchor();
Tim van der Lippe1d6e57a2019-09-30 11:55:34361 if (this._anchorElement) {
Erik Luo5976c8c2018-07-24 02:03:09362 formattedMessage.appendChild(this._anchorElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34363 }
Blink Reformat4c46d092018-04-07 15:32:37364 formattedMessage.appendChild(messageElement);
365 return formattedMessage;
366 }
367
Jan Scheffler19cd7ec2021-02-12 14:16:30368 _formatAsNetworkRequest(): HTMLElement|null {
Sigurd Schneidercf5b8302021-04-23 07:52:27369 const request = Logs.NetworkLog.NetworkLog.requestForConsoleMessage(this._message);
Tim van der Lippe1d6e57a2019-09-30 11:55:34370 if (!request) {
Erik Luofc2214f2018-11-21 19:54:58371 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34372 }
Jan Scheffler19cd7ec2021-02-12 14:16:30373 const messageElement = (document.createElement('span') as HTMLElement);
Tim van der Lippeeb876c62021-05-14 15:02:11374 if (this._message.level === Protocol.Log.LogEntryLevel.Error) {
Sigurd Schneider23c52972020-10-13 09:31:14375 UI.UIUtils.createTextChild(messageElement, request.requestMethod + ' ');
Tim van der Lippe9b2f8712020-02-12 17:46:22376 const linkElement = Components.Linkifier.Linkifier.linkifyRevealable(request, request.url(), request.url());
Erik Luo182bece2018-11-29 03:15:22377 // Focus is handled by the viewport.
378 linkElement.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:30379 this._selectableChildren.push({element: linkElement, forceSelect: (): void => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22380 messageElement.appendChild(linkElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34381 if (request.failed) {
Sigurd Schneider23c52972020-10-13 09:31:14382 UI.UIUtils.createTextChildren(messageElement, ' ', request.localizedFailDescription || '');
Tim van der Lippe1d6e57a2019-09-30 11:55:34383 }
384 if (request.statusCode !== 0) {
Sigurd Schneider23c52972020-10-13 09:31:14385 UI.UIUtils.createTextChildren(messageElement, ' ', String(request.statusCode));
Tim van der Lippe1d6e57a2019-09-30 11:55:34386 }
387 if (request.statusText) {
Sigurd Schneider23c52972020-10-13 09:31:14388 UI.UIUtils.createTextChildren(messageElement, ' (', request.statusText, ')');
Tim van der Lippe1d6e57a2019-09-30 11:55:34389 }
Erik Luofc2214f2018-11-21 19:54:58390 } else {
Erik Luoad5f3942019-03-26 20:53:44391 const messageText = this._message.messageText;
392 const fragment = this._linkifyWithCustomLinkifier(messageText, (text, url, lineNumber, columnNumber) => {
Sigurd Schneider45f32c32020-10-13 13:32:05393 const linkElement = url === request.url() ?
394 Components.Linkifier.Linkifier.linkifyRevealable(
Jan Scheffler19cd7ec2021-02-12 14:16:30395 (request as SDK.NetworkRequest.NetworkRequest), url, request.url()) :
Sigurd Schneider45f32c32020-10-13 13:32:05396 Components.Linkifier.Linkifier.linkifyURL(
Jan Scheffler19cd7ec2021-02-12 14:16:30397 url, ({text, lineNumber, columnNumber} as Components.Linkifier.LinkifyURLOptions));
Erik Luo182bece2018-11-29 03:15:22398 linkElement.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:30399 this._selectableChildren.push({element: linkElement, forceSelect: (): void => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22400 return linkElement;
401 });
Erik Luofc2214f2018-11-21 19:54:58402 messageElement.appendChild(fragment);
403 }
404 return messageElement;
405 }
406
Jan Scheffler19cd7ec2021-02-12 14:16:30407 _buildMessageAnchor(): HTMLElement|null {
408 const linkify = (message: SDK.ConsoleModel.ConsoleMessage): HTMLElement|null => {
Sigurd Schneider45f32c32020-10-13 13:32:05409 if (message.scriptId) {
410 return this._linkifyScriptId(message.scriptId, message.url || '', message.line, message.column);
411 }
412 if (message.stackTrace && message.stackTrace.callFrames.length) {
413 return this._linkifyStackTraceTopFrame(message.stackTrace);
414 }
415 if (message.url && message.url !== 'undefined') {
416 return this._linkifyLocation(message.url, message.line, message.column);
417 }
418 return null;
419 };
420 const anchorElement = linkify(this._message);
Blink Reformat4c46d092018-04-07 15:32:37421 // Append a space to prevent the anchor text from being glued to the console message when the user selects and copies the console messages.
422 if (anchorElement) {
John Emauf7e30fb2019-10-04 19:12:32423 anchorElement.tabIndex = -1;
424 this._selectableChildren.push({
425 element: anchorElement,
Jan Scheffler19cd7ec2021-02-12 14:16:30426 forceSelect: (): void => anchorElement.focus(),
John Emauf7e30fb2019-10-04 19:12:32427 });
Jan Scheffler19cd7ec2021-02-12 14:16:30428 const anchorWrapperElement = (document.createElement('span') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:09429 anchorWrapperElement.classList.add('console-message-anchor');
Blink Reformat4c46d092018-04-07 15:32:37430 anchorWrapperElement.appendChild(anchorElement);
Sigurd Schneider23c52972020-10-13 09:31:14431 UI.UIUtils.createTextChild(anchorWrapperElement, ' ');
Blink Reformat4c46d092018-04-07 15:32:37432 return anchorWrapperElement;
433 }
434 return null;
435 }
436
Jan Scheffler19cd7ec2021-02-12 14:16:30437 _buildMessageWithStackTrace(runtimeModel: SDK.RuntimeModel.RuntimeModel): HTMLElement {
438 const toggleElement = (document.createElement('div') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:09439 toggleElement.classList.add('console-message-stack-trace-toggle');
Blink Reformat4c46d092018-04-07 15:32:37440 const contentElement = toggleElement.createChild('div', 'console-message-stack-trace-wrapper');
Brandon Waldermana004e2a2021-04-06 18:41:59441 UI.ARIAUtils.markAsTree(contentElement);
Blink Reformat4c46d092018-04-07 15:32:37442
443 const messageElement = this._buildMessage();
Tim van der Lippe9b2f8712020-02-12 17:46:22444 const icon = UI.Icon.Icon.create('smallicon-triangle-right', 'console-message-expand-icon');
Blink Reformat4c46d092018-04-07 15:32:37445 const clickableElement = contentElement.createChild('div');
Brandon Waldermana004e2a2021-04-06 18:41:59446 UI.ARIAUtils.markAsTreeitem(clickableElement);
447 UI.ARIAUtils.setExpanded(clickableElement, false);
Blink Reformat4c46d092018-04-07 15:32:37448 clickableElement.appendChild(icon);
Erik Luob5bfff42018-09-20 02:52:39449 // Intercept focus to avoid highlight on click.
450 clickableElement.tabIndex = -1;
Blink Reformat4c46d092018-04-07 15:32:37451 clickableElement.appendChild(messageElement);
452 const stackTraceElement = contentElement.createChild('div');
453 const stackTracePreview = Components.JSPresentationUtils.buildStackTracePreviewContents(
Wolfgang Beyer08261c72021-03-09 09:21:34454 runtimeModel.target(), this._linkifier, {stackTrace: this._message.stackTrace, tabStops: undefined});
Erik Luo182bece2018-11-29 03:15:22455 stackTraceElement.appendChild(stackTracePreview.element);
456 for (const linkElement of stackTracePreview.links) {
Jan Scheffler19cd7ec2021-02-12 14:16:30457 this._selectableChildren.push({element: linkElement, forceSelect: (): void => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22458 }
Blink Reformat4c46d092018-04-07 15:32:37459 stackTraceElement.classList.add('hidden');
Brandon Waldermana004e2a2021-04-06 18:41:59460 UI.ARIAUtils.markAsGroup(stackTraceElement);
Jan Scheffler19cd7ec2021-02-12 14:16:30461 this._expandTrace = (expand: boolean): void => {
Blink Reformat4c46d092018-04-07 15:32:37462 icon.setIconType(expand ? 'smallicon-triangle-down' : 'smallicon-triangle-right');
463 stackTraceElement.classList.toggle('hidden', !expand);
Brandon Waldermana004e2a2021-04-06 18:41:59464 UI.ARIAUtils.setExpanded(clickableElement, expand);
Erik Luo8ef5d0c2018-09-25 21:16:00465 this._traceExpanded = expand;
466 };
Blink Reformat4c46d092018-04-07 15:32:37467
Jan Scheffler19cd7ec2021-02-12 14:16:30468 const toggleStackTrace = (event: Event): void => {
Tim van der Lippe9b2f8712020-02-12 17:46:22469 if (UI.UIUtils.isEditing() || contentElement.hasSelection()) {
Blink Reformat4c46d092018-04-07 15:32:37470 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34471 }
Sigurd Schneider45f32c32020-10-13 13:32:05472 this._expandTrace && this._expandTrace(stackTraceElement.classList.contains('hidden'));
Blink Reformat4c46d092018-04-07 15:32:37473 event.consume();
Sigurd Schneider45f32c32020-10-13 13:32:05474 };
Blink Reformat4c46d092018-04-07 15:32:37475
Sigurd Schneider45f32c32020-10-13 13:32:05476 clickableElement.addEventListener('click', toggleStackTrace, false);
Tim van der Lippeeb876c62021-05-14 15:02:11477 if (this._message.type === Protocol.Runtime.ConsoleAPICalledEventType.Trace) {
Erik Luo8ef5d0c2018-09-25 21:16:00478 this._expandTrace(true);
Tim van der Lippe1d6e57a2019-09-30 11:55:34479 }
Blink Reformat4c46d092018-04-07 15:32:37480
Sigurd Schneider45f32c32020-10-13 13:32:05481 // @ts-ignore
Erik Luo8ef5d0c2018-09-25 21:16:00482 toggleElement._expandStackTraceForTest = this._expandTrace.bind(this, true);
Blink Reformat4c46d092018-04-07 15:32:37483 return toggleElement;
484 }
485
Jan Scheffler19cd7ec2021-02-12 14:16:30486 _linkifyLocation(url: string, lineNumber: number, columnNumber: number): HTMLElement|null {
Sigurd Schneider45f32c32020-10-13 13:32:05487 const runtimeModel = this._message.runtimeModel();
488 if (!runtimeModel) {
Blink Reformat4c46d092018-04-07 15:32:37489 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34490 }
Blink Reformat4c46d092018-04-07 15:32:37491 return this._linkifier.linkifyScriptLocation(
Sigurd Schneider45f32c32020-10-13 13:32:05492 runtimeModel.target(), /* scriptId */ null, url, lineNumber,
Philip Pfaffe068b01d2021-03-22 09:46:26493 {columnNumber, className: undefined, tabStop: undefined, inlineFrameIndex: 0});
Blink Reformat4c46d092018-04-07 15:32:37494 }
495
Jan Scheffler19cd7ec2021-02-12 14:16:30496 _linkifyStackTraceTopFrame(stackTrace: Protocol.Runtime.StackTrace): HTMLElement|null {
Sigurd Schneider45f32c32020-10-13 13:32:05497 const runtimeModel = this._message.runtimeModel();
498 if (!runtimeModel) {
Blink Reformat4c46d092018-04-07 15:32:37499 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34500 }
Sigurd Schneider45f32c32020-10-13 13:32:05501 return this._linkifier.linkifyStackTraceTopFrame(runtimeModel.target(), stackTrace);
Blink Reformat4c46d092018-04-07 15:32:37502 }
503
Jan Scheffler19cd7ec2021-02-12 14:16:30504 _linkifyScriptId(scriptId: string, url: string, lineNumber: number, columnNumber: number): HTMLElement|null {
Sigurd Schneider45f32c32020-10-13 13:32:05505 const runtimeModel = this._message.runtimeModel();
506 if (!runtimeModel) {
Blink Reformat4c46d092018-04-07 15:32:37507 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34508 }
Blink Reformat4c46d092018-04-07 15:32:37509 return this._linkifier.linkifyScriptLocation(
Philip Pfaffe068b01d2021-03-22 09:46:26510 runtimeModel.target(), scriptId, url, lineNumber,
511 {columnNumber, className: undefined, tabStop: undefined, inlineFrameIndex: 0});
Blink Reformat4c46d092018-04-07 15:32:37512 }
513
Jan Scheffler19cd7ec2021-02-12 14:16:30514 _format(rawParameters: (string|SDK.RemoteObject.RemoteObject|Protocol.Runtime.RemoteObject|undefined)[]):
515 HTMLElement {
Blink Reformat4c46d092018-04-07 15:32:37516 // This node is used like a Builder. Values are continually appended onto it.
Jan Scheffler19cd7ec2021-02-12 14:16:30517 const formattedResult = (document.createElement('span') as HTMLElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34518 if (this._messagePrefix) {
Pavel Feldman9f0f0a32018-12-18 02:09:13519 formattedResult.createChild('span').textContent = this._messagePrefix;
Tim van der Lippe1d6e57a2019-09-30 11:55:34520 }
521 if (!rawParameters.length) {
Blink Reformat4c46d092018-04-07 15:32:37522 return formattedResult;
Tim van der Lippe1d6e57a2019-09-30 11:55:34523 }
Blink Reformat4c46d092018-04-07 15:32:37524
525 // Formatting code below assumes that parameters are all wrappers whereas frontend console
526 // API allows passing arbitrary values as messages (strings, numbers, etc.). Wrap them here.
527 // FIXME: Only pass runtime wrappers here.
Sigurd Schneider8bfb4212020-10-27 10:27:37528 let parameters = rawParameters.map(parameterToRemoteObject(this._message.runtimeModel()));
Blink Reformat4c46d092018-04-07 15:32:37529
530 // There can be string log and string eval result. We distinguish between them based on message type.
531 const shouldFormatMessage =
Jan Scheffler19cd7ec2021-02-12 14:16:30532 SDK.RemoteObject.RemoteObject.type((parameters as SDK.RemoteObject.RemoteObject[])[0]) === 'string' &&
Tim van der Lippeeb876c62021-05-14 15:02:11533 (this._message.type !== SDK.ConsoleModel.FrontendMessageType.Result ||
534 this._message.level === Protocol.Log.LogEntryLevel.Error);
Blink Reformat4c46d092018-04-07 15:32:37535
536 // Multiple parameters with the first being a format string. Save unused substitutions.
537 if (shouldFormatMessage) {
538 const result = this._formatWithSubstitutionString(
Jan Scheffler19cd7ec2021-02-12 14:16:30539 (parameters[0].description as string), parameters.slice(1), formattedResult);
Sigurd Schneider45f32c32020-10-13 13:32:05540 parameters = Array.from(result.unusedSubstitutions || []);
Tim van der Lippe1d6e57a2019-09-30 11:55:34541 if (parameters.length) {
Sigurd Schneider23c52972020-10-13 09:31:14542 UI.UIUtils.createTextChild(formattedResult, ' ');
Tim van der Lippe1d6e57a2019-09-30 11:55:34543 }
Blink Reformat4c46d092018-04-07 15:32:37544 }
545
546 // Single parameter, or unused substitutions from above.
547 for (let i = 0; i < parameters.length; ++i) {
548 // Inline strings when formatting.
Tim van der Lippe1d6e57a2019-09-30 11:55:34549 if (shouldFormatMessage && parameters[i].type === 'string') {
Sigurd Schneider45f32c32020-10-13 13:32:05550 formattedResult.appendChild(this._linkifyStringAsFragment(parameters[i].description || ''));
Tim van der Lippe1d6e57a2019-09-30 11:55:34551 } else {
Blink Reformat4c46d092018-04-07 15:32:37552 formattedResult.appendChild(this._formatParameter(parameters[i], false, true));
Tim van der Lippe1d6e57a2019-09-30 11:55:34553 }
554 if (i < parameters.length - 1) {
Sigurd Schneider23c52972020-10-13 09:31:14555 UI.UIUtils.createTextChild(formattedResult, ' ');
Tim van der Lippe1d6e57a2019-09-30 11:55:34556 }
Blink Reformat4c46d092018-04-07 15:32:37557 }
558 return formattedResult;
559 }
560
Jan Scheffler19cd7ec2021-02-12 14:16:30561 _formatParameter(output: SDK.RemoteObject.RemoteObject, forceObjectFormat?: boolean, includePreview?: boolean):
562 HTMLElement {
Tim van der Lippe1d6e57a2019-09-30 11:55:34563 if (output.customPreview()) {
Jan Scheffler19cd7ec2021-02-12 14:16:30564 return new ObjectUI.CustomPreviewComponent.CustomPreviewComponent(output).element as HTMLElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:34565 }
Blink Reformat4c46d092018-04-07 15:32:37566
Alfonso Castaño20d22cd2020-10-28 16:23:58567 const outputType = forceObjectFormat ? 'object' : (output.subtype || output.type);
Blink Reformat4c46d092018-04-07 15:32:37568 let element;
Alfonso Castaño20d22cd2020-10-28 16:23:58569 switch (outputType) {
Blink Reformat4c46d092018-04-07 15:32:37570 case 'error':
571 element = this._formatParameterAsError(output);
572 break;
573 case 'function':
574 element = this._formatParameterAsFunction(output, includePreview);
575 break;
576 case 'array':
577 case 'arraybuffer':
578 case 'blob':
579 case 'dataview':
580 case 'generator':
581 case 'iterator':
582 case 'map':
583 case 'object':
584 case 'promise':
585 case 'proxy':
586 case 'set':
587 case 'typedarray':
Benedikt Meurer5658dd22021-03-18 09:37:23588 case 'wasmvalue':
Blink Reformat4c46d092018-04-07 15:32:37589 case 'weakmap':
590 case 'weakset':
Benedikt Meurerdead3152020-12-07 08:43:40591 case 'webassemblymemory':
Blink Reformat4c46d092018-04-07 15:32:37592 element = this._formatParameterAsObject(output, includePreview);
593 break;
594 case 'node':
595 element = output.isNode() ? this._formatParameterAsNode(output) : this._formatParameterAsObject(output, false);
596 break;
Alfonso Castaño20d22cd2020-10-28 16:23:58597 case 'trustedtype':
598 element = this._formatParameterAsObject(output, false);
599 break;
Blink Reformat4c46d092018-04-07 15:32:37600 case 'string':
601 element = this._formatParameterAsString(output);
602 break;
603 case 'boolean':
604 case 'date':
605 case 'null':
606 case 'number':
607 case 'regexp':
608 case 'symbol':
609 case 'undefined':
610 case 'bigint':
611 element = this._formatParameterAsValue(output);
612 break;
613 default:
614 element = this._formatParameterAsValue(output);
Alfonso Castaño20d22cd2020-10-28 16:23:58615 console.error(`Tried to format remote object of unknown type ${outputType}.`);
Blink Reformat4c46d092018-04-07 15:32:37616 }
Alfonso Castaño20d22cd2020-10-28 16:23:58617 element.classList.add(`object-value-${outputType}`);
Blink Reformat4c46d092018-04-07 15:32:37618 element.classList.add('source-code');
619 return element;
620 }
621
Jan Scheffler19cd7ec2021-02-12 14:16:30622 _formatParameterAsValue(obj: SDK.RemoteObject.RemoteObject): HTMLElement {
623 const result = (document.createElement('span') as HTMLElement);
Blink Reformat4c46d092018-04-07 15:32:37624 const description = obj.description || '';
Sigurd Schneider8f4ac862020-10-13 13:30:11625 if (description.length > getMaxTokenizableStringLength()) {
Tim van der Lippe9b2f8712020-02-12 17:46:22626 const propertyValue = new ObjectUI.ObjectPropertiesSection.ExpandableTextPropertyValue(
Sigurd Schneider8f4ac862020-10-13 13:30:11627 document.createElement('span'), description, getLongStringVisibleLength());
Connor Moody1a5c0d32019-12-19 07:23:36628 result.appendChild(propertyValue.element);
Tim van der Lippe1d6e57a2019-09-30 11:55:34629 } else {
Sigurd Schneider23c52972020-10-13 09:31:14630 UI.UIUtils.createTextChild(result, description);
Tim van der Lippe1d6e57a2019-09-30 11:55:34631 }
632 if (obj.objectId) {
Blink Reformat4c46d092018-04-07 15:32:37633 result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, obj), false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34634 }
Blink Reformat4c46d092018-04-07 15:32:37635 return result;
636 }
637
Jan Scheffler19cd7ec2021-02-12 14:16:30638 _formatParameterAsTrustedType(obj: SDK.RemoteObject.RemoteObject): HTMLElement {
639 const result = (document.createElement('span') as HTMLElement);
Alfonso Castaño20d22cd2020-10-28 16:23:58640 const trustedContentSpan = document.createElement('span');
641 trustedContentSpan.appendChild(this._formatParameterAsString(obj));
642 trustedContentSpan.classList.add('object-value-string');
Alfonso Castañodfe8ca32020-10-29 13:03:09643 UI.UIUtils.createTextChild(result, `${obj.className} `);
Alfonso Castaño20d22cd2020-10-28 16:23:58644 result.appendChild(trustedContentSpan);
Alfonso Castaño20d22cd2020-10-28 16:23:58645 return result;
646 }
647
Jan Scheffler19cd7ec2021-02-12 14:16:30648 _formatParameterAsObject(obj: SDK.RemoteObject.RemoteObject, includePreview?: boolean): HTMLElement {
649 const titleElement = (document.createElement('span') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:09650 titleElement.classList.add('console-object');
Blink Reformat4c46d092018-04-07 15:32:37651 if (includePreview && obj.preview) {
652 titleElement.classList.add('console-object-preview');
653 this._previewFormatter.appendObjectPreview(titleElement, obj.preview, false /* isEntry */);
654 } else if (obj.type === 'function') {
655 const functionElement = titleElement.createChild('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22656 ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection.formatObjectAsFunction(obj, functionElement, false);
Blink Reformat4c46d092018-04-07 15:32:37657 titleElement.classList.add('object-value-function');
Alfonso Castaño20d22cd2020-10-28 16:23:58658 } else if (obj.subtype === 'trustedtype') {
659 titleElement.appendChild(this._formatParameterAsTrustedType(obj));
Blink Reformat4c46d092018-04-07 15:32:37660 } else {
Sigurd Schneider23c52972020-10-13 09:31:14661 UI.UIUtils.createTextChild(titleElement, obj.description || '');
Blink Reformat4c46d092018-04-07 15:32:37662 }
663
Tim van der Lippe1d6e57a2019-09-30 11:55:34664 if (!obj.hasChildren || obj.customPreview()) {
Blink Reformat4c46d092018-04-07 15:32:37665 return titleElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:34666 }
Blink Reformat4c46d092018-04-07 15:32:37667
668 const note = titleElement.createChild('span', 'object-state-note info-note');
Tim van der Lippeeb876c62021-05-14 15:02:11669 if (this._message.type === SDK.ConsoleModel.FrontendMessageType.QueryObjectResult) {
Christy Chen9c6d8982021-02-08 02:28:31670 UI.Tooltip.Tooltip.install(note, i18nString(UIStrings.thisValueWillNotBeCollectedUntil));
Tim van der Lippe1d6e57a2019-09-30 11:55:34671 } else {
Christy Chen9c6d8982021-02-08 02:28:31672 UI.Tooltip.Tooltip.install(note, i18nString(UIStrings.thisValueWasEvaluatedUponFirst));
Tim van der Lippe1d6e57a2019-09-30 11:55:34673 }
Blink Reformat4c46d092018-04-07 15:32:37674
Tim van der Lippe9b2f8712020-02-12 17:46:22675 const section = new ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection(obj, titleElement, this._linkifier);
Blink Reformat4c46d092018-04-07 15:32:37676 section.element.classList.add('console-view-object-properties-section');
677 section.enableContextMenu();
Erik Luocc14b812018-11-03 01:33:09678 section.setShowSelectionOnKeyboardFocus(true, true);
Erik Luo383f21d2018-11-07 23:16:37679 this._selectableChildren.push(section);
Erik Luo840be6b2018-12-03 20:54:27680 section.addEventListener(UI.TreeOutline.Events.ElementAttached, this._messageResized);
681 section.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._messageResized);
682 section.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._messageResized);
Blink Reformat4c46d092018-04-07 15:32:37683 return section.element;
684 }
685
Jan Scheffler19cd7ec2021-02-12 14:16:30686 _formatParameterAsFunction(func: SDK.RemoteObject.RemoteObject, includePreview?: boolean): HTMLElement {
687 const result = (document.createElement('span') as HTMLElement);
Tim van der Lippe9b2f8712020-02-12 17:46:22688 SDK.RemoteObject.RemoteFunction.objectAsFunction(func).targetFunction().then(formatTargetFunction.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37689 return result;
690
Jan Scheffler19cd7ec2021-02-12 14:16:30691 function formatTargetFunction(this: ConsoleViewMessage, targetFunction: SDK.RemoteObject.RemoteObject): void {
Sigurd Schneider53f33522020-10-08 15:00:49692 const functionElement = document.createElement('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22693 const promise = ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection.formatObjectAsFunction(
Joey Arhard78a58f2018-12-05 01:59:45694 targetFunction, functionElement, true, includePreview);
Blink Reformat4c46d092018-04-07 15:32:37695 result.appendChild(functionElement);
696 if (targetFunction !== func) {
697 const note = result.createChild('span', 'object-info-state-note');
Christy Chen9c6d8982021-02-08 02:28:31698 UI.Tooltip.Tooltip.install(note, i18nString(UIStrings.functionWasResolvedFromBound));
Blink Reformat4c46d092018-04-07 15:32:37699 }
700 result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, targetFunction), false);
Joey Arhard78a58f2018-12-05 01:59:45701 promise.then(() => this._formattedParameterAsFunctionForTest());
Blink Reformat4c46d092018-04-07 15:32:37702 }
703 }
704
Jan Scheffler19cd7ec2021-02-12 14:16:30705 _formattedParameterAsFunctionForTest(): void {
Joey Arhard78a58f2018-12-05 01:59:45706 }
707
Jan Scheffler19cd7ec2021-02-12 14:16:30708 _contextMenuEventFired(obj: SDK.RemoteObject.RemoteObject, event: Event): void {
Tim van der Lippe9b2f8712020-02-12 17:46:22709 const contextMenu = new UI.ContextMenu.ContextMenu(event);
Blink Reformat4c46d092018-04-07 15:32:37710 contextMenu.appendApplicableItems(obj);
711 contextMenu.show();
712 }
713
Jan Scheffler19cd7ec2021-02-12 14:16:30714 _renderPropertyPreviewOrAccessor(
715 object: SDK.RemoteObject.RemoteObject|null, property: Protocol.Runtime.PropertyPreview, propertyPath: {
716 name: (string|symbol),
717 }[]): HTMLElement {
Tim van der Lippe1d6e57a2019-09-30 11:55:34718 if (property.type === 'accessor') {
Sigurd Schneider45f32c32020-10-13 13:32:05719 return this._formatAsAccessorProperty(object, propertyPath.map(property => property.name.toString()), false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34720 }
Blink Reformat4c46d092018-04-07 15:32:37721 return this._previewFormatter.renderPropertyPreview(
Alfonso Castaño20d22cd2020-10-28 16:23:58722 property.type, 'subtype' in property ? property.subtype : undefined, null, property.value);
Blink Reformat4c46d092018-04-07 15:32:37723 }
724
Jan Scheffler19cd7ec2021-02-12 14:16:30725 _formatParameterAsNode(remoteObject: SDK.RemoteObject.RemoteObject): HTMLElement {
726 const result = document.createElement('span');
Blink Reformat4c46d092018-04-07 15:32:37727
Tim van der Lippe9b2f8712020-02-12 17:46:22728 const domModel = remoteObject.runtimeModel().target().model(SDK.DOMModel.DOMModel);
Tim van der Lippe1d6e57a2019-09-30 11:55:34729 if (!domModel) {
Blink Reformat4c46d092018-04-07 15:32:37730 return result;
Tim van der Lippe1d6e57a2019-09-30 11:55:34731 }
Jan Scheffler19cd7ec2021-02-12 14:16:30732 domModel.pushObjectAsNodeToFrontend(remoteObject).then(async (node: SDK.DOMModel.DOMNode|null) => {
Blink Reformat4c46d092018-04-07 15:32:37733 if (!node) {
734 result.appendChild(this._formatParameterAsObject(remoteObject, false));
735 return;
736 }
Jan Scheffler19cd7ec2021-02-12 14:16:30737 const renderResult = await UI.UIUtils.Renderer.render((node as Object));
Erik Luofc6a6302018-11-02 06:48:52738 if (renderResult) {
Erik Luo840be6b2018-12-03 20:54:27739 if (renderResult.tree) {
Erik Luo383f21d2018-11-07 23:16:37740 this._selectableChildren.push(renderResult.tree);
Erik Luo840be6b2018-12-03 20:54:27741 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementAttached, this._messageResized);
742 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._messageResized);
743 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._messageResized);
744 }
Erik Luofc6a6302018-11-02 06:48:52745 result.appendChild(renderResult.node);
746 } else {
747 result.appendChild(this._formatParameterAsObject(remoteObject, false));
748 }
Erik Luo54fdd912018-11-01 17:57:01749 this._formattedParameterAsNodeForTest();
Blink Reformat4c46d092018-04-07 15:32:37750 });
751
752 return result;
753 }
754
Jan Scheffler19cd7ec2021-02-12 14:16:30755 _formattedParameterAsNodeForTest(): void {
Blink Reformat4c46d092018-04-07 15:32:37756 }
757
Jan Scheffler19cd7ec2021-02-12 14:16:30758 _formatParameterAsString(output: SDK.RemoteObject.RemoteObject): HTMLElement {
Tim van der Lippe8b2737f2021-06-21 14:50:47759 // Properly escape double quotes here, so users don't get surprised
760 // when they copy strings from the console (https://crbug.com/1178530).
Benedikt Meurer62b49da2021-02-18 09:15:55761 const description = output.description ?? '';
Tim van der Lippe8b2737f2021-06-21 14:50:47762 const text = JSON.stringify(description);
Jan Scheffler19cd7ec2021-02-12 14:16:30763 const result = (document.createElement('span') as HTMLElement);
Benedikt Meurer62b49da2021-02-18 09:15:55764 result.appendChild(this._linkifyStringAsFragment(text));
Blink Reformat4c46d092018-04-07 15:32:37765 return result;
766 }
767
Jan Scheffler19cd7ec2021-02-12 14:16:30768 _formatParameterAsError(output: SDK.RemoteObject.RemoteObject): HTMLElement {
769 const result = (document.createElement('span') as HTMLElement);
Blink Reformat4c46d092018-04-07 15:32:37770 const errorSpan = this._tryFormatAsError(output.description || '');
Erik Luo383f21d2018-11-07 23:16:37771 result.appendChild(errorSpan ? errorSpan : this._linkifyStringAsFragment(output.description || ''));
Blink Reformat4c46d092018-04-07 15:32:37772 return result;
773 }
774
Jan Scheffler19cd7ec2021-02-12 14:16:30775 _formatAsArrayEntry(output: SDK.RemoteObject.RemoteObject): HTMLElement {
Alfonso Castaño20d22cd2020-10-28 16:23:58776 return this._previewFormatter.renderPropertyPreview(
777 output.type, output.subtype, output.className, output.description);
Blink Reformat4c46d092018-04-07 15:32:37778 }
779
Jan Scheffler19cd7ec2021-02-12 14:16:30780 _formatAsAccessorProperty(object: SDK.RemoteObject.RemoteObject|null, propertyPath: string[], isArrayEntry: boolean):
781 HTMLElement {
Tim van der Lippe9b2f8712020-02-12 17:46:22782 const rootElement =
783 ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan(
784 object, propertyPath, onInvokeGetterClick.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37785
Jan Scheffler19cd7ec2021-02-12 14:16:30786 function onInvokeGetterClick(this: ConsoleViewMessage, result: SDK.RemoteObject.CallFunctionResult): void {
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18787 const wasThrown = result.wasThrown;
788 const object = result.object;
Tim van der Lippe1d6e57a2019-09-30 11:55:34789 if (!object) {
Blink Reformat4c46d092018-04-07 15:32:37790 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34791 }
Blink Reformat4c46d092018-04-07 15:32:37792 rootElement.removeChildren();
793 if (wasThrown) {
794 const element = rootElement.createChild('span');
Christy Chen9c6d8982021-02-08 02:28:31795 element.textContent = i18nString(UIStrings.exception);
Jan Scheffler19cd7ec2021-02-12 14:16:30796 UI.Tooltip.Tooltip.install(element, (object.description as string));
Blink Reformat4c46d092018-04-07 15:32:37797 } else if (isArrayEntry) {
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18798 rootElement.appendChild(this._formatAsArrayEntry(object));
Blink Reformat4c46d092018-04-07 15:32:37799 } else {
800 // Make a PropertyPreview from the RemoteObject similar to the backend logic.
801 const maxLength = 100;
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18802 const type = object.type;
803 const subtype = object.subtype;
Blink Reformat4c46d092018-04-07 15:32:37804 let description = '';
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18805 if (type !== 'function' && object.description) {
Alfonso Castaño20d22cd2020-10-28 16:23:58806 if (type === 'string' || subtype === 'regexp' || subtype === 'trustedtype') {
Tim van der Lippe213266c2021-01-18 15:48:31807 description = Platform.StringUtilities.trimMiddle(object.description, maxLength);
Tim van der Lippe1d6e57a2019-09-30 11:55:34808 } else {
Tim van der Lippe3cc3af32021-01-19 14:25:26809 description = Platform.StringUtilities.trimEndWithMaxLength(object.description, maxLength);
Tim van der Lippe1d6e57a2019-09-30 11:55:34810 }
Blink Reformat4c46d092018-04-07 15:32:37811 }
Alfonso Castaño20d22cd2020-10-28 16:23:58812 rootElement.appendChild(
813 this._previewFormatter.renderPropertyPreview(type, subtype, object.className, description));
Blink Reformat4c46d092018-04-07 15:32:37814 }
815 }
816
817 return rootElement;
818 }
819
Jan Scheffler19cd7ec2021-02-12 14:16:30820 _formatWithSubstitutionString(
821 format: string, parameters: SDK.RemoteObject.RemoteObject[], formattedResult: HTMLElement): {
822 formattedResult: Element,
823 unusedSubstitutions: ArrayLike<SDK.RemoteObject.RemoteObject>|null,
824 } {
825 function parameterFormatter(
826 this: ConsoleViewMessage, force: boolean, includePreview: boolean,
827 obj?: string|SDK.RemoteObject.RemoteObject): string|HTMLElement|undefined {
Sigurd Schneider45f32c32020-10-13 13:32:05828 if (obj instanceof SDK.RemoteObject.RemoteObject) {
829 return this._formatParameter(obj, force, includePreview);
830 }
831 return stringFormatter(obj);
Blink Reformat4c46d092018-04-07 15:32:37832 }
833
Jan Scheffler19cd7ec2021-02-12 14:16:30834 function stringFormatter(obj?: string|SDK.RemoteObject.RemoteObject): string|undefined {
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
Jan Scheffler19cd7ec2021-02-12 14:16:30844 function floatFormatter(obj?: string|SDK.RemoteObject.RemoteObject): number|string|undefined {
Sigurd Schneider45f32c32020-10-13 13:32:05845 if (obj instanceof SDK.RemoteObject.RemoteObject) {
846 if (typeof obj.value !== 'number') {
847 return 'NaN';
848 }
849 return obj.value;
Tim van der Lippe1d6e57a2019-09-30 11:55:34850 }
Sigurd Schneider45f32c32020-10-13 13:32:05851 return undefined;
Blink Reformat4c46d092018-04-07 15:32:37852 }
853
Jan Scheffler19cd7ec2021-02-12 14:16:30854 function integerFormatter(obj?: string|SDK.RemoteObject.RemoteObject): string|number|undefined {
Sigurd Schneider45f32c32020-10-13 13:32:05855 if (obj instanceof SDK.RemoteObject.RemoteObject) {
856 if (obj.type === 'bigint') {
857 return obj.description;
858 }
859 if (typeof obj.value !== 'number') {
860 return 'NaN';
861 }
862 return Math.floor(obj.value);
Tim van der Lippe1d6e57a2019-09-30 11:55:34863 }
Sigurd Schneider45f32c32020-10-13 13:32:05864 return undefined;
Blink Reformat4c46d092018-04-07 15:32:37865 }
866
Jan Scheffler19cd7ec2021-02-12 14:16:30867 function bypassFormatter(obj?: string|SDK.RemoteObject.RemoteObject): Node|string {
Blink Reformat4c46d092018-04-07 15:32:37868 return (obj instanceof Node) ? obj : '';
869 }
870
Jan Scheffler19cd7ec2021-02-12 14:16:30871 let currentStyle: Map<string, {value: string, priority: string}>|null = null;
872 function styleFormatter(obj?: string|SDK.RemoteObject.RemoteObject): void {
Sigurd Schneider45f32c32020-10-13 13:32:05873 currentStyle = new Map();
Sigurd Schneider53f33522020-10-08 15:00:49874 const buffer = document.createElement('span');
Sigurd Schneider45f32c32020-10-13 13:32:05875 if (obj === undefined) {
876 return;
877 }
878 if (typeof obj === 'string' || !obj.description) {
879 return;
880 }
Blink Reformat4c46d092018-04-07 15:32:37881 buffer.setAttribute('style', obj.description);
Sigurd Schneider45f32c32020-10-13 13:32:05882 for (const property of buffer.style) {
Mathias Bynens5165a7a2020-06-10 05:51:43883 if (isAllowedProperty(property)) {
Sigurd Schneider45f32c32020-10-13 13:32:05884 const info = {
885 value: buffer.style.getPropertyValue(property),
Jan Scheffler19cd7ec2021-02-12 14:16:30886 priority: buffer.style.getPropertyPriority(property),
Sigurd Schneider45f32c32020-10-13 13:32:05887 };
888 currentStyle.set(property, info);
Tim van der Lippe1d6e57a2019-09-30 11:55:34889 }
Blink Reformat4c46d092018-04-07 15:32:37890 }
891 }
892
Jan Scheffler19cd7ec2021-02-12 14:16:30893 function isAllowedProperty(property: string): boolean {
Blink Reformat4c46d092018-04-07 15:32:37894 // Make sure that allowed properties do not interfere with link visibility.
895 const prefixes = [
Jan Scheffler19cd7ec2021-02-12 14:16:30896 'background',
897 'border',
898 'color',
899 'font',
900 'line',
901 'margin',
902 'padding',
903 'text',
904 '-webkit-background',
905 '-webkit-border',
906 '-webkit-font',
907 '-webkit-margin',
908 '-webkit-padding',
909 '-webkit-text',
Blink Reformat4c46d092018-04-07 15:32:37910 ];
Sigurd Schneider45f32c32020-10-13 13:32:05911 for (const prefix of prefixes) {
912 if (property.startsWith(prefix)) {
Blink Reformat4c46d092018-04-07 15:32:37913 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:34914 }
Blink Reformat4c46d092018-04-07 15:32:37915 }
916 return false;
917 }
918
Jan Scheffler19cd7ec2021-02-12 14:16:30919 // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
920 // eslint-disable-next-line @typescript-eslint/no-explicit-any
921 const formatters: Record<string, Platform.StringUtilities.FormatterFunction<any>> = {};
Blink Reformat4c46d092018-04-07 15:32:37922 // Firebug uses %o for formatting objects.
923 formatters.o = parameterFormatter.bind(this, false /* force */, true /* includePreview */);
924 formatters.s = stringFormatter;
925 formatters.f = floatFormatter;
926 // Firebug allows both %i and %d for formatting integers.
927 formatters.i = integerFormatter;
928 formatters.d = integerFormatter;
929
930 // Firebug uses %c for styling the message.
931 formatters.c = styleFormatter;
932
933 // Support %O to force object formatting, instead of the type-based %o formatting.
934 formatters.O = parameterFormatter.bind(this, true /* force */, false /* includePreview */);
935
936 formatters._ = bypassFormatter;
937
Jan Scheffler19cd7ec2021-02-12 14:16:30938 function append(this: ConsoleViewMessage, a: HTMLElement, b?: string|Node): HTMLElement {
Blink Reformat4c46d092018-04-07 15:32:37939 if (b instanceof Node) {
940 a.appendChild(b);
Erik Luo17926392018-05-17 22:06:12941 return a;
942 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34943 if (typeof b === 'undefined') {
Erik Luo17926392018-05-17 22:06:12944 return a;
Tim van der Lippe1d6e57a2019-09-30 11:55:34945 }
Erik Luo17926392018-05-17 22:06:12946 if (!currentStyle) {
Erik Luo383f21d2018-11-07 23:16:37947 a.appendChild(this._linkifyStringAsFragment(String(b)));
Erik Luo17926392018-05-17 22:06:12948 return a;
949 }
950 const lines = String(b).split('\n');
951 for (let i = 0; i < lines.length; i++) {
952 const line = lines[i];
Erik Luo383f21d2018-11-07 23:16:37953 const lineFragment = this._linkifyStringAsFragment(line);
Jan Scheffler19cd7ec2021-02-12 14:16:30954 const wrapper = (document.createElement('span') as HTMLElement);
Erik Luo17926392018-05-17 22:06:12955 wrapper.style.setProperty('contain', 'paint');
956 wrapper.style.setProperty('display', 'inline-block');
957 wrapper.style.setProperty('max-width', '100%');
958 wrapper.appendChild(lineFragment);
959 applyCurrentStyle(wrapper);
960 for (const child of wrapper.children) {
Sigurd Schneider53f33522020-10-08 15:00:49961 if (child.classList.contains('devtools-link') && child instanceof HTMLElement) {
Erik Luo17926392018-05-17 22:06:12962 this._applyForcedVisibleStyle(child);
Tim van der Lippe1d6e57a2019-09-30 11:55:34963 }
Blink Reformat4c46d092018-04-07 15:32:37964 }
Erik Luo17926392018-05-17 22:06:12965 a.appendChild(wrapper);
Tim van der Lippe1d6e57a2019-09-30 11:55:34966 if (i < lines.length - 1) {
Sigurd Schneider53f33522020-10-08 15:00:49967 a.appendChild(document.createElement('br'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34968 }
Blink Reformat4c46d092018-04-07 15:32:37969 }
970 return a;
971 }
972
Jan Scheffler19cd7ec2021-02-12 14:16:30973 function applyCurrentStyle(element: HTMLElement): void {
Sigurd Schneider45f32c32020-10-13 13:32:05974 if (!currentStyle) {
975 return;
976 }
977 for (const [property, {value, priority}] of currentStyle.entries()) {
Jan Scheffler19cd7ec2021-02-12 14:16:30978 element.style.setProperty((property as string), value, priority);
Tim van der Lippe1d6e57a2019-09-30 11:55:34979 }
Blink Reformat4c46d092018-04-07 15:32:37980 }
981
Tim van der Lippe93b57c32020-02-20 17:38:44982 // Platform.StringUtilities.format does treat formattedResult like a Builder, result is an object.
983 return Platform.StringUtilities.format(format, parameters, formatters, formattedResult, append.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37984 }
985
Jan Scheffler19cd7ec2021-02-12 14:16:30986 _applyForcedVisibleStyle(element: HTMLElement): void {
Blink Reformat4c46d092018-04-07 15:32:37987 element.style.setProperty('-webkit-text-stroke', '0', 'important');
988 element.style.setProperty('text-decoration', 'underline', 'important');
989
Paul Lewisca569a52020-09-09 16:11:51990 const themedColor = ThemeSupport.ThemeSupport.instance().patchColorText(
991 'rgb(33%, 33%, 33%)', ThemeSupport.ThemeSupport.ColorUsage.Foreground);
Blink Reformat4c46d092018-04-07 15:32:37992 element.style.setProperty('color', themedColor, 'important');
993
994 let backgroundColor = 'hsl(0, 0%, 100%)';
Tim van der Lippeeb876c62021-05-14 15:02:11995 if (this._message.level === Protocol.Log.LogEntryLevel.Error) {
Blink Reformat4c46d092018-04-07 15:32:37996 backgroundColor = 'hsl(0, 100%, 97%)';
Tim van der Lippeeb876c62021-05-14 15:02:11997 } else if (this._message.level === Protocol.Log.LogEntryLevel.Warning || this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:37998 backgroundColor = 'hsl(50, 100%, 95%)';
Tim van der Lippe1d6e57a2019-09-30 11:55:34999 }
Paul Lewisca569a52020-09-09 16:11:511000 const themedBackgroundColor = ThemeSupport.ThemeSupport.instance().patchColorText(
1001 backgroundColor, ThemeSupport.ThemeSupport.ColorUsage.Background);
Blink Reformat4c46d092018-04-07 15:32:371002 element.style.setProperty('background-color', themedBackgroundColor, 'important');
1003 }
1004
Jan Scheffler19cd7ec2021-02-12 14:16:301005 matchesFilterRegex(regexObject: RegExp): boolean {
Blink Reformat4c46d092018-04-07 15:32:371006 regexObject.lastIndex = 0;
Erik Luo5976c8c2018-07-24 02:03:091007 const contentElement = this.contentElement();
1008 const anchorText = this._anchorElement ? this._anchorElement.deepTextContent() : '';
Tim van der Lipped7cfd142021-01-07 12:17:241009 return (Boolean(anchorText) && regexObject.test(anchorText.trim())) ||
Erik Luo5976c8c2018-07-24 02:03:091010 regexObject.test(contentElement.deepTextContent().slice(anchorText.length));
Blink Reformat4c46d092018-04-07 15:32:371011 }
1012
Jan Scheffler19cd7ec2021-02-12 14:16:301013 matchesFilterText(filter: string): boolean {
Blink Reformat4c46d092018-04-07 15:32:371014 const text = this.contentElement().deepTextContent();
1015 return text.toLowerCase().includes(filter.toLowerCase());
1016 }
1017
Jan Scheffler19cd7ec2021-02-12 14:16:301018 updateTimestamp(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341019 if (!this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371020 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341021 }
Blink Reformat4c46d092018-04-07 15:32:371022
Paul Lewis2d7d65c2020-03-16 17:26:301023 if (Common.Settings.Settings.instance().moduleSetting('consoleTimestampsEnabled').get()) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341024 if (!this._timestampElement) {
Jan Scheffler19cd7ec2021-02-12 14:16:301025 this._timestampElement = (document.createElement('span') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:091026 this._timestampElement.classList.add('console-timestamp');
Tim van der Lippe1d6e57a2019-09-30 11:55:341027 }
Tim van der Lippe9b2f8712020-02-12 17:46:221028 this._timestampElement.textContent = UI.UIUtils.formatTimestamp(this._message.timestamp, false) + ' ';
Tim van der Lippe70842f32020-11-23 16:56:571029 UI.Tooltip.Tooltip.install(this._timestampElement, UI.UIUtils.formatTimestamp(this._message.timestamp, true));
Blink Reformat4c46d092018-04-07 15:32:371030 this._contentElement.insertBefore(this._timestampElement, this._contentElement.firstChild);
1031 } else if (this._timestampElement) {
1032 this._timestampElement.remove();
Sigurd Schneider53e98632020-10-26 15:29:501033 this._timestampElement = null;
Blink Reformat4c46d092018-04-07 15:32:371034 }
Blink Reformat4c46d092018-04-07 15:32:371035 }
1036
Jan Scheffler19cd7ec2021-02-12 14:16:301037 nestingLevel(): number {
Blink Reformat4c46d092018-04-07 15:32:371038 return this._nestingLevel;
1039 }
1040
Jan Scheffler19cd7ec2021-02-12 14:16:301041 setInSimilarGroup(inSimilarGroup: boolean, isLast?: boolean): void {
Blink Reformat4c46d092018-04-07 15:32:371042 this._inSimilarGroup = inSimilarGroup;
Tim van der Lipped7cfd142021-01-07 12:17:241043 this._lastInSimilarGroup = inSimilarGroup && Boolean(isLast);
Blink Reformat4c46d092018-04-07 15:32:371044 if (this._similarGroupMarker && !inSimilarGroup) {
1045 this._similarGroupMarker.remove();
1046 this._similarGroupMarker = null;
1047 } else if (this._element && !this._similarGroupMarker && inSimilarGroup) {
Jan Scheffler19cd7ec2021-02-12 14:16:301048 this._similarGroupMarker = (document.createElement('div') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:091049 this._similarGroupMarker.classList.add('nesting-level-marker');
Blink Reformat4c46d092018-04-07 15:32:371050 this._element.insertBefore(this._similarGroupMarker, this._element.firstChild);
1051 this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
1052 }
1053 }
1054
Jan Scheffler19cd7ec2021-02-12 14:16:301055 isLastInSimilarGroup(): boolean {
Tim van der Lipped7cfd142021-01-07 12:17:241056 return Boolean(this._inSimilarGroup) && Boolean(this._lastInSimilarGroup);
Blink Reformat4c46d092018-04-07 15:32:371057 }
1058
Jan Scheffler19cd7ec2021-02-12 14:16:301059 resetCloseGroupDecorationCount(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341060 if (!this._closeGroupDecorationCount) {
Blink Reformat4c46d092018-04-07 15:32:371061 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341062 }
Blink Reformat4c46d092018-04-07 15:32:371063 this._closeGroupDecorationCount = 0;
1064 this._updateCloseGroupDecorations();
1065 }
1066
Jan Scheffler19cd7ec2021-02-12 14:16:301067 incrementCloseGroupDecorationCount(): void {
Blink Reformat4c46d092018-04-07 15:32:371068 ++this._closeGroupDecorationCount;
1069 this._updateCloseGroupDecorations();
1070 }
1071
Jan Scheffler19cd7ec2021-02-12 14:16:301072 _updateCloseGroupDecorations(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341073 if (!this._nestingLevelMarkers) {
Blink Reformat4c46d092018-04-07 15:32:371074 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341075 }
Blink Reformat4c46d092018-04-07 15:32:371076 for (let i = 0, n = this._nestingLevelMarkers.length; i < n; ++i) {
1077 const marker = this._nestingLevelMarkers[i];
1078 marker.classList.toggle('group-closed', n - i <= this._closeGroupDecorationCount);
1079 }
1080 }
1081
Jan Scheffler19cd7ec2021-02-12 14:16:301082 _focusedChildIndex(): number {
Tim van der Lippe1d6e57a2019-09-30 11:55:341083 if (!this._selectableChildren.length) {
Erik Luo0b8282e2018-10-08 20:37:461084 return -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341085 }
Erik Luo383f21d2018-11-07 23:16:371086 return this._selectableChildren.findIndex(child => child.element.hasFocus());
Erik Luo0b8282e2018-10-08 20:37:461087 }
1088
Jan Scheffler19cd7ec2021-02-12 14:16:301089 _onKeyDown(event: KeyboardEvent): void {
Sigurd Schneider45f32c32020-10-13 13:32:051090 if (UI.UIUtils.isEditing() || !this._element || !this._element.hasFocus() || this._element.hasSelection()) {
Erik Luo8ef5d0c2018-09-25 21:16:001091 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341092 }
1093 if (this.maybeHandleOnKeyDown(event)) {
Erik Luo8ef5d0c2018-09-25 21:16:001094 event.consume(true);
Tim van der Lippe1d6e57a2019-09-30 11:55:341095 }
Erik Luo8ef5d0c2018-09-25 21:16:001096 }
1097
Jan Scheffler19cd7ec2021-02-12 14:16:301098 maybeHandleOnKeyDown(event: KeyboardEvent): boolean {
Erik Luo8ef5d0c2018-09-25 21:16:001099 // Handle trace expansion.
Erik Luo0b8282e2018-10-08 20:37:461100 const focusedChildIndex = this._focusedChildIndex();
1101 const isWrapperFocused = focusedChildIndex === -1;
1102 if (this._expandTrace && isWrapperFocused) {
Erik Luo8ef5d0c2018-09-25 21:16:001103 if ((event.key === 'ArrowLeft' && this._traceExpanded) || (event.key === 'ArrowRight' && !this._traceExpanded)) {
1104 this._expandTrace(!this._traceExpanded);
1105 return true;
1106 }
1107 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341108 if (!this._selectableChildren.length) {
Erik Luo0b8282e2018-10-08 20:37:461109 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341110 }
Erik Luo0b8282e2018-10-08 20:37:461111
1112 if (event.key === 'ArrowLeft') {
Sigurd Schneider45f32c32020-10-13 13:32:051113 this._element && this._element.focus();
Erik Luo0b8282e2018-10-08 20:37:461114 return true;
1115 }
1116 if (event.key === 'ArrowRight') {
Tim van der Lippe1d6e57a2019-09-30 11:55:341117 if (isWrapperFocused && this._selectNearestVisibleChild(0)) {
Erik Luo0b8282e2018-10-08 20:37:461118 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341119 }
Erik Luo0b8282e2018-10-08 20:37:461120 }
1121 if (event.key === 'ArrowUp') {
Erik Luo182bece2018-11-29 03:15:221122 const firstVisibleChild = this._nearestVisibleChild(0);
1123 if (this._selectableChildren[focusedChildIndex] === firstVisibleChild && firstVisibleChild) {
Sigurd Schneider45f32c32020-10-13 13:32:051124 this._element && this._element.focus();
Erik Luo0b8282e2018-10-08 20:37:461125 return true;
Mathias Bynensf06e8c02020-02-28 13:58:281126 }
1127 if (this._selectNearestVisibleChild(focusedChildIndex - 1, true /* backwards */)) {
Erik Luo0b8282e2018-10-08 20:37:461128 return true;
1129 }
1130 }
1131 if (event.key === 'ArrowDown') {
Tim van der Lippe1d6e57a2019-09-30 11:55:341132 if (isWrapperFocused && this._selectNearestVisibleChild(0)) {
Erik Luo0b8282e2018-10-08 20:37:461133 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341134 }
1135 if (!isWrapperFocused && this._selectNearestVisibleChild(focusedChildIndex + 1)) {
Erik Luo0b8282e2018-10-08 20:37:461136 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341137 }
Erik Luo0b8282e2018-10-08 20:37:461138 }
Erik Luo8ef5d0c2018-09-25 21:16:001139 return false;
1140 }
1141
Jan Scheffler19cd7ec2021-02-12 14:16:301142 _selectNearestVisibleChild(fromIndex: number, backwards?: boolean): boolean {
Erik Luo182bece2018-11-29 03:15:221143 const nearestChild = this._nearestVisibleChild(fromIndex, backwards);
1144 if (nearestChild) {
Erik Luo31c21f62018-12-13 03:39:391145 nearestChild.forceSelect();
Erik Luo182bece2018-11-29 03:15:221146 return true;
1147 }
1148 return false;
1149 }
1150
Jan Scheffler19cd7ec2021-02-12 14:16:301151 _nearestVisibleChild(fromIndex: number, backwards?: boolean): {
1152 element: Element,
1153 forceSelect: () => void,
1154 }|null {
Erik Luo182bece2018-11-29 03:15:221155 const childCount = this._selectableChildren.length;
Tim van der Lippe1d6e57a2019-09-30 11:55:341156 if (fromIndex < 0 || fromIndex >= childCount) {
Erik Luo182bece2018-11-29 03:15:221157 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341158 }
Erik Luo182bece2018-11-29 03:15:221159 const direction = backwards ? -1 : 1;
1160 let index = fromIndex;
1161
1162 while (!this._selectableChildren[index].element.offsetParent) {
1163 index += direction;
Tim van der Lippe1d6e57a2019-09-30 11:55:341164 if (index < 0 || index >= childCount) {
Erik Luo182bece2018-11-29 03:15:221165 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341166 }
Erik Luo182bece2018-11-29 03:15:221167 }
1168 return this._selectableChildren[index];
1169 }
1170
Jan Scheffler19cd7ec2021-02-12 14:16:301171 focusLastChildOrSelf(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341172 if (this._element && !this._selectNearestVisibleChild(this._selectableChildren.length - 1, true /* backwards */)) {
Erik Luo0b8282e2018-10-08 20:37:461173 this._element.focus();
Tim van der Lippe1d6e57a2019-09-30 11:55:341174 }
Erik Luo0b8282e2018-10-08 20:37:461175 }
1176
Jan Scheffler19cd7ec2021-02-12 14:16:301177 setContentElement(element: HTMLElement): void {
Sigurd Schneiderb2953b22020-10-09 09:30:151178 console.assert(!this._contentElement, 'Cannot set content element twice');
1179 this._contentElement = element;
1180 }
1181
Jan Scheffler19cd7ec2021-02-12 14:16:301182 getContentElement(): HTMLElement|null {
Sigurd Schneiderb2953b22020-10-09 09:30:151183 return this._contentElement;
1184 }
1185
Jan Scheffler19cd7ec2021-02-12 14:16:301186 contentElement(): HTMLElement {
Tim van der Lippe1d6e57a2019-09-30 11:55:341187 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371188 return this._contentElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:341189 }
Blink Reformat4c46d092018-04-07 15:32:371190
Jan Scheffler19cd7ec2021-02-12 14:16:301191 const contentElement = (document.createElement('div') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:091192 contentElement.classList.add('console-message');
Tim van der Lippe1d6e57a2019-09-30 11:55:341193 if (this._messageLevelIcon) {
Blink Reformat4c46d092018-04-07 15:32:371194 contentElement.appendChild(this._messageLevelIcon);
Tim van der Lippe1d6e57a2019-09-30 11:55:341195 }
Blink Reformat4c46d092018-04-07 15:32:371196 this._contentElement = contentElement;
1197
Sigurd Schneider45f32c32020-10-13 13:32:051198 const runtimeModel = this._message.runtimeModel();
Blink Reformat4c46d092018-04-07 15:32:371199 let formattedMessage;
Tim van der Lipped7cfd142021-01-07 12:17:241200 const shouldIncludeTrace = Boolean(this._message.stackTrace) &&
Tim van der Lippeeb876c62021-05-14 15:02:111201 (this._message.source === Protocol.Log.LogEntrySource.Network ||
1202 this._message.source === Protocol.Log.LogEntrySource.Violation ||
1203 this._message.level === Protocol.Log.LogEntryLevel.Error ||
1204 this._message.level === Protocol.Log.LogEntryLevel.Warning ||
1205 this._message.type === Protocol.Runtime.ConsoleAPICalledEventType.Trace);
Sigurd Schneider45f32c32020-10-13 13:32:051206 if (runtimeModel && shouldIncludeTrace) {
1207 formattedMessage = this._buildMessageWithStackTrace(runtimeModel);
Tim van der Lippe1d6e57a2019-09-30 11:55:341208 } else {
Blink Reformat4c46d092018-04-07 15:32:371209 formattedMessage = this._buildMessage();
Tim van der Lippe1d6e57a2019-09-30 11:55:341210 }
Blink Reformat4c46d092018-04-07 15:32:371211 contentElement.appendChild(formattedMessage);
1212
1213 this.updateTimestamp();
1214 return this._contentElement;
1215 }
1216
Jan Scheffler19cd7ec2021-02-12 14:16:301217 toMessageElement(): HTMLElement {
Tim van der Lippe1d6e57a2019-09-30 11:55:341218 if (this._element) {
Blink Reformat4c46d092018-04-07 15:32:371219 return this._element;
Tim van der Lippe1d6e57a2019-09-30 11:55:341220 }
Jan Scheffler19cd7ec2021-02-12 14:16:301221 this._element = (document.createElement('div') as HTMLElement);
Pavel Feldmandb310912019-01-30 00:31:201222 this._element.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:301223 this._element.addEventListener('keydown', (this._onKeyDown.bind(this) as EventListener));
Blink Reformat4c46d092018-04-07 15:32:371224 this.updateMessageElement();
1225 return this._element;
1226 }
1227
Jan Scheffler19cd7ec2021-02-12 14:16:301228 updateMessageElement(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341229 if (!this._element) {
Blink Reformat4c46d092018-04-07 15:32:371230 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341231 }
Blink Reformat4c46d092018-04-07 15:32:371232
1233 this._element.className = 'console-message-wrapper';
1234 this._element.removeChildren();
Tim van der Lippe1d6e57a2019-09-30 11:55:341235 if (this._message.isGroupStartMessage()) {
Blink Reformat4c46d092018-04-07 15:32:371236 this._element.classList.add('console-group-title');
Tim van der Lippe1d6e57a2019-09-30 11:55:341237 }
Tim van der Lippeeb876c62021-05-14 15:02:111238 if (this._message.source === SDK.ConsoleModel.FrontendMessageSource.ConsoleAPI) {
Blink Reformat4c46d092018-04-07 15:32:371239 this._element.classList.add('console-from-api');
Tim van der Lippe1d6e57a2019-09-30 11:55:341240 }
Blink Reformat4c46d092018-04-07 15:32:371241 if (this._inSimilarGroup) {
Jan Scheffler19cd7ec2021-02-12 14:16:301242 this._similarGroupMarker = (this._element.createChild('div', 'nesting-level-marker') as HTMLElement);
Blink Reformat4c46d092018-04-07 15:32:371243 this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
1244 }
1245
1246 this._nestingLevelMarkers = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341247 for (let i = 0; i < this._nestingLevel; ++i) {
Blink Reformat4c46d092018-04-07 15:32:371248 this._nestingLevelMarkers.push(this._element.createChild('div', 'nesting-level-marker'));
Tim van der Lippe1d6e57a2019-09-30 11:55:341249 }
Blink Reformat4c46d092018-04-07 15:32:371250 this._updateCloseGroupDecorations();
Sigurd Schneiderca7b4ff2020-10-14 07:45:471251 elementToMessage.set(this._element, this);
Blink Reformat4c46d092018-04-07 15:32:371252
1253 switch (this._message.level) {
Tim van der Lippeeb876c62021-05-14 15:02:111254 case Protocol.Log.LogEntryLevel.Verbose:
Blink Reformat4c46d092018-04-07 15:32:371255 this._element.classList.add('console-verbose-level');
Blink Reformat4c46d092018-04-07 15:32:371256 break;
Tim van der Lippeeb876c62021-05-14 15:02:111257 case Protocol.Log.LogEntryLevel.Info:
Blink Reformat4c46d092018-04-07 15:32:371258 this._element.classList.add('console-info-level');
Tim van der Lippeeb876c62021-05-14 15:02:111259 if (this._message.type === SDK.ConsoleModel.FrontendMessageType.System) {
Blink Reformat4c46d092018-04-07 15:32:371260 this._element.classList.add('console-system-type');
Tim van der Lippe1d6e57a2019-09-30 11:55:341261 }
Blink Reformat4c46d092018-04-07 15:32:371262 break;
Tim van der Lippeeb876c62021-05-14 15:02:111263 case Protocol.Log.LogEntryLevel.Warning:
Blink Reformat4c46d092018-04-07 15:32:371264 this._element.classList.add('console-warning-level');
Blink Reformat4c46d092018-04-07 15:32:371265 break;
Tim van der Lippeeb876c62021-05-14 15:02:111266 case Protocol.Log.LogEntryLevel.Error:
Blink Reformat4c46d092018-04-07 15:32:371267 this._element.classList.add('console-error-level');
Blink Reformat4c46d092018-04-07 15:32:371268 break;
1269 }
Erik Luofd3e7d42018-09-25 02:12:351270 this._updateMessageLevelIcon();
Tim van der Lippe1d6e57a2019-09-30 11:55:341271 if (this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371272 this._element.classList.add('console-warning-level');
Tim van der Lippe1d6e57a2019-09-30 11:55:341273 }
Blink Reformat4c46d092018-04-07 15:32:371274
1275 this._element.appendChild(this.contentElement());
Tim van der Lippe1d6e57a2019-09-30 11:55:341276 if (this._repeatCount > 1) {
Blink Reformat4c46d092018-04-07 15:32:371277 this._showRepeatCountElement();
Tim van der Lippe1d6e57a2019-09-30 11:55:341278 }
Blink Reformat4c46d092018-04-07 15:32:371279 }
1280
Jan Scheffler19cd7ec2021-02-12 14:16:301281 _shouldRenderAsWarning(): boolean {
Tim van der Lippeeb876c62021-05-14 15:02:111282 return (this._message.level === Protocol.Log.LogEntryLevel.Verbose ||
1283 this._message.level === Protocol.Log.LogEntryLevel.Info) &&
1284 (this._message.source === Protocol.Log.LogEntrySource.Violation ||
1285 this._message.source === Protocol.Log.LogEntrySource.Deprecation ||
1286 this._message.source === Protocol.Log.LogEntrySource.Intervention ||
1287 this._message.source === Protocol.Log.LogEntrySource.Recommendation);
Blink Reformat4c46d092018-04-07 15:32:371288 }
1289
Jan Scheffler19cd7ec2021-02-12 14:16:301290 _updateMessageLevelIcon(): void {
Erik Luofd3e7d42018-09-25 02:12:351291 let iconType = '';
1292 let accessibleName = '';
Tim van der Lippeeb876c62021-05-14 15:02:111293 if (this._message.level === Protocol.Log.LogEntryLevel.Warning) {
Erik Luofd3e7d42018-09-25 02:12:351294 iconType = 'smallicon-warning';
Christy Chen9c6d8982021-02-08 02:28:311295 accessibleName = i18nString(UIStrings.warning);
Tim van der Lippeeb876c62021-05-14 15:02:111296 } else if (this._message.level === Protocol.Log.LogEntryLevel.Error) {
Erik Luofd3e7d42018-09-25 02:12:351297 iconType = 'smallicon-error';
Christy Chen9c6d8982021-02-08 02:28:311298 accessibleName = i18nString(UIStrings.error);
Erik Luofd3e7d42018-09-25 02:12:351299 }
Sigurd Schneider45f32c32020-10-13 13:32:051300 if (!this._messageLevelIcon) {
1301 if (!iconType) {
1302 return;
1303 }
Tim van der Lippe9b2f8712020-02-12 17:46:221304 this._messageLevelIcon = UI.Icon.Icon.create('', 'message-level-icon');
Tim van der Lippe1d6e57a2019-09-30 11:55:341305 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371306 this._contentElement.insertBefore(this._messageLevelIcon, this._contentElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341307 }
Blink Reformat4c46d092018-04-07 15:32:371308 }
1309 this._messageLevelIcon.setIconType(iconType);
Erik Luofd3e7d42018-09-25 02:12:351310 UI.ARIAUtils.setAccessibleName(this._messageLevelIcon, accessibleName);
Blink Reformat4c46d092018-04-07 15:32:371311 }
1312
Jan Scheffler19cd7ec2021-02-12 14:16:301313 repeatCount(): number {
Blink Reformat4c46d092018-04-07 15:32:371314 return this._repeatCount || 1;
1315 }
1316
Jan Scheffler19cd7ec2021-02-12 14:16:301317 resetIncrementRepeatCount(): void {
Blink Reformat4c46d092018-04-07 15:32:371318 this._repeatCount = 1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341319 if (!this._repeatCountElement) {
Blink Reformat4c46d092018-04-07 15:32:371320 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341321 }
Blink Reformat4c46d092018-04-07 15:32:371322
1323 this._repeatCountElement.remove();
Tim van der Lippe1d6e57a2019-09-30 11:55:341324 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371325 this._contentElement.classList.remove('repeated-message');
Tim van der Lippe1d6e57a2019-09-30 11:55:341326 }
Sigurd Schneider53e98632020-10-26 15:29:501327 this._repeatCountElement = null;
Blink Reformat4c46d092018-04-07 15:32:371328 }
1329
Jan Scheffler19cd7ec2021-02-12 14:16:301330 incrementRepeatCount(): void {
Blink Reformat4c46d092018-04-07 15:32:371331 this._repeatCount++;
1332 this._showRepeatCountElement();
1333 }
1334
Jan Scheffler19cd7ec2021-02-12 14:16:301335 setRepeatCount(repeatCount: number): void {
Blink Reformat4c46d092018-04-07 15:32:371336 this._repeatCount = repeatCount;
1337 this._showRepeatCountElement();
1338 }
Jan Scheffler19cd7ec2021-02-12 14:16:301339 _showRepeatCountElement(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341340 if (!this._element) {
Blink Reformat4c46d092018-04-07 15:32:371341 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341342 }
Blink Reformat4c46d092018-04-07 15:32:371343
1344 if (!this._repeatCountElement) {
Sigurd Schneider45f32c32020-10-13 13:32:051345 this._repeatCountElement =
Jan Scheffler19cd7ec2021-02-12 14:16:301346 (document.createElement('span', {is: 'dt-small-bubble'}) as UI.UIUtils.DevToolsSmallBubble);
Tim van der Lippeee954d42020-05-04 10:35:571347 this._repeatCountElement.classList.add('console-message-repeat-count');
Blink Reformat4c46d092018-04-07 15:32:371348 switch (this._message.level) {
Tim van der Lippeeb876c62021-05-14 15:02:111349 case Protocol.Log.LogEntryLevel.Warning:
Blink Reformat4c46d092018-04-07 15:32:371350 this._repeatCountElement.type = 'warning';
1351 break;
Tim van der Lippeeb876c62021-05-14 15:02:111352 case Protocol.Log.LogEntryLevel.Error:
Blink Reformat4c46d092018-04-07 15:32:371353 this._repeatCountElement.type = 'error';
1354 break;
Tim van der Lippeeb876c62021-05-14 15:02:111355 case Protocol.Log.LogEntryLevel.Verbose:
Blink Reformat4c46d092018-04-07 15:32:371356 this._repeatCountElement.type = 'verbose';
1357 break;
1358 default:
1359 this._repeatCountElement.type = 'info';
1360 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341361 if (this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371362 this._repeatCountElement.type = 'warning';
Tim van der Lippe1d6e57a2019-09-30 11:55:341363 }
Blink Reformat4c46d092018-04-07 15:32:371364
1365 this._element.insertBefore(this._repeatCountElement, this._contentElement);
Sigurd Schneider45f32c32020-10-13 13:32:051366 this.contentElement().classList.add('repeated-message');
Blink Reformat4c46d092018-04-07 15:32:371367 }
Sigurd Schneider45f32c32020-10-13 13:32:051368 this._repeatCountElement.textContent = `${this._repeatCount}`;
Peter Marshall2bdcc642021-03-03 10:02:091369
1370 let accessibleName;
Tim van der Lippeeb876c62021-05-14 15:02:111371 if (this._message.level === Protocol.Log.LogEntryLevel.Warning) {
Peter Marshall2bdcc642021-03-03 10:02:091372 accessibleName = i18nString(UIStrings.warningS, {n: this._repeatCount});
Tim van der Lippeeb876c62021-05-14 15:02:111373 } else if (this._message.level === Protocol.Log.LogEntryLevel.Error) {
Peter Marshall2bdcc642021-03-03 10:02:091374 accessibleName = i18nString(UIStrings.errorS, {n: this._repeatCount});
1375 } else {
1376 accessibleName = i18nString(UIStrings.repeatS, {n: this._repeatCount});
Tim van der Lippe1d6e57a2019-09-30 11:55:341377 }
Erik Luofd3e7d42018-09-25 02:12:351378 UI.ARIAUtils.setAccessibleName(this._repeatCountElement, accessibleName);
Blink Reformat4c46d092018-04-07 15:32:371379 }
1380
Jan Scheffler19cd7ec2021-02-12 14:16:301381 get text(): string {
Blink Reformat4c46d092018-04-07 15:32:371382 return this._message.messageText;
1383 }
1384
Jan Scheffler19cd7ec2021-02-12 14:16:301385 toExportString(): string {
Blink Reformat4c46d092018-04-07 15:32:371386 const lines = [];
1387 const nodes = this.contentElement().childTextNodes();
Tim van der Lippe9b2f8712020-02-12 17:46:221388 const messageContent = nodes.map(Components.Linkifier.Linkifier.untruncatedNodeText).join('');
Tim van der Lippe1d6e57a2019-09-30 11:55:341389 for (let i = 0; i < this.repeatCount(); ++i) {
Blink Reformat4c46d092018-04-07 15:32:371390 lines.push(messageContent);
Tim van der Lippe1d6e57a2019-09-30 11:55:341391 }
Blink Reformat4c46d092018-04-07 15:32:371392 return lines.join('\n');
1393 }
1394
Jan Scheffler19cd7ec2021-02-12 14:16:301395 setSearchRegex(regex: RegExp|null): void {
Sigurd Schneidere8e75cf2020-10-13 08:17:521396 if (this._searchHighlightNodeChanges && this._searchHighlightNodeChanges.length) {
1397 UI.UIUtils.revertDomChanges(this._searchHighlightNodeChanges);
Tim van der Lippe1d6e57a2019-09-30 11:55:341398 }
Blink Reformat4c46d092018-04-07 15:32:371399 this._searchRegex = regex;
1400 this._searchHighlightNodes = [];
Sigurd Schneidere8e75cf2020-10-13 08:17:521401 this._searchHighlightNodeChanges = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341402 if (!this._searchRegex) {
Blink Reformat4c46d092018-04-07 15:32:371403 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341404 }
Blink Reformat4c46d092018-04-07 15:32:371405
1406 const text = this.contentElement().deepTextContent();
1407 let match;
1408 this._searchRegex.lastIndex = 0;
1409 const sourceRanges = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341410 while ((match = this._searchRegex.exec(text)) && match[0]) {
Tim van der Lippe9b2f8712020-02-12 17:46:221411 sourceRanges.push(new TextUtils.TextRange.SourceRange(match.index, match[0].length));
Tim van der Lippe1d6e57a2019-09-30 11:55:341412 }
Blink Reformat4c46d092018-04-07 15:32:371413
1414 if (sourceRanges.length) {
1415 this._searchHighlightNodes =
Sigurd Schneidere8e75cf2020-10-13 08:17:521416 UI.UIUtils.highlightSearchResults(this.contentElement(), sourceRanges, this._searchHighlightNodeChanges);
Blink Reformat4c46d092018-04-07 15:32:371417 }
1418 }
1419
Jan Scheffler19cd7ec2021-02-12 14:16:301420 searchRegex(): RegExp|null {
Blink Reformat4c46d092018-04-07 15:32:371421 return this._searchRegex;
1422 }
1423
Jan Scheffler19cd7ec2021-02-12 14:16:301424 searchCount(): number {
Blink Reformat4c46d092018-04-07 15:32:371425 return this._searchHighlightNodes.length;
1426 }
1427
Jan Scheffler19cd7ec2021-02-12 14:16:301428 searchHighlightNode(index: number): Element {
Blink Reformat4c46d092018-04-07 15:32:371429 return this._searchHighlightNodes[index];
1430 }
1431
Philip Pfaffe068b01d2021-03-22 09:46:261432 async _getInlineFrames(
1433 debuggerModel: SDK.DebuggerModel.DebuggerModel, url: string, lineNumber: number|undefined,
1434 columnNumber: number|undefined): Promise<{frames: Bindings.DebuggerLanguagePlugins.FunctionInfo[]}> {
1435 const debuggerWorkspaceBinding = Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance();
1436 if (debuggerWorkspaceBinding.pluginManager) {
1437 const projects = Workspace.Workspace.WorkspaceImpl.instance().projects();
1438 const uiSourceCodes = projects.map(project => project.uiSourceCodeForURL(url)).flat().filter(f => Boolean(f)) as
1439 Workspace.UISourceCode.UISourceCode[];
1440 const scripts =
1441 uiSourceCodes.map(uiSourceCode => debuggerWorkspaceBinding.scriptsForUISourceCode(uiSourceCode)).flat();
1442 if (scripts.length) {
1443 const location =
1444 new SDK.DebuggerModel.Location(debuggerModel, scripts[0].scriptId, lineNumber || 0, columnNumber);
1445 return debuggerWorkspaceBinding.pluginManager.getFunctionInfo(scripts[0], location);
1446 }
1447 }
1448
1449 return {frames: []};
1450 }
1451
1452 // Expand inline stack frames in the formatted error in the stackTrace element, inserting new elements before the
1453 // insertBefore anchor.
1454 async _expandInlineStackFrames(
1455 debuggerModel: SDK.DebuggerModel.DebuggerModel, prefix: string, suffix: string, url: string,
1456 lineNumber: number|undefined, columnNumber: number|undefined, stackTrace: HTMLElement,
1457 insertBefore: HTMLElement): Promise<boolean> {
1458 const {frames} = await this._getInlineFrames(debuggerModel, url, lineNumber, columnNumber);
1459 if (!frames.length) {
1460 return false;
1461 }
1462
1463 for (let f = 0; f < frames.length; ++f) {
1464 const {name} = frames[f];
1465 const formattedLine = document.createElement('span');
1466 formattedLine.appendChild(this._linkifyStringAsFragment(`${prefix} ${name} (`));
1467 const scriptLocationLink = this._linkifier.linkifyScriptLocation(
1468 debuggerModel.target(), null, url, lineNumber,
1469 {columnNumber, className: undefined, tabStop: undefined, inlineFrameIndex: f});
1470 scriptLocationLink.tabIndex = -1;
1471 this._selectableChildren.push({element: scriptLocationLink, forceSelect: (): void => scriptLocationLink.focus()});
1472 formattedLine.appendChild(scriptLocationLink);
1473 formattedLine.appendChild(this._linkifyStringAsFragment(suffix));
1474 stackTrace.insertBefore(formattedLine, insertBefore);
1475 }
1476 return true;
1477 }
1478
Jan Scheffler19cd7ec2021-02-12 14:16:301479 _tryFormatAsError(string: string): HTMLElement|null {
1480 function startsWith(prefix: string): boolean {
Blink Reformat4c46d092018-04-07 15:32:371481 return string.startsWith(prefix);
1482 }
1483
Sigurd Schneider45f32c32020-10-13 13:32:051484 const runtimeModel = this._message.runtimeModel();
Sigurd Schneider8d0fe542021-03-17 12:28:291485 // TODO: Consider removing these in favor of a simpler regex.
Mathias Bynensfdcb3012021-03-17 14:07:211486 const errorPrefixes = [
1487 'AggregateError',
1488 'Error',
1489 'EvalError',
1490 'RangeError',
1491 'ReferenceError',
1492 'SyntaxError',
1493 'TypeError',
1494 'URIError',
1495 ];
Sigurd Schneider8d0fe542021-03-17 12:28:291496 if (!runtimeModel || !errorPrefixes.some(startsWith) && !/^[\w.]+Error\b/.test(string)) {
Blink Reformat4c46d092018-04-07 15:32:371497 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341498 }
Sigurd Schneider45f32c32020-10-13 13:32:051499 const debuggerModel = runtimeModel.debuggerModel();
1500 const baseURL = runtimeModel.target().inspectedURL();
Blink Reformat4c46d092018-04-07 15:32:371501
1502 const lines = string.split('\n');
Philip Pfaffe068b01d2021-03-22 09:46:261503 const linkInfos = [];
1504 for (const line of lines) {
1505 const isCallFrameLine = /^\s*at\s/.test(line);
1506 if (!isCallFrameLine && linkInfos.length && linkInfos[linkInfos.length - 1].link) {
Blink Reformat4c46d092018-04-07 15:32:371507 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341508 }
Blink Reformat4c46d092018-04-07 15:32:371509
Tim van der Lippe1d6e57a2019-09-30 11:55:341510 if (!isCallFrameLine) {
Philip Pfaffe068b01d2021-03-22 09:46:261511 linkInfos.push({line});
Blink Reformat4c46d092018-04-07 15:32:371512 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341513 }
Blink Reformat4c46d092018-04-07 15:32:371514
1515 let openBracketIndex = -1;
1516 let closeBracketIndex = -1;
Yang Guo39256bd2019-07-18 06:02:251517 const inBracketsWithLineAndColumn = /\([^\)\(]+:\d+:\d+\)/g;
1518 const inBrackets = /\([^\)\(]+\)/g;
Jan Scheffler19cd7ec2021-02-12 14:16:301519 let lastMatch: RegExpExecArray|null = null;
Yang Guo39256bd2019-07-18 06:02:251520 let currentMatch;
Philip Pfaffe068b01d2021-03-22 09:46:261521 while ((currentMatch = inBracketsWithLineAndColumn.exec(line))) {
Yang Guo39256bd2019-07-18 06:02:251522 lastMatch = currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341523 }
Yang Guo39256bd2019-07-18 06:02:251524 if (!lastMatch) {
Philip Pfaffe068b01d2021-03-22 09:46:261525 while ((currentMatch = inBrackets.exec(line))) {
Yang Guo39256bd2019-07-18 06:02:251526 lastMatch = currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341527 }
Yang Guo39256bd2019-07-18 06:02:251528 }
1529 if (lastMatch) {
1530 openBracketIndex = lastMatch.index;
1531 closeBracketIndex = lastMatch.index + lastMatch[0].length - 1;
Blink Reformat4c46d092018-04-07 15:32:371532 }
1533 const hasOpenBracket = openBracketIndex !== -1;
Philip Pfaffe068b01d2021-03-22 09:46:261534 let left = hasOpenBracket ? openBracketIndex + 1 : line.indexOf('at') + 3;
1535 if (!hasOpenBracket && line.indexOf('async ') === left) {
Benedikt Meureraef3b592021-03-17 16:34:401536 left += 6;
1537 }
Philip Pfaffe068b01d2021-03-22 09:46:261538 const right = hasOpenBracket ? closeBracketIndex : line.length;
1539 const linkCandidate = line.substring(left, right);
Tim van der Lippe9b2f8712020-02-12 17:46:221540 const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(linkCandidate);
Tim van der Lippe1d6e57a2019-09-30 11:55:341541 if (!splitResult) {
Blink Reformat4c46d092018-04-07 15:32:371542 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341543 }
Blink Reformat4c46d092018-04-07 15:32:371544
Tim van der Lippe1d6e57a2019-09-30 11:55:341545 if (splitResult.url === '<anonymous>') {
Philip Pfaffe068b01d2021-03-22 09:46:261546 linkInfos.push({line});
Blink Reformat4c46d092018-04-07 15:32:371547 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341548 }
Blink Reformat4c46d092018-04-07 15:32:371549 let url = parseOrScriptMatch(splitResult.url);
Tim van der Lippe9b2f8712020-02-12 17:46:221550 if (!url && Common.ParsedURL.ParsedURL.isRelativeURL(splitResult.url)) {
1551 url = parseOrScriptMatch(Common.ParsedURL.ParsedURL.completeURL(baseURL, splitResult.url));
Tim van der Lippe1d6e57a2019-09-30 11:55:341552 }
1553 if (!url) {
Blink Reformat4c46d092018-04-07 15:32:371554 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341555 }
Blink Reformat4c46d092018-04-07 15:32:371556
Philip Pfaffe068b01d2021-03-22 09:46:261557 linkInfos.push({
1558 line,
1559 link: {
1560 url,
1561 enclosedInBraces: hasOpenBracket,
1562 positionLeft: left,
1563 positionRight: right,
1564 lineNumber: splitResult.lineNumber,
1565 columnNumber: splitResult.columnNumber,
1566 },
Blink Reformat4c46d092018-04-07 15:32:371567 });
1568 }
1569
Philip Pfaffe068b01d2021-03-22 09:46:261570 if (!linkInfos.length) {
Blink Reformat4c46d092018-04-07 15:32:371571 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341572 }
Blink Reformat4c46d092018-04-07 15:32:371573
Jan Scheffler19cd7ec2021-02-12 14:16:301574 const formattedResult = document.createElement('span');
Philip Pfaffe068b01d2021-03-22 09:46:261575 for (let i = 0; i < linkInfos.length; ++i) {
1576 const newline = i < linkInfos.length - 1 ? '\n' : '';
1577 const {line, link} = linkInfos[i];
1578 if (!link) {
1579 formattedResult.appendChild(this._linkifyStringAsFragment(`${line}${newline}`));
1580 continue;
1581 }
1582 const formattedLine = document.createElement('span');
1583 const prefix = line.substring(0, link.positionLeft);
1584 const suffix = `${line.substring(link.positionRight)}${newline}`;
1585
1586 formattedLine.appendChild(this._linkifyStringAsFragment(prefix));
Erik Luo182bece2018-11-29 03:15:221587 const scriptLocationLink = this._linkifier.linkifyScriptLocation(
Philip Pfaffe068b01d2021-03-22 09:46:261588 debuggerModel.target(), null, link.url, link.lineNumber,
1589 {columnNumber: link.columnNumber, className: undefined, tabStop: undefined, inlineFrameIndex: 0});
Erik Luo182bece2018-11-29 03:15:221590 scriptLocationLink.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:301591 this._selectableChildren.push({element: scriptLocationLink, forceSelect: (): void => scriptLocationLink.focus()});
Philip Pfaffe068b01d2021-03-22 09:46:261592 formattedLine.appendChild(scriptLocationLink);
1593 formattedLine.appendChild(this._linkifyStringAsFragment(suffix));
1594 formattedResult.appendChild(formattedLine);
Blink Reformat4c46d092018-04-07 15:32:371595
Philip Pfaffe068b01d2021-03-22 09:46:261596 if (!link.enclosedInBraces) {
1597 continue;
1598 }
1599
1600 const prefixWithoutFunction = prefix.substring(0, prefix.lastIndexOf(' ', prefix.length - 3));
1601
1602 // If we were able to parse the function name from the stack trace line, try to replace it with an expansion of
1603 // any inline frames.
1604 const selectableChildIndex = this._selectableChildren.length - 1;
1605 this._expandInlineStackFrames(
1606 debuggerModel, prefixWithoutFunction, suffix, link.url, link.lineNumber, link.columnNumber,
1607 formattedResult, formattedLine)
1608 .then(modified => {
1609 if (modified) {
1610 formattedResult.removeChild(formattedLine);
1611 this._selectableChildren.splice(selectableChildIndex, 1);
1612 }
1613 });
Tim van der Lippe1d6e57a2019-09-30 11:55:341614 }
Blink Reformat4c46d092018-04-07 15:32:371615
1616 return formattedResult;
1617
Jan Scheffler19cd7ec2021-02-12 14:16:301618 function parseOrScriptMatch(url: string|null): string|null {
Tim van der Lippe1d6e57a2019-09-30 11:55:341619 if (!url) {
Blink Reformat4c46d092018-04-07 15:32:371620 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341621 }
Tim van der Lippe9b2f8712020-02-12 17:46:221622 const parsedURL = Common.ParsedURL.ParsedURL.fromString(url);
Tim van der Lippe1d6e57a2019-09-30 11:55:341623 if (parsedURL) {
Blink Reformat4c46d092018-04-07 15:32:371624 return parsedURL.url;
Tim van der Lippe1d6e57a2019-09-30 11:55:341625 }
1626 if (debuggerModel.scriptsForSourceURL(url).length) {
Blink Reformat4c46d092018-04-07 15:32:371627 return url;
Tim van der Lippe1d6e57a2019-09-30 11:55:341628 }
Blink Reformat4c46d092018-04-07 15:32:371629 return null;
1630 }
1631 }
1632
Jan Scheffler19cd7ec2021-02-12 14:16:301633 _linkifyWithCustomLinkifier(
1634 string: string, linkifier: (arg0: string, arg1: string, arg2?: number, arg3?: number) => Node): DocumentFragment {
Sigurd Schneider8f4ac862020-10-13 13:30:111635 if (string.length > getMaxTokenizableStringLength()) {
Tim van der Lippe9b2f8712020-02-12 17:46:221636 const propertyValue = new ObjectUI.ObjectPropertiesSection.ExpandableTextPropertyValue(
Sigurd Schneider8f4ac862020-10-13 13:30:111637 document.createElement('span'), string, getLongStringVisibleLength());
Sigurd Schneider45f32c32020-10-13 13:32:051638 const fragment = document.createDocumentFragment();
Connor Moody1a5c0d32019-12-19 07:23:361639 fragment.appendChild(propertyValue.element);
1640 return fragment;
Tim van der Lippe1d6e57a2019-09-30 11:55:341641 }
Sigurd Schneider45f32c32020-10-13 13:32:051642 const container = document.createDocumentFragment();
Tim van der Lippeeaacb722020-01-10 12:16:001643 const tokens = ConsoleViewMessage._tokenizeMessageText(string);
Blink Reformat4c46d092018-04-07 15:32:371644 for (const token of tokens) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341645 if (!token.text) {
Erik Luofc2214f2018-11-21 19:54:581646 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341647 }
Blink Reformat4c46d092018-04-07 15:32:371648 switch (token.type) {
1649 case 'url': {
1650 const realURL = (token.text.startsWith('www.') ? 'http://' + token.text : token.text);
Tim van der Lippe9b2f8712020-02-12 17:46:221651 const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(realURL);
Kim-Anh Tran9e49a452020-02-17 09:46:101652 const sourceURL = Common.ParsedURL.ParsedURL.removeWasmFunctionInfoFromURL(splitResult.url);
Blink Reformat4c46d092018-04-07 15:32:371653 let linkNode;
Tim van der Lippe1d6e57a2019-09-30 11:55:341654 if (splitResult) {
Kim-Anh Tran9e49a452020-02-17 09:46:101655 linkNode = linkifier(token.text, sourceURL, splitResult.lineNumber, splitResult.columnNumber);
Tim van der Lippe1d6e57a2019-09-30 11:55:341656 } else {
Sigurd Schneider45f32c32020-10-13 13:32:051657 linkNode = linkifier(token.text, '');
Tim van der Lippe1d6e57a2019-09-30 11:55:341658 }
Blink Reformat4c46d092018-04-07 15:32:371659 container.appendChild(linkNode);
1660 break;
1661 }
1662 default:
Sigurd Schneider45f32c32020-10-13 13:32:051663 container.appendChild(document.createTextNode(token.text));
Blink Reformat4c46d092018-04-07 15:32:371664 break;
1665 }
1666 }
1667 return container;
1668 }
1669
Jan Scheffler19cd7ec2021-02-12 14:16:301670 _linkifyStringAsFragment(string: string): DocumentFragment {
Erik Luofc2214f2018-11-21 19:54:581671 return this._linkifyWithCustomLinkifier(string, (text, url, lineNumber, columnNumber) => {
Sigurd Schneider45f32c32020-10-13 13:32:051672 const options = {text, lineNumber, columnNumber};
Jan Scheffler19cd7ec2021-02-12 14:16:301673 const linkElement =
1674 Components.Linkifier.Linkifier.linkifyURL(url, (options as Components.Linkifier.LinkifyURLOptions));
Erik Luo383f21d2018-11-07 23:16:371675 linkElement.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:301676 this._selectableChildren.push({element: linkElement, forceSelect: (): void => linkElement.focus()});
Erik Luo383f21d2018-11-07 23:16:371677 return linkElement;
Blink Reformat4c46d092018-04-07 15:32:371678 });
1679 }
1680
Jan Scheffler19cd7ec2021-02-12 14:16:301681 static _tokenizeMessageText(string: string): {
1682 type?: string, text: string,
1683 }[] {
Sigurd Schneider30ac3dd2020-10-13 09:06:391684 const {tokenizerRegexes, tokenizerTypes} = getOrCreateTokenizers();
Sigurd Schneider8f4ac862020-10-13 13:30:111685 if (string.length > getMaxTokenizableStringLength()) {
Blink Reformat4c46d092018-04-07 15:32:371686 return [{text: string, type: undefined}];
Tim van der Lippe1d6e57a2019-09-30 11:55:341687 }
Sigurd Schneider30ac3dd2020-10-13 09:06:391688 const results = TextUtils.TextUtils.Utils.splitStringByRegexes(string, tokenizerRegexes);
1689 return results.map(result => ({text: result.value, type: tokenizerTypes[result.regexIndex]}));
Blink Reformat4c46d092018-04-07 15:32:371690 }
1691
Jan Scheffler19cd7ec2021-02-12 14:16:301692 groupKey(): string {
Tim van der Lippe1d6e57a2019-09-30 11:55:341693 if (!this._groupKey) {
Blink Reformat4c46d092018-04-07 15:32:371694 this._groupKey = this._message.groupCategoryKey() + ':' + this.groupTitle();
Tim van der Lippe1d6e57a2019-09-30 11:55:341695 }
Blink Reformat4c46d092018-04-07 15:32:371696 return this._groupKey;
1697 }
1698
Jan Scheffler19cd7ec2021-02-12 14:16:301699 groupTitle(): string {
Tim van der Lippeeaacb722020-01-10 12:16:001700 const tokens = ConsoleViewMessage._tokenizeMessageText(this._message.messageText);
Blink Reformat4c46d092018-04-07 15:32:371701 const result = tokens.reduce((acc, token) => {
Jan Scheffler19cd7ec2021-02-12 14:16:301702 let text: Common.UIString.LocalizedString|string = token.text;
Tim van der Lippe1d6e57a2019-09-30 11:55:341703 if (token.type === 'url') {
Christy Chen9c6d8982021-02-08 02:28:311704 text = i18nString(UIStrings.url);
Tim van der Lippe1d6e57a2019-09-30 11:55:341705 } else if (token.type === 'time') {
Christy Chen9c6d8982021-02-08 02:28:311706 text = i18nString(UIStrings.tookNms);
Tim van der Lippe1d6e57a2019-09-30 11:55:341707 } else if (token.type === 'event') {
Christy Chen9c6d8982021-02-08 02:28:311708 text = i18nString(UIStrings.someEvent);
Tim van der Lippe1d6e57a2019-09-30 11:55:341709 } else if (token.type === 'milestone') {
Christy Chen9c6d8982021-02-08 02:28:311710 text = i18nString(UIStrings.Mxx);
Tim van der Lippe1d6e57a2019-09-30 11:55:341711 } else if (token.type === 'autofill') {
Christy Chen9c6d8982021-02-08 02:28:311712 text = i18nString(UIStrings.attribute);
Tim van der Lippe1d6e57a2019-09-30 11:55:341713 }
Blink Reformat4c46d092018-04-07 15:32:371714 return acc + text;
1715 }, '');
1716 return result.replace(/[%]o/g, '');
1717 }
Paul Lewisbf7aa3c2019-11-20 17:03:381718}
Blink Reformat4c46d092018-04-07 15:32:371719
Jan Scheffler19cd7ec2021-02-12 14:16:301720let tokenizerRegexes: RegExp[]|null = null;
1721let tokenizerTypes: string[]|null = null;
Sigurd Schneider30ac3dd2020-10-13 09:06:391722
Jan Scheffler19cd7ec2021-02-12 14:16:301723function getOrCreateTokenizers(): {
1724 tokenizerRegexes: Array<RegExp>,
1725 tokenizerTypes: Array<string>,
1726} {
Sigurd Schneider30ac3dd2020-10-13 09:06:391727 if (!tokenizerRegexes || !tokenizerTypes) {
1728 const controlCodes = '\\u0000-\\u0020\\u007f-\\u009f';
1729 const linkStringRegex = new RegExp(
1730 '(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\\/\\/|data:|www\\.)[^\\s' + controlCodes + '"]{2,}[^\\s' + controlCodes +
1731 '"\')}\\],:;.!?]',
1732 'u');
1733 const pathLineRegex = /(?:\/[\w\.-]*)+\:[\d]+/;
1734 const timeRegex = /took [\d]+ms/;
1735 const eventRegex = /'\w+' event/;
1736 const milestoneRegex = /\sM[6-7]\d/;
1737 const autofillRegex = /\(suggested: \"[\w-]+\"\)/;
Jan Scheffler19cd7ec2021-02-12 14:16:301738 const handlers = new Map<RegExp, string>();
Sigurd Schneider30ac3dd2020-10-13 09:06:391739 handlers.set(linkStringRegex, 'url');
1740 handlers.set(pathLineRegex, 'url');
1741 handlers.set(timeRegex, 'time');
1742 handlers.set(eventRegex, 'event');
1743 handlers.set(milestoneRegex, 'milestone');
1744 handlers.set(autofillRegex, 'autofill');
1745 tokenizerRegexes = Array.from(handlers.keys());
1746 tokenizerTypes = Array.from(handlers.values());
1747 return {tokenizerRegexes, tokenizerTypes};
1748 }
1749 return {tokenizerRegexes, tokenizerTypes};
1750}
1751
Paul Lewisbf7aa3c2019-11-20 17:03:381752export class ConsoleGroupViewMessage extends ConsoleViewMessage {
Jan Scheffler19cd7ec2021-02-12 14:16:301753 _collapsed: boolean;
1754 _expandGroupIcon: UI.Icon.Icon|null;
1755 _onToggle: () => void;
1756
1757 constructor(
1758 consoleMessage: SDK.ConsoleModel.ConsoleMessage, linkifier: Components.Linkifier.Linkifier, nestingLevel: number,
1759 onToggle: () => void, onResize: (arg0: Common.EventTarget.EventTargetEvent) => void) {
Blink Reformat4c46d092018-04-07 15:32:371760 console.assert(consoleMessage.isGroupStartMessage());
Tim van der Lippeb45d9a02019-11-05 17:24:411761 super(consoleMessage, linkifier, nestingLevel, onResize);
Tim van der Lippeeb876c62021-05-14 15:02:111762 this._collapsed = consoleMessage.type === Protocol.Runtime.ConsoleAPICalledEventType.StartGroupCollapsed;
Blink Reformat4c46d092018-04-07 15:32:371763 this._expandGroupIcon = null;
Erik Luo8ef5d0c2018-09-25 21:16:001764 this._onToggle = onToggle;
Blink Reformat4c46d092018-04-07 15:32:371765 }
1766
Jan Scheffler19cd7ec2021-02-12 14:16:301767 _setCollapsed(collapsed: boolean): void {
Blink Reformat4c46d092018-04-07 15:32:371768 this._collapsed = collapsed;
Tim van der Lippe1d6e57a2019-09-30 11:55:341769 if (this._expandGroupIcon) {
Blink Reformat4c46d092018-04-07 15:32:371770 this._expandGroupIcon.setIconType(this._collapsed ? 'smallicon-triangle-right' : 'smallicon-triangle-down');
Tim van der Lippe1d6e57a2019-09-30 11:55:341771 }
Erik Luo8ef5d0c2018-09-25 21:16:001772 this._onToggle.call(null);
Blink Reformat4c46d092018-04-07 15:32:371773 }
1774
Jan Scheffler19cd7ec2021-02-12 14:16:301775 collapsed(): boolean {
Blink Reformat4c46d092018-04-07 15:32:371776 return this._collapsed;
1777 }
1778
Jan Scheffler19cd7ec2021-02-12 14:16:301779 maybeHandleOnKeyDown(event: KeyboardEvent): boolean {
Erik Luo0b8282e2018-10-08 20:37:461780 const focusedChildIndex = this._focusedChildIndex();
1781 if (focusedChildIndex === -1) {
1782 if ((event.key === 'ArrowLeft' && !this._collapsed) || (event.key === 'ArrowRight' && this._collapsed)) {
1783 this._setCollapsed(!this._collapsed);
1784 return true;
1785 }
Erik Luo8ef5d0c2018-09-25 21:16:001786 }
1787 return super.maybeHandleOnKeyDown(event);
1788 }
1789
Jan Scheffler19cd7ec2021-02-12 14:16:301790 toMessageElement(): HTMLElement {
1791 let element: HTMLElement|null = this._element || null;
Sigurd Schneider45f32c32020-10-13 13:32:051792 if (!element) {
1793 element = super.toMessageElement();
Erik Luo8ef5d0c2018-09-25 21:16:001794 const iconType = this._collapsed ? 'smallicon-triangle-right' : 'smallicon-triangle-down';
Tim van der Lippe9b2f8712020-02-12 17:46:221795 this._expandGroupIcon = UI.Icon.Icon.create(iconType, 'expand-group-icon');
Erik Luob5bfff42018-09-20 02:52:391796 // Intercept focus to avoid highlight on click.
Sigurd Schneider45f32c32020-10-13 13:32:051797 this.contentElement().tabIndex = -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341798 if (this._repeatCountElement) {
Blink Reformat4c46d092018-04-07 15:32:371799 this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341800 } else {
Sigurd Schneider45f32c32020-10-13 13:32:051801 element.insertBefore(this._expandGroupIcon, this._contentElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:341802 }
Sigurd Schneider45f32c32020-10-13 13:32:051803 element.addEventListener('click', () => this._setCollapsed(!this._collapsed));
Blink Reformat4c46d092018-04-07 15:32:371804 }
Sigurd Schneider45f32c32020-10-13 13:32:051805 return element;
Blink Reformat4c46d092018-04-07 15:32:371806 }
1807
Jan Scheffler19cd7ec2021-02-12 14:16:301808 _showRepeatCountElement(): void {
Blink Reformat4c46d092018-04-07 15:32:371809 super._showRepeatCountElement();
Tim van der Lippe1d6e57a2019-09-30 11:55:341810 if (this._repeatCountElement && this._expandGroupIcon) {
Blink Reformat4c46d092018-04-07 15:32:371811 this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341812 }
Blink Reformat4c46d092018-04-07 15:32:371813 }
Paul Lewisbf7aa3c2019-11-20 17:03:381814}
Blink Reformat4c46d092018-04-07 15:32:371815
Sigurd Schneiderca7b4ff2020-10-14 07:45:471816export class ConsoleCommand extends ConsoleViewMessage {
Jan Scheffler19cd7ec2021-02-12 14:16:301817 _formattedCommand: HTMLElement|null;
1818
1819 constructor(
1820 consoleMessage: SDK.ConsoleModel.ConsoleMessage, linkifier: Components.Linkifier.Linkifier, nestingLevel: number,
1821 onResize: (arg0: Common.EventTarget.EventTargetEvent) => void) {
Sigurd Schneiderca7b4ff2020-10-14 07:45:471822 super(consoleMessage, linkifier, nestingLevel, onResize);
Sigurd Schneiderca7b4ff2020-10-14 07:45:471823 this._formattedCommand = null;
1824 }
1825
Jan Scheffler19cd7ec2021-02-12 14:16:301826 contentElement(): HTMLElement {
Sigurd Schneiderca7b4ff2020-10-14 07:45:471827 const contentElement = this.getContentElement();
1828 if (contentElement) {
1829 return contentElement;
1830 }
Jan Scheffler19cd7ec2021-02-12 14:16:301831 const newContentElement = (document.createElement('div') as HTMLElement);
Sigurd Schneiderca7b4ff2020-10-14 07:45:471832 this.setContentElement(newContentElement);
1833 newContentElement.classList.add('console-user-command');
1834 const icon = UI.Icon.Icon.create('smallicon-user-command', 'command-result-icon');
1835 newContentElement.appendChild(icon);
1836
1837 elementToMessage.set(newContentElement, this);
Jan Scheffler19cd7ec2021-02-12 14:16:301838 this._formattedCommand = (document.createElement('span') as HTMLElement);
Sigurd Schneiderca7b4ff2020-10-14 07:45:471839 this._formattedCommand.classList.add('source-code');
1840 this._formattedCommand.textContent = Platform.StringUtilities.replaceControlCharacters(this.text);
1841 newContentElement.appendChild(this._formattedCommand);
1842
1843 if (this._formattedCommand.textContent.length < MaxLengthToIgnoreHighlighter) {
Andres Olivaresf59e6de2021-02-18 13:10:251844 const javascriptSyntaxHighlighter = new TextEditor.SyntaxHighlighter.SyntaxHighlighter('text/javascript', true);
Sigurd Schneiderca7b4ff2020-10-14 07:45:471845 javascriptSyntaxHighlighter.syntaxHighlightNode(this._formattedCommand).then(this._updateSearch.bind(this));
1846 } else {
1847 this._updateSearch();
1848 }
1849
1850 this.updateTimestamp();
1851 return newContentElement;
1852 }
1853
Jan Scheffler19cd7ec2021-02-12 14:16:301854 _updateSearch(): void {
Sigurd Schneiderca7b4ff2020-10-14 07:45:471855 this.setSearchRegex(this.searchRegex());
1856 }
1857}
1858
1859export class ConsoleCommandResult extends ConsoleViewMessage {
Jan Scheffler19cd7ec2021-02-12 14:16:301860 contentElement(): HTMLElement {
Sigurd Schneiderca7b4ff2020-10-14 07:45:471861 const element = super.contentElement();
1862 if (!element.classList.contains('console-user-command-result')) {
1863 element.classList.add('console-user-command-result');
Tim van der Lippeeb876c62021-05-14 15:02:111864 if (this.consoleMessage().level === Protocol.Log.LogEntryLevel.Info) {
Sigurd Schneiderca7b4ff2020-10-14 07:45:471865 const icon = UI.Icon.Icon.create('smallicon-command-result', 'command-result-icon');
1866 element.insertBefore(icon, element.firstChild);
1867 }
1868 }
1869 return element;
1870 }
1871}
1872
Sigurd Schneider8bfb4212020-10-27 10:27:371873export class ConsoleTableMessageView extends ConsoleViewMessage {
Jan Scheffler19cd7ec2021-02-12 14:16:301874 _dataGrid: DataGrid.SortableDataGrid.SortableDataGrid<unknown>|null;
1875
1876 constructor(
1877 consoleMessage: SDK.ConsoleModel.ConsoleMessage, linkifier: Components.Linkifier.Linkifier, nestingLevel: number,
1878 onResize: (arg0: Common.EventTarget.EventTargetEvent) => void) {
Sigurd Schneider8bfb4212020-10-27 10:27:371879 super(consoleMessage, linkifier, nestingLevel, onResize);
Tim van der Lippeeb876c62021-05-14 15:02:111880 console.assert(consoleMessage.type === Protocol.Runtime.ConsoleAPICalledEventType.Table);
Sigurd Schneider8bfb4212020-10-27 10:27:371881 this._dataGrid = null;
1882 }
1883
Jan Scheffler19cd7ec2021-02-12 14:16:301884 wasShown(): void {
Sigurd Schneider8bfb4212020-10-27 10:27:371885 if (this._dataGrid) {
1886 this._dataGrid.updateWidths();
1887 }
1888 super.wasShown();
1889 }
1890
Jan Scheffler19cd7ec2021-02-12 14:16:301891 onResize(): void {
Sigurd Schneider8bfb4212020-10-27 10:27:371892 if (!this.isVisible()) {
1893 return;
1894 }
1895 if (this._dataGrid) {
1896 this._dataGrid.onResize();
1897 }
1898 }
1899
Jan Scheffler19cd7ec2021-02-12 14:16:301900 contentElement(): HTMLElement {
Sigurd Schneider8bfb4212020-10-27 10:27:371901 const contentElement = this.getContentElement();
1902 if (contentElement) {
1903 return contentElement;
1904 }
1905
Jan Scheffler19cd7ec2021-02-12 14:16:301906 const newContentElement = (document.createElement('div') as HTMLElement);
Sigurd Schneider8bfb4212020-10-27 10:27:371907 newContentElement.classList.add('console-message');
1908 if (this._messageLevelIcon) {
1909 newContentElement.appendChild(this._messageLevelIcon);
1910 }
1911 this.setContentElement(newContentElement);
1912
1913 newContentElement.appendChild(this._buildTableMessage());
1914 this.updateTimestamp();
1915 return newContentElement;
1916 }
1917
Jan Scheffler19cd7ec2021-02-12 14:16:301918 _buildTableMessage(): HTMLElement {
1919 const formattedMessage = (document.createElement('span') as HTMLElement);
Sigurd Schneider8bfb4212020-10-27 10:27:371920 formattedMessage.classList.add('source-code');
1921 this._anchorElement = this._buildMessageAnchor();
1922 if (this._anchorElement) {
1923 formattedMessage.appendChild(this._anchorElement);
1924 }
1925
1926 const table = this._message.parameters && this._message.parameters.length ? this._message.parameters[0] : null;
1927 if (!table) {
1928 return this._buildMessage();
1929 }
1930 const actualTable = parameterToRemoteObject(this._message.runtimeModel())(table);
1931 if (!actualTable || !actualTable.preview) {
1932 return this._buildMessage();
1933 }
1934
1935 const rawValueColumnSymbol = Symbol('rawValueColumn');
Jan Scheffler19cd7ec2021-02-12 14:16:301936 const columnNames: (string|symbol)[] = [];
Sigurd Schneider8bfb4212020-10-27 10:27:371937 const preview = actualTable.preview;
1938 const rows = [];
1939 for (let i = 0; i < preview.properties.length; ++i) {
1940 const rowProperty = preview.properties[i];
Jan Scheffler19cd7ec2021-02-12 14:16:301941 let rowSubProperties: Protocol.Runtime.PropertyPreview[];
Sigurd Schneiderb393a432020-11-06 12:08:211942 if (rowProperty.valuePreview && rowProperty.valuePreview.properties.length) {
Sigurd Schneider8bfb4212020-10-27 10:27:371943 rowSubProperties = rowProperty.valuePreview.properties;
1944 } else if (rowProperty.value) {
Jan Scheffler19cd7ec2021-02-12 14:16:301945 rowSubProperties =
1946 [{name: rawValueColumnSymbol as unknown as string, type: rowProperty.type, value: rowProperty.value}];
Sigurd Schneider8bfb4212020-10-27 10:27:371947 } else {
1948 continue;
1949 }
1950
Jan Scheffler19cd7ec2021-02-12 14:16:301951 const rowValue = new Map<string|symbol, HTMLElement>();
Sigurd Schneider8bfb4212020-10-27 10:27:371952 const maxColumnsToRender = 20;
1953 for (let j = 0; j < rowSubProperties.length; ++j) {
1954 const cellProperty = rowSubProperties[j];
Jan Scheffler19cd7ec2021-02-12 14:16:301955 let columnRendered: true|boolean = columnNames.indexOf(cellProperty.name) !== -1;
Sigurd Schneider8bfb4212020-10-27 10:27:371956 if (!columnRendered) {
1957 if (columnNames.length === maxColumnsToRender) {
1958 continue;
1959 }
1960 columnRendered = true;
1961 columnNames.push(cellProperty.name);
1962 }
1963
1964 if (columnRendered) {
1965 const cellElement =
1966 this._renderPropertyPreviewOrAccessor(actualTable, cellProperty, [rowProperty, cellProperty]);
1967 cellElement.classList.add('console-message-nowrap-below');
1968 rowValue.set(cellProperty.name, cellElement);
1969 }
1970 }
1971 rows.push({rowName: rowProperty.name, rowValue});
1972 }
1973
1974 const flatValues = [];
1975 for (const {rowName, rowValue} of rows) {
1976 flatValues.push(rowName);
1977 for (let j = 0; j < columnNames.length; ++j) {
1978 flatValues.push(rowValue.get(columnNames[j]));
1979 }
1980 }
Christy Chen9c6d8982021-02-08 02:28:311981 columnNames.unshift(i18nString(UIStrings.index));
Sigurd Schneider8bfb4212020-10-27 10:27:371982 const columnDisplayNames =
Christy Chen9c6d8982021-02-08 02:28:311983 columnNames.map(name => name === rawValueColumnSymbol ? i18nString(UIStrings.value) : name.toString());
Sigurd Schneider8bfb4212020-10-27 10:27:371984
1985 if (flatValues.length) {
Christy Chen9c6d8982021-02-08 02:28:311986 this._dataGrid = DataGrid.SortableDataGrid.SortableDataGrid.create(
1987 columnDisplayNames, flatValues, i18nString(UIStrings.console));
Sigurd Schneider8bfb4212020-10-27 10:27:371988 if (this._dataGrid) {
1989 this._dataGrid.setStriped(true);
1990 this._dataGrid.setFocusable(false);
1991
1992 const formattedResult = document.createElement('span');
1993 formattedResult.classList.add('console-message-text');
1994 const tableElement = formattedResult.createChild('div', 'console-message-formatted-table');
1995 const dataGridContainer = tableElement.createChild('span');
1996 tableElement.appendChild(this._formatParameter(actualTable, true, false));
1997 dataGridContainer.appendChild(this._dataGrid.element);
1998 formattedMessage.appendChild(formattedResult);
1999 this._dataGrid.renderInline();
2000 }
2001 }
2002 return formattedMessage;
2003 }
2004
Jan Scheffler19cd7ec2021-02-12 14:16:302005 approximateFastHeight(): number {
Sigurd Schneider8bfb4212020-10-27 10:27:372006 const table = this._message.parameters && this._message.parameters[0];
2007 if (table && typeof table !== 'string' && table.preview) {
2008 return defaultConsoleRowHeight * table.preview.properties.length;
2009 }
2010 return defaultConsoleRowHeight;
2011 }
2012}
2013
Sigurd Schneiderca7b4ff2020-10-14 07:45:472014/**
2015 * The maximum length before strings are considered too long for syntax highlighting.
2016 * @const
Sigurd Schneiderca7b4ff2020-10-14 07:45:472017 */
Jan Scheffler19cd7ec2021-02-12 14:16:302018const MaxLengthToIgnoreHighlighter: number = 10000;
Sigurd Schneiderca7b4ff2020-10-14 07:45:472019
Blink Reformat4c46d092018-04-07 15:32:372020/**
2021 * @const
Blink Reformat4c46d092018-04-07 15:32:372022 */
Jan Scheffler19cd7ec2021-02-12 14:16:302023export const MaxLengthForLinks: number = 40;
Blink Reformat4c46d092018-04-07 15:32:372024
Sigurd Schneider17c74452021-02-15 12:14:102025let maxTokenizableStringLength = 10000;
2026let longStringVisibleLength = 5000;
Sigurd Schneider8f4ac862020-10-13 13:30:112027
Jan Scheffler19cd7ec2021-02-12 14:16:302028export const getMaxTokenizableStringLength = (): number => {
Sigurd Schneider17c74452021-02-15 12:14:102029 return maxTokenizableStringLength;
Sigurd Schneider8f4ac862020-10-13 13:30:112030};
2031
Jan Scheffler19cd7ec2021-02-12 14:16:302032export const setMaxTokenizableStringLength = (length: number): void => {
Sigurd Schneider17c74452021-02-15 12:14:102033 maxTokenizableStringLength = length;
Sigurd Schneider8f4ac862020-10-13 13:30:112034};
2035
Jan Scheffler19cd7ec2021-02-12 14:16:302036export const getLongStringVisibleLength = (): number => {
Sigurd Schneider17c74452021-02-15 12:14:102037 return longStringVisibleLength;
Sigurd Schneider8f4ac862020-10-13 13:30:112038};
2039
Jan Scheffler19cd7ec2021-02-12 14:16:302040export const setLongStringVisibleLength = (length: number): void => {
Sigurd Schneider17c74452021-02-15 12:14:102041 longStringVisibleLength = length;
Sigurd Schneider8f4ac862020-10-13 13:30:112042};