blob: 6ddcb0d9fce5dc8f5f5a4615b97f48a2f8331765 [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
Philip Pfaffe068b01d2021-03-22 09:46:2637import * as Bindings from '../../bindings/bindings.js';
Tim van der Lippe586c8022021-03-18 15:18:2038import * as Common from '../../common/common.js';
39import * as Components from '../../components/components.js';
Tim van der Lippeaa1ed7a2021-03-31 14:38:2740import * as Platform from '../../core/platform/platform.js';
Tim van der Lippe586c8022021-03-18 15:18:2041import * as DataGrid from '../../data_grid/data_grid.js';
42import * as i18n from '../../i18n/i18n.js';
43import * as ObjectUI from '../../object_ui/object_ui.js';
Tim van der Lippe586c8022021-03-18 15:18:2044import * as SDK from '../../sdk/sdk.js';
45import * as TextEditor from '../../text_editor/text_editor.js';
46import * as TextUtils from '../../text_utils/text_utils.js';
47import * as ThemeSupport from '../../theme_support/theme_support.js';
48import * as UI from '../../ui/ui.js';
Philip Pfaffe068b01d2021-03-22 09:46:2649import * as Workspace from '../../workspace/workspace.js';
Tim van der Lippe9b2f8712020-02-12 17:46:2250
Tim van der Lippebfbb58f2021-02-25 17:34:1951import type {ConsoleViewportElement} from './ConsoleViewport.js';
Tim van der Lippeeaacb722020-01-10 12:16:0052
Simon Zündfbfd1072021-03-01 07:38:5353const UIStrings = {
Christy Chen9c6d8982021-02-08 02:28:3154 /**
Peter Marshallf295a4b2021-02-26 09:48:0355 * @description Message element text content in Console View Message of the Console panel. Shown
56 * when the user tried to run console.clear() but the 'Preserve log' option is enabled, which stops
57 * the log from being cleared.
Christy Chen9c6d8982021-02-08 02:28:3158 */
59 consoleclearWasPreventedDueTo: '`console.clear()` was prevented due to \'Preserve log\'',
60 /**
Peter Marshallb8bd00f2021-02-24 08:25:1861 * @description Text shown in the Console panel after the user has cleared the console, which
62 * removes all messages from the console so that it is empty.
Christy Chen9c6d8982021-02-08 02:28:3163 */
64 consoleWasCleared: 'Console was cleared',
65 /**
66 *@description Message element title in Console View Message of the Console panel
67 *@example {Ctrl+L} PH1
68 */
69 clearAllMessagesWithS: 'Clear all messages with {PH1}',
70 /**
71 *@description Message prefix in Console View Message of the Console panel
72 */
73 assertionFailed: 'Assertion failed: ',
74 /**
75 *@description Message text in Console View Message of the Console panel
76 *@example {console.log(1)} PH1
77 */
Peter Marshall40dd7d92021-02-19 11:07:3778 violationS: '`[Violation]` {PH1}',
Christy Chen9c6d8982021-02-08 02:28:3179 /**
80 *@description Message text in Console View Message of the Console panel
81 *@example {console.log(1)} PH1
82 */
Peter Marshall40dd7d92021-02-19 11:07:3783 interventionS: '`[Intervention]` {PH1}',
Christy Chen9c6d8982021-02-08 02:28:3184 /**
85 *@description Message text in Console View Message of the Console panel
86 *@example {console.log(1)} PH1
87 */
Peter Marshall40dd7d92021-02-19 11:07:3788 deprecationS: '`[Deprecation]` {PH1}',
Christy Chen9c6d8982021-02-08 02:28:3189 /**
90 *@description Note title in Console View Message of the Console panel
91 */
92 thisValueWillNotBeCollectedUntil: 'This value will not be collected until console is cleared.',
93 /**
94 *@description Note title in Console View Message of the Console panel
95 */
96 thisValueWasEvaluatedUponFirst: 'This value was evaluated upon first expanding. It may have changed since then.',
97 /**
98 *@description Note title in Console View Message of the Console panel
99 */
100 functionWasResolvedFromBound: 'Function was resolved from bound function.',
101 /**
Peter Marshallf625dc82021-03-02 08:10:57102 * @description Shown in the Console panel when an exception is thrown when trying to access a
103 * property on an object. Should be translated.
Christy Chen9c6d8982021-02-08 02:28:31104 */
105 exception: '<exception>',
106 /**
107 *@description Text to indicate an item is a warning
108 */
109 warning: 'Warning',
110 /**
111 *@description Text for errors
112 */
113 error: 'Error',
114 /**
Peter Marshall2bdcc642021-03-03 10:02:09115 * @description Announced by the screen reader to indicate how many times a particular message in
116 * the console was repeated.
Christy Chen9c6d8982021-02-08 02:28:31117 */
Peter Marshall2bdcc642021-03-03 10:02:09118 repeatS: '{n, plural, =1 {Repeated # time} other {Repeated # times}}',
Christy Chen9c6d8982021-02-08 02:28:31119 /**
Peter Marshall2bdcc642021-03-03 10:02:09120 * @description Announced by the screen reader to indicate how many times a particular warning
121 * message in the console was repeated.
Christy Chen9c6d8982021-02-08 02:28:31122 */
Peter Marshall2bdcc642021-03-03 10:02:09123 warningS: '{n, plural, =1 {Warning, Repeated # time} other {Warning, Repeated # times}}',
Christy Chen9c6d8982021-02-08 02:28:31124 /**
Peter Marshall2bdcc642021-03-03 10:02:09125 * @description Announced by the screen reader to indicate how many times a particular error
126 * message in the console was repeated.
Christy Chen9c6d8982021-02-08 02:28:31127 */
Peter Marshall2bdcc642021-03-03 10:02:09128 errorS: '{n, plural, =1 {Error, Repeated # time} other {Error, Repeated # times}}',
Christy Chen9c6d8982021-02-08 02:28:31129 /**
Tim van der Lippee4b96c62021-02-17 12:43:16130 *@description Text appended to grouped console messages that are related to URL requests
Christy Chen9c6d8982021-02-08 02:28:31131 */
132 url: '<URL>',
133 /**
Tim van der Lippee4b96c62021-02-17 12:43:16134 *@description Text appended to grouped console messages about tasks that took longer than N ms
Christy Chen9c6d8982021-02-08 02:28:31135 */
136 tookNms: 'took <N>ms',
137 /**
Tim van der Lippee4b96c62021-02-17 12:43:16138 *@description Text appended to grouped console messages about tasks that are related to some DOM event
Christy Chen9c6d8982021-02-08 02:28:31139 */
140 someEvent: '<some> event',
141 /**
Tim van der Lippee4b96c62021-02-17 12:43:16142 *@description Text appended to grouped console messages about tasks that are related to a particular milestone
Christy Chen9c6d8982021-02-08 02:28:31143 */
144 Mxx: ' M<XX>',
145 /**
Tim van der Lippee4b96c62021-02-17 12:43:16146 *@description Text appended to grouped console messages about tasks that are related to autofill completions
Christy Chen9c6d8982021-02-08 02:28:31147 */
148 attribute: '<attribute>',
149 /**
150 *@description Text for the index of something
151 */
152 index: '(index)',
153 /**
154 *@description Text for the value of something
155 */
156 value: 'Value',
157 /**
158 *@description Title of the Console tool
159 */
160 console: 'Console',
161};
Tim van der Lippe586c8022021-03-18 15:18:20162const str_ = i18n.i18n.registerUIStrings('panels/console/ConsoleViewMessage.ts', UIStrings);
Christy Chen9c6d8982021-02-08 02:28:31163const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
Jan Scheffler19cd7ec2021-02-12 14:16:30164const elementToMessage = new WeakMap<Element, ConsoleViewMessage>();
Sigurd Schneiderca7b4ff2020-10-14 07:45:47165
Jan Scheffler19cd7ec2021-02-12 14:16:30166export const getMessageForElement = (element: Element): ConsoleViewMessage|undefined => {
Sigurd Schneiderca7b4ff2020-10-14 07:45:47167 return elementToMessage.get(element);
168};
169
Sigurd Schneider8bfb4212020-10-27 10:27:37170// This value reflects the 18px min-height of .console-message, plus the
171// 1px border of .console-message-wrapper. Keep in sync with consoleView.css.
172const defaultConsoleRowHeight = 19;
173
Jan Scheffler19cd7ec2021-02-12 14:16:30174const parameterToRemoteObject = (runtimeModel: SDK.RuntimeModel.RuntimeModel|null): (
175 parameter?: SDK.RemoteObject.RemoteObject|Protocol.Runtime.RemoteObject|string) => SDK.RemoteObject.RemoteObject =>
176 (parameter?: string|SDK.RemoteObject.RemoteObject|Protocol.Runtime.RemoteObject): SDK.RemoteObject.RemoteObject => {
Sigurd Schneider8bfb4212020-10-27 10:27:37177 if (parameter instanceof SDK.RemoteObject.RemoteObject) {
178 return parameter;
179 }
180 if (!runtimeModel) {
181 return SDK.RemoteObject.RemoteObject.fromLocalObject(parameter);
182 }
183 if (typeof parameter === 'object') {
184 return runtimeModel.createRemoteObject(parameter);
185 }
186 return runtimeModel.createRemoteObjectFromPrimitiveValue(parameter);
187 };
188
Jan Scheffler19cd7ec2021-02-12 14:16:30189export class ConsoleViewMessage implements ConsoleViewportElement {
190 _message: SDK.ConsoleModel.ConsoleMessage;
191 _linkifier: Components.Linkifier.Linkifier;
192 _repeatCount: number;
193 _closeGroupDecorationCount: number;
194 _nestingLevel: number;
195 _selectableChildren: {
196 element: HTMLElement,
197 forceSelect: () => void,
198 }[];
199 _messageResized: (arg0: Common.EventTarget.EventTargetEvent) => void;
200 _element: HTMLElement|null;
201 _previewFormatter: ObjectUI.RemoteObjectPreviewFormatter.RemoteObjectPreviewFormatter;
202 _searchRegex: RegExp|null;
203 _messageLevelIcon: UI.Icon.Icon|null;
204 _traceExpanded: boolean;
205 _expandTrace: ((arg0: boolean) => void)|null;
206 _anchorElement: HTMLElement|null;
207 _contentElement: HTMLElement|null;
208 _nestingLevelMarkers: HTMLElement[]|null;
209 _searchHighlightNodes: Element[];
210 _searchHighlightNodeChanges: UI.UIUtils.HighlightChange[];
211 _isVisible: boolean;
212 _cachedHeight: number;
213 _messagePrefix: string;
214 _timestampElement: HTMLElement|null;
215 _inSimilarGroup: boolean;
216 _similarGroupMarker: HTMLElement|null;
217 _lastInSimilarGroup: boolean;
218 _groupKey: string;
219 _repeatCountElement: UI.UIUtils.DevToolsSmallBubble|null;
220
221 constructor(
222 consoleMessage: SDK.ConsoleModel.ConsoleMessage, linkifier: Components.Linkifier.Linkifier, nestingLevel: number,
223 onResize: (arg0: Common.EventTarget.EventTargetEvent) => void) {
Blink Reformat4c46d092018-04-07 15:32:37224 this._message = consoleMessage;
225 this._linkifier = linkifier;
Blink Reformat4c46d092018-04-07 15:32:37226 this._repeatCount = 1;
227 this._closeGroupDecorationCount = 0;
228 this._nestingLevel = nestingLevel;
Erik Luo383f21d2018-11-07 23:16:37229 this._selectableChildren = [];
Erik Luo840be6b2018-12-03 20:54:27230 this._messageResized = onResize;
Sigurd Schneider53e98632020-10-26 15:29:50231 this._element = null;
Blink Reformat4c46d092018-04-07 15:32:37232
Tim van der Lippe9b2f8712020-02-12 17:46:22233 this._previewFormatter = new ObjectUI.RemoteObjectPreviewFormatter.RemoteObjectPreviewFormatter();
Blink Reformat4c46d092018-04-07 15:32:37234 this._searchRegex = null;
Blink Reformat4c46d092018-04-07 15:32:37235 this._messageLevelIcon = null;
Erik Luo8ef5d0c2018-09-25 21:16:00236 this._traceExpanded = false;
Erik Luo8ef5d0c2018-09-25 21:16:00237 this._expandTrace = null;
John Emaubb2897a2019-10-04 17:37:32238 this._anchorElement = null;
Sigurd Schneider45f32c32020-10-13 13:32:05239 this._contentElement = null;
Sigurd Schneider45f32c32020-10-13 13:32:05240 this._nestingLevelMarkers = null;
Sigurd Schneider45f32c32020-10-13 13:32:05241 this._searchHighlightNodes = [];
Sigurd Schneidere8e75cf2020-10-13 08:17:52242 this._searchHighlightNodeChanges = [];
Sigurd Schneider53e98632020-10-26 15:29:50243 this._isVisible = false;
244 this._cachedHeight = 0;
245 this._messagePrefix = '';
Sigurd Schneider53e98632020-10-26 15:29:50246 this._timestampElement = null;
247 this._inSimilarGroup = false;
Sigurd Schneider53e98632020-10-26 15:29:50248 this._similarGroupMarker = null;
249 this._lastInSimilarGroup = false;
250 this._groupKey = '';
Sigurd Schneider53e98632020-10-26 15:29:50251 this._repeatCountElement = null;
Blink Reformat4c46d092018-04-07 15:32:37252 }
253
Jan Scheffler19cd7ec2021-02-12 14:16:30254 element(): HTMLElement {
Blink Reformat4c46d092018-04-07 15:32:37255 return this.toMessageElement();
256 }
257
Jan Scheffler19cd7ec2021-02-12 14:16:30258 wasShown(): void {
Blink Reformat4c46d092018-04-07 15:32:37259 this._isVisible = true;
260 }
261
Jan Scheffler19cd7ec2021-02-12 14:16:30262 onResize(): void {
Blink Reformat4c46d092018-04-07 15:32:37263 }
264
Jan Scheffler19cd7ec2021-02-12 14:16:30265 willHide(): void {
Blink Reformat4c46d092018-04-07 15:32:37266 this._isVisible = false;
Erik Luo4b002322018-07-30 21:23:31267 this._cachedHeight = this.element().offsetHeight;
Blink Reformat4c46d092018-04-07 15:32:37268 }
269
Jan Scheffler19cd7ec2021-02-12 14:16:30270 isVisible(): boolean {
Sigurd Schneider8bfb4212020-10-27 10:27:37271 return this._isVisible;
272 }
273
Jan Scheffler19cd7ec2021-02-12 14:16:30274 fastHeight(): number {
Tim van der Lippe1d6e57a2019-09-30 11:55:34275 if (this._cachedHeight) {
Blink Reformat4c46d092018-04-07 15:32:37276 return this._cachedHeight;
Tim van der Lippe1d6e57a2019-09-30 11:55:34277 }
Sigurd Schneider8bfb4212020-10-27 10:27:37278 return this.approximateFastHeight();
279 }
280
Jan Scheffler19cd7ec2021-02-12 14:16:30281 approximateFastHeight(): number {
Blink Reformat4c46d092018-04-07 15:32:37282 return defaultConsoleRowHeight;
283 }
284
Jan Scheffler19cd7ec2021-02-12 14:16:30285 consoleMessage(): SDK.ConsoleModel.ConsoleMessage {
Blink Reformat4c46d092018-04-07 15:32:37286 return this._message;
287 }
288
Jan Scheffler19cd7ec2021-02-12 14:16:30289 _buildMessage(): HTMLElement {
Blink Reformat4c46d092018-04-07 15:32:37290 let messageElement;
Jan Scheffler19cd7ec2021-02-12 14:16:30291 let messageText: Common.UIString.LocalizedString|string = this._message.messageText;
Tim van der Lippe9b2f8712020-02-12 17:46:22292 if (this._message.source === SDK.ConsoleModel.MessageSource.ConsoleAPI) {
Blink Reformat4c46d092018-04-07 15:32:37293 switch (this._message.type) {
Tim van der Lippe9b2f8712020-02-12 17:46:22294 case SDK.ConsoleModel.MessageType.Trace:
Blink Reformat4c46d092018-04-07 15:32:37295 messageElement = this._format(this._message.parameters || ['console.trace']);
296 break;
Tim van der Lippe9b2f8712020-02-12 17:46:22297 case SDK.ConsoleModel.MessageType.Clear:
Tim van der Lippef49e2322020-05-01 15:03:09298 messageElement = document.createElement('span');
299 messageElement.classList.add('console-info');
Paul Lewis2d7d65c2020-03-16 17:26:30300 if (Common.Settings.Settings.instance().moduleSetting('preserveConsoleLog').get()) {
Christy Chen9c6d8982021-02-08 02:28:31301 messageElement.textContent = i18nString(UIStrings.consoleclearWasPreventedDueTo);
Tim van der Lippe1d6e57a2019-09-30 11:55:34302 } else {
Christy Chen9c6d8982021-02-08 02:28:31303 messageElement.textContent = i18nString(UIStrings.consoleWasCleared);
Tim van der Lippe1d6e57a2019-09-30 11:55:34304 }
Tim van der Lippe420e5e32020-11-23 16:58:46305 UI.Tooltip.Tooltip.install(
Christy Chen9c6d8982021-02-08 02:28:31306 messageElement, i18nString(UIStrings.clearAllMessagesWithS, {
Jan Scheffler19cd7ec2021-02-12 14:16:30307 PH1: UI.ShortcutRegistry.ShortcutRegistry.instance().shortcutTitleForAction('console.clear'),
Christy Chen9c6d8982021-02-08 02:28:31308 }));
Blink Reformat4c46d092018-04-07 15:32:37309 break;
Tim van der Lippe9b2f8712020-02-12 17:46:22310 case SDK.ConsoleModel.MessageType.Dir: {
Blink Reformat4c46d092018-04-07 15:32:37311 const obj = this._message.parameters ? this._message.parameters[0] : undefined;
312 const args = ['%O', obj];
313 messageElement = this._format(args);
314 break;
315 }
Tim van der Lippe9b2f8712020-02-12 17:46:22316 case SDK.ConsoleModel.MessageType.Profile:
317 case SDK.ConsoleModel.MessageType.ProfileEnd:
Blink Reformat4c46d092018-04-07 15:32:37318 messageElement = this._format([messageText]);
319 break;
320 default: {
Sigurd Schneider45f32c32020-10-13 13:32:05321 if (this._message.type === SDK.ConsoleModel.MessageType.Assert) {
Christy Chen9c6d8982021-02-08 02:28:31322 this._messagePrefix = i18nString(UIStrings.assertionFailed);
Sigurd Schneider45f32c32020-10-13 13:32:05323 }
324 if (this._message.parameters && this._message.parameters.length === 1) {
325 const parameter = this._message.parameters[0];
326 if (typeof parameter !== 'string' && parameter.type === 'string') {
Jan Scheffler19cd7ec2021-02-12 14:16:30327 messageElement = this._tryFormatAsError((parameter.value as string));
Sigurd Schneider45f32c32020-10-13 13:32:05328 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34329 }
Blink Reformat4c46d092018-04-07 15:32:37330 const args = this._message.parameters || [messageText];
331 messageElement = messageElement || this._format(args);
332 }
333 }
334 } else {
Tim van der Lippe9b2f8712020-02-12 17:46:22335 if (this._message.source === SDK.ConsoleModel.MessageSource.Network) {
Erik Luofc2214f2018-11-21 19:54:58336 messageElement = this._formatAsNetworkRequest() || this._format([messageText]);
337 } else {
Jan Scheffler19cd7ec2021-02-12 14:16:30338 const messageInParameters = this._message.parameters && messageText === (this._message.parameters[0] as string);
Peter Marshall40dd7d92021-02-19 11:07:37339 // These terms are locked because the console message will not be translated anyway.
Tim van der Lippe9b2f8712020-02-12 17:46:22340 if (this._message.source === SDK.ConsoleModel.MessageSource.Violation) {
Christy Chen9c6d8982021-02-08 02:28:31341 messageText = i18nString(UIStrings.violationS, {PH1: messageText});
Tim van der Lippe9b2f8712020-02-12 17:46:22342 } else if (this._message.source === SDK.ConsoleModel.MessageSource.Intervention) {
Christy Chen9c6d8982021-02-08 02:28:31343 messageText = i18nString(UIStrings.interventionS, {PH1: messageText});
Tim van der Lippe9b2f8712020-02-12 17:46:22344 } else if (this._message.source === SDK.ConsoleModel.MessageSource.Deprecation) {
Christy Chen9c6d8982021-02-08 02:28:31345 messageText = i18nString(UIStrings.deprecationS, {PH1: messageText});
Tim van der Lippe1d6e57a2019-09-30 11:55:34346 }
Blink Reformat4c46d092018-04-07 15:32:37347 const args = this._message.parameters || [messageText];
Tim van der Lippe1d6e57a2019-09-30 11:55:34348 if (messageInParameters) {
Blink Reformat4c46d092018-04-07 15:32:37349 args[0] = messageText;
Tim van der Lippe1d6e57a2019-09-30 11:55:34350 }
Blink Reformat4c46d092018-04-07 15:32:37351 messageElement = this._format(args);
352 }
353 }
354 messageElement.classList.add('console-message-text');
355
Jan Scheffler19cd7ec2021-02-12 14:16:30356 const formattedMessage = (document.createElement('span') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:09357 formattedMessage.classList.add('source-code');
Erik Luo5976c8c2018-07-24 02:03:09358 this._anchorElement = this._buildMessageAnchor();
Tim van der Lippe1d6e57a2019-09-30 11:55:34359 if (this._anchorElement) {
Erik Luo5976c8c2018-07-24 02:03:09360 formattedMessage.appendChild(this._anchorElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34361 }
Blink Reformat4c46d092018-04-07 15:32:37362 formattedMessage.appendChild(messageElement);
363 return formattedMessage;
364 }
365
Jan Scheffler19cd7ec2021-02-12 14:16:30366 _formatAsNetworkRequest(): HTMLElement|null {
Tim van der Lippe9b2f8712020-02-12 17:46:22367 const request = SDK.NetworkLog.NetworkLog.requestForConsoleMessage(this._message);
Tim van der Lippe1d6e57a2019-09-30 11:55:34368 if (!request) {
Erik Luofc2214f2018-11-21 19:54:58369 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34370 }
Jan Scheffler19cd7ec2021-02-12 14:16:30371 const messageElement = (document.createElement('span') as HTMLElement);
Tim van der Lippe9b2f8712020-02-12 17:46:22372 if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Sigurd Schneider23c52972020-10-13 09:31:14373 UI.UIUtils.createTextChild(messageElement, request.requestMethod + ' ');
Tim van der Lippe9b2f8712020-02-12 17:46:22374 const linkElement = Components.Linkifier.Linkifier.linkifyRevealable(request, request.url(), request.url());
Erik Luo182bece2018-11-29 03:15:22375 // Focus is handled by the viewport.
376 linkElement.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:30377 this._selectableChildren.push({element: linkElement, forceSelect: (): void => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22378 messageElement.appendChild(linkElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34379 if (request.failed) {
Sigurd Schneider23c52972020-10-13 09:31:14380 UI.UIUtils.createTextChildren(messageElement, ' ', request.localizedFailDescription || '');
Tim van der Lippe1d6e57a2019-09-30 11:55:34381 }
382 if (request.statusCode !== 0) {
Sigurd Schneider23c52972020-10-13 09:31:14383 UI.UIUtils.createTextChildren(messageElement, ' ', String(request.statusCode));
Tim van der Lippe1d6e57a2019-09-30 11:55:34384 }
385 if (request.statusText) {
Sigurd Schneider23c52972020-10-13 09:31:14386 UI.UIUtils.createTextChildren(messageElement, ' (', request.statusText, ')');
Tim van der Lippe1d6e57a2019-09-30 11:55:34387 }
Erik Luofc2214f2018-11-21 19:54:58388 } else {
Erik Luoad5f3942019-03-26 20:53:44389 const messageText = this._message.messageText;
390 const fragment = this._linkifyWithCustomLinkifier(messageText, (text, url, lineNumber, columnNumber) => {
Sigurd Schneider45f32c32020-10-13 13:32:05391 const linkElement = url === request.url() ?
392 Components.Linkifier.Linkifier.linkifyRevealable(
Jan Scheffler19cd7ec2021-02-12 14:16:30393 (request as SDK.NetworkRequest.NetworkRequest), url, request.url()) :
Sigurd Schneider45f32c32020-10-13 13:32:05394 Components.Linkifier.Linkifier.linkifyURL(
Jan Scheffler19cd7ec2021-02-12 14:16:30395 url, ({text, lineNumber, columnNumber} as Components.Linkifier.LinkifyURLOptions));
Erik Luo182bece2018-11-29 03:15:22396 linkElement.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:30397 this._selectableChildren.push({element: linkElement, forceSelect: (): void => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22398 return linkElement;
399 });
Erik Luofc2214f2018-11-21 19:54:58400 messageElement.appendChild(fragment);
401 }
402 return messageElement;
403 }
404
Jan Scheffler19cd7ec2021-02-12 14:16:30405 _buildMessageAnchor(): HTMLElement|null {
406 const linkify = (message: SDK.ConsoleModel.ConsoleMessage): HTMLElement|null => {
Sigurd Schneider45f32c32020-10-13 13:32:05407 if (message.scriptId) {
408 return this._linkifyScriptId(message.scriptId, message.url || '', message.line, message.column);
409 }
410 if (message.stackTrace && message.stackTrace.callFrames.length) {
411 return this._linkifyStackTraceTopFrame(message.stackTrace);
412 }
413 if (message.url && message.url !== 'undefined') {
414 return this._linkifyLocation(message.url, message.line, message.column);
415 }
416 return null;
417 };
418 const anchorElement = linkify(this._message);
Blink Reformat4c46d092018-04-07 15:32:37419 // Append a space to prevent the anchor text from being glued to the console message when the user selects and copies the console messages.
420 if (anchorElement) {
John Emauf7e30fb2019-10-04 19:12:32421 anchorElement.tabIndex = -1;
422 this._selectableChildren.push({
423 element: anchorElement,
Jan Scheffler19cd7ec2021-02-12 14:16:30424 forceSelect: (): void => anchorElement.focus(),
John Emauf7e30fb2019-10-04 19:12:32425 });
Jan Scheffler19cd7ec2021-02-12 14:16:30426 const anchorWrapperElement = (document.createElement('span') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:09427 anchorWrapperElement.classList.add('console-message-anchor');
Blink Reformat4c46d092018-04-07 15:32:37428 anchorWrapperElement.appendChild(anchorElement);
Sigurd Schneider23c52972020-10-13 09:31:14429 UI.UIUtils.createTextChild(anchorWrapperElement, ' ');
Blink Reformat4c46d092018-04-07 15:32:37430 return anchorWrapperElement;
431 }
432 return null;
433 }
434
Jan Scheffler19cd7ec2021-02-12 14:16:30435 _buildMessageWithStackTrace(runtimeModel: SDK.RuntimeModel.RuntimeModel): HTMLElement {
436 const toggleElement = (document.createElement('div') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:09437 toggleElement.classList.add('console-message-stack-trace-toggle');
Blink Reformat4c46d092018-04-07 15:32:37438 const contentElement = toggleElement.createChild('div', 'console-message-stack-trace-wrapper');
439
440 const messageElement = this._buildMessage();
Tim van der Lippe9b2f8712020-02-12 17:46:22441 const icon = UI.Icon.Icon.create('smallicon-triangle-right', 'console-message-expand-icon');
Blink Reformat4c46d092018-04-07 15:32:37442 const clickableElement = contentElement.createChild('div');
443 clickableElement.appendChild(icon);
Erik Luob5bfff42018-09-20 02:52:39444 // Intercept focus to avoid highlight on click.
445 clickableElement.tabIndex = -1;
Blink Reformat4c46d092018-04-07 15:32:37446 clickableElement.appendChild(messageElement);
447 const stackTraceElement = contentElement.createChild('div');
448 const stackTracePreview = Components.JSPresentationUtils.buildStackTracePreviewContents(
Wolfgang Beyer08261c72021-03-09 09:21:34449 runtimeModel.target(), this._linkifier, {stackTrace: this._message.stackTrace, tabStops: undefined});
Erik Luo182bece2018-11-29 03:15:22450 stackTraceElement.appendChild(stackTracePreview.element);
451 for (const linkElement of stackTracePreview.links) {
Jan Scheffler19cd7ec2021-02-12 14:16:30452 this._selectableChildren.push({element: linkElement, forceSelect: (): void => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22453 }
Blink Reformat4c46d092018-04-07 15:32:37454 stackTraceElement.classList.add('hidden');
Brandon Goddard04a5a762019-12-10 16:45:53455 UI.ARIAUtils.markAsTreeitem(this.element());
456 UI.ARIAUtils.setExpanded(this.element(), false);
Jan Scheffler19cd7ec2021-02-12 14:16:30457 this._expandTrace = (expand: boolean): void => {
Blink Reformat4c46d092018-04-07 15:32:37458 icon.setIconType(expand ? 'smallicon-triangle-down' : 'smallicon-triangle-right');
459 stackTraceElement.classList.toggle('hidden', !expand);
Brandon Goddard04a5a762019-12-10 16:45:53460 UI.ARIAUtils.setExpanded(this.element(), expand);
Erik Luo8ef5d0c2018-09-25 21:16:00461 this._traceExpanded = expand;
462 };
Blink Reformat4c46d092018-04-07 15:32:37463
Jan Scheffler19cd7ec2021-02-12 14:16:30464 const toggleStackTrace = (event: Event): void => {
Tim van der Lippe9b2f8712020-02-12 17:46:22465 if (UI.UIUtils.isEditing() || contentElement.hasSelection()) {
Blink Reformat4c46d092018-04-07 15:32:37466 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34467 }
Sigurd Schneider45f32c32020-10-13 13:32:05468 this._expandTrace && this._expandTrace(stackTraceElement.classList.contains('hidden'));
Blink Reformat4c46d092018-04-07 15:32:37469 event.consume();
Sigurd Schneider45f32c32020-10-13 13:32:05470 };
Blink Reformat4c46d092018-04-07 15:32:37471
Sigurd Schneider45f32c32020-10-13 13:32:05472 clickableElement.addEventListener('click', toggleStackTrace, false);
Tim van der Lippe9b2f8712020-02-12 17:46:22473 if (this._message.type === SDK.ConsoleModel.MessageType.Trace) {
Erik Luo8ef5d0c2018-09-25 21:16:00474 this._expandTrace(true);
Tim van der Lippe1d6e57a2019-09-30 11:55:34475 }
Blink Reformat4c46d092018-04-07 15:32:37476
Sigurd Schneider45f32c32020-10-13 13:32:05477 // @ts-ignore
Erik Luo8ef5d0c2018-09-25 21:16:00478 toggleElement._expandStackTraceForTest = this._expandTrace.bind(this, true);
Blink Reformat4c46d092018-04-07 15:32:37479 return toggleElement;
480 }
481
Jan Scheffler19cd7ec2021-02-12 14:16:30482 _linkifyLocation(url: string, lineNumber: number, columnNumber: number): HTMLElement|null {
Sigurd Schneider45f32c32020-10-13 13:32:05483 const runtimeModel = this._message.runtimeModel();
484 if (!runtimeModel) {
Blink Reformat4c46d092018-04-07 15:32:37485 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34486 }
Blink Reformat4c46d092018-04-07 15:32:37487 return this._linkifier.linkifyScriptLocation(
Sigurd Schneider45f32c32020-10-13 13:32:05488 runtimeModel.target(), /* scriptId */ null, url, lineNumber,
Philip Pfaffe068b01d2021-03-22 09:46:26489 {columnNumber, className: undefined, tabStop: undefined, inlineFrameIndex: 0});
Blink Reformat4c46d092018-04-07 15:32:37490 }
491
Jan Scheffler19cd7ec2021-02-12 14:16:30492 _linkifyStackTraceTopFrame(stackTrace: Protocol.Runtime.StackTrace): HTMLElement|null {
Sigurd Schneider45f32c32020-10-13 13:32:05493 const runtimeModel = this._message.runtimeModel();
494 if (!runtimeModel) {
Blink Reformat4c46d092018-04-07 15:32:37495 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34496 }
Sigurd Schneider45f32c32020-10-13 13:32:05497 return this._linkifier.linkifyStackTraceTopFrame(runtimeModel.target(), stackTrace);
Blink Reformat4c46d092018-04-07 15:32:37498 }
499
Jan Scheffler19cd7ec2021-02-12 14:16:30500 _linkifyScriptId(scriptId: string, url: string, lineNumber: number, columnNumber: number): HTMLElement|null {
Sigurd Schneider45f32c32020-10-13 13:32:05501 const runtimeModel = this._message.runtimeModel();
502 if (!runtimeModel) {
Blink Reformat4c46d092018-04-07 15:32:37503 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34504 }
Blink Reformat4c46d092018-04-07 15:32:37505 return this._linkifier.linkifyScriptLocation(
Philip Pfaffe068b01d2021-03-22 09:46:26506 runtimeModel.target(), scriptId, url, lineNumber,
507 {columnNumber, className: undefined, tabStop: undefined, inlineFrameIndex: 0});
Blink Reformat4c46d092018-04-07 15:32:37508 }
509
Jan Scheffler19cd7ec2021-02-12 14:16:30510 _format(rawParameters: (string|SDK.RemoteObject.RemoteObject|Protocol.Runtime.RemoteObject|undefined)[]):
511 HTMLElement {
Blink Reformat4c46d092018-04-07 15:32:37512 // This node is used like a Builder. Values are continually appended onto it.
Jan Scheffler19cd7ec2021-02-12 14:16:30513 const formattedResult = (document.createElement('span') as HTMLElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34514 if (this._messagePrefix) {
Pavel Feldman9f0f0a32018-12-18 02:09:13515 formattedResult.createChild('span').textContent = this._messagePrefix;
Tim van der Lippe1d6e57a2019-09-30 11:55:34516 }
517 if (!rawParameters.length) {
Blink Reformat4c46d092018-04-07 15:32:37518 return formattedResult;
Tim van der Lippe1d6e57a2019-09-30 11:55:34519 }
Blink Reformat4c46d092018-04-07 15:32:37520
521 // Formatting code below assumes that parameters are all wrappers whereas frontend console
522 // API allows passing arbitrary values as messages (strings, numbers, etc.). Wrap them here.
523 // FIXME: Only pass runtime wrappers here.
Sigurd Schneider8bfb4212020-10-27 10:27:37524 let parameters = rawParameters.map(parameterToRemoteObject(this._message.runtimeModel()));
Blink Reformat4c46d092018-04-07 15:32:37525
526 // There can be string log and string eval result. We distinguish between them based on message type.
527 const shouldFormatMessage =
Jan Scheffler19cd7ec2021-02-12 14:16:30528 SDK.RemoteObject.RemoteObject.type((parameters as SDK.RemoteObject.RemoteObject[])[0]) === 'string' &&
Tim van der Lippe9b2f8712020-02-12 17:46:22529 (this._message.type !== SDK.ConsoleModel.MessageType.Result ||
530 this._message.level === SDK.ConsoleModel.MessageLevel.Error);
Blink Reformat4c46d092018-04-07 15:32:37531
532 // Multiple parameters with the first being a format string. Save unused substitutions.
533 if (shouldFormatMessage) {
534 const result = this._formatWithSubstitutionString(
Jan Scheffler19cd7ec2021-02-12 14:16:30535 (parameters[0].description as string), parameters.slice(1), formattedResult);
Sigurd Schneider45f32c32020-10-13 13:32:05536 parameters = Array.from(result.unusedSubstitutions || []);
Tim van der Lippe1d6e57a2019-09-30 11:55:34537 if (parameters.length) {
Sigurd Schneider23c52972020-10-13 09:31:14538 UI.UIUtils.createTextChild(formattedResult, ' ');
Tim van der Lippe1d6e57a2019-09-30 11:55:34539 }
Blink Reformat4c46d092018-04-07 15:32:37540 }
541
542 // Single parameter, or unused substitutions from above.
543 for (let i = 0; i < parameters.length; ++i) {
544 // Inline strings when formatting.
Tim van der Lippe1d6e57a2019-09-30 11:55:34545 if (shouldFormatMessage && parameters[i].type === 'string') {
Sigurd Schneider45f32c32020-10-13 13:32:05546 formattedResult.appendChild(this._linkifyStringAsFragment(parameters[i].description || ''));
Tim van der Lippe1d6e57a2019-09-30 11:55:34547 } else {
Blink Reformat4c46d092018-04-07 15:32:37548 formattedResult.appendChild(this._formatParameter(parameters[i], false, true));
Tim van der Lippe1d6e57a2019-09-30 11:55:34549 }
550 if (i < parameters.length - 1) {
Sigurd Schneider23c52972020-10-13 09:31:14551 UI.UIUtils.createTextChild(formattedResult, ' ');
Tim van der Lippe1d6e57a2019-09-30 11:55:34552 }
Blink Reformat4c46d092018-04-07 15:32:37553 }
554 return formattedResult;
555 }
556
Jan Scheffler19cd7ec2021-02-12 14:16:30557 _formatParameter(output: SDK.RemoteObject.RemoteObject, forceObjectFormat?: boolean, includePreview?: boolean):
558 HTMLElement {
Tim van der Lippe1d6e57a2019-09-30 11:55:34559 if (output.customPreview()) {
Jan Scheffler19cd7ec2021-02-12 14:16:30560 return new ObjectUI.CustomPreviewComponent.CustomPreviewComponent(output).element as HTMLElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:34561 }
Blink Reformat4c46d092018-04-07 15:32:37562
Alfonso Castaño20d22cd2020-10-28 16:23:58563 const outputType = forceObjectFormat ? 'object' : (output.subtype || output.type);
Blink Reformat4c46d092018-04-07 15:32:37564 let element;
Alfonso Castaño20d22cd2020-10-28 16:23:58565 switch (outputType) {
Blink Reformat4c46d092018-04-07 15:32:37566 case 'error':
567 element = this._formatParameterAsError(output);
568 break;
569 case 'function':
570 element = this._formatParameterAsFunction(output, includePreview);
571 break;
572 case 'array':
573 case 'arraybuffer':
574 case 'blob':
575 case 'dataview':
576 case 'generator':
577 case 'iterator':
578 case 'map':
579 case 'object':
580 case 'promise':
581 case 'proxy':
582 case 'set':
583 case 'typedarray':
Benedikt Meurer5658dd22021-03-18 09:37:23584 case 'wasmvalue':
Blink Reformat4c46d092018-04-07 15:32:37585 case 'weakmap':
586 case 'weakset':
Benedikt Meurerdead3152020-12-07 08:43:40587 case 'webassemblymemory':
Blink Reformat4c46d092018-04-07 15:32:37588 element = this._formatParameterAsObject(output, includePreview);
589 break;
590 case 'node':
591 element = output.isNode() ? this._formatParameterAsNode(output) : this._formatParameterAsObject(output, false);
592 break;
Alfonso Castaño20d22cd2020-10-28 16:23:58593 case 'trustedtype':
594 element = this._formatParameterAsObject(output, false);
595 break;
Blink Reformat4c46d092018-04-07 15:32:37596 case 'string':
597 element = this._formatParameterAsString(output);
598 break;
599 case 'boolean':
600 case 'date':
601 case 'null':
602 case 'number':
603 case 'regexp':
604 case 'symbol':
605 case 'undefined':
606 case 'bigint':
607 element = this._formatParameterAsValue(output);
608 break;
609 default:
610 element = this._formatParameterAsValue(output);
Alfonso Castaño20d22cd2020-10-28 16:23:58611 console.error(`Tried to format remote object of unknown type ${outputType}.`);
Blink Reformat4c46d092018-04-07 15:32:37612 }
Alfonso Castaño20d22cd2020-10-28 16:23:58613 element.classList.add(`object-value-${outputType}`);
Blink Reformat4c46d092018-04-07 15:32:37614 element.classList.add('source-code');
615 return element;
616 }
617
Jan Scheffler19cd7ec2021-02-12 14:16:30618 _formatParameterAsValue(obj: SDK.RemoteObject.RemoteObject): HTMLElement {
619 const result = (document.createElement('span') as HTMLElement);
Blink Reformat4c46d092018-04-07 15:32:37620 const description = obj.description || '';
Sigurd Schneider8f4ac862020-10-13 13:30:11621 if (description.length > getMaxTokenizableStringLength()) {
Tim van der Lippe9b2f8712020-02-12 17:46:22622 const propertyValue = new ObjectUI.ObjectPropertiesSection.ExpandableTextPropertyValue(
Sigurd Schneider8f4ac862020-10-13 13:30:11623 document.createElement('span'), description, getLongStringVisibleLength());
Connor Moody1a5c0d32019-12-19 07:23:36624 result.appendChild(propertyValue.element);
Tim van der Lippe1d6e57a2019-09-30 11:55:34625 } else {
Sigurd Schneider23c52972020-10-13 09:31:14626 UI.UIUtils.createTextChild(result, description);
Tim van der Lippe1d6e57a2019-09-30 11:55:34627 }
628 if (obj.objectId) {
Blink Reformat4c46d092018-04-07 15:32:37629 result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, obj), false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34630 }
Blink Reformat4c46d092018-04-07 15:32:37631 return result;
632 }
633
Jan Scheffler19cd7ec2021-02-12 14:16:30634 _formatParameterAsTrustedType(obj: SDK.RemoteObject.RemoteObject): HTMLElement {
635 const result = (document.createElement('span') as HTMLElement);
Alfonso Castaño20d22cd2020-10-28 16:23:58636 const trustedContentSpan = document.createElement('span');
637 trustedContentSpan.appendChild(this._formatParameterAsString(obj));
638 trustedContentSpan.classList.add('object-value-string');
Alfonso Castañodfe8ca32020-10-29 13:03:09639 UI.UIUtils.createTextChild(result, `${obj.className} `);
Alfonso Castaño20d22cd2020-10-28 16:23:58640 result.appendChild(trustedContentSpan);
Alfonso Castaño20d22cd2020-10-28 16:23:58641 return result;
642 }
643
Jan Scheffler19cd7ec2021-02-12 14:16:30644 _formatParameterAsObject(obj: SDK.RemoteObject.RemoteObject, includePreview?: boolean): HTMLElement {
645 const titleElement = (document.createElement('span') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:09646 titleElement.classList.add('console-object');
Blink Reformat4c46d092018-04-07 15:32:37647 if (includePreview && obj.preview) {
648 titleElement.classList.add('console-object-preview');
649 this._previewFormatter.appendObjectPreview(titleElement, obj.preview, false /* isEntry */);
650 } else if (obj.type === 'function') {
651 const functionElement = titleElement.createChild('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22652 ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection.formatObjectAsFunction(obj, functionElement, false);
Blink Reformat4c46d092018-04-07 15:32:37653 titleElement.classList.add('object-value-function');
Alfonso Castaño20d22cd2020-10-28 16:23:58654 } else if (obj.subtype === 'trustedtype') {
655 titleElement.appendChild(this._formatParameterAsTrustedType(obj));
Blink Reformat4c46d092018-04-07 15:32:37656 } else {
Sigurd Schneider23c52972020-10-13 09:31:14657 UI.UIUtils.createTextChild(titleElement, obj.description || '');
Blink Reformat4c46d092018-04-07 15:32:37658 }
659
Tim van der Lippe1d6e57a2019-09-30 11:55:34660 if (!obj.hasChildren || obj.customPreview()) {
Blink Reformat4c46d092018-04-07 15:32:37661 return titleElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:34662 }
Blink Reformat4c46d092018-04-07 15:32:37663
664 const note = titleElement.createChild('span', 'object-state-note info-note');
Tim van der Lippe9b2f8712020-02-12 17:46:22665 if (this._message.type === SDK.ConsoleModel.MessageType.QueryObjectResult) {
Christy Chen9c6d8982021-02-08 02:28:31666 UI.Tooltip.Tooltip.install(note, i18nString(UIStrings.thisValueWillNotBeCollectedUntil));
Tim van der Lippe1d6e57a2019-09-30 11:55:34667 } else {
Christy Chen9c6d8982021-02-08 02:28:31668 UI.Tooltip.Tooltip.install(note, i18nString(UIStrings.thisValueWasEvaluatedUponFirst));
Tim van der Lippe1d6e57a2019-09-30 11:55:34669 }
Blink Reformat4c46d092018-04-07 15:32:37670
Tim van der Lippe9b2f8712020-02-12 17:46:22671 const section = new ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection(obj, titleElement, this._linkifier);
Blink Reformat4c46d092018-04-07 15:32:37672 section.element.classList.add('console-view-object-properties-section');
673 section.enableContextMenu();
Erik Luocc14b812018-11-03 01:33:09674 section.setShowSelectionOnKeyboardFocus(true, true);
Erik Luo383f21d2018-11-07 23:16:37675 this._selectableChildren.push(section);
Erik Luo840be6b2018-12-03 20:54:27676 section.addEventListener(UI.TreeOutline.Events.ElementAttached, this._messageResized);
677 section.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._messageResized);
678 section.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._messageResized);
Blink Reformat4c46d092018-04-07 15:32:37679 return section.element;
680 }
681
Jan Scheffler19cd7ec2021-02-12 14:16:30682 _formatParameterAsFunction(func: SDK.RemoteObject.RemoteObject, includePreview?: boolean): HTMLElement {
683 const result = (document.createElement('span') as HTMLElement);
Tim van der Lippe9b2f8712020-02-12 17:46:22684 SDK.RemoteObject.RemoteFunction.objectAsFunction(func).targetFunction().then(formatTargetFunction.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37685 return result;
686
Jan Scheffler19cd7ec2021-02-12 14:16:30687 function formatTargetFunction(this: ConsoleViewMessage, targetFunction: SDK.RemoteObject.RemoteObject): void {
Sigurd Schneider53f33522020-10-08 15:00:49688 const functionElement = document.createElement('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22689 const promise = ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection.formatObjectAsFunction(
Joey Arhard78a58f2018-12-05 01:59:45690 targetFunction, functionElement, true, includePreview);
Blink Reformat4c46d092018-04-07 15:32:37691 result.appendChild(functionElement);
692 if (targetFunction !== func) {
693 const note = result.createChild('span', 'object-info-state-note');
Christy Chen9c6d8982021-02-08 02:28:31694 UI.Tooltip.Tooltip.install(note, i18nString(UIStrings.functionWasResolvedFromBound));
Blink Reformat4c46d092018-04-07 15:32:37695 }
696 result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, targetFunction), false);
Joey Arhard78a58f2018-12-05 01:59:45697 promise.then(() => this._formattedParameterAsFunctionForTest());
Blink Reformat4c46d092018-04-07 15:32:37698 }
699 }
700
Jan Scheffler19cd7ec2021-02-12 14:16:30701 _formattedParameterAsFunctionForTest(): void {
Joey Arhard78a58f2018-12-05 01:59:45702 }
703
Jan Scheffler19cd7ec2021-02-12 14:16:30704 _contextMenuEventFired(obj: SDK.RemoteObject.RemoteObject, event: Event): void {
Tim van der Lippe9b2f8712020-02-12 17:46:22705 const contextMenu = new UI.ContextMenu.ContextMenu(event);
Blink Reformat4c46d092018-04-07 15:32:37706 contextMenu.appendApplicableItems(obj);
707 contextMenu.show();
708 }
709
Jan Scheffler19cd7ec2021-02-12 14:16:30710 _renderPropertyPreviewOrAccessor(
711 object: SDK.RemoteObject.RemoteObject|null, property: Protocol.Runtime.PropertyPreview, propertyPath: {
712 name: (string|symbol),
713 }[]): HTMLElement {
Tim van der Lippe1d6e57a2019-09-30 11:55:34714 if (property.type === 'accessor') {
Sigurd Schneider45f32c32020-10-13 13:32:05715 return this._formatAsAccessorProperty(object, propertyPath.map(property => property.name.toString()), false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34716 }
Blink Reformat4c46d092018-04-07 15:32:37717 return this._previewFormatter.renderPropertyPreview(
Alfonso Castaño20d22cd2020-10-28 16:23:58718 property.type, 'subtype' in property ? property.subtype : undefined, null, property.value);
Blink Reformat4c46d092018-04-07 15:32:37719 }
720
Jan Scheffler19cd7ec2021-02-12 14:16:30721 _formatParameterAsNode(remoteObject: SDK.RemoteObject.RemoteObject): HTMLElement {
722 const result = document.createElement('span');
Blink Reformat4c46d092018-04-07 15:32:37723
Tim van der Lippe9b2f8712020-02-12 17:46:22724 const domModel = remoteObject.runtimeModel().target().model(SDK.DOMModel.DOMModel);
Tim van der Lippe1d6e57a2019-09-30 11:55:34725 if (!domModel) {
Blink Reformat4c46d092018-04-07 15:32:37726 return result;
Tim van der Lippe1d6e57a2019-09-30 11:55:34727 }
Jan Scheffler19cd7ec2021-02-12 14:16:30728 domModel.pushObjectAsNodeToFrontend(remoteObject).then(async (node: SDK.DOMModel.DOMNode|null) => {
Blink Reformat4c46d092018-04-07 15:32:37729 if (!node) {
730 result.appendChild(this._formatParameterAsObject(remoteObject, false));
731 return;
732 }
Jan Scheffler19cd7ec2021-02-12 14:16:30733 const renderResult = await UI.UIUtils.Renderer.render((node as Object));
Erik Luofc6a6302018-11-02 06:48:52734 if (renderResult) {
Erik Luo840be6b2018-12-03 20:54:27735 if (renderResult.tree) {
Erik Luo383f21d2018-11-07 23:16:37736 this._selectableChildren.push(renderResult.tree);
Erik Luo840be6b2018-12-03 20:54:27737 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementAttached, this._messageResized);
738 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._messageResized);
739 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._messageResized);
740 }
Erik Luofc6a6302018-11-02 06:48:52741 result.appendChild(renderResult.node);
742 } else {
743 result.appendChild(this._formatParameterAsObject(remoteObject, false));
744 }
Erik Luo54fdd912018-11-01 17:57:01745 this._formattedParameterAsNodeForTest();
Blink Reformat4c46d092018-04-07 15:32:37746 });
747
748 return result;
749 }
750
Jan Scheffler19cd7ec2021-02-12 14:16:30751 _formattedParameterAsNodeForTest(): void {
Blink Reformat4c46d092018-04-07 15:32:37752 }
753
Jan Scheffler19cd7ec2021-02-12 14:16:30754 _formatParameterAsString(output: SDK.RemoteObject.RemoteObject): HTMLElement {
Benedikt Meurer62b49da2021-02-18 09:15:55755 // Properly escape double quotes here, so users don't get surprised
756 // when they copy strings from the console (https://crbug.com/1178530).
757 const description = output.description ?? '';
758 const text = JSON.stringify(description);
Jan Scheffler19cd7ec2021-02-12 14:16:30759 const result = (document.createElement('span') as HTMLElement);
Benedikt Meurer62b49da2021-02-18 09:15:55760 result.appendChild(this._linkifyStringAsFragment(text));
Blink Reformat4c46d092018-04-07 15:32:37761 return result;
762 }
763
Jan Scheffler19cd7ec2021-02-12 14:16:30764 _formatParameterAsError(output: SDK.RemoteObject.RemoteObject): HTMLElement {
765 const result = (document.createElement('span') as HTMLElement);
Blink Reformat4c46d092018-04-07 15:32:37766 const errorSpan = this._tryFormatAsError(output.description || '');
Erik Luo383f21d2018-11-07 23:16:37767 result.appendChild(errorSpan ? errorSpan : this._linkifyStringAsFragment(output.description || ''));
Blink Reformat4c46d092018-04-07 15:32:37768 return result;
769 }
770
Jan Scheffler19cd7ec2021-02-12 14:16:30771 _formatAsArrayEntry(output: SDK.RemoteObject.RemoteObject): HTMLElement {
Alfonso Castaño20d22cd2020-10-28 16:23:58772 return this._previewFormatter.renderPropertyPreview(
773 output.type, output.subtype, output.className, output.description);
Blink Reformat4c46d092018-04-07 15:32:37774 }
775
Jan Scheffler19cd7ec2021-02-12 14:16:30776 _formatAsAccessorProperty(object: SDK.RemoteObject.RemoteObject|null, propertyPath: string[], isArrayEntry: boolean):
777 HTMLElement {
Tim van der Lippe9b2f8712020-02-12 17:46:22778 const rootElement =
779 ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan(
780 object, propertyPath, onInvokeGetterClick.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37781
Jan Scheffler19cd7ec2021-02-12 14:16:30782 function onInvokeGetterClick(this: ConsoleViewMessage, result: SDK.RemoteObject.CallFunctionResult): void {
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18783 const wasThrown = result.wasThrown;
784 const object = result.object;
Tim van der Lippe1d6e57a2019-09-30 11:55:34785 if (!object) {
Blink Reformat4c46d092018-04-07 15:32:37786 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34787 }
Blink Reformat4c46d092018-04-07 15:32:37788 rootElement.removeChildren();
789 if (wasThrown) {
790 const element = rootElement.createChild('span');
Christy Chen9c6d8982021-02-08 02:28:31791 element.textContent = i18nString(UIStrings.exception);
Jan Scheffler19cd7ec2021-02-12 14:16:30792 UI.Tooltip.Tooltip.install(element, (object.description as string));
Blink Reformat4c46d092018-04-07 15:32:37793 } else if (isArrayEntry) {
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18794 rootElement.appendChild(this._formatAsArrayEntry(object));
Blink Reformat4c46d092018-04-07 15:32:37795 } else {
796 // Make a PropertyPreview from the RemoteObject similar to the backend logic.
797 const maxLength = 100;
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18798 const type = object.type;
799 const subtype = object.subtype;
Blink Reformat4c46d092018-04-07 15:32:37800 let description = '';
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18801 if (type !== 'function' && object.description) {
Alfonso Castaño20d22cd2020-10-28 16:23:58802 if (type === 'string' || subtype === 'regexp' || subtype === 'trustedtype') {
Tim van der Lippe213266c2021-01-18 15:48:31803 description = Platform.StringUtilities.trimMiddle(object.description, maxLength);
Tim van der Lippe1d6e57a2019-09-30 11:55:34804 } else {
Tim van der Lippe3cc3af32021-01-19 14:25:26805 description = Platform.StringUtilities.trimEndWithMaxLength(object.description, maxLength);
Tim van der Lippe1d6e57a2019-09-30 11:55:34806 }
Blink Reformat4c46d092018-04-07 15:32:37807 }
Alfonso Castaño20d22cd2020-10-28 16:23:58808 rootElement.appendChild(
809 this._previewFormatter.renderPropertyPreview(type, subtype, object.className, description));
Blink Reformat4c46d092018-04-07 15:32:37810 }
811 }
812
813 return rootElement;
814 }
815
Jan Scheffler19cd7ec2021-02-12 14:16:30816 _formatWithSubstitutionString(
817 format: string, parameters: SDK.RemoteObject.RemoteObject[], formattedResult: HTMLElement): {
818 formattedResult: Element,
819 unusedSubstitutions: ArrayLike<SDK.RemoteObject.RemoteObject>|null,
820 } {
821 function parameterFormatter(
822 this: ConsoleViewMessage, force: boolean, includePreview: boolean,
823 obj?: string|SDK.RemoteObject.RemoteObject): string|HTMLElement|undefined {
Sigurd Schneider45f32c32020-10-13 13:32:05824 if (obj instanceof SDK.RemoteObject.RemoteObject) {
825 return this._formatParameter(obj, force, includePreview);
826 }
827 return stringFormatter(obj);
Blink Reformat4c46d092018-04-07 15:32:37828 }
829
Jan Scheffler19cd7ec2021-02-12 14:16:30830 function stringFormatter(obj?: string|SDK.RemoteObject.RemoteObject): string|undefined {
Sigurd Schneider45f32c32020-10-13 13:32:05831 if (obj === undefined) {
832 return undefined;
833 }
834 if (typeof obj === 'string') {
835 return obj;
836 }
Blink Reformat4c46d092018-04-07 15:32:37837 return obj.description;
838 }
839
Jan Scheffler19cd7ec2021-02-12 14:16:30840 function floatFormatter(obj?: string|SDK.RemoteObject.RemoteObject): number|string|undefined {
Sigurd Schneider45f32c32020-10-13 13:32:05841 if (obj instanceof SDK.RemoteObject.RemoteObject) {
842 if (typeof obj.value !== 'number') {
843 return 'NaN';
844 }
845 return obj.value;
Tim van der Lippe1d6e57a2019-09-30 11:55:34846 }
Sigurd Schneider45f32c32020-10-13 13:32:05847 return undefined;
Blink Reformat4c46d092018-04-07 15:32:37848 }
849
Jan Scheffler19cd7ec2021-02-12 14:16:30850 function integerFormatter(obj?: string|SDK.RemoteObject.RemoteObject): string|number|undefined {
Sigurd Schneider45f32c32020-10-13 13:32:05851 if (obj instanceof SDK.RemoteObject.RemoteObject) {
852 if (obj.type === 'bigint') {
853 return obj.description;
854 }
855 if (typeof obj.value !== 'number') {
856 return 'NaN';
857 }
858 return Math.floor(obj.value);
Tim van der Lippe1d6e57a2019-09-30 11:55:34859 }
Sigurd Schneider45f32c32020-10-13 13:32:05860 return undefined;
Blink Reformat4c46d092018-04-07 15:32:37861 }
862
Jan Scheffler19cd7ec2021-02-12 14:16:30863 function bypassFormatter(obj?: string|SDK.RemoteObject.RemoteObject): Node|string {
Blink Reformat4c46d092018-04-07 15:32:37864 return (obj instanceof Node) ? obj : '';
865 }
866
Jan Scheffler19cd7ec2021-02-12 14:16:30867 let currentStyle: Map<string, {value: string, priority: string}>|null = null;
868 function styleFormatter(obj?: string|SDK.RemoteObject.RemoteObject): void {
Sigurd Schneider45f32c32020-10-13 13:32:05869 currentStyle = new Map();
Sigurd Schneider53f33522020-10-08 15:00:49870 const buffer = document.createElement('span');
Sigurd Schneider45f32c32020-10-13 13:32:05871 if (obj === undefined) {
872 return;
873 }
874 if (typeof obj === 'string' || !obj.description) {
875 return;
876 }
Blink Reformat4c46d092018-04-07 15:32:37877 buffer.setAttribute('style', obj.description);
Sigurd Schneider45f32c32020-10-13 13:32:05878 for (const property of buffer.style) {
Mathias Bynens5165a7a2020-06-10 05:51:43879 if (isAllowedProperty(property)) {
Sigurd Schneider45f32c32020-10-13 13:32:05880 const info = {
881 value: buffer.style.getPropertyValue(property),
Jan Scheffler19cd7ec2021-02-12 14:16:30882 priority: buffer.style.getPropertyPriority(property),
Sigurd Schneider45f32c32020-10-13 13:32:05883 };
884 currentStyle.set(property, info);
Tim van der Lippe1d6e57a2019-09-30 11:55:34885 }
Blink Reformat4c46d092018-04-07 15:32:37886 }
887 }
888
Jan Scheffler19cd7ec2021-02-12 14:16:30889 function isAllowedProperty(property: string): boolean {
Blink Reformat4c46d092018-04-07 15:32:37890 // Make sure that allowed properties do not interfere with link visibility.
891 const prefixes = [
Jan Scheffler19cd7ec2021-02-12 14:16:30892 'background',
893 'border',
894 'color',
895 'font',
896 'line',
897 'margin',
898 'padding',
899 'text',
900 '-webkit-background',
901 '-webkit-border',
902 '-webkit-font',
903 '-webkit-margin',
904 '-webkit-padding',
905 '-webkit-text',
Blink Reformat4c46d092018-04-07 15:32:37906 ];
Sigurd Schneider45f32c32020-10-13 13:32:05907 for (const prefix of prefixes) {
908 if (property.startsWith(prefix)) {
Blink Reformat4c46d092018-04-07 15:32:37909 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:34910 }
Blink Reformat4c46d092018-04-07 15:32:37911 }
912 return false;
913 }
914
Jan Scheffler19cd7ec2021-02-12 14:16:30915 // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
916 // eslint-disable-next-line @typescript-eslint/no-explicit-any
917 const formatters: Record<string, Platform.StringUtilities.FormatterFunction<any>> = {};
Blink Reformat4c46d092018-04-07 15:32:37918 // Firebug uses %o for formatting objects.
919 formatters.o = parameterFormatter.bind(this, false /* force */, true /* includePreview */);
920 formatters.s = stringFormatter;
921 formatters.f = floatFormatter;
922 // Firebug allows both %i and %d for formatting integers.
923 formatters.i = integerFormatter;
924 formatters.d = integerFormatter;
925
926 // Firebug uses %c for styling the message.
927 formatters.c = styleFormatter;
928
929 // Support %O to force object formatting, instead of the type-based %o formatting.
930 formatters.O = parameterFormatter.bind(this, true /* force */, false /* includePreview */);
931
932 formatters._ = bypassFormatter;
933
Jan Scheffler19cd7ec2021-02-12 14:16:30934 function append(this: ConsoleViewMessage, a: HTMLElement, b?: string|Node): HTMLElement {
Blink Reformat4c46d092018-04-07 15:32:37935 if (b instanceof Node) {
936 a.appendChild(b);
Erik Luo17926392018-05-17 22:06:12937 return a;
938 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34939 if (typeof b === 'undefined') {
Erik Luo17926392018-05-17 22:06:12940 return a;
Tim van der Lippe1d6e57a2019-09-30 11:55:34941 }
Erik Luo17926392018-05-17 22:06:12942 if (!currentStyle) {
Erik Luo383f21d2018-11-07 23:16:37943 a.appendChild(this._linkifyStringAsFragment(String(b)));
Erik Luo17926392018-05-17 22:06:12944 return a;
945 }
946 const lines = String(b).split('\n');
947 for (let i = 0; i < lines.length; i++) {
948 const line = lines[i];
Erik Luo383f21d2018-11-07 23:16:37949 const lineFragment = this._linkifyStringAsFragment(line);
Jan Scheffler19cd7ec2021-02-12 14:16:30950 const wrapper = (document.createElement('span') as HTMLElement);
Erik Luo17926392018-05-17 22:06:12951 wrapper.style.setProperty('contain', 'paint');
952 wrapper.style.setProperty('display', 'inline-block');
953 wrapper.style.setProperty('max-width', '100%');
954 wrapper.appendChild(lineFragment);
955 applyCurrentStyle(wrapper);
956 for (const child of wrapper.children) {
Sigurd Schneider53f33522020-10-08 15:00:49957 if (child.classList.contains('devtools-link') && child instanceof HTMLElement) {
Erik Luo17926392018-05-17 22:06:12958 this._applyForcedVisibleStyle(child);
Tim van der Lippe1d6e57a2019-09-30 11:55:34959 }
Blink Reformat4c46d092018-04-07 15:32:37960 }
Erik Luo17926392018-05-17 22:06:12961 a.appendChild(wrapper);
Tim van der Lippe1d6e57a2019-09-30 11:55:34962 if (i < lines.length - 1) {
Sigurd Schneider53f33522020-10-08 15:00:49963 a.appendChild(document.createElement('br'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34964 }
Blink Reformat4c46d092018-04-07 15:32:37965 }
966 return a;
967 }
968
Jan Scheffler19cd7ec2021-02-12 14:16:30969 function applyCurrentStyle(element: HTMLElement): void {
Sigurd Schneider45f32c32020-10-13 13:32:05970 if (!currentStyle) {
971 return;
972 }
973 for (const [property, {value, priority}] of currentStyle.entries()) {
Jan Scheffler19cd7ec2021-02-12 14:16:30974 element.style.setProperty((property as string), value, priority);
Tim van der Lippe1d6e57a2019-09-30 11:55:34975 }
Blink Reformat4c46d092018-04-07 15:32:37976 }
977
Tim van der Lippe93b57c32020-02-20 17:38:44978 // Platform.StringUtilities.format does treat formattedResult like a Builder, result is an object.
979 return Platform.StringUtilities.format(format, parameters, formatters, formattedResult, append.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37980 }
981
Jan Scheffler19cd7ec2021-02-12 14:16:30982 _applyForcedVisibleStyle(element: HTMLElement): void {
Blink Reformat4c46d092018-04-07 15:32:37983 element.style.setProperty('-webkit-text-stroke', '0', 'important');
984 element.style.setProperty('text-decoration', 'underline', 'important');
985
Paul Lewisca569a52020-09-09 16:11:51986 const themedColor = ThemeSupport.ThemeSupport.instance().patchColorText(
987 'rgb(33%, 33%, 33%)', ThemeSupport.ThemeSupport.ColorUsage.Foreground);
Blink Reformat4c46d092018-04-07 15:32:37988 element.style.setProperty('color', themedColor, 'important');
989
990 let backgroundColor = 'hsl(0, 0%, 100%)';
Tim van der Lippe9b2f8712020-02-12 17:46:22991 if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Blink Reformat4c46d092018-04-07 15:32:37992 backgroundColor = 'hsl(0, 100%, 97%)';
Tim van der Lippe9b2f8712020-02-12 17:46:22993 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning || this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:37994 backgroundColor = 'hsl(50, 100%, 95%)';
Tim van der Lippe1d6e57a2019-09-30 11:55:34995 }
Paul Lewisca569a52020-09-09 16:11:51996 const themedBackgroundColor = ThemeSupport.ThemeSupport.instance().patchColorText(
997 backgroundColor, ThemeSupport.ThemeSupport.ColorUsage.Background);
Blink Reformat4c46d092018-04-07 15:32:37998 element.style.setProperty('background-color', themedBackgroundColor, 'important');
999 }
1000
Jan Scheffler19cd7ec2021-02-12 14:16:301001 matchesFilterRegex(regexObject: RegExp): boolean {
Blink Reformat4c46d092018-04-07 15:32:371002 regexObject.lastIndex = 0;
Erik Luo5976c8c2018-07-24 02:03:091003 const contentElement = this.contentElement();
1004 const anchorText = this._anchorElement ? this._anchorElement.deepTextContent() : '';
Tim van der Lipped7cfd142021-01-07 12:17:241005 return (Boolean(anchorText) && regexObject.test(anchorText.trim())) ||
Erik Luo5976c8c2018-07-24 02:03:091006 regexObject.test(contentElement.deepTextContent().slice(anchorText.length));
Blink Reformat4c46d092018-04-07 15:32:371007 }
1008
Jan Scheffler19cd7ec2021-02-12 14:16:301009 matchesFilterText(filter: string): boolean {
Blink Reformat4c46d092018-04-07 15:32:371010 const text = this.contentElement().deepTextContent();
1011 return text.toLowerCase().includes(filter.toLowerCase());
1012 }
1013
Jan Scheffler19cd7ec2021-02-12 14:16:301014 updateTimestamp(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341015 if (!this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371016 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341017 }
Blink Reformat4c46d092018-04-07 15:32:371018
Paul Lewis2d7d65c2020-03-16 17:26:301019 if (Common.Settings.Settings.instance().moduleSetting('consoleTimestampsEnabled').get()) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341020 if (!this._timestampElement) {
Jan Scheffler19cd7ec2021-02-12 14:16:301021 this._timestampElement = (document.createElement('span') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:091022 this._timestampElement.classList.add('console-timestamp');
Tim van der Lippe1d6e57a2019-09-30 11:55:341023 }
Tim van der Lippe9b2f8712020-02-12 17:46:221024 this._timestampElement.textContent = UI.UIUtils.formatTimestamp(this._message.timestamp, false) + ' ';
Tim van der Lippe70842f32020-11-23 16:56:571025 UI.Tooltip.Tooltip.install(this._timestampElement, UI.UIUtils.formatTimestamp(this._message.timestamp, true));
Blink Reformat4c46d092018-04-07 15:32:371026 this._contentElement.insertBefore(this._timestampElement, this._contentElement.firstChild);
1027 } else if (this._timestampElement) {
1028 this._timestampElement.remove();
Sigurd Schneider53e98632020-10-26 15:29:501029 this._timestampElement = null;
Blink Reformat4c46d092018-04-07 15:32:371030 }
Blink Reformat4c46d092018-04-07 15:32:371031 }
1032
Jan Scheffler19cd7ec2021-02-12 14:16:301033 nestingLevel(): number {
Blink Reformat4c46d092018-04-07 15:32:371034 return this._nestingLevel;
1035 }
1036
Jan Scheffler19cd7ec2021-02-12 14:16:301037 setInSimilarGroup(inSimilarGroup: boolean, isLast?: boolean): void {
Blink Reformat4c46d092018-04-07 15:32:371038 this._inSimilarGroup = inSimilarGroup;
Tim van der Lipped7cfd142021-01-07 12:17:241039 this._lastInSimilarGroup = inSimilarGroup && Boolean(isLast);
Blink Reformat4c46d092018-04-07 15:32:371040 if (this._similarGroupMarker && !inSimilarGroup) {
1041 this._similarGroupMarker.remove();
1042 this._similarGroupMarker = null;
1043 } else if (this._element && !this._similarGroupMarker && inSimilarGroup) {
Jan Scheffler19cd7ec2021-02-12 14:16:301044 this._similarGroupMarker = (document.createElement('div') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:091045 this._similarGroupMarker.classList.add('nesting-level-marker');
Blink Reformat4c46d092018-04-07 15:32:371046 this._element.insertBefore(this._similarGroupMarker, this._element.firstChild);
1047 this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
1048 }
1049 }
1050
Jan Scheffler19cd7ec2021-02-12 14:16:301051 isLastInSimilarGroup(): boolean {
Tim van der Lipped7cfd142021-01-07 12:17:241052 return Boolean(this._inSimilarGroup) && Boolean(this._lastInSimilarGroup);
Blink Reformat4c46d092018-04-07 15:32:371053 }
1054
Jan Scheffler19cd7ec2021-02-12 14:16:301055 resetCloseGroupDecorationCount(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341056 if (!this._closeGroupDecorationCount) {
Blink Reformat4c46d092018-04-07 15:32:371057 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341058 }
Blink Reformat4c46d092018-04-07 15:32:371059 this._closeGroupDecorationCount = 0;
1060 this._updateCloseGroupDecorations();
1061 }
1062
Jan Scheffler19cd7ec2021-02-12 14:16:301063 incrementCloseGroupDecorationCount(): void {
Blink Reformat4c46d092018-04-07 15:32:371064 ++this._closeGroupDecorationCount;
1065 this._updateCloseGroupDecorations();
1066 }
1067
Jan Scheffler19cd7ec2021-02-12 14:16:301068 _updateCloseGroupDecorations(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341069 if (!this._nestingLevelMarkers) {
Blink Reformat4c46d092018-04-07 15:32:371070 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341071 }
Blink Reformat4c46d092018-04-07 15:32:371072 for (let i = 0, n = this._nestingLevelMarkers.length; i < n; ++i) {
1073 const marker = this._nestingLevelMarkers[i];
1074 marker.classList.toggle('group-closed', n - i <= this._closeGroupDecorationCount);
1075 }
1076 }
1077
Jan Scheffler19cd7ec2021-02-12 14:16:301078 _focusedChildIndex(): number {
Tim van der Lippe1d6e57a2019-09-30 11:55:341079 if (!this._selectableChildren.length) {
Erik Luo0b8282e2018-10-08 20:37:461080 return -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341081 }
Erik Luo383f21d2018-11-07 23:16:371082 return this._selectableChildren.findIndex(child => child.element.hasFocus());
Erik Luo0b8282e2018-10-08 20:37:461083 }
1084
Jan Scheffler19cd7ec2021-02-12 14:16:301085 _onKeyDown(event: KeyboardEvent): void {
Sigurd Schneider45f32c32020-10-13 13:32:051086 if (UI.UIUtils.isEditing() || !this._element || !this._element.hasFocus() || this._element.hasSelection()) {
Erik Luo8ef5d0c2018-09-25 21:16:001087 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341088 }
1089 if (this.maybeHandleOnKeyDown(event)) {
Erik Luo8ef5d0c2018-09-25 21:16:001090 event.consume(true);
Tim van der Lippe1d6e57a2019-09-30 11:55:341091 }
Erik Luo8ef5d0c2018-09-25 21:16:001092 }
1093
Jan Scheffler19cd7ec2021-02-12 14:16:301094 maybeHandleOnKeyDown(event: KeyboardEvent): boolean {
Erik Luo8ef5d0c2018-09-25 21:16:001095 // Handle trace expansion.
Erik Luo0b8282e2018-10-08 20:37:461096 const focusedChildIndex = this._focusedChildIndex();
1097 const isWrapperFocused = focusedChildIndex === -1;
1098 if (this._expandTrace && isWrapperFocused) {
Erik Luo8ef5d0c2018-09-25 21:16:001099 if ((event.key === 'ArrowLeft' && this._traceExpanded) || (event.key === 'ArrowRight' && !this._traceExpanded)) {
1100 this._expandTrace(!this._traceExpanded);
1101 return true;
1102 }
1103 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341104 if (!this._selectableChildren.length) {
Erik Luo0b8282e2018-10-08 20:37:461105 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341106 }
Erik Luo0b8282e2018-10-08 20:37:461107
1108 if (event.key === 'ArrowLeft') {
Sigurd Schneider45f32c32020-10-13 13:32:051109 this._element && this._element.focus();
Erik Luo0b8282e2018-10-08 20:37:461110 return true;
1111 }
1112 if (event.key === 'ArrowRight') {
Tim van der Lippe1d6e57a2019-09-30 11:55:341113 if (isWrapperFocused && this._selectNearestVisibleChild(0)) {
Erik Luo0b8282e2018-10-08 20:37:461114 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341115 }
Erik Luo0b8282e2018-10-08 20:37:461116 }
1117 if (event.key === 'ArrowUp') {
Erik Luo182bece2018-11-29 03:15:221118 const firstVisibleChild = this._nearestVisibleChild(0);
1119 if (this._selectableChildren[focusedChildIndex] === firstVisibleChild && firstVisibleChild) {
Sigurd Schneider45f32c32020-10-13 13:32:051120 this._element && this._element.focus();
Erik Luo0b8282e2018-10-08 20:37:461121 return true;
Mathias Bynensf06e8c02020-02-28 13:58:281122 }
1123 if (this._selectNearestVisibleChild(focusedChildIndex - 1, true /* backwards */)) {
Erik Luo0b8282e2018-10-08 20:37:461124 return true;
1125 }
1126 }
1127 if (event.key === 'ArrowDown') {
Tim van der Lippe1d6e57a2019-09-30 11:55:341128 if (isWrapperFocused && this._selectNearestVisibleChild(0)) {
Erik Luo0b8282e2018-10-08 20:37:461129 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341130 }
1131 if (!isWrapperFocused && this._selectNearestVisibleChild(focusedChildIndex + 1)) {
Erik Luo0b8282e2018-10-08 20:37:461132 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341133 }
Erik Luo0b8282e2018-10-08 20:37:461134 }
Erik Luo8ef5d0c2018-09-25 21:16:001135 return false;
1136 }
1137
Jan Scheffler19cd7ec2021-02-12 14:16:301138 _selectNearestVisibleChild(fromIndex: number, backwards?: boolean): boolean {
Erik Luo182bece2018-11-29 03:15:221139 const nearestChild = this._nearestVisibleChild(fromIndex, backwards);
1140 if (nearestChild) {
Erik Luo31c21f62018-12-13 03:39:391141 nearestChild.forceSelect();
Erik Luo182bece2018-11-29 03:15:221142 return true;
1143 }
1144 return false;
1145 }
1146
Jan Scheffler19cd7ec2021-02-12 14:16:301147 _nearestVisibleChild(fromIndex: number, backwards?: boolean): {
1148 element: Element,
1149 forceSelect: () => void,
1150 }|null {
Erik Luo182bece2018-11-29 03:15:221151 const childCount = this._selectableChildren.length;
Tim van der Lippe1d6e57a2019-09-30 11:55:341152 if (fromIndex < 0 || fromIndex >= childCount) {
Erik Luo182bece2018-11-29 03:15:221153 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341154 }
Erik Luo182bece2018-11-29 03:15:221155 const direction = backwards ? -1 : 1;
1156 let index = fromIndex;
1157
1158 while (!this._selectableChildren[index].element.offsetParent) {
1159 index += direction;
Tim van der Lippe1d6e57a2019-09-30 11:55:341160 if (index < 0 || index >= childCount) {
Erik Luo182bece2018-11-29 03:15:221161 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341162 }
Erik Luo182bece2018-11-29 03:15:221163 }
1164 return this._selectableChildren[index];
1165 }
1166
Jan Scheffler19cd7ec2021-02-12 14:16:301167 focusLastChildOrSelf(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341168 if (this._element && !this._selectNearestVisibleChild(this._selectableChildren.length - 1, true /* backwards */)) {
Erik Luo0b8282e2018-10-08 20:37:461169 this._element.focus();
Tim van der Lippe1d6e57a2019-09-30 11:55:341170 }
Erik Luo0b8282e2018-10-08 20:37:461171 }
1172
Jan Scheffler19cd7ec2021-02-12 14:16:301173 setContentElement(element: HTMLElement): void {
Sigurd Schneiderb2953b22020-10-09 09:30:151174 console.assert(!this._contentElement, 'Cannot set content element twice');
1175 this._contentElement = element;
1176 }
1177
Jan Scheffler19cd7ec2021-02-12 14:16:301178 getContentElement(): HTMLElement|null {
Sigurd Schneiderb2953b22020-10-09 09:30:151179 return this._contentElement;
1180 }
1181
Jan Scheffler19cd7ec2021-02-12 14:16:301182 contentElement(): HTMLElement {
Tim van der Lippe1d6e57a2019-09-30 11:55:341183 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371184 return this._contentElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:341185 }
Blink Reformat4c46d092018-04-07 15:32:371186
Jan Scheffler19cd7ec2021-02-12 14:16:301187 const contentElement = (document.createElement('div') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:091188 contentElement.classList.add('console-message');
Tim van der Lippe1d6e57a2019-09-30 11:55:341189 if (this._messageLevelIcon) {
Blink Reformat4c46d092018-04-07 15:32:371190 contentElement.appendChild(this._messageLevelIcon);
Tim van der Lippe1d6e57a2019-09-30 11:55:341191 }
Blink Reformat4c46d092018-04-07 15:32:371192 this._contentElement = contentElement;
1193
Sigurd Schneider45f32c32020-10-13 13:32:051194 const runtimeModel = this._message.runtimeModel();
Blink Reformat4c46d092018-04-07 15:32:371195 let formattedMessage;
Tim van der Lipped7cfd142021-01-07 12:17:241196 const shouldIncludeTrace = Boolean(this._message.stackTrace) &&
Tim van der Lippe9b2f8712020-02-12 17:46:221197 (this._message.source === SDK.ConsoleModel.MessageSource.Network ||
1198 this._message.source === SDK.ConsoleModel.MessageSource.Violation ||
1199 this._message.level === SDK.ConsoleModel.MessageLevel.Error ||
1200 this._message.level === SDK.ConsoleModel.MessageLevel.Warning ||
1201 this._message.type === SDK.ConsoleModel.MessageType.Trace);
Sigurd Schneider45f32c32020-10-13 13:32:051202 if (runtimeModel && shouldIncludeTrace) {
1203 formattedMessage = this._buildMessageWithStackTrace(runtimeModel);
Tim van der Lippe1d6e57a2019-09-30 11:55:341204 } else {
Blink Reformat4c46d092018-04-07 15:32:371205 formattedMessage = this._buildMessage();
Tim van der Lippe1d6e57a2019-09-30 11:55:341206 }
Blink Reformat4c46d092018-04-07 15:32:371207 contentElement.appendChild(formattedMessage);
1208
1209 this.updateTimestamp();
1210 return this._contentElement;
1211 }
1212
Jan Scheffler19cd7ec2021-02-12 14:16:301213 toMessageElement(): HTMLElement {
Tim van der Lippe1d6e57a2019-09-30 11:55:341214 if (this._element) {
Blink Reformat4c46d092018-04-07 15:32:371215 return this._element;
Tim van der Lippe1d6e57a2019-09-30 11:55:341216 }
Jan Scheffler19cd7ec2021-02-12 14:16:301217 this._element = (document.createElement('div') as HTMLElement);
Pavel Feldmandb310912019-01-30 00:31:201218 this._element.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:301219 this._element.addEventListener('keydown', (this._onKeyDown.bind(this) as EventListener));
Blink Reformat4c46d092018-04-07 15:32:371220 this.updateMessageElement();
1221 return this._element;
1222 }
1223
Jan Scheffler19cd7ec2021-02-12 14:16:301224 updateMessageElement(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341225 if (!this._element) {
Blink Reformat4c46d092018-04-07 15:32:371226 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341227 }
Blink Reformat4c46d092018-04-07 15:32:371228
1229 this._element.className = 'console-message-wrapper';
1230 this._element.removeChildren();
Tim van der Lippe1d6e57a2019-09-30 11:55:341231 if (this._message.isGroupStartMessage()) {
Blink Reformat4c46d092018-04-07 15:32:371232 this._element.classList.add('console-group-title');
Tim van der Lippe1d6e57a2019-09-30 11:55:341233 }
Tim van der Lippe9b2f8712020-02-12 17:46:221234 if (this._message.source === SDK.ConsoleModel.MessageSource.ConsoleAPI) {
Blink Reformat4c46d092018-04-07 15:32:371235 this._element.classList.add('console-from-api');
Tim van der Lippe1d6e57a2019-09-30 11:55:341236 }
Blink Reformat4c46d092018-04-07 15:32:371237 if (this._inSimilarGroup) {
Jan Scheffler19cd7ec2021-02-12 14:16:301238 this._similarGroupMarker = (this._element.createChild('div', 'nesting-level-marker') as HTMLElement);
Blink Reformat4c46d092018-04-07 15:32:371239 this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
1240 }
1241
1242 this._nestingLevelMarkers = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341243 for (let i = 0; i < this._nestingLevel; ++i) {
Blink Reformat4c46d092018-04-07 15:32:371244 this._nestingLevelMarkers.push(this._element.createChild('div', 'nesting-level-marker'));
Tim van der Lippe1d6e57a2019-09-30 11:55:341245 }
Blink Reformat4c46d092018-04-07 15:32:371246 this._updateCloseGroupDecorations();
Sigurd Schneiderca7b4ff2020-10-14 07:45:471247 elementToMessage.set(this._element, this);
Blink Reformat4c46d092018-04-07 15:32:371248
1249 switch (this._message.level) {
Tim van der Lippe9b2f8712020-02-12 17:46:221250 case SDK.ConsoleModel.MessageLevel.Verbose:
Blink Reformat4c46d092018-04-07 15:32:371251 this._element.classList.add('console-verbose-level');
Blink Reformat4c46d092018-04-07 15:32:371252 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221253 case SDK.ConsoleModel.MessageLevel.Info:
Blink Reformat4c46d092018-04-07 15:32:371254 this._element.classList.add('console-info-level');
Tim van der Lippe9b2f8712020-02-12 17:46:221255 if (this._message.type === SDK.ConsoleModel.MessageType.System) {
Blink Reformat4c46d092018-04-07 15:32:371256 this._element.classList.add('console-system-type');
Tim van der Lippe1d6e57a2019-09-30 11:55:341257 }
Blink Reformat4c46d092018-04-07 15:32:371258 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221259 case SDK.ConsoleModel.MessageLevel.Warning:
Blink Reformat4c46d092018-04-07 15:32:371260 this._element.classList.add('console-warning-level');
Blink Reformat4c46d092018-04-07 15:32:371261 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221262 case SDK.ConsoleModel.MessageLevel.Error:
Blink Reformat4c46d092018-04-07 15:32:371263 this._element.classList.add('console-error-level');
Blink Reformat4c46d092018-04-07 15:32:371264 break;
1265 }
Erik Luofd3e7d42018-09-25 02:12:351266 this._updateMessageLevelIcon();
Tim van der Lippe1d6e57a2019-09-30 11:55:341267 if (this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371268 this._element.classList.add('console-warning-level');
Tim van der Lippe1d6e57a2019-09-30 11:55:341269 }
Blink Reformat4c46d092018-04-07 15:32:371270
1271 this._element.appendChild(this.contentElement());
Tim van der Lippe1d6e57a2019-09-30 11:55:341272 if (this._repeatCount > 1) {
Blink Reformat4c46d092018-04-07 15:32:371273 this._showRepeatCountElement();
Tim van der Lippe1d6e57a2019-09-30 11:55:341274 }
Blink Reformat4c46d092018-04-07 15:32:371275 }
1276
Jan Scheffler19cd7ec2021-02-12 14:16:301277 _shouldRenderAsWarning(): boolean {
Tim van der Lippe9b2f8712020-02-12 17:46:221278 return (this._message.level === SDK.ConsoleModel.MessageLevel.Verbose ||
1279 this._message.level === SDK.ConsoleModel.MessageLevel.Info) &&
1280 (this._message.source === SDK.ConsoleModel.MessageSource.Violation ||
1281 this._message.source === SDK.ConsoleModel.MessageSource.Deprecation ||
1282 this._message.source === SDK.ConsoleModel.MessageSource.Intervention ||
1283 this._message.source === SDK.ConsoleModel.MessageSource.Recommendation);
Blink Reformat4c46d092018-04-07 15:32:371284 }
1285
Jan Scheffler19cd7ec2021-02-12 14:16:301286 _updateMessageLevelIcon(): void {
Erik Luofd3e7d42018-09-25 02:12:351287 let iconType = '';
1288 let accessibleName = '';
Tim van der Lippe9b2f8712020-02-12 17:46:221289 if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning) {
Erik Luofd3e7d42018-09-25 02:12:351290 iconType = 'smallicon-warning';
Christy Chen9c6d8982021-02-08 02:28:311291 accessibleName = i18nString(UIStrings.warning);
Tim van der Lippe9b2f8712020-02-12 17:46:221292 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Erik Luofd3e7d42018-09-25 02:12:351293 iconType = 'smallicon-error';
Christy Chen9c6d8982021-02-08 02:28:311294 accessibleName = i18nString(UIStrings.error);
Erik Luofd3e7d42018-09-25 02:12:351295 }
Sigurd Schneider45f32c32020-10-13 13:32:051296 if (!this._messageLevelIcon) {
1297 if (!iconType) {
1298 return;
1299 }
Tim van der Lippe9b2f8712020-02-12 17:46:221300 this._messageLevelIcon = UI.Icon.Icon.create('', 'message-level-icon');
Tim van der Lippe1d6e57a2019-09-30 11:55:341301 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371302 this._contentElement.insertBefore(this._messageLevelIcon, this._contentElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341303 }
Blink Reformat4c46d092018-04-07 15:32:371304 }
1305 this._messageLevelIcon.setIconType(iconType);
Erik Luofd3e7d42018-09-25 02:12:351306 UI.ARIAUtils.setAccessibleName(this._messageLevelIcon, accessibleName);
Blink Reformat4c46d092018-04-07 15:32:371307 }
1308
Jan Scheffler19cd7ec2021-02-12 14:16:301309 repeatCount(): number {
Blink Reformat4c46d092018-04-07 15:32:371310 return this._repeatCount || 1;
1311 }
1312
Jan Scheffler19cd7ec2021-02-12 14:16:301313 resetIncrementRepeatCount(): void {
Blink Reformat4c46d092018-04-07 15:32:371314 this._repeatCount = 1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341315 if (!this._repeatCountElement) {
Blink Reformat4c46d092018-04-07 15:32:371316 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341317 }
Blink Reformat4c46d092018-04-07 15:32:371318
1319 this._repeatCountElement.remove();
Tim van der Lippe1d6e57a2019-09-30 11:55:341320 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371321 this._contentElement.classList.remove('repeated-message');
Tim van der Lippe1d6e57a2019-09-30 11:55:341322 }
Sigurd Schneider53e98632020-10-26 15:29:501323 this._repeatCountElement = null;
Blink Reformat4c46d092018-04-07 15:32:371324 }
1325
Jan Scheffler19cd7ec2021-02-12 14:16:301326 incrementRepeatCount(): void {
Blink Reformat4c46d092018-04-07 15:32:371327 this._repeatCount++;
1328 this._showRepeatCountElement();
1329 }
1330
Jan Scheffler19cd7ec2021-02-12 14:16:301331 setRepeatCount(repeatCount: number): void {
Blink Reformat4c46d092018-04-07 15:32:371332 this._repeatCount = repeatCount;
1333 this._showRepeatCountElement();
1334 }
Jan Scheffler19cd7ec2021-02-12 14:16:301335 _showRepeatCountElement(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341336 if (!this._element) {
Blink Reformat4c46d092018-04-07 15:32:371337 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341338 }
Blink Reformat4c46d092018-04-07 15:32:371339
1340 if (!this._repeatCountElement) {
Sigurd Schneider45f32c32020-10-13 13:32:051341 this._repeatCountElement =
Jan Scheffler19cd7ec2021-02-12 14:16:301342 (document.createElement('span', {is: 'dt-small-bubble'}) as UI.UIUtils.DevToolsSmallBubble);
Tim van der Lippeee954d42020-05-04 10:35:571343 this._repeatCountElement.classList.add('console-message-repeat-count');
Blink Reformat4c46d092018-04-07 15:32:371344 switch (this._message.level) {
Tim van der Lippe9b2f8712020-02-12 17:46:221345 case SDK.ConsoleModel.MessageLevel.Warning:
Blink Reformat4c46d092018-04-07 15:32:371346 this._repeatCountElement.type = 'warning';
1347 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221348 case SDK.ConsoleModel.MessageLevel.Error:
Blink Reformat4c46d092018-04-07 15:32:371349 this._repeatCountElement.type = 'error';
1350 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221351 case SDK.ConsoleModel.MessageLevel.Verbose:
Blink Reformat4c46d092018-04-07 15:32:371352 this._repeatCountElement.type = 'verbose';
1353 break;
1354 default:
1355 this._repeatCountElement.type = 'info';
1356 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341357 if (this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371358 this._repeatCountElement.type = 'warning';
Tim van der Lippe1d6e57a2019-09-30 11:55:341359 }
Blink Reformat4c46d092018-04-07 15:32:371360
1361 this._element.insertBefore(this._repeatCountElement, this._contentElement);
Sigurd Schneider45f32c32020-10-13 13:32:051362 this.contentElement().classList.add('repeated-message');
Blink Reformat4c46d092018-04-07 15:32:371363 }
Sigurd Schneider45f32c32020-10-13 13:32:051364 this._repeatCountElement.textContent = `${this._repeatCount}`;
Peter Marshall2bdcc642021-03-03 10:02:091365
1366 let accessibleName;
Tim van der Lippe9b2f8712020-02-12 17:46:221367 if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning) {
Peter Marshall2bdcc642021-03-03 10:02:091368 accessibleName = i18nString(UIStrings.warningS, {n: this._repeatCount});
Tim van der Lippe9b2f8712020-02-12 17:46:221369 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Peter Marshall2bdcc642021-03-03 10:02:091370 accessibleName = i18nString(UIStrings.errorS, {n: this._repeatCount});
1371 } else {
1372 accessibleName = i18nString(UIStrings.repeatS, {n: this._repeatCount});
Tim van der Lippe1d6e57a2019-09-30 11:55:341373 }
Erik Luofd3e7d42018-09-25 02:12:351374 UI.ARIAUtils.setAccessibleName(this._repeatCountElement, accessibleName);
Blink Reformat4c46d092018-04-07 15:32:371375 }
1376
Jan Scheffler19cd7ec2021-02-12 14:16:301377 get text(): string {
Blink Reformat4c46d092018-04-07 15:32:371378 return this._message.messageText;
1379 }
1380
Jan Scheffler19cd7ec2021-02-12 14:16:301381 toExportString(): string {
Blink Reformat4c46d092018-04-07 15:32:371382 const lines = [];
1383 const nodes = this.contentElement().childTextNodes();
Tim van der Lippe9b2f8712020-02-12 17:46:221384 const messageContent = nodes.map(Components.Linkifier.Linkifier.untruncatedNodeText).join('');
Tim van der Lippe1d6e57a2019-09-30 11:55:341385 for (let i = 0; i < this.repeatCount(); ++i) {
Blink Reformat4c46d092018-04-07 15:32:371386 lines.push(messageContent);
Tim van der Lippe1d6e57a2019-09-30 11:55:341387 }
Blink Reformat4c46d092018-04-07 15:32:371388 return lines.join('\n');
1389 }
1390
Jan Scheffler19cd7ec2021-02-12 14:16:301391 setSearchRegex(regex: RegExp|null): void {
Sigurd Schneidere8e75cf2020-10-13 08:17:521392 if (this._searchHighlightNodeChanges && this._searchHighlightNodeChanges.length) {
1393 UI.UIUtils.revertDomChanges(this._searchHighlightNodeChanges);
Tim van der Lippe1d6e57a2019-09-30 11:55:341394 }
Blink Reformat4c46d092018-04-07 15:32:371395 this._searchRegex = regex;
1396 this._searchHighlightNodes = [];
Sigurd Schneidere8e75cf2020-10-13 08:17:521397 this._searchHighlightNodeChanges = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341398 if (!this._searchRegex) {
Blink Reformat4c46d092018-04-07 15:32:371399 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341400 }
Blink Reformat4c46d092018-04-07 15:32:371401
1402 const text = this.contentElement().deepTextContent();
1403 let match;
1404 this._searchRegex.lastIndex = 0;
1405 const sourceRanges = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341406 while ((match = this._searchRegex.exec(text)) && match[0]) {
Tim van der Lippe9b2f8712020-02-12 17:46:221407 sourceRanges.push(new TextUtils.TextRange.SourceRange(match.index, match[0].length));
Tim van der Lippe1d6e57a2019-09-30 11:55:341408 }
Blink Reformat4c46d092018-04-07 15:32:371409
1410 if (sourceRanges.length) {
1411 this._searchHighlightNodes =
Sigurd Schneidere8e75cf2020-10-13 08:17:521412 UI.UIUtils.highlightSearchResults(this.contentElement(), sourceRanges, this._searchHighlightNodeChanges);
Blink Reformat4c46d092018-04-07 15:32:371413 }
1414 }
1415
Jan Scheffler19cd7ec2021-02-12 14:16:301416 searchRegex(): RegExp|null {
Blink Reformat4c46d092018-04-07 15:32:371417 return this._searchRegex;
1418 }
1419
Jan Scheffler19cd7ec2021-02-12 14:16:301420 searchCount(): number {
Blink Reformat4c46d092018-04-07 15:32:371421 return this._searchHighlightNodes.length;
1422 }
1423
Jan Scheffler19cd7ec2021-02-12 14:16:301424 searchHighlightNode(index: number): Element {
Blink Reformat4c46d092018-04-07 15:32:371425 return this._searchHighlightNodes[index];
1426 }
1427
Philip Pfaffe068b01d2021-03-22 09:46:261428 async _getInlineFrames(
1429 debuggerModel: SDK.DebuggerModel.DebuggerModel, url: string, lineNumber: number|undefined,
1430 columnNumber: number|undefined): Promise<{frames: Bindings.DebuggerLanguagePlugins.FunctionInfo[]}> {
1431 const debuggerWorkspaceBinding = Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance();
1432 if (debuggerWorkspaceBinding.pluginManager) {
1433 const projects = Workspace.Workspace.WorkspaceImpl.instance().projects();
1434 const uiSourceCodes = projects.map(project => project.uiSourceCodeForURL(url)).flat().filter(f => Boolean(f)) as
1435 Workspace.UISourceCode.UISourceCode[];
1436 const scripts =
1437 uiSourceCodes.map(uiSourceCode => debuggerWorkspaceBinding.scriptsForUISourceCode(uiSourceCode)).flat();
1438 if (scripts.length) {
1439 const location =
1440 new SDK.DebuggerModel.Location(debuggerModel, scripts[0].scriptId, lineNumber || 0, columnNumber);
1441 return debuggerWorkspaceBinding.pluginManager.getFunctionInfo(scripts[0], location);
1442 }
1443 }
1444
1445 return {frames: []};
1446 }
1447
1448 // Expand inline stack frames in the formatted error in the stackTrace element, inserting new elements before the
1449 // insertBefore anchor.
1450 async _expandInlineStackFrames(
1451 debuggerModel: SDK.DebuggerModel.DebuggerModel, prefix: string, suffix: string, url: string,
1452 lineNumber: number|undefined, columnNumber: number|undefined, stackTrace: HTMLElement,
1453 insertBefore: HTMLElement): Promise<boolean> {
1454 const {frames} = await this._getInlineFrames(debuggerModel, url, lineNumber, columnNumber);
1455 if (!frames.length) {
1456 return false;
1457 }
1458
1459 for (let f = 0; f < frames.length; ++f) {
1460 const {name} = frames[f];
1461 const formattedLine = document.createElement('span');
1462 formattedLine.appendChild(this._linkifyStringAsFragment(`${prefix} ${name} (`));
1463 const scriptLocationLink = this._linkifier.linkifyScriptLocation(
1464 debuggerModel.target(), null, url, lineNumber,
1465 {columnNumber, className: undefined, tabStop: undefined, inlineFrameIndex: f});
1466 scriptLocationLink.tabIndex = -1;
1467 this._selectableChildren.push({element: scriptLocationLink, forceSelect: (): void => scriptLocationLink.focus()});
1468 formattedLine.appendChild(scriptLocationLink);
1469 formattedLine.appendChild(this._linkifyStringAsFragment(suffix));
1470 stackTrace.insertBefore(formattedLine, insertBefore);
1471 }
1472 return true;
1473 }
1474
Jan Scheffler19cd7ec2021-02-12 14:16:301475 _tryFormatAsError(string: string): HTMLElement|null {
1476 function startsWith(prefix: string): boolean {
Blink Reformat4c46d092018-04-07 15:32:371477 return string.startsWith(prefix);
1478 }
1479
Sigurd Schneider45f32c32020-10-13 13:32:051480 const runtimeModel = this._message.runtimeModel();
Sigurd Schneider8d0fe542021-03-17 12:28:291481 // TODO: Consider removing these in favor of a simpler regex.
Mathias Bynensfdcb3012021-03-17 14:07:211482 const errorPrefixes = [
1483 'AggregateError',
1484 'Error',
1485 'EvalError',
1486 'RangeError',
1487 'ReferenceError',
1488 'SyntaxError',
1489 'TypeError',
1490 'URIError',
1491 ];
Sigurd Schneider8d0fe542021-03-17 12:28:291492 if (!runtimeModel || !errorPrefixes.some(startsWith) && !/^[\w.]+Error\b/.test(string)) {
Blink Reformat4c46d092018-04-07 15:32:371493 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341494 }
Sigurd Schneider45f32c32020-10-13 13:32:051495 const debuggerModel = runtimeModel.debuggerModel();
1496 const baseURL = runtimeModel.target().inspectedURL();
Blink Reformat4c46d092018-04-07 15:32:371497
1498 const lines = string.split('\n');
Philip Pfaffe068b01d2021-03-22 09:46:261499 const linkInfos = [];
1500 for (const line of lines) {
1501 const isCallFrameLine = /^\s*at\s/.test(line);
1502 if (!isCallFrameLine && linkInfos.length && linkInfos[linkInfos.length - 1].link) {
Blink Reformat4c46d092018-04-07 15:32:371503 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341504 }
Blink Reformat4c46d092018-04-07 15:32:371505
Tim van der Lippe1d6e57a2019-09-30 11:55:341506 if (!isCallFrameLine) {
Philip Pfaffe068b01d2021-03-22 09:46:261507 linkInfos.push({line});
Blink Reformat4c46d092018-04-07 15:32:371508 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341509 }
Blink Reformat4c46d092018-04-07 15:32:371510
1511 let openBracketIndex = -1;
1512 let closeBracketIndex = -1;
Yang Guo39256bd2019-07-18 06:02:251513 const inBracketsWithLineAndColumn = /\([^\)\(]+:\d+:\d+\)/g;
1514 const inBrackets = /\([^\)\(]+\)/g;
Jan Scheffler19cd7ec2021-02-12 14:16:301515 let lastMatch: RegExpExecArray|null = null;
Yang Guo39256bd2019-07-18 06:02:251516 let currentMatch;
Philip Pfaffe068b01d2021-03-22 09:46:261517 while ((currentMatch = inBracketsWithLineAndColumn.exec(line))) {
Yang Guo39256bd2019-07-18 06:02:251518 lastMatch = currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341519 }
Yang Guo39256bd2019-07-18 06:02:251520 if (!lastMatch) {
Philip Pfaffe068b01d2021-03-22 09:46:261521 while ((currentMatch = inBrackets.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 }
1525 if (lastMatch) {
1526 openBracketIndex = lastMatch.index;
1527 closeBracketIndex = lastMatch.index + lastMatch[0].length - 1;
Blink Reformat4c46d092018-04-07 15:32:371528 }
1529 const hasOpenBracket = openBracketIndex !== -1;
Philip Pfaffe068b01d2021-03-22 09:46:261530 let left = hasOpenBracket ? openBracketIndex + 1 : line.indexOf('at') + 3;
1531 if (!hasOpenBracket && line.indexOf('async ') === left) {
Benedikt Meureraef3b592021-03-17 16:34:401532 left += 6;
1533 }
Philip Pfaffe068b01d2021-03-22 09:46:261534 const right = hasOpenBracket ? closeBracketIndex : line.length;
1535 const linkCandidate = line.substring(left, right);
Tim van der Lippe9b2f8712020-02-12 17:46:221536 const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(linkCandidate);
Tim van der Lippe1d6e57a2019-09-30 11:55:341537 if (!splitResult) {
Blink Reformat4c46d092018-04-07 15:32:371538 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341539 }
Blink Reformat4c46d092018-04-07 15:32:371540
Tim van der Lippe1d6e57a2019-09-30 11:55:341541 if (splitResult.url === '<anonymous>') {
Philip Pfaffe068b01d2021-03-22 09:46:261542 linkInfos.push({line});
Blink Reformat4c46d092018-04-07 15:32:371543 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341544 }
Blink Reformat4c46d092018-04-07 15:32:371545 let url = parseOrScriptMatch(splitResult.url);
Tim van der Lippe9b2f8712020-02-12 17:46:221546 if (!url && Common.ParsedURL.ParsedURL.isRelativeURL(splitResult.url)) {
1547 url = parseOrScriptMatch(Common.ParsedURL.ParsedURL.completeURL(baseURL, splitResult.url));
Tim van der Lippe1d6e57a2019-09-30 11:55:341548 }
1549 if (!url) {
Blink Reformat4c46d092018-04-07 15:32:371550 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341551 }
Blink Reformat4c46d092018-04-07 15:32:371552
Philip Pfaffe068b01d2021-03-22 09:46:261553 linkInfos.push({
1554 line,
1555 link: {
1556 url,
1557 enclosedInBraces: hasOpenBracket,
1558 positionLeft: left,
1559 positionRight: right,
1560 lineNumber: splitResult.lineNumber,
1561 columnNumber: splitResult.columnNumber,
1562 },
Blink Reformat4c46d092018-04-07 15:32:371563 });
1564 }
1565
Philip Pfaffe068b01d2021-03-22 09:46:261566 if (!linkInfos.length) {
Blink Reformat4c46d092018-04-07 15:32:371567 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341568 }
Blink Reformat4c46d092018-04-07 15:32:371569
Jan Scheffler19cd7ec2021-02-12 14:16:301570 const formattedResult = document.createElement('span');
Philip Pfaffe068b01d2021-03-22 09:46:261571 for (let i = 0; i < linkInfos.length; ++i) {
1572 const newline = i < linkInfos.length - 1 ? '\n' : '';
1573 const {line, link} = linkInfos[i];
1574 if (!link) {
1575 formattedResult.appendChild(this._linkifyStringAsFragment(`${line}${newline}`));
1576 continue;
1577 }
1578 const formattedLine = document.createElement('span');
1579 const prefix = line.substring(0, link.positionLeft);
1580 const suffix = `${line.substring(link.positionRight)}${newline}`;
1581
1582 formattedLine.appendChild(this._linkifyStringAsFragment(prefix));
Erik Luo182bece2018-11-29 03:15:221583 const scriptLocationLink = this._linkifier.linkifyScriptLocation(
Philip Pfaffe068b01d2021-03-22 09:46:261584 debuggerModel.target(), null, link.url, link.lineNumber,
1585 {columnNumber: link.columnNumber, className: undefined, tabStop: undefined, inlineFrameIndex: 0});
Erik Luo182bece2018-11-29 03:15:221586 scriptLocationLink.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:301587 this._selectableChildren.push({element: scriptLocationLink, forceSelect: (): void => scriptLocationLink.focus()});
Philip Pfaffe068b01d2021-03-22 09:46:261588 formattedLine.appendChild(scriptLocationLink);
1589 formattedLine.appendChild(this._linkifyStringAsFragment(suffix));
1590 formattedResult.appendChild(formattedLine);
Blink Reformat4c46d092018-04-07 15:32:371591
Philip Pfaffe068b01d2021-03-22 09:46:261592 if (!link.enclosedInBraces) {
1593 continue;
1594 }
1595
1596 const prefixWithoutFunction = prefix.substring(0, prefix.lastIndexOf(' ', prefix.length - 3));
1597
1598 // If we were able to parse the function name from the stack trace line, try to replace it with an expansion of
1599 // any inline frames.
1600 const selectableChildIndex = this._selectableChildren.length - 1;
1601 this._expandInlineStackFrames(
1602 debuggerModel, prefixWithoutFunction, suffix, link.url, link.lineNumber, link.columnNumber,
1603 formattedResult, formattedLine)
1604 .then(modified => {
1605 if (modified) {
1606 formattedResult.removeChild(formattedLine);
1607 this._selectableChildren.splice(selectableChildIndex, 1);
1608 }
1609 });
Tim van der Lippe1d6e57a2019-09-30 11:55:341610 }
Blink Reformat4c46d092018-04-07 15:32:371611
1612 return formattedResult;
1613
Jan Scheffler19cd7ec2021-02-12 14:16:301614 function parseOrScriptMatch(url: string|null): string|null {
Tim van der Lippe1d6e57a2019-09-30 11:55:341615 if (!url) {
Blink Reformat4c46d092018-04-07 15:32:371616 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341617 }
Tim van der Lippe9b2f8712020-02-12 17:46:221618 const parsedURL = Common.ParsedURL.ParsedURL.fromString(url);
Tim van der Lippe1d6e57a2019-09-30 11:55:341619 if (parsedURL) {
Blink Reformat4c46d092018-04-07 15:32:371620 return parsedURL.url;
Tim van der Lippe1d6e57a2019-09-30 11:55:341621 }
1622 if (debuggerModel.scriptsForSourceURL(url).length) {
Blink Reformat4c46d092018-04-07 15:32:371623 return url;
Tim van der Lippe1d6e57a2019-09-30 11:55:341624 }
Blink Reformat4c46d092018-04-07 15:32:371625 return null;
1626 }
1627 }
1628
Jan Scheffler19cd7ec2021-02-12 14:16:301629 _linkifyWithCustomLinkifier(
1630 string: string, linkifier: (arg0: string, arg1: string, arg2?: number, arg3?: number) => Node): DocumentFragment {
Sigurd Schneider8f4ac862020-10-13 13:30:111631 if (string.length > getMaxTokenizableStringLength()) {
Tim van der Lippe9b2f8712020-02-12 17:46:221632 const propertyValue = new ObjectUI.ObjectPropertiesSection.ExpandableTextPropertyValue(
Sigurd Schneider8f4ac862020-10-13 13:30:111633 document.createElement('span'), string, getLongStringVisibleLength());
Sigurd Schneider45f32c32020-10-13 13:32:051634 const fragment = document.createDocumentFragment();
Connor Moody1a5c0d32019-12-19 07:23:361635 fragment.appendChild(propertyValue.element);
1636 return fragment;
Tim van der Lippe1d6e57a2019-09-30 11:55:341637 }
Sigurd Schneider45f32c32020-10-13 13:32:051638 const container = document.createDocumentFragment();
Tim van der Lippeeaacb722020-01-10 12:16:001639 const tokens = ConsoleViewMessage._tokenizeMessageText(string);
Blink Reformat4c46d092018-04-07 15:32:371640 for (const token of tokens) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341641 if (!token.text) {
Erik Luofc2214f2018-11-21 19:54:581642 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341643 }
Blink Reformat4c46d092018-04-07 15:32:371644 switch (token.type) {
1645 case 'url': {
1646 const realURL = (token.text.startsWith('www.') ? 'http://' + token.text : token.text);
Tim van der Lippe9b2f8712020-02-12 17:46:221647 const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(realURL);
Kim-Anh Tran9e49a452020-02-17 09:46:101648 const sourceURL = Common.ParsedURL.ParsedURL.removeWasmFunctionInfoFromURL(splitResult.url);
Blink Reformat4c46d092018-04-07 15:32:371649 let linkNode;
Tim van der Lippe1d6e57a2019-09-30 11:55:341650 if (splitResult) {
Kim-Anh Tran9e49a452020-02-17 09:46:101651 linkNode = linkifier(token.text, sourceURL, splitResult.lineNumber, splitResult.columnNumber);
Tim van der Lippe1d6e57a2019-09-30 11:55:341652 } else {
Sigurd Schneider45f32c32020-10-13 13:32:051653 linkNode = linkifier(token.text, '');
Tim van der Lippe1d6e57a2019-09-30 11:55:341654 }
Blink Reformat4c46d092018-04-07 15:32:371655 container.appendChild(linkNode);
1656 break;
1657 }
1658 default:
Sigurd Schneider45f32c32020-10-13 13:32:051659 container.appendChild(document.createTextNode(token.text));
Blink Reformat4c46d092018-04-07 15:32:371660 break;
1661 }
1662 }
1663 return container;
1664 }
1665
Jan Scheffler19cd7ec2021-02-12 14:16:301666 _linkifyStringAsFragment(string: string): DocumentFragment {
Erik Luofc2214f2018-11-21 19:54:581667 return this._linkifyWithCustomLinkifier(string, (text, url, lineNumber, columnNumber) => {
Sigurd Schneider45f32c32020-10-13 13:32:051668 const options = {text, lineNumber, columnNumber};
Jan Scheffler19cd7ec2021-02-12 14:16:301669 const linkElement =
1670 Components.Linkifier.Linkifier.linkifyURL(url, (options as Components.Linkifier.LinkifyURLOptions));
Erik Luo383f21d2018-11-07 23:16:371671 linkElement.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:301672 this._selectableChildren.push({element: linkElement, forceSelect: (): void => linkElement.focus()});
Erik Luo383f21d2018-11-07 23:16:371673 return linkElement;
Blink Reformat4c46d092018-04-07 15:32:371674 });
1675 }
1676
Jan Scheffler19cd7ec2021-02-12 14:16:301677 static _tokenizeMessageText(string: string): {
1678 type?: string, text: string,
1679 }[] {
Sigurd Schneider30ac3dd2020-10-13 09:06:391680 const {tokenizerRegexes, tokenizerTypes} = getOrCreateTokenizers();
Sigurd Schneider8f4ac862020-10-13 13:30:111681 if (string.length > getMaxTokenizableStringLength()) {
Blink Reformat4c46d092018-04-07 15:32:371682 return [{text: string, type: undefined}];
Tim van der Lippe1d6e57a2019-09-30 11:55:341683 }
Sigurd Schneider30ac3dd2020-10-13 09:06:391684 const results = TextUtils.TextUtils.Utils.splitStringByRegexes(string, tokenizerRegexes);
1685 return results.map(result => ({text: result.value, type: tokenizerTypes[result.regexIndex]}));
Blink Reformat4c46d092018-04-07 15:32:371686 }
1687
Jan Scheffler19cd7ec2021-02-12 14:16:301688 groupKey(): string {
Tim van der Lippe1d6e57a2019-09-30 11:55:341689 if (!this._groupKey) {
Blink Reformat4c46d092018-04-07 15:32:371690 this._groupKey = this._message.groupCategoryKey() + ':' + this.groupTitle();
Tim van der Lippe1d6e57a2019-09-30 11:55:341691 }
Blink Reformat4c46d092018-04-07 15:32:371692 return this._groupKey;
1693 }
1694
Jan Scheffler19cd7ec2021-02-12 14:16:301695 groupTitle(): string {
Tim van der Lippeeaacb722020-01-10 12:16:001696 const tokens = ConsoleViewMessage._tokenizeMessageText(this._message.messageText);
Blink Reformat4c46d092018-04-07 15:32:371697 const result = tokens.reduce((acc, token) => {
Jan Scheffler19cd7ec2021-02-12 14:16:301698 let text: Common.UIString.LocalizedString|string = token.text;
Tim van der Lippe1d6e57a2019-09-30 11:55:341699 if (token.type === 'url') {
Christy Chen9c6d8982021-02-08 02:28:311700 text = i18nString(UIStrings.url);
Tim van der Lippe1d6e57a2019-09-30 11:55:341701 } else if (token.type === 'time') {
Christy Chen9c6d8982021-02-08 02:28:311702 text = i18nString(UIStrings.tookNms);
Tim van der Lippe1d6e57a2019-09-30 11:55:341703 } else if (token.type === 'event') {
Christy Chen9c6d8982021-02-08 02:28:311704 text = i18nString(UIStrings.someEvent);
Tim van der Lippe1d6e57a2019-09-30 11:55:341705 } else if (token.type === 'milestone') {
Christy Chen9c6d8982021-02-08 02:28:311706 text = i18nString(UIStrings.Mxx);
Tim van der Lippe1d6e57a2019-09-30 11:55:341707 } else if (token.type === 'autofill') {
Christy Chen9c6d8982021-02-08 02:28:311708 text = i18nString(UIStrings.attribute);
Tim van der Lippe1d6e57a2019-09-30 11:55:341709 }
Blink Reformat4c46d092018-04-07 15:32:371710 return acc + text;
1711 }, '');
1712 return result.replace(/[%]o/g, '');
1713 }
Paul Lewisbf7aa3c2019-11-20 17:03:381714}
Blink Reformat4c46d092018-04-07 15:32:371715
Jan Scheffler19cd7ec2021-02-12 14:16:301716let tokenizerRegexes: RegExp[]|null = null;
1717let tokenizerTypes: string[]|null = null;
Sigurd Schneider30ac3dd2020-10-13 09:06:391718
Jan Scheffler19cd7ec2021-02-12 14:16:301719function getOrCreateTokenizers(): {
1720 tokenizerRegexes: Array<RegExp>,
1721 tokenizerTypes: Array<string>,
1722} {
Sigurd Schneider30ac3dd2020-10-13 09:06:391723 if (!tokenizerRegexes || !tokenizerTypes) {
1724 const controlCodes = '\\u0000-\\u0020\\u007f-\\u009f';
1725 const linkStringRegex = new RegExp(
1726 '(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\\/\\/|data:|www\\.)[^\\s' + controlCodes + '"]{2,}[^\\s' + controlCodes +
1727 '"\')}\\],:;.!?]',
1728 'u');
1729 const pathLineRegex = /(?:\/[\w\.-]*)+\:[\d]+/;
1730 const timeRegex = /took [\d]+ms/;
1731 const eventRegex = /'\w+' event/;
1732 const milestoneRegex = /\sM[6-7]\d/;
1733 const autofillRegex = /\(suggested: \"[\w-]+\"\)/;
Jan Scheffler19cd7ec2021-02-12 14:16:301734 const handlers = new Map<RegExp, string>();
Sigurd Schneider30ac3dd2020-10-13 09:06:391735 handlers.set(linkStringRegex, 'url');
1736 handlers.set(pathLineRegex, 'url');
1737 handlers.set(timeRegex, 'time');
1738 handlers.set(eventRegex, 'event');
1739 handlers.set(milestoneRegex, 'milestone');
1740 handlers.set(autofillRegex, 'autofill');
1741 tokenizerRegexes = Array.from(handlers.keys());
1742 tokenizerTypes = Array.from(handlers.values());
1743 return {tokenizerRegexes, tokenizerTypes};
1744 }
1745 return {tokenizerRegexes, tokenizerTypes};
1746}
1747
Paul Lewisbf7aa3c2019-11-20 17:03:381748export class ConsoleGroupViewMessage extends ConsoleViewMessage {
Jan Scheffler19cd7ec2021-02-12 14:16:301749 _collapsed: boolean;
1750 _expandGroupIcon: UI.Icon.Icon|null;
1751 _onToggle: () => void;
1752
1753 constructor(
1754 consoleMessage: SDK.ConsoleModel.ConsoleMessage, linkifier: Components.Linkifier.Linkifier, nestingLevel: number,
1755 onToggle: () => void, onResize: (arg0: Common.EventTarget.EventTargetEvent) => void) {
Blink Reformat4c46d092018-04-07 15:32:371756 console.assert(consoleMessage.isGroupStartMessage());
Tim van der Lippeb45d9a02019-11-05 17:24:411757 super(consoleMessage, linkifier, nestingLevel, onResize);
Tim van der Lippe9b2f8712020-02-12 17:46:221758 this._collapsed = consoleMessage.type === SDK.ConsoleModel.MessageType.StartGroupCollapsed;
Blink Reformat4c46d092018-04-07 15:32:371759 this._expandGroupIcon = null;
Erik Luo8ef5d0c2018-09-25 21:16:001760 this._onToggle = onToggle;
Blink Reformat4c46d092018-04-07 15:32:371761 }
1762
Jan Scheffler19cd7ec2021-02-12 14:16:301763 _setCollapsed(collapsed: boolean): void {
Blink Reformat4c46d092018-04-07 15:32:371764 this._collapsed = collapsed;
Tim van der Lippe1d6e57a2019-09-30 11:55:341765 if (this._expandGroupIcon) {
Blink Reformat4c46d092018-04-07 15:32:371766 this._expandGroupIcon.setIconType(this._collapsed ? 'smallicon-triangle-right' : 'smallicon-triangle-down');
Tim van der Lippe1d6e57a2019-09-30 11:55:341767 }
Erik Luo8ef5d0c2018-09-25 21:16:001768 this._onToggle.call(null);
Blink Reformat4c46d092018-04-07 15:32:371769 }
1770
Jan Scheffler19cd7ec2021-02-12 14:16:301771 collapsed(): boolean {
Blink Reformat4c46d092018-04-07 15:32:371772 return this._collapsed;
1773 }
1774
Jan Scheffler19cd7ec2021-02-12 14:16:301775 maybeHandleOnKeyDown(event: KeyboardEvent): boolean {
Erik Luo0b8282e2018-10-08 20:37:461776 const focusedChildIndex = this._focusedChildIndex();
1777 if (focusedChildIndex === -1) {
1778 if ((event.key === 'ArrowLeft' && !this._collapsed) || (event.key === 'ArrowRight' && this._collapsed)) {
1779 this._setCollapsed(!this._collapsed);
1780 return true;
1781 }
Erik Luo8ef5d0c2018-09-25 21:16:001782 }
1783 return super.maybeHandleOnKeyDown(event);
1784 }
1785
Jan Scheffler19cd7ec2021-02-12 14:16:301786 toMessageElement(): HTMLElement {
1787 let element: HTMLElement|null = this._element || null;
Sigurd Schneider45f32c32020-10-13 13:32:051788 if (!element) {
1789 element = super.toMessageElement();
Erik Luo8ef5d0c2018-09-25 21:16:001790 const iconType = this._collapsed ? 'smallicon-triangle-right' : 'smallicon-triangle-down';
Tim van der Lippe9b2f8712020-02-12 17:46:221791 this._expandGroupIcon = UI.Icon.Icon.create(iconType, 'expand-group-icon');
Erik Luob5bfff42018-09-20 02:52:391792 // Intercept focus to avoid highlight on click.
Sigurd Schneider45f32c32020-10-13 13:32:051793 this.contentElement().tabIndex = -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341794 if (this._repeatCountElement) {
Blink Reformat4c46d092018-04-07 15:32:371795 this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341796 } else {
Sigurd Schneider45f32c32020-10-13 13:32:051797 element.insertBefore(this._expandGroupIcon, this._contentElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:341798 }
Sigurd Schneider45f32c32020-10-13 13:32:051799 element.addEventListener('click', () => this._setCollapsed(!this._collapsed));
Blink Reformat4c46d092018-04-07 15:32:371800 }
Sigurd Schneider45f32c32020-10-13 13:32:051801 return element;
Blink Reformat4c46d092018-04-07 15:32:371802 }
1803
Jan Scheffler19cd7ec2021-02-12 14:16:301804 _showRepeatCountElement(): void {
Blink Reformat4c46d092018-04-07 15:32:371805 super._showRepeatCountElement();
Tim van der Lippe1d6e57a2019-09-30 11:55:341806 if (this._repeatCountElement && this._expandGroupIcon) {
Blink Reformat4c46d092018-04-07 15:32:371807 this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341808 }
Blink Reformat4c46d092018-04-07 15:32:371809 }
Paul Lewisbf7aa3c2019-11-20 17:03:381810}
Blink Reformat4c46d092018-04-07 15:32:371811
Sigurd Schneiderca7b4ff2020-10-14 07:45:471812export class ConsoleCommand extends ConsoleViewMessage {
Jan Scheffler19cd7ec2021-02-12 14:16:301813 _formattedCommand: HTMLElement|null;
1814
1815 constructor(
1816 consoleMessage: SDK.ConsoleModel.ConsoleMessage, linkifier: Components.Linkifier.Linkifier, nestingLevel: number,
1817 onResize: (arg0: Common.EventTarget.EventTargetEvent) => void) {
Sigurd Schneiderca7b4ff2020-10-14 07:45:471818 super(consoleMessage, linkifier, nestingLevel, onResize);
Sigurd Schneiderca7b4ff2020-10-14 07:45:471819 this._formattedCommand = null;
1820 }
1821
Jan Scheffler19cd7ec2021-02-12 14:16:301822 contentElement(): HTMLElement {
Sigurd Schneiderca7b4ff2020-10-14 07:45:471823 const contentElement = this.getContentElement();
1824 if (contentElement) {
1825 return contentElement;
1826 }
Jan Scheffler19cd7ec2021-02-12 14:16:301827 const newContentElement = (document.createElement('div') as HTMLElement);
Sigurd Schneiderca7b4ff2020-10-14 07:45:471828 this.setContentElement(newContentElement);
1829 newContentElement.classList.add('console-user-command');
1830 const icon = UI.Icon.Icon.create('smallicon-user-command', 'command-result-icon');
1831 newContentElement.appendChild(icon);
1832
1833 elementToMessage.set(newContentElement, this);
Jan Scheffler19cd7ec2021-02-12 14:16:301834 this._formattedCommand = (document.createElement('span') as HTMLElement);
Sigurd Schneiderca7b4ff2020-10-14 07:45:471835 this._formattedCommand.classList.add('source-code');
1836 this._formattedCommand.textContent = Platform.StringUtilities.replaceControlCharacters(this.text);
1837 newContentElement.appendChild(this._formattedCommand);
1838
1839 if (this._formattedCommand.textContent.length < MaxLengthToIgnoreHighlighter) {
Andres Olivaresf59e6de2021-02-18 13:10:251840 const javascriptSyntaxHighlighter = new TextEditor.SyntaxHighlighter.SyntaxHighlighter('text/javascript', true);
Sigurd Schneiderca7b4ff2020-10-14 07:45:471841 javascriptSyntaxHighlighter.syntaxHighlightNode(this._formattedCommand).then(this._updateSearch.bind(this));
1842 } else {
1843 this._updateSearch();
1844 }
1845
1846 this.updateTimestamp();
1847 return newContentElement;
1848 }
1849
Jan Scheffler19cd7ec2021-02-12 14:16:301850 _updateSearch(): void {
Sigurd Schneiderca7b4ff2020-10-14 07:45:471851 this.setSearchRegex(this.searchRegex());
1852 }
1853}
1854
1855export class ConsoleCommandResult extends ConsoleViewMessage {
Jan Scheffler19cd7ec2021-02-12 14:16:301856 contentElement(): HTMLElement {
Sigurd Schneiderca7b4ff2020-10-14 07:45:471857 const element = super.contentElement();
1858 if (!element.classList.contains('console-user-command-result')) {
1859 element.classList.add('console-user-command-result');
1860 if (this.consoleMessage().level === SDK.ConsoleModel.MessageLevel.Info) {
1861 const icon = UI.Icon.Icon.create('smallicon-command-result', 'command-result-icon');
1862 element.insertBefore(icon, element.firstChild);
1863 }
1864 }
1865 return element;
1866 }
1867}
1868
Sigurd Schneider8bfb4212020-10-27 10:27:371869export class ConsoleTableMessageView extends ConsoleViewMessage {
Jan Scheffler19cd7ec2021-02-12 14:16:301870 _dataGrid: DataGrid.SortableDataGrid.SortableDataGrid<unknown>|null;
1871
1872 constructor(
1873 consoleMessage: SDK.ConsoleModel.ConsoleMessage, linkifier: Components.Linkifier.Linkifier, nestingLevel: number,
1874 onResize: (arg0: Common.EventTarget.EventTargetEvent) => void) {
Sigurd Schneider8bfb4212020-10-27 10:27:371875 super(consoleMessage, linkifier, nestingLevel, onResize);
1876 console.assert(consoleMessage.type === SDK.ConsoleModel.MessageType.Table);
Sigurd Schneider8bfb4212020-10-27 10:27:371877 this._dataGrid = null;
1878 }
1879
Jan Scheffler19cd7ec2021-02-12 14:16:301880 wasShown(): void {
Sigurd Schneider8bfb4212020-10-27 10:27:371881 if (this._dataGrid) {
1882 this._dataGrid.updateWidths();
1883 }
1884 super.wasShown();
1885 }
1886
Jan Scheffler19cd7ec2021-02-12 14:16:301887 onResize(): void {
Sigurd Schneider8bfb4212020-10-27 10:27:371888 if (!this.isVisible()) {
1889 return;
1890 }
1891 if (this._dataGrid) {
1892 this._dataGrid.onResize();
1893 }
1894 }
1895
Jan Scheffler19cd7ec2021-02-12 14:16:301896 contentElement(): HTMLElement {
Sigurd Schneider8bfb4212020-10-27 10:27:371897 const contentElement = this.getContentElement();
1898 if (contentElement) {
1899 return contentElement;
1900 }
1901
Jan Scheffler19cd7ec2021-02-12 14:16:301902 const newContentElement = (document.createElement('div') as HTMLElement);
Sigurd Schneider8bfb4212020-10-27 10:27:371903 newContentElement.classList.add('console-message');
1904 if (this._messageLevelIcon) {
1905 newContentElement.appendChild(this._messageLevelIcon);
1906 }
1907 this.setContentElement(newContentElement);
1908
1909 newContentElement.appendChild(this._buildTableMessage());
1910 this.updateTimestamp();
1911 return newContentElement;
1912 }
1913
Jan Scheffler19cd7ec2021-02-12 14:16:301914 _buildTableMessage(): HTMLElement {
1915 const formattedMessage = (document.createElement('span') as HTMLElement);
Sigurd Schneider8bfb4212020-10-27 10:27:371916 formattedMessage.classList.add('source-code');
1917 this._anchorElement = this._buildMessageAnchor();
1918 if (this._anchorElement) {
1919 formattedMessage.appendChild(this._anchorElement);
1920 }
1921
1922 const table = this._message.parameters && this._message.parameters.length ? this._message.parameters[0] : null;
1923 if (!table) {
1924 return this._buildMessage();
1925 }
1926 const actualTable = parameterToRemoteObject(this._message.runtimeModel())(table);
1927 if (!actualTable || !actualTable.preview) {
1928 return this._buildMessage();
1929 }
1930
1931 const rawValueColumnSymbol = Symbol('rawValueColumn');
Jan Scheffler19cd7ec2021-02-12 14:16:301932 const columnNames: (string|symbol)[] = [];
Sigurd Schneider8bfb4212020-10-27 10:27:371933 const preview = actualTable.preview;
1934 const rows = [];
1935 for (let i = 0; i < preview.properties.length; ++i) {
1936 const rowProperty = preview.properties[i];
Jan Scheffler19cd7ec2021-02-12 14:16:301937 let rowSubProperties: Protocol.Runtime.PropertyPreview[];
Sigurd Schneiderb393a432020-11-06 12:08:211938 if (rowProperty.valuePreview && rowProperty.valuePreview.properties.length) {
Sigurd Schneider8bfb4212020-10-27 10:27:371939 rowSubProperties = rowProperty.valuePreview.properties;
1940 } else if (rowProperty.value) {
Jan Scheffler19cd7ec2021-02-12 14:16:301941 rowSubProperties =
1942 [{name: rawValueColumnSymbol as unknown as string, type: rowProperty.type, value: rowProperty.value}];
Sigurd Schneider8bfb4212020-10-27 10:27:371943 } else {
1944 continue;
1945 }
1946
Jan Scheffler19cd7ec2021-02-12 14:16:301947 const rowValue = new Map<string|symbol, HTMLElement>();
Sigurd Schneider8bfb4212020-10-27 10:27:371948 const maxColumnsToRender = 20;
1949 for (let j = 0; j < rowSubProperties.length; ++j) {
1950 const cellProperty = rowSubProperties[j];
Jan Scheffler19cd7ec2021-02-12 14:16:301951 let columnRendered: true|boolean = columnNames.indexOf(cellProperty.name) !== -1;
Sigurd Schneider8bfb4212020-10-27 10:27:371952 if (!columnRendered) {
1953 if (columnNames.length === maxColumnsToRender) {
1954 continue;
1955 }
1956 columnRendered = true;
1957 columnNames.push(cellProperty.name);
1958 }
1959
1960 if (columnRendered) {
1961 const cellElement =
1962 this._renderPropertyPreviewOrAccessor(actualTable, cellProperty, [rowProperty, cellProperty]);
1963 cellElement.classList.add('console-message-nowrap-below');
1964 rowValue.set(cellProperty.name, cellElement);
1965 }
1966 }
1967 rows.push({rowName: rowProperty.name, rowValue});
1968 }
1969
1970 const flatValues = [];
1971 for (const {rowName, rowValue} of rows) {
1972 flatValues.push(rowName);
1973 for (let j = 0; j < columnNames.length; ++j) {
1974 flatValues.push(rowValue.get(columnNames[j]));
1975 }
1976 }
Christy Chen9c6d8982021-02-08 02:28:311977 columnNames.unshift(i18nString(UIStrings.index));
Sigurd Schneider8bfb4212020-10-27 10:27:371978 const columnDisplayNames =
Christy Chen9c6d8982021-02-08 02:28:311979 columnNames.map(name => name === rawValueColumnSymbol ? i18nString(UIStrings.value) : name.toString());
Sigurd Schneider8bfb4212020-10-27 10:27:371980
1981 if (flatValues.length) {
Christy Chen9c6d8982021-02-08 02:28:311982 this._dataGrid = DataGrid.SortableDataGrid.SortableDataGrid.create(
1983 columnDisplayNames, flatValues, i18nString(UIStrings.console));
Sigurd Schneider8bfb4212020-10-27 10:27:371984 if (this._dataGrid) {
1985 this._dataGrid.setStriped(true);
1986 this._dataGrid.setFocusable(false);
1987
1988 const formattedResult = document.createElement('span');
1989 formattedResult.classList.add('console-message-text');
1990 const tableElement = formattedResult.createChild('div', 'console-message-formatted-table');
1991 const dataGridContainer = tableElement.createChild('span');
1992 tableElement.appendChild(this._formatParameter(actualTable, true, false));
1993 dataGridContainer.appendChild(this._dataGrid.element);
1994 formattedMessage.appendChild(formattedResult);
1995 this._dataGrid.renderInline();
1996 }
1997 }
1998 return formattedMessage;
1999 }
2000
Jan Scheffler19cd7ec2021-02-12 14:16:302001 approximateFastHeight(): number {
Sigurd Schneider8bfb4212020-10-27 10:27:372002 const table = this._message.parameters && this._message.parameters[0];
2003 if (table && typeof table !== 'string' && table.preview) {
2004 return defaultConsoleRowHeight * table.preview.properties.length;
2005 }
2006 return defaultConsoleRowHeight;
2007 }
2008}
2009
Sigurd Schneiderca7b4ff2020-10-14 07:45:472010/**
2011 * The maximum length before strings are considered too long for syntax highlighting.
2012 * @const
Sigurd Schneiderca7b4ff2020-10-14 07:45:472013 */
Jan Scheffler19cd7ec2021-02-12 14:16:302014const MaxLengthToIgnoreHighlighter: number = 10000;
Sigurd Schneiderca7b4ff2020-10-14 07:45:472015
Blink Reformat4c46d092018-04-07 15:32:372016/**
2017 * @const
Blink Reformat4c46d092018-04-07 15:32:372018 */
Jan Scheffler19cd7ec2021-02-12 14:16:302019export const MaxLengthForLinks: number = 40;
Blink Reformat4c46d092018-04-07 15:32:372020
Sigurd Schneider17c74452021-02-15 12:14:102021let maxTokenizableStringLength = 10000;
2022let longStringVisibleLength = 5000;
Sigurd Schneider8f4ac862020-10-13 13:30:112023
Jan Scheffler19cd7ec2021-02-12 14:16:302024export const getMaxTokenizableStringLength = (): number => {
Sigurd Schneider17c74452021-02-15 12:14:102025 return maxTokenizableStringLength;
Sigurd Schneider8f4ac862020-10-13 13:30:112026};
2027
Jan Scheffler19cd7ec2021-02-12 14:16:302028export const setMaxTokenizableStringLength = (length: number): void => {
Sigurd Schneider17c74452021-02-15 12:14:102029 maxTokenizableStringLength = length;
Sigurd Schneider8f4ac862020-10-13 13:30:112030};
2031
Jan Scheffler19cd7ec2021-02-12 14:16:302032export const getLongStringVisibleLength = (): number => {
Sigurd Schneider17c74452021-02-15 12:14:102033 return longStringVisibleLength;
Sigurd Schneider8f4ac862020-10-13 13:30:112034};
2035
Jan Scheffler19cd7ec2021-02-12 14:16:302036export const setLongStringVisibleLength = (length: number): void => {
Sigurd Schneider17c74452021-02-15 12:14:102037 longStringVisibleLength = length;
Sigurd Schneider8f4ac862020-10-13 13:30:112038};