blob: 31ee82513236f32ae80d5427e349e5c3e0a25eb7 [file] [log] [blame]
Jan Scheffler19cd7ec2021-02-12 14:16:301// Copyright 2020 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Blink Reformat4c46d092018-04-07 15:32:375/*
6 * Copyright (C) 2011 Google Inc. All rights reserved.
7 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
8 * Copyright (C) 2009 Joseph Pecoraro
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
20 * its contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
Tim van der Lippe9b2f8712020-02-12 17:46:2234
Jan Scheffler19cd7ec2021-02-12 14:16:3035/* eslint-disable rulesdir/no_underscored_properties */
36
Tim van der Lippe586c8022021-03-18 15:18:2037import * as Common from '../../common/common.js';
38import * as Components from '../../components/components.js';
39import * as DataGrid from '../../data_grid/data_grid.js';
40import * as i18n from '../../i18n/i18n.js';
41import * as ObjectUI from '../../object_ui/object_ui.js';
42import * as Platform from '../../platform/platform.js';
43import * as SDK from '../../sdk/sdk.js';
44import * as TextEditor from '../../text_editor/text_editor.js';
45import * as TextUtils from '../../text_utils/text_utils.js';
46import * as ThemeSupport from '../../theme_support/theme_support.js';
47import * as UI from '../../ui/ui.js';
Tim van der Lippe9b2f8712020-02-12 17:46:2248
Tim van der Lippebfbb58f2021-02-25 17:34:1949import type {ConsoleViewportElement} from './ConsoleViewport.js';
Tim van der Lippeeaacb722020-01-10 12:16:0050
Simon Zündfbfd1072021-03-01 07:38:5351const UIStrings = {
Christy Chen9c6d8982021-02-08 02:28:3152 /**
Peter Marshallf295a4b2021-02-26 09:48:0353 * @description Message element text content in Console View Message of the Console panel. Shown
54 * when the user tried to run console.clear() but the 'Preserve log' option is enabled, which stops
55 * the log from being cleared.
Christy Chen9c6d8982021-02-08 02:28:3156 */
57 consoleclearWasPreventedDueTo: '`console.clear()` was prevented due to \'Preserve log\'',
58 /**
Peter Marshallb8bd00f2021-02-24 08:25:1859 * @description Text shown in the Console panel after the user has cleared the console, which
60 * removes all messages from the console so that it is empty.
Christy Chen9c6d8982021-02-08 02:28:3161 */
62 consoleWasCleared: 'Console was cleared',
63 /**
64 *@description Message element title in Console View Message of the Console panel
65 *@example {Ctrl+L} PH1
66 */
67 clearAllMessagesWithS: 'Clear all messages with {PH1}',
68 /**
69 *@description Message prefix in Console View Message of the Console panel
70 */
71 assertionFailed: 'Assertion failed: ',
72 /**
73 *@description Message text in Console View Message of the Console panel
74 *@example {console.log(1)} PH1
75 */
Peter Marshall40dd7d92021-02-19 11:07:3776 violationS: '`[Violation]` {PH1}',
Christy Chen9c6d8982021-02-08 02:28:3177 /**
78 *@description Message text in Console View Message of the Console panel
79 *@example {console.log(1)} PH1
80 */
Peter Marshall40dd7d92021-02-19 11:07:3781 interventionS: '`[Intervention]` {PH1}',
Christy Chen9c6d8982021-02-08 02:28:3182 /**
83 *@description Message text in Console View Message of the Console panel
84 *@example {console.log(1)} PH1
85 */
Peter Marshall40dd7d92021-02-19 11:07:3786 deprecationS: '`[Deprecation]` {PH1}',
Christy Chen9c6d8982021-02-08 02:28:3187 /**
88 *@description Note title in Console View Message of the Console panel
89 */
90 thisValueWillNotBeCollectedUntil: 'This value will not be collected until console is cleared.',
91 /**
92 *@description Note title in Console View Message of the Console panel
93 */
94 thisValueWasEvaluatedUponFirst: 'This value was evaluated upon first expanding. It may have changed since then.',
95 /**
96 *@description Note title in Console View Message of the Console panel
97 */
98 functionWasResolvedFromBound: 'Function was resolved from bound function.',
99 /**
Peter Marshallf625dc82021-03-02 08:10:57100 * @description Shown in the Console panel when an exception is thrown when trying to access a
101 * property on an object. Should be translated.
Christy Chen9c6d8982021-02-08 02:28:31102 */
103 exception: '<exception>',
104 /**
105 *@description Text to indicate an item is a warning
106 */
107 warning: 'Warning',
108 /**
109 *@description Text for errors
110 */
111 error: 'Error',
112 /**
Peter Marshall2bdcc642021-03-03 10:02:09113 * @description Announced by the screen reader to indicate how many times a particular message in
114 * the console was repeated.
Christy Chen9c6d8982021-02-08 02:28:31115 */
Peter Marshall2bdcc642021-03-03 10:02:09116 repeatS: '{n, plural, =1 {Repeated # time} other {Repeated # times}}',
Christy Chen9c6d8982021-02-08 02:28:31117 /**
Peter Marshall2bdcc642021-03-03 10:02:09118 * @description Announced by the screen reader to indicate how many times a particular warning
119 * message in the console was repeated.
Christy Chen9c6d8982021-02-08 02:28:31120 */
Peter Marshall2bdcc642021-03-03 10:02:09121 warningS: '{n, plural, =1 {Warning, Repeated # time} other {Warning, Repeated # times}}',
Christy Chen9c6d8982021-02-08 02:28:31122 /**
Peter Marshall2bdcc642021-03-03 10:02:09123 * @description Announced by the screen reader to indicate how many times a particular error
124 * message in the console was repeated.
Christy Chen9c6d8982021-02-08 02:28:31125 */
Peter Marshall2bdcc642021-03-03 10:02:09126 errorS: '{n, plural, =1 {Error, Repeated # time} other {Error, Repeated # times}}',
Christy Chen9c6d8982021-02-08 02:28:31127 /**
Tim van der Lippee4b96c62021-02-17 12:43:16128 *@description Text appended to grouped console messages that are related to URL requests
Christy Chen9c6d8982021-02-08 02:28:31129 */
130 url: '<URL>',
131 /**
Tim van der Lippee4b96c62021-02-17 12:43:16132 *@description Text appended to grouped console messages about tasks that took longer than N ms
Christy Chen9c6d8982021-02-08 02:28:31133 */
134 tookNms: 'took <N>ms',
135 /**
Tim van der Lippee4b96c62021-02-17 12:43:16136 *@description Text appended to grouped console messages about tasks that are related to some DOM event
Christy Chen9c6d8982021-02-08 02:28:31137 */
138 someEvent: '<some> event',
139 /**
Tim van der Lippee4b96c62021-02-17 12:43:16140 *@description Text appended to grouped console messages about tasks that are related to a particular milestone
Christy Chen9c6d8982021-02-08 02:28:31141 */
142 Mxx: ' M<XX>',
143 /**
Tim van der Lippee4b96c62021-02-17 12:43:16144 *@description Text appended to grouped console messages about tasks that are related to autofill completions
Christy Chen9c6d8982021-02-08 02:28:31145 */
146 attribute: '<attribute>',
147 /**
148 *@description Text for the index of something
149 */
150 index: '(index)',
151 /**
152 *@description Text for the value of something
153 */
154 value: 'Value',
155 /**
156 *@description Title of the Console tool
157 */
158 console: 'Console',
159};
Tim van der Lippe586c8022021-03-18 15:18:20160const str_ = i18n.i18n.registerUIStrings('panels/console/ConsoleViewMessage.ts', UIStrings);
Christy Chen9c6d8982021-02-08 02:28:31161const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
Jan Scheffler19cd7ec2021-02-12 14:16:30162const elementToMessage = new WeakMap<Element, ConsoleViewMessage>();
Sigurd Schneiderca7b4ff2020-10-14 07:45:47163
Jan Scheffler19cd7ec2021-02-12 14:16:30164export const getMessageForElement = (element: Element): ConsoleViewMessage|undefined => {
Sigurd Schneiderca7b4ff2020-10-14 07:45:47165 return elementToMessage.get(element);
166};
167
Sigurd Schneider8bfb4212020-10-27 10:27:37168// This value reflects the 18px min-height of .console-message, plus the
169// 1px border of .console-message-wrapper. Keep in sync with consoleView.css.
170const defaultConsoleRowHeight = 19;
171
Jan Scheffler19cd7ec2021-02-12 14:16:30172const parameterToRemoteObject = (runtimeModel: SDK.RuntimeModel.RuntimeModel|null): (
173 parameter?: SDK.RemoteObject.RemoteObject|Protocol.Runtime.RemoteObject|string) => SDK.RemoteObject.RemoteObject =>
174 (parameter?: string|SDK.RemoteObject.RemoteObject|Protocol.Runtime.RemoteObject): SDK.RemoteObject.RemoteObject => {
Sigurd Schneider8bfb4212020-10-27 10:27:37175 if (parameter instanceof SDK.RemoteObject.RemoteObject) {
176 return parameter;
177 }
178 if (!runtimeModel) {
179 return SDK.RemoteObject.RemoteObject.fromLocalObject(parameter);
180 }
181 if (typeof parameter === 'object') {
182 return runtimeModel.createRemoteObject(parameter);
183 }
184 return runtimeModel.createRemoteObjectFromPrimitiveValue(parameter);
185 };
186
Jan Scheffler19cd7ec2021-02-12 14:16:30187export class ConsoleViewMessage implements ConsoleViewportElement {
188 _message: SDK.ConsoleModel.ConsoleMessage;
189 _linkifier: Components.Linkifier.Linkifier;
190 _repeatCount: number;
191 _closeGroupDecorationCount: number;
192 _nestingLevel: number;
193 _selectableChildren: {
194 element: HTMLElement,
195 forceSelect: () => void,
196 }[];
197 _messageResized: (arg0: Common.EventTarget.EventTargetEvent) => void;
198 _element: HTMLElement|null;
199 _previewFormatter: ObjectUI.RemoteObjectPreviewFormatter.RemoteObjectPreviewFormatter;
200 _searchRegex: RegExp|null;
201 _messageLevelIcon: UI.Icon.Icon|null;
202 _traceExpanded: boolean;
203 _expandTrace: ((arg0: boolean) => void)|null;
204 _anchorElement: HTMLElement|null;
205 _contentElement: HTMLElement|null;
206 _nestingLevelMarkers: HTMLElement[]|null;
207 _searchHighlightNodes: Element[];
208 _searchHighlightNodeChanges: UI.UIUtils.HighlightChange[];
209 _isVisible: boolean;
210 _cachedHeight: number;
211 _messagePrefix: string;
212 _timestampElement: HTMLElement|null;
213 _inSimilarGroup: boolean;
214 _similarGroupMarker: HTMLElement|null;
215 _lastInSimilarGroup: boolean;
216 _groupKey: string;
217 _repeatCountElement: UI.UIUtils.DevToolsSmallBubble|null;
218
219 constructor(
220 consoleMessage: SDK.ConsoleModel.ConsoleMessage, linkifier: Components.Linkifier.Linkifier, nestingLevel: number,
221 onResize: (arg0: Common.EventTarget.EventTargetEvent) => void) {
Blink Reformat4c46d092018-04-07 15:32:37222 this._message = consoleMessage;
223 this._linkifier = linkifier;
Blink Reformat4c46d092018-04-07 15:32:37224 this._repeatCount = 1;
225 this._closeGroupDecorationCount = 0;
226 this._nestingLevel = nestingLevel;
Erik Luo383f21d2018-11-07 23:16:37227 this._selectableChildren = [];
Erik Luo840be6b2018-12-03 20:54:27228 this._messageResized = onResize;
Sigurd Schneider53e98632020-10-26 15:29:50229 this._element = null;
Blink Reformat4c46d092018-04-07 15:32:37230
Tim van der Lippe9b2f8712020-02-12 17:46:22231 this._previewFormatter = new ObjectUI.RemoteObjectPreviewFormatter.RemoteObjectPreviewFormatter();
Blink Reformat4c46d092018-04-07 15:32:37232 this._searchRegex = null;
Blink Reformat4c46d092018-04-07 15:32:37233 this._messageLevelIcon = null;
Erik Luo8ef5d0c2018-09-25 21:16:00234 this._traceExpanded = false;
Erik Luo8ef5d0c2018-09-25 21:16:00235 this._expandTrace = null;
John Emaubb2897a2019-10-04 17:37:32236 this._anchorElement = null;
Sigurd Schneider45f32c32020-10-13 13:32:05237 this._contentElement = null;
Sigurd Schneider45f32c32020-10-13 13:32:05238 this._nestingLevelMarkers = null;
Sigurd Schneider45f32c32020-10-13 13:32:05239 this._searchHighlightNodes = [];
Sigurd Schneidere8e75cf2020-10-13 08:17:52240 this._searchHighlightNodeChanges = [];
Sigurd Schneider53e98632020-10-26 15:29:50241 this._isVisible = false;
242 this._cachedHeight = 0;
243 this._messagePrefix = '';
Sigurd Schneider53e98632020-10-26 15:29:50244 this._timestampElement = null;
245 this._inSimilarGroup = false;
Sigurd Schneider53e98632020-10-26 15:29:50246 this._similarGroupMarker = null;
247 this._lastInSimilarGroup = false;
248 this._groupKey = '';
Sigurd Schneider53e98632020-10-26 15:29:50249 this._repeatCountElement = null;
Blink Reformat4c46d092018-04-07 15:32:37250 }
251
Jan Scheffler19cd7ec2021-02-12 14:16:30252 element(): HTMLElement {
Blink Reformat4c46d092018-04-07 15:32:37253 return this.toMessageElement();
254 }
255
Jan Scheffler19cd7ec2021-02-12 14:16:30256 wasShown(): void {
Blink Reformat4c46d092018-04-07 15:32:37257 this._isVisible = true;
258 }
259
Jan Scheffler19cd7ec2021-02-12 14:16:30260 onResize(): void {
Blink Reformat4c46d092018-04-07 15:32:37261 }
262
Jan Scheffler19cd7ec2021-02-12 14:16:30263 willHide(): void {
Blink Reformat4c46d092018-04-07 15:32:37264 this._isVisible = false;
Erik Luo4b002322018-07-30 21:23:31265 this._cachedHeight = this.element().offsetHeight;
Blink Reformat4c46d092018-04-07 15:32:37266 }
267
Jan Scheffler19cd7ec2021-02-12 14:16:30268 isVisible(): boolean {
Sigurd Schneider8bfb4212020-10-27 10:27:37269 return this._isVisible;
270 }
271
Jan Scheffler19cd7ec2021-02-12 14:16:30272 fastHeight(): number {
Tim van der Lippe1d6e57a2019-09-30 11:55:34273 if (this._cachedHeight) {
Blink Reformat4c46d092018-04-07 15:32:37274 return this._cachedHeight;
Tim van der Lippe1d6e57a2019-09-30 11:55:34275 }
Sigurd Schneider8bfb4212020-10-27 10:27:37276 return this.approximateFastHeight();
277 }
278
Jan Scheffler19cd7ec2021-02-12 14:16:30279 approximateFastHeight(): number {
Blink Reformat4c46d092018-04-07 15:32:37280 return defaultConsoleRowHeight;
281 }
282
Jan Scheffler19cd7ec2021-02-12 14:16:30283 consoleMessage(): SDK.ConsoleModel.ConsoleMessage {
Blink Reformat4c46d092018-04-07 15:32:37284 return this._message;
285 }
286
Jan Scheffler19cd7ec2021-02-12 14:16:30287 _buildMessage(): HTMLElement {
Blink Reformat4c46d092018-04-07 15:32:37288 let messageElement;
Jan Scheffler19cd7ec2021-02-12 14:16:30289 let messageText: Common.UIString.LocalizedString|string = this._message.messageText;
Tim van der Lippe9b2f8712020-02-12 17:46:22290 if (this._message.source === SDK.ConsoleModel.MessageSource.ConsoleAPI) {
Blink Reformat4c46d092018-04-07 15:32:37291 switch (this._message.type) {
Tim van der Lippe9b2f8712020-02-12 17:46:22292 case SDK.ConsoleModel.MessageType.Trace:
Blink Reformat4c46d092018-04-07 15:32:37293 messageElement = this._format(this._message.parameters || ['console.trace']);
294 break;
Tim van der Lippe9b2f8712020-02-12 17:46:22295 case SDK.ConsoleModel.MessageType.Clear:
Tim van der Lippef49e2322020-05-01 15:03:09296 messageElement = document.createElement('span');
297 messageElement.classList.add('console-info');
Paul Lewis2d7d65c2020-03-16 17:26:30298 if (Common.Settings.Settings.instance().moduleSetting('preserveConsoleLog').get()) {
Christy Chen9c6d8982021-02-08 02:28:31299 messageElement.textContent = i18nString(UIStrings.consoleclearWasPreventedDueTo);
Tim van der Lippe1d6e57a2019-09-30 11:55:34300 } else {
Christy Chen9c6d8982021-02-08 02:28:31301 messageElement.textContent = i18nString(UIStrings.consoleWasCleared);
Tim van der Lippe1d6e57a2019-09-30 11:55:34302 }
Tim van der Lippe420e5e32020-11-23 16:58:46303 UI.Tooltip.Tooltip.install(
Christy Chen9c6d8982021-02-08 02:28:31304 messageElement, i18nString(UIStrings.clearAllMessagesWithS, {
Jan Scheffler19cd7ec2021-02-12 14:16:30305 PH1: UI.ShortcutRegistry.ShortcutRegistry.instance().shortcutTitleForAction('console.clear'),
Christy Chen9c6d8982021-02-08 02:28:31306 }));
Blink Reformat4c46d092018-04-07 15:32:37307 break;
Tim van der Lippe9b2f8712020-02-12 17:46:22308 case SDK.ConsoleModel.MessageType.Dir: {
Blink Reformat4c46d092018-04-07 15:32:37309 const obj = this._message.parameters ? this._message.parameters[0] : undefined;
310 const args = ['%O', obj];
311 messageElement = this._format(args);
312 break;
313 }
Tim van der Lippe9b2f8712020-02-12 17:46:22314 case SDK.ConsoleModel.MessageType.Profile:
315 case SDK.ConsoleModel.MessageType.ProfileEnd:
Blink Reformat4c46d092018-04-07 15:32:37316 messageElement = this._format([messageText]);
317 break;
318 default: {
Sigurd Schneider45f32c32020-10-13 13:32:05319 if (this._message.type === SDK.ConsoleModel.MessageType.Assert) {
Christy Chen9c6d8982021-02-08 02:28:31320 this._messagePrefix = i18nString(UIStrings.assertionFailed);
Sigurd Schneider45f32c32020-10-13 13:32:05321 }
322 if (this._message.parameters && this._message.parameters.length === 1) {
323 const parameter = this._message.parameters[0];
324 if (typeof parameter !== 'string' && parameter.type === 'string') {
Jan Scheffler19cd7ec2021-02-12 14:16:30325 messageElement = this._tryFormatAsError((parameter.value as string));
Sigurd Schneider45f32c32020-10-13 13:32:05326 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34327 }
Blink Reformat4c46d092018-04-07 15:32:37328 const args = this._message.parameters || [messageText];
329 messageElement = messageElement || this._format(args);
330 }
331 }
332 } else {
Tim van der Lippe9b2f8712020-02-12 17:46:22333 if (this._message.source === SDK.ConsoleModel.MessageSource.Network) {
Erik Luofc2214f2018-11-21 19:54:58334 messageElement = this._formatAsNetworkRequest() || this._format([messageText]);
335 } else {
Jan Scheffler19cd7ec2021-02-12 14:16:30336 const messageInParameters = this._message.parameters && messageText === (this._message.parameters[0] as string);
Peter Marshall40dd7d92021-02-19 11:07:37337 // These terms are locked because the console message will not be translated anyway.
Tim van der Lippe9b2f8712020-02-12 17:46:22338 if (this._message.source === SDK.ConsoleModel.MessageSource.Violation) {
Christy Chen9c6d8982021-02-08 02:28:31339 messageText = i18nString(UIStrings.violationS, {PH1: messageText});
Tim van der Lippe9b2f8712020-02-12 17:46:22340 } else if (this._message.source === SDK.ConsoleModel.MessageSource.Intervention) {
Christy Chen9c6d8982021-02-08 02:28:31341 messageText = i18nString(UIStrings.interventionS, {PH1: messageText});
Tim van der Lippe9b2f8712020-02-12 17:46:22342 } else if (this._message.source === SDK.ConsoleModel.MessageSource.Deprecation) {
Christy Chen9c6d8982021-02-08 02:28:31343 messageText = i18nString(UIStrings.deprecationS, {PH1: messageText});
Tim van der Lippe1d6e57a2019-09-30 11:55:34344 }
Blink Reformat4c46d092018-04-07 15:32:37345 const args = this._message.parameters || [messageText];
Tim van der Lippe1d6e57a2019-09-30 11:55:34346 if (messageInParameters) {
Blink Reformat4c46d092018-04-07 15:32:37347 args[0] = messageText;
Tim van der Lippe1d6e57a2019-09-30 11:55:34348 }
Blink Reformat4c46d092018-04-07 15:32:37349 messageElement = this._format(args);
350 }
351 }
352 messageElement.classList.add('console-message-text');
353
Jan Scheffler19cd7ec2021-02-12 14:16:30354 const formattedMessage = (document.createElement('span') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:09355 formattedMessage.classList.add('source-code');
Erik Luo5976c8c2018-07-24 02:03:09356 this._anchorElement = this._buildMessageAnchor();
Tim van der Lippe1d6e57a2019-09-30 11:55:34357 if (this._anchorElement) {
Erik Luo5976c8c2018-07-24 02:03:09358 formattedMessage.appendChild(this._anchorElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34359 }
Blink Reformat4c46d092018-04-07 15:32:37360 formattedMessage.appendChild(messageElement);
361 return formattedMessage;
362 }
363
Jan Scheffler19cd7ec2021-02-12 14:16:30364 _formatAsNetworkRequest(): HTMLElement|null {
Tim van der Lippe9b2f8712020-02-12 17:46:22365 const request = SDK.NetworkLog.NetworkLog.requestForConsoleMessage(this._message);
Tim van der Lippe1d6e57a2019-09-30 11:55:34366 if (!request) {
Erik Luofc2214f2018-11-21 19:54:58367 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34368 }
Jan Scheffler19cd7ec2021-02-12 14:16:30369 const messageElement = (document.createElement('span') as HTMLElement);
Tim van der Lippe9b2f8712020-02-12 17:46:22370 if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Sigurd Schneider23c52972020-10-13 09:31:14371 UI.UIUtils.createTextChild(messageElement, request.requestMethod + ' ');
Tim van der Lippe9b2f8712020-02-12 17:46:22372 const linkElement = Components.Linkifier.Linkifier.linkifyRevealable(request, request.url(), request.url());
Erik Luo182bece2018-11-29 03:15:22373 // Focus is handled by the viewport.
374 linkElement.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:30375 this._selectableChildren.push({element: linkElement, forceSelect: (): void => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22376 messageElement.appendChild(linkElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34377 if (request.failed) {
Sigurd Schneider23c52972020-10-13 09:31:14378 UI.UIUtils.createTextChildren(messageElement, ' ', request.localizedFailDescription || '');
Tim van der Lippe1d6e57a2019-09-30 11:55:34379 }
380 if (request.statusCode !== 0) {
Sigurd Schneider23c52972020-10-13 09:31:14381 UI.UIUtils.createTextChildren(messageElement, ' ', String(request.statusCode));
Tim van der Lippe1d6e57a2019-09-30 11:55:34382 }
383 if (request.statusText) {
Sigurd Schneider23c52972020-10-13 09:31:14384 UI.UIUtils.createTextChildren(messageElement, ' (', request.statusText, ')');
Tim van der Lippe1d6e57a2019-09-30 11:55:34385 }
Erik Luofc2214f2018-11-21 19:54:58386 } else {
Erik Luoad5f3942019-03-26 20:53:44387 const messageText = this._message.messageText;
388 const fragment = this._linkifyWithCustomLinkifier(messageText, (text, url, lineNumber, columnNumber) => {
Sigurd Schneider45f32c32020-10-13 13:32:05389 const linkElement = url === request.url() ?
390 Components.Linkifier.Linkifier.linkifyRevealable(
Jan Scheffler19cd7ec2021-02-12 14:16:30391 (request as SDK.NetworkRequest.NetworkRequest), url, request.url()) :
Sigurd Schneider45f32c32020-10-13 13:32:05392 Components.Linkifier.Linkifier.linkifyURL(
Jan Scheffler19cd7ec2021-02-12 14:16:30393 url, ({text, lineNumber, columnNumber} as Components.Linkifier.LinkifyURLOptions));
Erik Luo182bece2018-11-29 03:15:22394 linkElement.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:30395 this._selectableChildren.push({element: linkElement, forceSelect: (): void => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22396 return linkElement;
397 });
Erik Luofc2214f2018-11-21 19:54:58398 messageElement.appendChild(fragment);
399 }
400 return messageElement;
401 }
402
Jan Scheffler19cd7ec2021-02-12 14:16:30403 _buildMessageAnchor(): HTMLElement|null {
404 const linkify = (message: SDK.ConsoleModel.ConsoleMessage): HTMLElement|null => {
Sigurd Schneider45f32c32020-10-13 13:32:05405 if (message.scriptId) {
406 return this._linkifyScriptId(message.scriptId, message.url || '', message.line, message.column);
407 }
408 if (message.stackTrace && message.stackTrace.callFrames.length) {
409 return this._linkifyStackTraceTopFrame(message.stackTrace);
410 }
411 if (message.url && message.url !== 'undefined') {
412 return this._linkifyLocation(message.url, message.line, message.column);
413 }
414 return null;
415 };
416 const anchorElement = linkify(this._message);
Blink Reformat4c46d092018-04-07 15:32:37417 // Append a space to prevent the anchor text from being glued to the console message when the user selects and copies the console messages.
418 if (anchorElement) {
John Emauf7e30fb2019-10-04 19:12:32419 anchorElement.tabIndex = -1;
420 this._selectableChildren.push({
421 element: anchorElement,
Jan Scheffler19cd7ec2021-02-12 14:16:30422 forceSelect: (): void => anchorElement.focus(),
John Emauf7e30fb2019-10-04 19:12:32423 });
Jan Scheffler19cd7ec2021-02-12 14:16:30424 const anchorWrapperElement = (document.createElement('span') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:09425 anchorWrapperElement.classList.add('console-message-anchor');
Blink Reformat4c46d092018-04-07 15:32:37426 anchorWrapperElement.appendChild(anchorElement);
Sigurd Schneider23c52972020-10-13 09:31:14427 UI.UIUtils.createTextChild(anchorWrapperElement, ' ');
Blink Reformat4c46d092018-04-07 15:32:37428 return anchorWrapperElement;
429 }
430 return null;
431 }
432
Jan Scheffler19cd7ec2021-02-12 14:16:30433 _buildMessageWithStackTrace(runtimeModel: SDK.RuntimeModel.RuntimeModel): HTMLElement {
434 const toggleElement = (document.createElement('div') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:09435 toggleElement.classList.add('console-message-stack-trace-toggle');
Blink Reformat4c46d092018-04-07 15:32:37436 const contentElement = toggleElement.createChild('div', 'console-message-stack-trace-wrapper');
437
438 const messageElement = this._buildMessage();
Tim van der Lippe9b2f8712020-02-12 17:46:22439 const icon = UI.Icon.Icon.create('smallicon-triangle-right', 'console-message-expand-icon');
Blink Reformat4c46d092018-04-07 15:32:37440 const clickableElement = contentElement.createChild('div');
441 clickableElement.appendChild(icon);
Erik Luob5bfff42018-09-20 02:52:39442 // Intercept focus to avoid highlight on click.
443 clickableElement.tabIndex = -1;
Blink Reformat4c46d092018-04-07 15:32:37444 clickableElement.appendChild(messageElement);
445 const stackTraceElement = contentElement.createChild('div');
446 const stackTracePreview = Components.JSPresentationUtils.buildStackTracePreviewContents(
Wolfgang Beyer08261c72021-03-09 09:21:34447 runtimeModel.target(), this._linkifier, {stackTrace: this._message.stackTrace, tabStops: undefined});
Erik Luo182bece2018-11-29 03:15:22448 stackTraceElement.appendChild(stackTracePreview.element);
449 for (const linkElement of stackTracePreview.links) {
Jan Scheffler19cd7ec2021-02-12 14:16:30450 this._selectableChildren.push({element: linkElement, forceSelect: (): void => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22451 }
Blink Reformat4c46d092018-04-07 15:32:37452 stackTraceElement.classList.add('hidden');
Brandon Goddard04a5a762019-12-10 16:45:53453 UI.ARIAUtils.markAsTreeitem(this.element());
454 UI.ARIAUtils.setExpanded(this.element(), false);
Jan Scheffler19cd7ec2021-02-12 14:16:30455 this._expandTrace = (expand: boolean): void => {
Blink Reformat4c46d092018-04-07 15:32:37456 icon.setIconType(expand ? 'smallicon-triangle-down' : 'smallicon-triangle-right');
457 stackTraceElement.classList.toggle('hidden', !expand);
Brandon Goddard04a5a762019-12-10 16:45:53458 UI.ARIAUtils.setExpanded(this.element(), expand);
Erik Luo8ef5d0c2018-09-25 21:16:00459 this._traceExpanded = expand;
460 };
Blink Reformat4c46d092018-04-07 15:32:37461
Jan Scheffler19cd7ec2021-02-12 14:16:30462 const toggleStackTrace = (event: Event): void => {
Tim van der Lippe9b2f8712020-02-12 17:46:22463 if (UI.UIUtils.isEditing() || contentElement.hasSelection()) {
Blink Reformat4c46d092018-04-07 15:32:37464 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34465 }
Sigurd Schneider45f32c32020-10-13 13:32:05466 this._expandTrace && this._expandTrace(stackTraceElement.classList.contains('hidden'));
Blink Reformat4c46d092018-04-07 15:32:37467 event.consume();
Sigurd Schneider45f32c32020-10-13 13:32:05468 };
Blink Reformat4c46d092018-04-07 15:32:37469
Sigurd Schneider45f32c32020-10-13 13:32:05470 clickableElement.addEventListener('click', toggleStackTrace, false);
Tim van der Lippe9b2f8712020-02-12 17:46:22471 if (this._message.type === SDK.ConsoleModel.MessageType.Trace) {
Erik Luo8ef5d0c2018-09-25 21:16:00472 this._expandTrace(true);
Tim van der Lippe1d6e57a2019-09-30 11:55:34473 }
Blink Reformat4c46d092018-04-07 15:32:37474
Sigurd Schneider45f32c32020-10-13 13:32:05475 // @ts-ignore
Erik Luo8ef5d0c2018-09-25 21:16:00476 toggleElement._expandStackTraceForTest = this._expandTrace.bind(this, true);
Blink Reformat4c46d092018-04-07 15:32:37477 return toggleElement;
478 }
479
Jan Scheffler19cd7ec2021-02-12 14:16:30480 _linkifyLocation(url: string, lineNumber: number, columnNumber: number): HTMLElement|null {
Sigurd Schneider45f32c32020-10-13 13:32:05481 const runtimeModel = this._message.runtimeModel();
482 if (!runtimeModel) {
Blink Reformat4c46d092018-04-07 15:32:37483 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34484 }
Blink Reformat4c46d092018-04-07 15:32:37485 return this._linkifier.linkifyScriptLocation(
Sigurd Schneider45f32c32020-10-13 13:32:05486 runtimeModel.target(), /* scriptId */ null, url, lineNumber,
487 {columnNumber, className: undefined, tabStop: undefined});
Blink Reformat4c46d092018-04-07 15:32:37488 }
489
Jan Scheffler19cd7ec2021-02-12 14:16:30490 _linkifyStackTraceTopFrame(stackTrace: Protocol.Runtime.StackTrace): HTMLElement|null {
Sigurd Schneider45f32c32020-10-13 13:32:05491 const runtimeModel = this._message.runtimeModel();
492 if (!runtimeModel) {
Blink Reformat4c46d092018-04-07 15:32:37493 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34494 }
Sigurd Schneider45f32c32020-10-13 13:32:05495 return this._linkifier.linkifyStackTraceTopFrame(runtimeModel.target(), stackTrace);
Blink Reformat4c46d092018-04-07 15:32:37496 }
497
Jan Scheffler19cd7ec2021-02-12 14:16:30498 _linkifyScriptId(scriptId: string, url: string, lineNumber: number, columnNumber: number): HTMLElement|null {
Sigurd Schneider45f32c32020-10-13 13:32:05499 const runtimeModel = this._message.runtimeModel();
500 if (!runtimeModel) {
Blink Reformat4c46d092018-04-07 15:32:37501 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34502 }
Blink Reformat4c46d092018-04-07 15:32:37503 return this._linkifier.linkifyScriptLocation(
Sigurd Schneider45f32c32020-10-13 13:32:05504 runtimeModel.target(), scriptId, url, lineNumber, {columnNumber, className: undefined, tabStop: undefined});
Blink Reformat4c46d092018-04-07 15:32:37505 }
506
Jan Scheffler19cd7ec2021-02-12 14:16:30507 _format(rawParameters: (string|SDK.RemoteObject.RemoteObject|Protocol.Runtime.RemoteObject|undefined)[]):
508 HTMLElement {
Blink Reformat4c46d092018-04-07 15:32:37509 // This node is used like a Builder. Values are continually appended onto it.
Jan Scheffler19cd7ec2021-02-12 14:16:30510 const formattedResult = (document.createElement('span') as HTMLElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34511 if (this._messagePrefix) {
Pavel Feldman9f0f0a32018-12-18 02:09:13512 formattedResult.createChild('span').textContent = this._messagePrefix;
Tim van der Lippe1d6e57a2019-09-30 11:55:34513 }
514 if (!rawParameters.length) {
Blink Reformat4c46d092018-04-07 15:32:37515 return formattedResult;
Tim van der Lippe1d6e57a2019-09-30 11:55:34516 }
Blink Reformat4c46d092018-04-07 15:32:37517
518 // Formatting code below assumes that parameters are all wrappers whereas frontend console
519 // API allows passing arbitrary values as messages (strings, numbers, etc.). Wrap them here.
520 // FIXME: Only pass runtime wrappers here.
Sigurd Schneider8bfb4212020-10-27 10:27:37521 let parameters = rawParameters.map(parameterToRemoteObject(this._message.runtimeModel()));
Blink Reformat4c46d092018-04-07 15:32:37522
523 // There can be string log and string eval result. We distinguish between them based on message type.
524 const shouldFormatMessage =
Jan Scheffler19cd7ec2021-02-12 14:16:30525 SDK.RemoteObject.RemoteObject.type((parameters as SDK.RemoteObject.RemoteObject[])[0]) === 'string' &&
Tim van der Lippe9b2f8712020-02-12 17:46:22526 (this._message.type !== SDK.ConsoleModel.MessageType.Result ||
527 this._message.level === SDK.ConsoleModel.MessageLevel.Error);
Blink Reformat4c46d092018-04-07 15:32:37528
529 // Multiple parameters with the first being a format string. Save unused substitutions.
530 if (shouldFormatMessage) {
531 const result = this._formatWithSubstitutionString(
Jan Scheffler19cd7ec2021-02-12 14:16:30532 (parameters[0].description as string), parameters.slice(1), formattedResult);
Sigurd Schneider45f32c32020-10-13 13:32:05533 parameters = Array.from(result.unusedSubstitutions || []);
Tim van der Lippe1d6e57a2019-09-30 11:55:34534 if (parameters.length) {
Sigurd Schneider23c52972020-10-13 09:31:14535 UI.UIUtils.createTextChild(formattedResult, ' ');
Tim van der Lippe1d6e57a2019-09-30 11:55:34536 }
Blink Reformat4c46d092018-04-07 15:32:37537 }
538
539 // Single parameter, or unused substitutions from above.
540 for (let i = 0; i < parameters.length; ++i) {
541 // Inline strings when formatting.
Tim van der Lippe1d6e57a2019-09-30 11:55:34542 if (shouldFormatMessage && parameters[i].type === 'string') {
Sigurd Schneider45f32c32020-10-13 13:32:05543 formattedResult.appendChild(this._linkifyStringAsFragment(parameters[i].description || ''));
Tim van der Lippe1d6e57a2019-09-30 11:55:34544 } else {
Blink Reformat4c46d092018-04-07 15:32:37545 formattedResult.appendChild(this._formatParameter(parameters[i], false, true));
Tim van der Lippe1d6e57a2019-09-30 11:55:34546 }
547 if (i < parameters.length - 1) {
Sigurd Schneider23c52972020-10-13 09:31:14548 UI.UIUtils.createTextChild(formattedResult, ' ');
Tim van der Lippe1d6e57a2019-09-30 11:55:34549 }
Blink Reformat4c46d092018-04-07 15:32:37550 }
551 return formattedResult;
552 }
553
Jan Scheffler19cd7ec2021-02-12 14:16:30554 _formatParameter(output: SDK.RemoteObject.RemoteObject, forceObjectFormat?: boolean, includePreview?: boolean):
555 HTMLElement {
Tim van der Lippe1d6e57a2019-09-30 11:55:34556 if (output.customPreview()) {
Jan Scheffler19cd7ec2021-02-12 14:16:30557 return new ObjectUI.CustomPreviewComponent.CustomPreviewComponent(output).element as HTMLElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:34558 }
Blink Reformat4c46d092018-04-07 15:32:37559
Alfonso Castaño20d22cd2020-10-28 16:23:58560 const outputType = forceObjectFormat ? 'object' : (output.subtype || output.type);
Blink Reformat4c46d092018-04-07 15:32:37561 let element;
Alfonso Castaño20d22cd2020-10-28 16:23:58562 switch (outputType) {
Blink Reformat4c46d092018-04-07 15:32:37563 case 'error':
564 element = this._formatParameterAsError(output);
565 break;
566 case 'function':
567 element = this._formatParameterAsFunction(output, includePreview);
568 break;
569 case 'array':
570 case 'arraybuffer':
571 case 'blob':
572 case 'dataview':
573 case 'generator':
574 case 'iterator':
575 case 'map':
576 case 'object':
577 case 'promise':
578 case 'proxy':
579 case 'set':
580 case 'typedarray':
Benedikt Meurer5658dd22021-03-18 09:37:23581 case 'wasmvalue':
Blink Reformat4c46d092018-04-07 15:32:37582 case 'weakmap':
583 case 'weakset':
Benedikt Meurerdead3152020-12-07 08:43:40584 case 'webassemblymemory':
Blink Reformat4c46d092018-04-07 15:32:37585 element = this._formatParameterAsObject(output, includePreview);
586 break;
587 case 'node':
588 element = output.isNode() ? this._formatParameterAsNode(output) : this._formatParameterAsObject(output, false);
589 break;
Alfonso Castaño20d22cd2020-10-28 16:23:58590 case 'trustedtype':
591 element = this._formatParameterAsObject(output, false);
592 break;
Blink Reformat4c46d092018-04-07 15:32:37593 case 'string':
594 element = this._formatParameterAsString(output);
595 break;
596 case 'boolean':
597 case 'date':
598 case 'null':
599 case 'number':
600 case 'regexp':
601 case 'symbol':
602 case 'undefined':
603 case 'bigint':
604 element = this._formatParameterAsValue(output);
605 break;
606 default:
607 element = this._formatParameterAsValue(output);
Alfonso Castaño20d22cd2020-10-28 16:23:58608 console.error(`Tried to format remote object of unknown type ${outputType}.`);
Blink Reformat4c46d092018-04-07 15:32:37609 }
Alfonso Castaño20d22cd2020-10-28 16:23:58610 element.classList.add(`object-value-${outputType}`);
Blink Reformat4c46d092018-04-07 15:32:37611 element.classList.add('source-code');
612 return element;
613 }
614
Jan Scheffler19cd7ec2021-02-12 14:16:30615 _formatParameterAsValue(obj: SDK.RemoteObject.RemoteObject): HTMLElement {
616 const result = (document.createElement('span') as HTMLElement);
Blink Reformat4c46d092018-04-07 15:32:37617 const description = obj.description || '';
Sigurd Schneider8f4ac862020-10-13 13:30:11618 if (description.length > getMaxTokenizableStringLength()) {
Tim van der Lippe9b2f8712020-02-12 17:46:22619 const propertyValue = new ObjectUI.ObjectPropertiesSection.ExpandableTextPropertyValue(
Sigurd Schneider8f4ac862020-10-13 13:30:11620 document.createElement('span'), description, getLongStringVisibleLength());
Connor Moody1a5c0d32019-12-19 07:23:36621 result.appendChild(propertyValue.element);
Tim van der Lippe1d6e57a2019-09-30 11:55:34622 } else {
Sigurd Schneider23c52972020-10-13 09:31:14623 UI.UIUtils.createTextChild(result, description);
Tim van der Lippe1d6e57a2019-09-30 11:55:34624 }
625 if (obj.objectId) {
Blink Reformat4c46d092018-04-07 15:32:37626 result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, obj), false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34627 }
Blink Reformat4c46d092018-04-07 15:32:37628 return result;
629 }
630
Jan Scheffler19cd7ec2021-02-12 14:16:30631 _formatParameterAsTrustedType(obj: SDK.RemoteObject.RemoteObject): HTMLElement {
632 const result = (document.createElement('span') as HTMLElement);
Alfonso Castaño20d22cd2020-10-28 16:23:58633 const trustedContentSpan = document.createElement('span');
634 trustedContentSpan.appendChild(this._formatParameterAsString(obj));
635 trustedContentSpan.classList.add('object-value-string');
Alfonso Castañodfe8ca32020-10-29 13:03:09636 UI.UIUtils.createTextChild(result, `${obj.className} `);
Alfonso Castaño20d22cd2020-10-28 16:23:58637 result.appendChild(trustedContentSpan);
Alfonso Castaño20d22cd2020-10-28 16:23:58638 return result;
639 }
640
Jan Scheffler19cd7ec2021-02-12 14:16:30641 _formatParameterAsObject(obj: SDK.RemoteObject.RemoteObject, includePreview?: boolean): HTMLElement {
642 const titleElement = (document.createElement('span') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:09643 titleElement.classList.add('console-object');
Blink Reformat4c46d092018-04-07 15:32:37644 if (includePreview && obj.preview) {
645 titleElement.classList.add('console-object-preview');
646 this._previewFormatter.appendObjectPreview(titleElement, obj.preview, false /* isEntry */);
647 } else if (obj.type === 'function') {
648 const functionElement = titleElement.createChild('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22649 ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection.formatObjectAsFunction(obj, functionElement, false);
Blink Reformat4c46d092018-04-07 15:32:37650 titleElement.classList.add('object-value-function');
Alfonso Castaño20d22cd2020-10-28 16:23:58651 } else if (obj.subtype === 'trustedtype') {
652 titleElement.appendChild(this._formatParameterAsTrustedType(obj));
Blink Reformat4c46d092018-04-07 15:32:37653 } else {
Sigurd Schneider23c52972020-10-13 09:31:14654 UI.UIUtils.createTextChild(titleElement, obj.description || '');
Blink Reformat4c46d092018-04-07 15:32:37655 }
656
Tim van der Lippe1d6e57a2019-09-30 11:55:34657 if (!obj.hasChildren || obj.customPreview()) {
Blink Reformat4c46d092018-04-07 15:32:37658 return titleElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:34659 }
Blink Reformat4c46d092018-04-07 15:32:37660
661 const note = titleElement.createChild('span', 'object-state-note info-note');
Tim van der Lippe9b2f8712020-02-12 17:46:22662 if (this._message.type === SDK.ConsoleModel.MessageType.QueryObjectResult) {
Christy Chen9c6d8982021-02-08 02:28:31663 UI.Tooltip.Tooltip.install(note, i18nString(UIStrings.thisValueWillNotBeCollectedUntil));
Tim van der Lippe1d6e57a2019-09-30 11:55:34664 } else {
Christy Chen9c6d8982021-02-08 02:28:31665 UI.Tooltip.Tooltip.install(note, i18nString(UIStrings.thisValueWasEvaluatedUponFirst));
Tim van der Lippe1d6e57a2019-09-30 11:55:34666 }
Blink Reformat4c46d092018-04-07 15:32:37667
Tim van der Lippe9b2f8712020-02-12 17:46:22668 const section = new ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection(obj, titleElement, this._linkifier);
Blink Reformat4c46d092018-04-07 15:32:37669 section.element.classList.add('console-view-object-properties-section');
670 section.enableContextMenu();
Erik Luocc14b812018-11-03 01:33:09671 section.setShowSelectionOnKeyboardFocus(true, true);
Erik Luo383f21d2018-11-07 23:16:37672 this._selectableChildren.push(section);
Erik Luo840be6b2018-12-03 20:54:27673 section.addEventListener(UI.TreeOutline.Events.ElementAttached, this._messageResized);
674 section.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._messageResized);
675 section.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._messageResized);
Blink Reformat4c46d092018-04-07 15:32:37676 return section.element;
677 }
678
Jan Scheffler19cd7ec2021-02-12 14:16:30679 _formatParameterAsFunction(func: SDK.RemoteObject.RemoteObject, includePreview?: boolean): HTMLElement {
680 const result = (document.createElement('span') as HTMLElement);
Tim van der Lippe9b2f8712020-02-12 17:46:22681 SDK.RemoteObject.RemoteFunction.objectAsFunction(func).targetFunction().then(formatTargetFunction.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37682 return result;
683
Jan Scheffler19cd7ec2021-02-12 14:16:30684 function formatTargetFunction(this: ConsoleViewMessage, targetFunction: SDK.RemoteObject.RemoteObject): void {
Sigurd Schneider53f33522020-10-08 15:00:49685 const functionElement = document.createElement('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22686 const promise = ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection.formatObjectAsFunction(
Joey Arhard78a58f2018-12-05 01:59:45687 targetFunction, functionElement, true, includePreview);
Blink Reformat4c46d092018-04-07 15:32:37688 result.appendChild(functionElement);
689 if (targetFunction !== func) {
690 const note = result.createChild('span', 'object-info-state-note');
Christy Chen9c6d8982021-02-08 02:28:31691 UI.Tooltip.Tooltip.install(note, i18nString(UIStrings.functionWasResolvedFromBound));
Blink Reformat4c46d092018-04-07 15:32:37692 }
693 result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, targetFunction), false);
Joey Arhard78a58f2018-12-05 01:59:45694 promise.then(() => this._formattedParameterAsFunctionForTest());
Blink Reformat4c46d092018-04-07 15:32:37695 }
696 }
697
Jan Scheffler19cd7ec2021-02-12 14:16:30698 _formattedParameterAsFunctionForTest(): void {
Joey Arhard78a58f2018-12-05 01:59:45699 }
700
Jan Scheffler19cd7ec2021-02-12 14:16:30701 _contextMenuEventFired(obj: SDK.RemoteObject.RemoteObject, event: Event): void {
Tim van der Lippe9b2f8712020-02-12 17:46:22702 const contextMenu = new UI.ContextMenu.ContextMenu(event);
Blink Reformat4c46d092018-04-07 15:32:37703 contextMenu.appendApplicableItems(obj);
704 contextMenu.show();
705 }
706
Jan Scheffler19cd7ec2021-02-12 14:16:30707 _renderPropertyPreviewOrAccessor(
708 object: SDK.RemoteObject.RemoteObject|null, property: Protocol.Runtime.PropertyPreview, propertyPath: {
709 name: (string|symbol),
710 }[]): HTMLElement {
Tim van der Lippe1d6e57a2019-09-30 11:55:34711 if (property.type === 'accessor') {
Sigurd Schneider45f32c32020-10-13 13:32:05712 return this._formatAsAccessorProperty(object, propertyPath.map(property => property.name.toString()), false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34713 }
Blink Reformat4c46d092018-04-07 15:32:37714 return this._previewFormatter.renderPropertyPreview(
Alfonso Castaño20d22cd2020-10-28 16:23:58715 property.type, 'subtype' in property ? property.subtype : undefined, null, property.value);
Blink Reformat4c46d092018-04-07 15:32:37716 }
717
Jan Scheffler19cd7ec2021-02-12 14:16:30718 _formatParameterAsNode(remoteObject: SDK.RemoteObject.RemoteObject): HTMLElement {
719 const result = document.createElement('span');
Blink Reformat4c46d092018-04-07 15:32:37720
Tim van der Lippe9b2f8712020-02-12 17:46:22721 const domModel = remoteObject.runtimeModel().target().model(SDK.DOMModel.DOMModel);
Tim van der Lippe1d6e57a2019-09-30 11:55:34722 if (!domModel) {
Blink Reformat4c46d092018-04-07 15:32:37723 return result;
Tim van der Lippe1d6e57a2019-09-30 11:55:34724 }
Jan Scheffler19cd7ec2021-02-12 14:16:30725 domModel.pushObjectAsNodeToFrontend(remoteObject).then(async (node: SDK.DOMModel.DOMNode|null) => {
Blink Reformat4c46d092018-04-07 15:32:37726 if (!node) {
727 result.appendChild(this._formatParameterAsObject(remoteObject, false));
728 return;
729 }
Jan Scheffler19cd7ec2021-02-12 14:16:30730 const renderResult = await UI.UIUtils.Renderer.render((node as Object));
Erik Luofc6a6302018-11-02 06:48:52731 if (renderResult) {
Erik Luo840be6b2018-12-03 20:54:27732 if (renderResult.tree) {
Erik Luo383f21d2018-11-07 23:16:37733 this._selectableChildren.push(renderResult.tree);
Erik Luo840be6b2018-12-03 20:54:27734 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementAttached, this._messageResized);
735 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._messageResized);
736 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._messageResized);
737 }
Erik Luofc6a6302018-11-02 06:48:52738 result.appendChild(renderResult.node);
739 } else {
740 result.appendChild(this._formatParameterAsObject(remoteObject, false));
741 }
Erik Luo54fdd912018-11-01 17:57:01742 this._formattedParameterAsNodeForTest();
Blink Reformat4c46d092018-04-07 15:32:37743 });
744
745 return result;
746 }
747
Jan Scheffler19cd7ec2021-02-12 14:16:30748 _formattedParameterAsNodeForTest(): void {
Blink Reformat4c46d092018-04-07 15:32:37749 }
750
Jan Scheffler19cd7ec2021-02-12 14:16:30751 _formatParameterAsString(output: SDK.RemoteObject.RemoteObject): HTMLElement {
Benedikt Meurer62b49da2021-02-18 09:15:55752 // Properly escape double quotes here, so users don't get surprised
753 // when they copy strings from the console (https://crbug.com/1178530).
754 const description = output.description ?? '';
755 const text = JSON.stringify(description);
Jan Scheffler19cd7ec2021-02-12 14:16:30756 const result = (document.createElement('span') as HTMLElement);
Benedikt Meurer62b49da2021-02-18 09:15:55757 result.appendChild(this._linkifyStringAsFragment(text));
Blink Reformat4c46d092018-04-07 15:32:37758 return result;
759 }
760
Jan Scheffler19cd7ec2021-02-12 14:16:30761 _formatParameterAsError(output: SDK.RemoteObject.RemoteObject): HTMLElement {
762 const result = (document.createElement('span') as HTMLElement);
Blink Reformat4c46d092018-04-07 15:32:37763 const errorSpan = this._tryFormatAsError(output.description || '');
Erik Luo383f21d2018-11-07 23:16:37764 result.appendChild(errorSpan ? errorSpan : this._linkifyStringAsFragment(output.description || ''));
Blink Reformat4c46d092018-04-07 15:32:37765 return result;
766 }
767
Jan Scheffler19cd7ec2021-02-12 14:16:30768 _formatAsArrayEntry(output: SDK.RemoteObject.RemoteObject): HTMLElement {
Alfonso Castaño20d22cd2020-10-28 16:23:58769 return this._previewFormatter.renderPropertyPreview(
770 output.type, output.subtype, output.className, output.description);
Blink Reformat4c46d092018-04-07 15:32:37771 }
772
Jan Scheffler19cd7ec2021-02-12 14:16:30773 _formatAsAccessorProperty(object: SDK.RemoteObject.RemoteObject|null, propertyPath: string[], isArrayEntry: boolean):
774 HTMLElement {
Tim van der Lippe9b2f8712020-02-12 17:46:22775 const rootElement =
776 ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan(
777 object, propertyPath, onInvokeGetterClick.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37778
Jan Scheffler19cd7ec2021-02-12 14:16:30779 function onInvokeGetterClick(this: ConsoleViewMessage, result: SDK.RemoteObject.CallFunctionResult): void {
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18780 const wasThrown = result.wasThrown;
781 const object = result.object;
Tim van der Lippe1d6e57a2019-09-30 11:55:34782 if (!object) {
Blink Reformat4c46d092018-04-07 15:32:37783 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34784 }
Blink Reformat4c46d092018-04-07 15:32:37785 rootElement.removeChildren();
786 if (wasThrown) {
787 const element = rootElement.createChild('span');
Christy Chen9c6d8982021-02-08 02:28:31788 element.textContent = i18nString(UIStrings.exception);
Jan Scheffler19cd7ec2021-02-12 14:16:30789 UI.Tooltip.Tooltip.install(element, (object.description as string));
Blink Reformat4c46d092018-04-07 15:32:37790 } else if (isArrayEntry) {
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18791 rootElement.appendChild(this._formatAsArrayEntry(object));
Blink Reformat4c46d092018-04-07 15:32:37792 } else {
793 // Make a PropertyPreview from the RemoteObject similar to the backend logic.
794 const maxLength = 100;
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18795 const type = object.type;
796 const subtype = object.subtype;
Blink Reformat4c46d092018-04-07 15:32:37797 let description = '';
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18798 if (type !== 'function' && object.description) {
Alfonso Castaño20d22cd2020-10-28 16:23:58799 if (type === 'string' || subtype === 'regexp' || subtype === 'trustedtype') {
Tim van der Lippe213266c2021-01-18 15:48:31800 description = Platform.StringUtilities.trimMiddle(object.description, maxLength);
Tim van der Lippe1d6e57a2019-09-30 11:55:34801 } else {
Tim van der Lippe3cc3af32021-01-19 14:25:26802 description = Platform.StringUtilities.trimEndWithMaxLength(object.description, maxLength);
Tim van der Lippe1d6e57a2019-09-30 11:55:34803 }
Blink Reformat4c46d092018-04-07 15:32:37804 }
Alfonso Castaño20d22cd2020-10-28 16:23:58805 rootElement.appendChild(
806 this._previewFormatter.renderPropertyPreview(type, subtype, object.className, description));
Blink Reformat4c46d092018-04-07 15:32:37807 }
808 }
809
810 return rootElement;
811 }
812
Jan Scheffler19cd7ec2021-02-12 14:16:30813 _formatWithSubstitutionString(
814 format: string, parameters: SDK.RemoteObject.RemoteObject[], formattedResult: HTMLElement): {
815 formattedResult: Element,
816 unusedSubstitutions: ArrayLike<SDK.RemoteObject.RemoteObject>|null,
817 } {
818 function parameterFormatter(
819 this: ConsoleViewMessage, force: boolean, includePreview: boolean,
820 obj?: string|SDK.RemoteObject.RemoteObject): string|HTMLElement|undefined {
Sigurd Schneider45f32c32020-10-13 13:32:05821 if (obj instanceof SDK.RemoteObject.RemoteObject) {
822 return this._formatParameter(obj, force, includePreview);
823 }
824 return stringFormatter(obj);
Blink Reformat4c46d092018-04-07 15:32:37825 }
826
Jan Scheffler19cd7ec2021-02-12 14:16:30827 function stringFormatter(obj?: string|SDK.RemoteObject.RemoteObject): string|undefined {
Sigurd Schneider45f32c32020-10-13 13:32:05828 if (obj === undefined) {
829 return undefined;
830 }
831 if (typeof obj === 'string') {
832 return obj;
833 }
Blink Reformat4c46d092018-04-07 15:32:37834 return obj.description;
835 }
836
Jan Scheffler19cd7ec2021-02-12 14:16:30837 function floatFormatter(obj?: string|SDK.RemoteObject.RemoteObject): number|string|undefined {
Sigurd Schneider45f32c32020-10-13 13:32:05838 if (obj instanceof SDK.RemoteObject.RemoteObject) {
839 if (typeof obj.value !== 'number') {
840 return 'NaN';
841 }
842 return obj.value;
Tim van der Lippe1d6e57a2019-09-30 11:55:34843 }
Sigurd Schneider45f32c32020-10-13 13:32:05844 return undefined;
Blink Reformat4c46d092018-04-07 15:32:37845 }
846
Jan Scheffler19cd7ec2021-02-12 14:16:30847 function integerFormatter(obj?: string|SDK.RemoteObject.RemoteObject): string|number|undefined {
Sigurd Schneider45f32c32020-10-13 13:32:05848 if (obj instanceof SDK.RemoteObject.RemoteObject) {
849 if (obj.type === 'bigint') {
850 return obj.description;
851 }
852 if (typeof obj.value !== 'number') {
853 return 'NaN';
854 }
855 return Math.floor(obj.value);
Tim van der Lippe1d6e57a2019-09-30 11:55:34856 }
Sigurd Schneider45f32c32020-10-13 13:32:05857 return undefined;
Blink Reformat4c46d092018-04-07 15:32:37858 }
859
Jan Scheffler19cd7ec2021-02-12 14:16:30860 function bypassFormatter(obj?: string|SDK.RemoteObject.RemoteObject): Node|string {
Blink Reformat4c46d092018-04-07 15:32:37861 return (obj instanceof Node) ? obj : '';
862 }
863
Jan Scheffler19cd7ec2021-02-12 14:16:30864 let currentStyle: Map<string, {value: string, priority: string}>|null = null;
865 function styleFormatter(obj?: string|SDK.RemoteObject.RemoteObject): void {
Sigurd Schneider45f32c32020-10-13 13:32:05866 currentStyle = new Map();
Sigurd Schneider53f33522020-10-08 15:00:49867 const buffer = document.createElement('span');
Sigurd Schneider45f32c32020-10-13 13:32:05868 if (obj === undefined) {
869 return;
870 }
871 if (typeof obj === 'string' || !obj.description) {
872 return;
873 }
Blink Reformat4c46d092018-04-07 15:32:37874 buffer.setAttribute('style', obj.description);
Sigurd Schneider45f32c32020-10-13 13:32:05875 for (const property of buffer.style) {
Mathias Bynens5165a7a2020-06-10 05:51:43876 if (isAllowedProperty(property)) {
Sigurd Schneider45f32c32020-10-13 13:32:05877 const info = {
878 value: buffer.style.getPropertyValue(property),
Jan Scheffler19cd7ec2021-02-12 14:16:30879 priority: buffer.style.getPropertyPriority(property),
Sigurd Schneider45f32c32020-10-13 13:32:05880 };
881 currentStyle.set(property, info);
Tim van der Lippe1d6e57a2019-09-30 11:55:34882 }
Blink Reformat4c46d092018-04-07 15:32:37883 }
884 }
885
Jan Scheffler19cd7ec2021-02-12 14:16:30886 function isAllowedProperty(property: string): boolean {
Blink Reformat4c46d092018-04-07 15:32:37887 // Make sure that allowed properties do not interfere with link visibility.
888 const prefixes = [
Jan Scheffler19cd7ec2021-02-12 14:16:30889 'background',
890 'border',
891 'color',
892 'font',
893 'line',
894 'margin',
895 'padding',
896 'text',
897 '-webkit-background',
898 '-webkit-border',
899 '-webkit-font',
900 '-webkit-margin',
901 '-webkit-padding',
902 '-webkit-text',
Blink Reformat4c46d092018-04-07 15:32:37903 ];
Sigurd Schneider45f32c32020-10-13 13:32:05904 for (const prefix of prefixes) {
905 if (property.startsWith(prefix)) {
Blink Reformat4c46d092018-04-07 15:32:37906 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:34907 }
Blink Reformat4c46d092018-04-07 15:32:37908 }
909 return false;
910 }
911
Jan Scheffler19cd7ec2021-02-12 14:16:30912 // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
913 // eslint-disable-next-line @typescript-eslint/no-explicit-any
914 const formatters: Record<string, Platform.StringUtilities.FormatterFunction<any>> = {};
Blink Reformat4c46d092018-04-07 15:32:37915 // Firebug uses %o for formatting objects.
916 formatters.o = parameterFormatter.bind(this, false /* force */, true /* includePreview */);
917 formatters.s = stringFormatter;
918 formatters.f = floatFormatter;
919 // Firebug allows both %i and %d for formatting integers.
920 formatters.i = integerFormatter;
921 formatters.d = integerFormatter;
922
923 // Firebug uses %c for styling the message.
924 formatters.c = styleFormatter;
925
926 // Support %O to force object formatting, instead of the type-based %o formatting.
927 formatters.O = parameterFormatter.bind(this, true /* force */, false /* includePreview */);
928
929 formatters._ = bypassFormatter;
930
Jan Scheffler19cd7ec2021-02-12 14:16:30931 function append(this: ConsoleViewMessage, a: HTMLElement, b?: string|Node): HTMLElement {
Blink Reformat4c46d092018-04-07 15:32:37932 if (b instanceof Node) {
933 a.appendChild(b);
Erik Luo17926392018-05-17 22:06:12934 return a;
935 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34936 if (typeof b === 'undefined') {
Erik Luo17926392018-05-17 22:06:12937 return a;
Tim van der Lippe1d6e57a2019-09-30 11:55:34938 }
Erik Luo17926392018-05-17 22:06:12939 if (!currentStyle) {
Erik Luo383f21d2018-11-07 23:16:37940 a.appendChild(this._linkifyStringAsFragment(String(b)));
Erik Luo17926392018-05-17 22:06:12941 return a;
942 }
943 const lines = String(b).split('\n');
944 for (let i = 0; i < lines.length; i++) {
945 const line = lines[i];
Erik Luo383f21d2018-11-07 23:16:37946 const lineFragment = this._linkifyStringAsFragment(line);
Jan Scheffler19cd7ec2021-02-12 14:16:30947 const wrapper = (document.createElement('span') as HTMLElement);
Erik Luo17926392018-05-17 22:06:12948 wrapper.style.setProperty('contain', 'paint');
949 wrapper.style.setProperty('display', 'inline-block');
950 wrapper.style.setProperty('max-width', '100%');
951 wrapper.appendChild(lineFragment);
952 applyCurrentStyle(wrapper);
953 for (const child of wrapper.children) {
Sigurd Schneider53f33522020-10-08 15:00:49954 if (child.classList.contains('devtools-link') && child instanceof HTMLElement) {
Erik Luo17926392018-05-17 22:06:12955 this._applyForcedVisibleStyle(child);
Tim van der Lippe1d6e57a2019-09-30 11:55:34956 }
Blink Reformat4c46d092018-04-07 15:32:37957 }
Erik Luo17926392018-05-17 22:06:12958 a.appendChild(wrapper);
Tim van der Lippe1d6e57a2019-09-30 11:55:34959 if (i < lines.length - 1) {
Sigurd Schneider53f33522020-10-08 15:00:49960 a.appendChild(document.createElement('br'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34961 }
Blink Reformat4c46d092018-04-07 15:32:37962 }
963 return a;
964 }
965
Jan Scheffler19cd7ec2021-02-12 14:16:30966 function applyCurrentStyle(element: HTMLElement): void {
Sigurd Schneider45f32c32020-10-13 13:32:05967 if (!currentStyle) {
968 return;
969 }
970 for (const [property, {value, priority}] of currentStyle.entries()) {
Jan Scheffler19cd7ec2021-02-12 14:16:30971 element.style.setProperty((property as string), value, priority);
Tim van der Lippe1d6e57a2019-09-30 11:55:34972 }
Blink Reformat4c46d092018-04-07 15:32:37973 }
974
Tim van der Lippe93b57c32020-02-20 17:38:44975 // Platform.StringUtilities.format does treat formattedResult like a Builder, result is an object.
976 return Platform.StringUtilities.format(format, parameters, formatters, formattedResult, append.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37977 }
978
Jan Scheffler19cd7ec2021-02-12 14:16:30979 _applyForcedVisibleStyle(element: HTMLElement): void {
Blink Reformat4c46d092018-04-07 15:32:37980 element.style.setProperty('-webkit-text-stroke', '0', 'important');
981 element.style.setProperty('text-decoration', 'underline', 'important');
982
Paul Lewisca569a52020-09-09 16:11:51983 const themedColor = ThemeSupport.ThemeSupport.instance().patchColorText(
984 'rgb(33%, 33%, 33%)', ThemeSupport.ThemeSupport.ColorUsage.Foreground);
Blink Reformat4c46d092018-04-07 15:32:37985 element.style.setProperty('color', themedColor, 'important');
986
987 let backgroundColor = 'hsl(0, 0%, 100%)';
Tim van der Lippe9b2f8712020-02-12 17:46:22988 if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Blink Reformat4c46d092018-04-07 15:32:37989 backgroundColor = 'hsl(0, 100%, 97%)';
Tim van der Lippe9b2f8712020-02-12 17:46:22990 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning || this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:37991 backgroundColor = 'hsl(50, 100%, 95%)';
Tim van der Lippe1d6e57a2019-09-30 11:55:34992 }
Paul Lewisca569a52020-09-09 16:11:51993 const themedBackgroundColor = ThemeSupport.ThemeSupport.instance().patchColorText(
994 backgroundColor, ThemeSupport.ThemeSupport.ColorUsage.Background);
Blink Reformat4c46d092018-04-07 15:32:37995 element.style.setProperty('background-color', themedBackgroundColor, 'important');
996 }
997
Jan Scheffler19cd7ec2021-02-12 14:16:30998 matchesFilterRegex(regexObject: RegExp): boolean {
Blink Reformat4c46d092018-04-07 15:32:37999 regexObject.lastIndex = 0;
Erik Luo5976c8c2018-07-24 02:03:091000 const contentElement = this.contentElement();
1001 const anchorText = this._anchorElement ? this._anchorElement.deepTextContent() : '';
Tim van der Lipped7cfd142021-01-07 12:17:241002 return (Boolean(anchorText) && regexObject.test(anchorText.trim())) ||
Erik Luo5976c8c2018-07-24 02:03:091003 regexObject.test(contentElement.deepTextContent().slice(anchorText.length));
Blink Reformat4c46d092018-04-07 15:32:371004 }
1005
Jan Scheffler19cd7ec2021-02-12 14:16:301006 matchesFilterText(filter: string): boolean {
Blink Reformat4c46d092018-04-07 15:32:371007 const text = this.contentElement().deepTextContent();
1008 return text.toLowerCase().includes(filter.toLowerCase());
1009 }
1010
Jan Scheffler19cd7ec2021-02-12 14:16:301011 updateTimestamp(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341012 if (!this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371013 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341014 }
Blink Reformat4c46d092018-04-07 15:32:371015
Paul Lewis2d7d65c2020-03-16 17:26:301016 if (Common.Settings.Settings.instance().moduleSetting('consoleTimestampsEnabled').get()) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341017 if (!this._timestampElement) {
Jan Scheffler19cd7ec2021-02-12 14:16:301018 this._timestampElement = (document.createElement('span') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:091019 this._timestampElement.classList.add('console-timestamp');
Tim van der Lippe1d6e57a2019-09-30 11:55:341020 }
Tim van der Lippe9b2f8712020-02-12 17:46:221021 this._timestampElement.textContent = UI.UIUtils.formatTimestamp(this._message.timestamp, false) + ' ';
Tim van der Lippe70842f32020-11-23 16:56:571022 UI.Tooltip.Tooltip.install(this._timestampElement, UI.UIUtils.formatTimestamp(this._message.timestamp, true));
Blink Reformat4c46d092018-04-07 15:32:371023 this._contentElement.insertBefore(this._timestampElement, this._contentElement.firstChild);
1024 } else if (this._timestampElement) {
1025 this._timestampElement.remove();
Sigurd Schneider53e98632020-10-26 15:29:501026 this._timestampElement = null;
Blink Reformat4c46d092018-04-07 15:32:371027 }
Blink Reformat4c46d092018-04-07 15:32:371028 }
1029
Jan Scheffler19cd7ec2021-02-12 14:16:301030 nestingLevel(): number {
Blink Reformat4c46d092018-04-07 15:32:371031 return this._nestingLevel;
1032 }
1033
Jan Scheffler19cd7ec2021-02-12 14:16:301034 setInSimilarGroup(inSimilarGroup: boolean, isLast?: boolean): void {
Blink Reformat4c46d092018-04-07 15:32:371035 this._inSimilarGroup = inSimilarGroup;
Tim van der Lipped7cfd142021-01-07 12:17:241036 this._lastInSimilarGroup = inSimilarGroup && Boolean(isLast);
Blink Reformat4c46d092018-04-07 15:32:371037 if (this._similarGroupMarker && !inSimilarGroup) {
1038 this._similarGroupMarker.remove();
1039 this._similarGroupMarker = null;
1040 } else if (this._element && !this._similarGroupMarker && inSimilarGroup) {
Jan Scheffler19cd7ec2021-02-12 14:16:301041 this._similarGroupMarker = (document.createElement('div') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:091042 this._similarGroupMarker.classList.add('nesting-level-marker');
Blink Reformat4c46d092018-04-07 15:32:371043 this._element.insertBefore(this._similarGroupMarker, this._element.firstChild);
1044 this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
1045 }
1046 }
1047
Jan Scheffler19cd7ec2021-02-12 14:16:301048 isLastInSimilarGroup(): boolean {
Tim van der Lipped7cfd142021-01-07 12:17:241049 return Boolean(this._inSimilarGroup) && Boolean(this._lastInSimilarGroup);
Blink Reformat4c46d092018-04-07 15:32:371050 }
1051
Jan Scheffler19cd7ec2021-02-12 14:16:301052 resetCloseGroupDecorationCount(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341053 if (!this._closeGroupDecorationCount) {
Blink Reformat4c46d092018-04-07 15:32:371054 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341055 }
Blink Reformat4c46d092018-04-07 15:32:371056 this._closeGroupDecorationCount = 0;
1057 this._updateCloseGroupDecorations();
1058 }
1059
Jan Scheffler19cd7ec2021-02-12 14:16:301060 incrementCloseGroupDecorationCount(): void {
Blink Reformat4c46d092018-04-07 15:32:371061 ++this._closeGroupDecorationCount;
1062 this._updateCloseGroupDecorations();
1063 }
1064
Jan Scheffler19cd7ec2021-02-12 14:16:301065 _updateCloseGroupDecorations(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341066 if (!this._nestingLevelMarkers) {
Blink Reformat4c46d092018-04-07 15:32:371067 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341068 }
Blink Reformat4c46d092018-04-07 15:32:371069 for (let i = 0, n = this._nestingLevelMarkers.length; i < n; ++i) {
1070 const marker = this._nestingLevelMarkers[i];
1071 marker.classList.toggle('group-closed', n - i <= this._closeGroupDecorationCount);
1072 }
1073 }
1074
Jan Scheffler19cd7ec2021-02-12 14:16:301075 _focusedChildIndex(): number {
Tim van der Lippe1d6e57a2019-09-30 11:55:341076 if (!this._selectableChildren.length) {
Erik Luo0b8282e2018-10-08 20:37:461077 return -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341078 }
Erik Luo383f21d2018-11-07 23:16:371079 return this._selectableChildren.findIndex(child => child.element.hasFocus());
Erik Luo0b8282e2018-10-08 20:37:461080 }
1081
Jan Scheffler19cd7ec2021-02-12 14:16:301082 _onKeyDown(event: KeyboardEvent): void {
Sigurd Schneider45f32c32020-10-13 13:32:051083 if (UI.UIUtils.isEditing() || !this._element || !this._element.hasFocus() || this._element.hasSelection()) {
Erik Luo8ef5d0c2018-09-25 21:16:001084 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341085 }
1086 if (this.maybeHandleOnKeyDown(event)) {
Erik Luo8ef5d0c2018-09-25 21:16:001087 event.consume(true);
Tim van der Lippe1d6e57a2019-09-30 11:55:341088 }
Erik Luo8ef5d0c2018-09-25 21:16:001089 }
1090
Jan Scheffler19cd7ec2021-02-12 14:16:301091 maybeHandleOnKeyDown(event: KeyboardEvent): boolean {
Erik Luo8ef5d0c2018-09-25 21:16:001092 // Handle trace expansion.
Erik Luo0b8282e2018-10-08 20:37:461093 const focusedChildIndex = this._focusedChildIndex();
1094 const isWrapperFocused = focusedChildIndex === -1;
1095 if (this._expandTrace && isWrapperFocused) {
Erik Luo8ef5d0c2018-09-25 21:16:001096 if ((event.key === 'ArrowLeft' && this._traceExpanded) || (event.key === 'ArrowRight' && !this._traceExpanded)) {
1097 this._expandTrace(!this._traceExpanded);
1098 return true;
1099 }
1100 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341101 if (!this._selectableChildren.length) {
Erik Luo0b8282e2018-10-08 20:37:461102 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341103 }
Erik Luo0b8282e2018-10-08 20:37:461104
1105 if (event.key === 'ArrowLeft') {
Sigurd Schneider45f32c32020-10-13 13:32:051106 this._element && this._element.focus();
Erik Luo0b8282e2018-10-08 20:37:461107 return true;
1108 }
1109 if (event.key === 'ArrowRight') {
Tim van der Lippe1d6e57a2019-09-30 11:55:341110 if (isWrapperFocused && this._selectNearestVisibleChild(0)) {
Erik Luo0b8282e2018-10-08 20:37:461111 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341112 }
Erik Luo0b8282e2018-10-08 20:37:461113 }
1114 if (event.key === 'ArrowUp') {
Erik Luo182bece2018-11-29 03:15:221115 const firstVisibleChild = this._nearestVisibleChild(0);
1116 if (this._selectableChildren[focusedChildIndex] === firstVisibleChild && firstVisibleChild) {
Sigurd Schneider45f32c32020-10-13 13:32:051117 this._element && this._element.focus();
Erik Luo0b8282e2018-10-08 20:37:461118 return true;
Mathias Bynensf06e8c02020-02-28 13:58:281119 }
1120 if (this._selectNearestVisibleChild(focusedChildIndex - 1, true /* backwards */)) {
Erik Luo0b8282e2018-10-08 20:37:461121 return true;
1122 }
1123 }
1124 if (event.key === 'ArrowDown') {
Tim van der Lippe1d6e57a2019-09-30 11:55:341125 if (isWrapperFocused && this._selectNearestVisibleChild(0)) {
Erik Luo0b8282e2018-10-08 20:37:461126 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341127 }
1128 if (!isWrapperFocused && this._selectNearestVisibleChild(focusedChildIndex + 1)) {
Erik Luo0b8282e2018-10-08 20:37:461129 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341130 }
Erik Luo0b8282e2018-10-08 20:37:461131 }
Erik Luo8ef5d0c2018-09-25 21:16:001132 return false;
1133 }
1134
Jan Scheffler19cd7ec2021-02-12 14:16:301135 _selectNearestVisibleChild(fromIndex: number, backwards?: boolean): boolean {
Erik Luo182bece2018-11-29 03:15:221136 const nearestChild = this._nearestVisibleChild(fromIndex, backwards);
1137 if (nearestChild) {
Erik Luo31c21f62018-12-13 03:39:391138 nearestChild.forceSelect();
Erik Luo182bece2018-11-29 03:15:221139 return true;
1140 }
1141 return false;
1142 }
1143
Jan Scheffler19cd7ec2021-02-12 14:16:301144 _nearestVisibleChild(fromIndex: number, backwards?: boolean): {
1145 element: Element,
1146 forceSelect: () => void,
1147 }|null {
Erik Luo182bece2018-11-29 03:15:221148 const childCount = this._selectableChildren.length;
Tim van der Lippe1d6e57a2019-09-30 11:55:341149 if (fromIndex < 0 || fromIndex >= childCount) {
Erik Luo182bece2018-11-29 03:15:221150 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341151 }
Erik Luo182bece2018-11-29 03:15:221152 const direction = backwards ? -1 : 1;
1153 let index = fromIndex;
1154
1155 while (!this._selectableChildren[index].element.offsetParent) {
1156 index += direction;
Tim van der Lippe1d6e57a2019-09-30 11:55:341157 if (index < 0 || index >= childCount) {
Erik Luo182bece2018-11-29 03:15:221158 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341159 }
Erik Luo182bece2018-11-29 03:15:221160 }
1161 return this._selectableChildren[index];
1162 }
1163
Jan Scheffler19cd7ec2021-02-12 14:16:301164 focusLastChildOrSelf(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341165 if (this._element && !this._selectNearestVisibleChild(this._selectableChildren.length - 1, true /* backwards */)) {
Erik Luo0b8282e2018-10-08 20:37:461166 this._element.focus();
Tim van der Lippe1d6e57a2019-09-30 11:55:341167 }
Erik Luo0b8282e2018-10-08 20:37:461168 }
1169
Jan Scheffler19cd7ec2021-02-12 14:16:301170 setContentElement(element: HTMLElement): void {
Sigurd Schneiderb2953b22020-10-09 09:30:151171 console.assert(!this._contentElement, 'Cannot set content element twice');
1172 this._contentElement = element;
1173 }
1174
Jan Scheffler19cd7ec2021-02-12 14:16:301175 getContentElement(): HTMLElement|null {
Sigurd Schneiderb2953b22020-10-09 09:30:151176 return this._contentElement;
1177 }
1178
Jan Scheffler19cd7ec2021-02-12 14:16:301179 contentElement(): HTMLElement {
Tim van der Lippe1d6e57a2019-09-30 11:55:341180 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371181 return this._contentElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:341182 }
Blink Reformat4c46d092018-04-07 15:32:371183
Jan Scheffler19cd7ec2021-02-12 14:16:301184 const contentElement = (document.createElement('div') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:091185 contentElement.classList.add('console-message');
Tim van der Lippe1d6e57a2019-09-30 11:55:341186 if (this._messageLevelIcon) {
Blink Reformat4c46d092018-04-07 15:32:371187 contentElement.appendChild(this._messageLevelIcon);
Tim van der Lippe1d6e57a2019-09-30 11:55:341188 }
Blink Reformat4c46d092018-04-07 15:32:371189 this._contentElement = contentElement;
1190
Sigurd Schneider45f32c32020-10-13 13:32:051191 const runtimeModel = this._message.runtimeModel();
Blink Reformat4c46d092018-04-07 15:32:371192 let formattedMessage;
Tim van der Lipped7cfd142021-01-07 12:17:241193 const shouldIncludeTrace = Boolean(this._message.stackTrace) &&
Tim van der Lippe9b2f8712020-02-12 17:46:221194 (this._message.source === SDK.ConsoleModel.MessageSource.Network ||
1195 this._message.source === SDK.ConsoleModel.MessageSource.Violation ||
1196 this._message.level === SDK.ConsoleModel.MessageLevel.Error ||
1197 this._message.level === SDK.ConsoleModel.MessageLevel.Warning ||
1198 this._message.type === SDK.ConsoleModel.MessageType.Trace);
Sigurd Schneider45f32c32020-10-13 13:32:051199 if (runtimeModel && shouldIncludeTrace) {
1200 formattedMessage = this._buildMessageWithStackTrace(runtimeModel);
Tim van der Lippe1d6e57a2019-09-30 11:55:341201 } else {
Blink Reformat4c46d092018-04-07 15:32:371202 formattedMessage = this._buildMessage();
Tim van der Lippe1d6e57a2019-09-30 11:55:341203 }
Blink Reformat4c46d092018-04-07 15:32:371204 contentElement.appendChild(formattedMessage);
1205
1206 this.updateTimestamp();
1207 return this._contentElement;
1208 }
1209
Jan Scheffler19cd7ec2021-02-12 14:16:301210 toMessageElement(): HTMLElement {
Tim van der Lippe1d6e57a2019-09-30 11:55:341211 if (this._element) {
Blink Reformat4c46d092018-04-07 15:32:371212 return this._element;
Tim van der Lippe1d6e57a2019-09-30 11:55:341213 }
Jan Scheffler19cd7ec2021-02-12 14:16:301214 this._element = (document.createElement('div') as HTMLElement);
Pavel Feldmandb310912019-01-30 00:31:201215 this._element.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:301216 this._element.addEventListener('keydown', (this._onKeyDown.bind(this) as EventListener));
Blink Reformat4c46d092018-04-07 15:32:371217 this.updateMessageElement();
1218 return this._element;
1219 }
1220
Jan Scheffler19cd7ec2021-02-12 14:16:301221 updateMessageElement(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341222 if (!this._element) {
Blink Reformat4c46d092018-04-07 15:32:371223 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341224 }
Blink Reformat4c46d092018-04-07 15:32:371225
1226 this._element.className = 'console-message-wrapper';
1227 this._element.removeChildren();
Tim van der Lippe1d6e57a2019-09-30 11:55:341228 if (this._message.isGroupStartMessage()) {
Blink Reformat4c46d092018-04-07 15:32:371229 this._element.classList.add('console-group-title');
Tim van der Lippe1d6e57a2019-09-30 11:55:341230 }
Tim van der Lippe9b2f8712020-02-12 17:46:221231 if (this._message.source === SDK.ConsoleModel.MessageSource.ConsoleAPI) {
Blink Reformat4c46d092018-04-07 15:32:371232 this._element.classList.add('console-from-api');
Tim van der Lippe1d6e57a2019-09-30 11:55:341233 }
Blink Reformat4c46d092018-04-07 15:32:371234 if (this._inSimilarGroup) {
Jan Scheffler19cd7ec2021-02-12 14:16:301235 this._similarGroupMarker = (this._element.createChild('div', 'nesting-level-marker') as HTMLElement);
Blink Reformat4c46d092018-04-07 15:32:371236 this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
1237 }
1238
1239 this._nestingLevelMarkers = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341240 for (let i = 0; i < this._nestingLevel; ++i) {
Blink Reformat4c46d092018-04-07 15:32:371241 this._nestingLevelMarkers.push(this._element.createChild('div', 'nesting-level-marker'));
Tim van der Lippe1d6e57a2019-09-30 11:55:341242 }
Blink Reformat4c46d092018-04-07 15:32:371243 this._updateCloseGroupDecorations();
Sigurd Schneiderca7b4ff2020-10-14 07:45:471244 elementToMessage.set(this._element, this);
Blink Reformat4c46d092018-04-07 15:32:371245
1246 switch (this._message.level) {
Tim van der Lippe9b2f8712020-02-12 17:46:221247 case SDK.ConsoleModel.MessageLevel.Verbose:
Blink Reformat4c46d092018-04-07 15:32:371248 this._element.classList.add('console-verbose-level');
Blink Reformat4c46d092018-04-07 15:32:371249 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221250 case SDK.ConsoleModel.MessageLevel.Info:
Blink Reformat4c46d092018-04-07 15:32:371251 this._element.classList.add('console-info-level');
Tim van der Lippe9b2f8712020-02-12 17:46:221252 if (this._message.type === SDK.ConsoleModel.MessageType.System) {
Blink Reformat4c46d092018-04-07 15:32:371253 this._element.classList.add('console-system-type');
Tim van der Lippe1d6e57a2019-09-30 11:55:341254 }
Blink Reformat4c46d092018-04-07 15:32:371255 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221256 case SDK.ConsoleModel.MessageLevel.Warning:
Blink Reformat4c46d092018-04-07 15:32:371257 this._element.classList.add('console-warning-level');
Blink Reformat4c46d092018-04-07 15:32:371258 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221259 case SDK.ConsoleModel.MessageLevel.Error:
Blink Reformat4c46d092018-04-07 15:32:371260 this._element.classList.add('console-error-level');
Blink Reformat4c46d092018-04-07 15:32:371261 break;
1262 }
Erik Luofd3e7d42018-09-25 02:12:351263 this._updateMessageLevelIcon();
Tim van der Lippe1d6e57a2019-09-30 11:55:341264 if (this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371265 this._element.classList.add('console-warning-level');
Tim van der Lippe1d6e57a2019-09-30 11:55:341266 }
Blink Reformat4c46d092018-04-07 15:32:371267
1268 this._element.appendChild(this.contentElement());
Tim van der Lippe1d6e57a2019-09-30 11:55:341269 if (this._repeatCount > 1) {
Blink Reformat4c46d092018-04-07 15:32:371270 this._showRepeatCountElement();
Tim van der Lippe1d6e57a2019-09-30 11:55:341271 }
Blink Reformat4c46d092018-04-07 15:32:371272 }
1273
Jan Scheffler19cd7ec2021-02-12 14:16:301274 _shouldRenderAsWarning(): boolean {
Tim van der Lippe9b2f8712020-02-12 17:46:221275 return (this._message.level === SDK.ConsoleModel.MessageLevel.Verbose ||
1276 this._message.level === SDK.ConsoleModel.MessageLevel.Info) &&
1277 (this._message.source === SDK.ConsoleModel.MessageSource.Violation ||
1278 this._message.source === SDK.ConsoleModel.MessageSource.Deprecation ||
1279 this._message.source === SDK.ConsoleModel.MessageSource.Intervention ||
1280 this._message.source === SDK.ConsoleModel.MessageSource.Recommendation);
Blink Reformat4c46d092018-04-07 15:32:371281 }
1282
Jan Scheffler19cd7ec2021-02-12 14:16:301283 _updateMessageLevelIcon(): void {
Erik Luofd3e7d42018-09-25 02:12:351284 let iconType = '';
1285 let accessibleName = '';
Tim van der Lippe9b2f8712020-02-12 17:46:221286 if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning) {
Erik Luofd3e7d42018-09-25 02:12:351287 iconType = 'smallicon-warning';
Christy Chen9c6d8982021-02-08 02:28:311288 accessibleName = i18nString(UIStrings.warning);
Tim van der Lippe9b2f8712020-02-12 17:46:221289 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Erik Luofd3e7d42018-09-25 02:12:351290 iconType = 'smallicon-error';
Christy Chen9c6d8982021-02-08 02:28:311291 accessibleName = i18nString(UIStrings.error);
Erik Luofd3e7d42018-09-25 02:12:351292 }
Sigurd Schneider45f32c32020-10-13 13:32:051293 if (!this._messageLevelIcon) {
1294 if (!iconType) {
1295 return;
1296 }
Tim van der Lippe9b2f8712020-02-12 17:46:221297 this._messageLevelIcon = UI.Icon.Icon.create('', 'message-level-icon');
Tim van der Lippe1d6e57a2019-09-30 11:55:341298 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371299 this._contentElement.insertBefore(this._messageLevelIcon, this._contentElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341300 }
Blink Reformat4c46d092018-04-07 15:32:371301 }
1302 this._messageLevelIcon.setIconType(iconType);
Erik Luofd3e7d42018-09-25 02:12:351303 UI.ARIAUtils.setAccessibleName(this._messageLevelIcon, accessibleName);
Blink Reformat4c46d092018-04-07 15:32:371304 }
1305
Jan Scheffler19cd7ec2021-02-12 14:16:301306 repeatCount(): number {
Blink Reformat4c46d092018-04-07 15:32:371307 return this._repeatCount || 1;
1308 }
1309
Jan Scheffler19cd7ec2021-02-12 14:16:301310 resetIncrementRepeatCount(): void {
Blink Reformat4c46d092018-04-07 15:32:371311 this._repeatCount = 1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341312 if (!this._repeatCountElement) {
Blink Reformat4c46d092018-04-07 15:32:371313 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341314 }
Blink Reformat4c46d092018-04-07 15:32:371315
1316 this._repeatCountElement.remove();
Tim van der Lippe1d6e57a2019-09-30 11:55:341317 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371318 this._contentElement.classList.remove('repeated-message');
Tim van der Lippe1d6e57a2019-09-30 11:55:341319 }
Sigurd Schneider53e98632020-10-26 15:29:501320 this._repeatCountElement = null;
Blink Reformat4c46d092018-04-07 15:32:371321 }
1322
Jan Scheffler19cd7ec2021-02-12 14:16:301323 incrementRepeatCount(): void {
Blink Reformat4c46d092018-04-07 15:32:371324 this._repeatCount++;
1325 this._showRepeatCountElement();
1326 }
1327
Jan Scheffler19cd7ec2021-02-12 14:16:301328 setRepeatCount(repeatCount: number): void {
Blink Reformat4c46d092018-04-07 15:32:371329 this._repeatCount = repeatCount;
1330 this._showRepeatCountElement();
1331 }
Jan Scheffler19cd7ec2021-02-12 14:16:301332 _showRepeatCountElement(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341333 if (!this._element) {
Blink Reformat4c46d092018-04-07 15:32:371334 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341335 }
Blink Reformat4c46d092018-04-07 15:32:371336
1337 if (!this._repeatCountElement) {
Sigurd Schneider45f32c32020-10-13 13:32:051338 this._repeatCountElement =
Jan Scheffler19cd7ec2021-02-12 14:16:301339 (document.createElement('span', {is: 'dt-small-bubble'}) as UI.UIUtils.DevToolsSmallBubble);
Tim van der Lippeee954d42020-05-04 10:35:571340 this._repeatCountElement.classList.add('console-message-repeat-count');
Blink Reformat4c46d092018-04-07 15:32:371341 switch (this._message.level) {
Tim van der Lippe9b2f8712020-02-12 17:46:221342 case SDK.ConsoleModel.MessageLevel.Warning:
Blink Reformat4c46d092018-04-07 15:32:371343 this._repeatCountElement.type = 'warning';
1344 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221345 case SDK.ConsoleModel.MessageLevel.Error:
Blink Reformat4c46d092018-04-07 15:32:371346 this._repeatCountElement.type = 'error';
1347 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221348 case SDK.ConsoleModel.MessageLevel.Verbose:
Blink Reformat4c46d092018-04-07 15:32:371349 this._repeatCountElement.type = 'verbose';
1350 break;
1351 default:
1352 this._repeatCountElement.type = 'info';
1353 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341354 if (this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371355 this._repeatCountElement.type = 'warning';
Tim van der Lippe1d6e57a2019-09-30 11:55:341356 }
Blink Reformat4c46d092018-04-07 15:32:371357
1358 this._element.insertBefore(this._repeatCountElement, this._contentElement);
Sigurd Schneider45f32c32020-10-13 13:32:051359 this.contentElement().classList.add('repeated-message');
Blink Reformat4c46d092018-04-07 15:32:371360 }
Sigurd Schneider45f32c32020-10-13 13:32:051361 this._repeatCountElement.textContent = `${this._repeatCount}`;
Peter Marshall2bdcc642021-03-03 10:02:091362
1363 let accessibleName;
Tim van der Lippe9b2f8712020-02-12 17:46:221364 if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning) {
Peter Marshall2bdcc642021-03-03 10:02:091365 accessibleName = i18nString(UIStrings.warningS, {n: this._repeatCount});
Tim van der Lippe9b2f8712020-02-12 17:46:221366 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Peter Marshall2bdcc642021-03-03 10:02:091367 accessibleName = i18nString(UIStrings.errorS, {n: this._repeatCount});
1368 } else {
1369 accessibleName = i18nString(UIStrings.repeatS, {n: this._repeatCount});
Tim van der Lippe1d6e57a2019-09-30 11:55:341370 }
Erik Luofd3e7d42018-09-25 02:12:351371 UI.ARIAUtils.setAccessibleName(this._repeatCountElement, accessibleName);
Blink Reformat4c46d092018-04-07 15:32:371372 }
1373
Jan Scheffler19cd7ec2021-02-12 14:16:301374 get text(): string {
Blink Reformat4c46d092018-04-07 15:32:371375 return this._message.messageText;
1376 }
1377
Jan Scheffler19cd7ec2021-02-12 14:16:301378 toExportString(): string {
Blink Reformat4c46d092018-04-07 15:32:371379 const lines = [];
1380 const nodes = this.contentElement().childTextNodes();
Tim van der Lippe9b2f8712020-02-12 17:46:221381 const messageContent = nodes.map(Components.Linkifier.Linkifier.untruncatedNodeText).join('');
Tim van der Lippe1d6e57a2019-09-30 11:55:341382 for (let i = 0; i < this.repeatCount(); ++i) {
Blink Reformat4c46d092018-04-07 15:32:371383 lines.push(messageContent);
Tim van der Lippe1d6e57a2019-09-30 11:55:341384 }
Blink Reformat4c46d092018-04-07 15:32:371385 return lines.join('\n');
1386 }
1387
Jan Scheffler19cd7ec2021-02-12 14:16:301388 setSearchRegex(regex: RegExp|null): void {
Sigurd Schneidere8e75cf2020-10-13 08:17:521389 if (this._searchHighlightNodeChanges && this._searchHighlightNodeChanges.length) {
1390 UI.UIUtils.revertDomChanges(this._searchHighlightNodeChanges);
Tim van der Lippe1d6e57a2019-09-30 11:55:341391 }
Blink Reformat4c46d092018-04-07 15:32:371392 this._searchRegex = regex;
1393 this._searchHighlightNodes = [];
Sigurd Schneidere8e75cf2020-10-13 08:17:521394 this._searchHighlightNodeChanges = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341395 if (!this._searchRegex) {
Blink Reformat4c46d092018-04-07 15:32:371396 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341397 }
Blink Reformat4c46d092018-04-07 15:32:371398
1399 const text = this.contentElement().deepTextContent();
1400 let match;
1401 this._searchRegex.lastIndex = 0;
1402 const sourceRanges = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341403 while ((match = this._searchRegex.exec(text)) && match[0]) {
Tim van der Lippe9b2f8712020-02-12 17:46:221404 sourceRanges.push(new TextUtils.TextRange.SourceRange(match.index, match[0].length));
Tim van der Lippe1d6e57a2019-09-30 11:55:341405 }
Blink Reformat4c46d092018-04-07 15:32:371406
1407 if (sourceRanges.length) {
1408 this._searchHighlightNodes =
Sigurd Schneidere8e75cf2020-10-13 08:17:521409 UI.UIUtils.highlightSearchResults(this.contentElement(), sourceRanges, this._searchHighlightNodeChanges);
Blink Reformat4c46d092018-04-07 15:32:371410 }
1411 }
1412
Jan Scheffler19cd7ec2021-02-12 14:16:301413 searchRegex(): RegExp|null {
Blink Reformat4c46d092018-04-07 15:32:371414 return this._searchRegex;
1415 }
1416
Jan Scheffler19cd7ec2021-02-12 14:16:301417 searchCount(): number {
Blink Reformat4c46d092018-04-07 15:32:371418 return this._searchHighlightNodes.length;
1419 }
1420
Jan Scheffler19cd7ec2021-02-12 14:16:301421 searchHighlightNode(index: number): Element {
Blink Reformat4c46d092018-04-07 15:32:371422 return this._searchHighlightNodes[index];
1423 }
1424
Jan Scheffler19cd7ec2021-02-12 14:16:301425 _tryFormatAsError(string: string): HTMLElement|null {
1426 function startsWith(prefix: string): boolean {
Blink Reformat4c46d092018-04-07 15:32:371427 return string.startsWith(prefix);
1428 }
1429
Sigurd Schneider45f32c32020-10-13 13:32:051430 const runtimeModel = this._message.runtimeModel();
Sigurd Schneider8d0fe542021-03-17 12:28:291431 // TODO: Consider removing these in favor of a simpler regex.
Mathias Bynensfdcb3012021-03-17 14:07:211432 const errorPrefixes = [
1433 'AggregateError',
1434 'Error',
1435 'EvalError',
1436 'RangeError',
1437 'ReferenceError',
1438 'SyntaxError',
1439 'TypeError',
1440 'URIError',
1441 ];
Sigurd Schneider8d0fe542021-03-17 12:28:291442 if (!runtimeModel || !errorPrefixes.some(startsWith) && !/^[\w.]+Error\b/.test(string)) {
Blink Reformat4c46d092018-04-07 15:32:371443 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341444 }
Sigurd Schneider45f32c32020-10-13 13:32:051445 const debuggerModel = runtimeModel.debuggerModel();
1446 const baseURL = runtimeModel.target().inspectedURL();
Blink Reformat4c46d092018-04-07 15:32:371447
1448 const lines = string.split('\n');
1449 const links = [];
1450 let position = 0;
1451 for (let i = 0; i < lines.length; ++i) {
1452 position += i > 0 ? lines[i - 1].length + 1 : 0;
1453 const isCallFrameLine = /^\s*at\s/.test(lines[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:341454 if (!isCallFrameLine && links.length) {
Blink Reformat4c46d092018-04-07 15:32:371455 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341456 }
Blink Reformat4c46d092018-04-07 15:32:371457
Tim van der Lippe1d6e57a2019-09-30 11:55:341458 if (!isCallFrameLine) {
Blink Reformat4c46d092018-04-07 15:32:371459 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341460 }
Blink Reformat4c46d092018-04-07 15:32:371461
1462 let openBracketIndex = -1;
1463 let closeBracketIndex = -1;
Yang Guo39256bd2019-07-18 06:02:251464 const inBracketsWithLineAndColumn = /\([^\)\(]+:\d+:\d+\)/g;
1465 const inBrackets = /\([^\)\(]+\)/g;
Jan Scheffler19cd7ec2021-02-12 14:16:301466 let lastMatch: RegExpExecArray|null = null;
Yang Guo39256bd2019-07-18 06:02:251467 let currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341468 while ((currentMatch = inBracketsWithLineAndColumn.exec(lines[i]))) {
Yang Guo39256bd2019-07-18 06:02:251469 lastMatch = currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341470 }
Yang Guo39256bd2019-07-18 06:02:251471 if (!lastMatch) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341472 while ((currentMatch = inBrackets.exec(lines[i]))) {
Yang Guo39256bd2019-07-18 06:02:251473 lastMatch = currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341474 }
Yang Guo39256bd2019-07-18 06:02:251475 }
1476 if (lastMatch) {
1477 openBracketIndex = lastMatch.index;
1478 closeBracketIndex = lastMatch.index + lastMatch[0].length - 1;
Blink Reformat4c46d092018-04-07 15:32:371479 }
1480 const hasOpenBracket = openBracketIndex !== -1;
Benedikt Meureraef3b592021-03-17 16:34:401481 let left = hasOpenBracket ? openBracketIndex + 1 : lines[i].indexOf('at') + 3;
1482 if (!hasOpenBracket && lines[i].indexOf('async ') === left) {
1483 left += 6;
1484 }
Blink Reformat4c46d092018-04-07 15:32:371485 const right = hasOpenBracket ? closeBracketIndex : lines[i].length;
1486 const linkCandidate = lines[i].substring(left, right);
Tim van der Lippe9b2f8712020-02-12 17:46:221487 const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(linkCandidate);
Tim van der Lippe1d6e57a2019-09-30 11:55:341488 if (!splitResult) {
Blink Reformat4c46d092018-04-07 15:32:371489 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341490 }
Blink Reformat4c46d092018-04-07 15:32:371491
Tim van der Lippe1d6e57a2019-09-30 11:55:341492 if (splitResult.url === '<anonymous>') {
Blink Reformat4c46d092018-04-07 15:32:371493 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341494 }
Blink Reformat4c46d092018-04-07 15:32:371495 let url = parseOrScriptMatch(splitResult.url);
Tim van der Lippe9b2f8712020-02-12 17:46:221496 if (!url && Common.ParsedURL.ParsedURL.isRelativeURL(splitResult.url)) {
1497 url = parseOrScriptMatch(Common.ParsedURL.ParsedURL.completeURL(baseURL, splitResult.url));
Tim van der Lippe1d6e57a2019-09-30 11:55:341498 }
1499 if (!url) {
Blink Reformat4c46d092018-04-07 15:32:371500 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341501 }
Blink Reformat4c46d092018-04-07 15:32:371502
1503 links.push({
1504 url: url,
1505 positionLeft: position + left,
1506 positionRight: position + right,
1507 lineNumber: splitResult.lineNumber,
Jan Scheffler19cd7ec2021-02-12 14:16:301508 columnNumber: splitResult.columnNumber,
Blink Reformat4c46d092018-04-07 15:32:371509 });
1510 }
1511
Tim van der Lippe1d6e57a2019-09-30 11:55:341512 if (!links.length) {
Blink Reformat4c46d092018-04-07 15:32:371513 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341514 }
Blink Reformat4c46d092018-04-07 15:32:371515
Jan Scheffler19cd7ec2021-02-12 14:16:301516 const formattedResult = document.createElement('span');
Blink Reformat4c46d092018-04-07 15:32:371517 let start = 0;
1518 for (let i = 0; i < links.length; ++i) {
Erik Luo383f21d2018-11-07 23:16:371519 formattedResult.appendChild(this._linkifyStringAsFragment(string.substring(start, links[i].positionLeft)));
Erik Luo182bece2018-11-29 03:15:221520 const scriptLocationLink = this._linkifier.linkifyScriptLocation(
Sigurd Schneider45f32c32020-10-13 13:32:051521 debuggerModel.target(), null, links[i].url, links[i].lineNumber,
1522 {columnNumber: links[i].columnNumber, className: undefined, tabStop: undefined});
Erik Luo182bece2018-11-29 03:15:221523 scriptLocationLink.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:301524 this._selectableChildren.push({element: scriptLocationLink, forceSelect: (): void => scriptLocationLink.focus()});
Erik Luo182bece2018-11-29 03:15:221525 formattedResult.appendChild(scriptLocationLink);
Blink Reformat4c46d092018-04-07 15:32:371526 start = links[i].positionRight;
1527 }
1528
Tim van der Lippe1d6e57a2019-09-30 11:55:341529 if (start !== string.length) {
Erik Luo383f21d2018-11-07 23:16:371530 formattedResult.appendChild(this._linkifyStringAsFragment(string.substring(start)));
Tim van der Lippe1d6e57a2019-09-30 11:55:341531 }
Blink Reformat4c46d092018-04-07 15:32:371532
1533 return formattedResult;
1534
Jan Scheffler19cd7ec2021-02-12 14:16:301535 function parseOrScriptMatch(url: string|null): string|null {
Tim van der Lippe1d6e57a2019-09-30 11:55:341536 if (!url) {
Blink Reformat4c46d092018-04-07 15:32:371537 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341538 }
Tim van der Lippe9b2f8712020-02-12 17:46:221539 const parsedURL = Common.ParsedURL.ParsedURL.fromString(url);
Tim van der Lippe1d6e57a2019-09-30 11:55:341540 if (parsedURL) {
Blink Reformat4c46d092018-04-07 15:32:371541 return parsedURL.url;
Tim van der Lippe1d6e57a2019-09-30 11:55:341542 }
1543 if (debuggerModel.scriptsForSourceURL(url).length) {
Blink Reformat4c46d092018-04-07 15:32:371544 return url;
Tim van der Lippe1d6e57a2019-09-30 11:55:341545 }
Blink Reformat4c46d092018-04-07 15:32:371546 return null;
1547 }
1548 }
1549
Jan Scheffler19cd7ec2021-02-12 14:16:301550 _linkifyWithCustomLinkifier(
1551 string: string, linkifier: (arg0: string, arg1: string, arg2?: number, arg3?: number) => Node): DocumentFragment {
Sigurd Schneider8f4ac862020-10-13 13:30:111552 if (string.length > getMaxTokenizableStringLength()) {
Tim van der Lippe9b2f8712020-02-12 17:46:221553 const propertyValue = new ObjectUI.ObjectPropertiesSection.ExpandableTextPropertyValue(
Sigurd Schneider8f4ac862020-10-13 13:30:111554 document.createElement('span'), string, getLongStringVisibleLength());
Sigurd Schneider45f32c32020-10-13 13:32:051555 const fragment = document.createDocumentFragment();
Connor Moody1a5c0d32019-12-19 07:23:361556 fragment.appendChild(propertyValue.element);
1557 return fragment;
Tim van der Lippe1d6e57a2019-09-30 11:55:341558 }
Sigurd Schneider45f32c32020-10-13 13:32:051559 const container = document.createDocumentFragment();
Tim van der Lippeeaacb722020-01-10 12:16:001560 const tokens = ConsoleViewMessage._tokenizeMessageText(string);
Blink Reformat4c46d092018-04-07 15:32:371561 for (const token of tokens) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341562 if (!token.text) {
Erik Luofc2214f2018-11-21 19:54:581563 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341564 }
Blink Reformat4c46d092018-04-07 15:32:371565 switch (token.type) {
1566 case 'url': {
1567 const realURL = (token.text.startsWith('www.') ? 'http://' + token.text : token.text);
Tim van der Lippe9b2f8712020-02-12 17:46:221568 const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(realURL);
Kim-Anh Tran9e49a452020-02-17 09:46:101569 const sourceURL = Common.ParsedURL.ParsedURL.removeWasmFunctionInfoFromURL(splitResult.url);
Blink Reformat4c46d092018-04-07 15:32:371570 let linkNode;
Tim van der Lippe1d6e57a2019-09-30 11:55:341571 if (splitResult) {
Kim-Anh Tran9e49a452020-02-17 09:46:101572 linkNode = linkifier(token.text, sourceURL, splitResult.lineNumber, splitResult.columnNumber);
Tim van der Lippe1d6e57a2019-09-30 11:55:341573 } else {
Sigurd Schneider45f32c32020-10-13 13:32:051574 linkNode = linkifier(token.text, '');
Tim van der Lippe1d6e57a2019-09-30 11:55:341575 }
Blink Reformat4c46d092018-04-07 15:32:371576 container.appendChild(linkNode);
1577 break;
1578 }
1579 default:
Sigurd Schneider45f32c32020-10-13 13:32:051580 container.appendChild(document.createTextNode(token.text));
Blink Reformat4c46d092018-04-07 15:32:371581 break;
1582 }
1583 }
1584 return container;
1585 }
1586
Jan Scheffler19cd7ec2021-02-12 14:16:301587 _linkifyStringAsFragment(string: string): DocumentFragment {
Erik Luofc2214f2018-11-21 19:54:581588 return this._linkifyWithCustomLinkifier(string, (text, url, lineNumber, columnNumber) => {
Sigurd Schneider45f32c32020-10-13 13:32:051589 const options = {text, lineNumber, columnNumber};
Jan Scheffler19cd7ec2021-02-12 14:16:301590 const linkElement =
1591 Components.Linkifier.Linkifier.linkifyURL(url, (options as Components.Linkifier.LinkifyURLOptions));
Erik Luo383f21d2018-11-07 23:16:371592 linkElement.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:301593 this._selectableChildren.push({element: linkElement, forceSelect: (): void => linkElement.focus()});
Erik Luo383f21d2018-11-07 23:16:371594 return linkElement;
Blink Reformat4c46d092018-04-07 15:32:371595 });
1596 }
1597
Jan Scheffler19cd7ec2021-02-12 14:16:301598 static _tokenizeMessageText(string: string): {
1599 type?: string, text: string,
1600 }[] {
Sigurd Schneider30ac3dd2020-10-13 09:06:391601 const {tokenizerRegexes, tokenizerTypes} = getOrCreateTokenizers();
Sigurd Schneider8f4ac862020-10-13 13:30:111602 if (string.length > getMaxTokenizableStringLength()) {
Blink Reformat4c46d092018-04-07 15:32:371603 return [{text: string, type: undefined}];
Tim van der Lippe1d6e57a2019-09-30 11:55:341604 }
Sigurd Schneider30ac3dd2020-10-13 09:06:391605 const results = TextUtils.TextUtils.Utils.splitStringByRegexes(string, tokenizerRegexes);
1606 return results.map(result => ({text: result.value, type: tokenizerTypes[result.regexIndex]}));
Blink Reformat4c46d092018-04-07 15:32:371607 }
1608
Jan Scheffler19cd7ec2021-02-12 14:16:301609 groupKey(): string {
Tim van der Lippe1d6e57a2019-09-30 11:55:341610 if (!this._groupKey) {
Blink Reformat4c46d092018-04-07 15:32:371611 this._groupKey = this._message.groupCategoryKey() + ':' + this.groupTitle();
Tim van der Lippe1d6e57a2019-09-30 11:55:341612 }
Blink Reformat4c46d092018-04-07 15:32:371613 return this._groupKey;
1614 }
1615
Jan Scheffler19cd7ec2021-02-12 14:16:301616 groupTitle(): string {
Tim van der Lippeeaacb722020-01-10 12:16:001617 const tokens = ConsoleViewMessage._tokenizeMessageText(this._message.messageText);
Blink Reformat4c46d092018-04-07 15:32:371618 const result = tokens.reduce((acc, token) => {
Jan Scheffler19cd7ec2021-02-12 14:16:301619 let text: Common.UIString.LocalizedString|string = token.text;
Tim van der Lippe1d6e57a2019-09-30 11:55:341620 if (token.type === 'url') {
Christy Chen9c6d8982021-02-08 02:28:311621 text = i18nString(UIStrings.url);
Tim van der Lippe1d6e57a2019-09-30 11:55:341622 } else if (token.type === 'time') {
Christy Chen9c6d8982021-02-08 02:28:311623 text = i18nString(UIStrings.tookNms);
Tim van der Lippe1d6e57a2019-09-30 11:55:341624 } else if (token.type === 'event') {
Christy Chen9c6d8982021-02-08 02:28:311625 text = i18nString(UIStrings.someEvent);
Tim van der Lippe1d6e57a2019-09-30 11:55:341626 } else if (token.type === 'milestone') {
Christy Chen9c6d8982021-02-08 02:28:311627 text = i18nString(UIStrings.Mxx);
Tim van der Lippe1d6e57a2019-09-30 11:55:341628 } else if (token.type === 'autofill') {
Christy Chen9c6d8982021-02-08 02:28:311629 text = i18nString(UIStrings.attribute);
Tim van der Lippe1d6e57a2019-09-30 11:55:341630 }
Blink Reformat4c46d092018-04-07 15:32:371631 return acc + text;
1632 }, '');
1633 return result.replace(/[%]o/g, '');
1634 }
Paul Lewisbf7aa3c2019-11-20 17:03:381635}
Blink Reformat4c46d092018-04-07 15:32:371636
Jan Scheffler19cd7ec2021-02-12 14:16:301637let tokenizerRegexes: RegExp[]|null = null;
1638let tokenizerTypes: string[]|null = null;
Sigurd Schneider30ac3dd2020-10-13 09:06:391639
Jan Scheffler19cd7ec2021-02-12 14:16:301640function getOrCreateTokenizers(): {
1641 tokenizerRegexes: Array<RegExp>,
1642 tokenizerTypes: Array<string>,
1643} {
Sigurd Schneider30ac3dd2020-10-13 09:06:391644 if (!tokenizerRegexes || !tokenizerTypes) {
1645 const controlCodes = '\\u0000-\\u0020\\u007f-\\u009f';
1646 const linkStringRegex = new RegExp(
1647 '(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\\/\\/|data:|www\\.)[^\\s' + controlCodes + '"]{2,}[^\\s' + controlCodes +
1648 '"\')}\\],:;.!?]',
1649 'u');
1650 const pathLineRegex = /(?:\/[\w\.-]*)+\:[\d]+/;
1651 const timeRegex = /took [\d]+ms/;
1652 const eventRegex = /'\w+' event/;
1653 const milestoneRegex = /\sM[6-7]\d/;
1654 const autofillRegex = /\(suggested: \"[\w-]+\"\)/;
Jan Scheffler19cd7ec2021-02-12 14:16:301655 const handlers = new Map<RegExp, string>();
Sigurd Schneider30ac3dd2020-10-13 09:06:391656 handlers.set(linkStringRegex, 'url');
1657 handlers.set(pathLineRegex, 'url');
1658 handlers.set(timeRegex, 'time');
1659 handlers.set(eventRegex, 'event');
1660 handlers.set(milestoneRegex, 'milestone');
1661 handlers.set(autofillRegex, 'autofill');
1662 tokenizerRegexes = Array.from(handlers.keys());
1663 tokenizerTypes = Array.from(handlers.values());
1664 return {tokenizerRegexes, tokenizerTypes};
1665 }
1666 return {tokenizerRegexes, tokenizerTypes};
1667}
1668
Paul Lewisbf7aa3c2019-11-20 17:03:381669export class ConsoleGroupViewMessage extends ConsoleViewMessage {
Jan Scheffler19cd7ec2021-02-12 14:16:301670 _collapsed: boolean;
1671 _expandGroupIcon: UI.Icon.Icon|null;
1672 _onToggle: () => void;
1673
1674 constructor(
1675 consoleMessage: SDK.ConsoleModel.ConsoleMessage, linkifier: Components.Linkifier.Linkifier, nestingLevel: number,
1676 onToggle: () => void, onResize: (arg0: Common.EventTarget.EventTargetEvent) => void) {
Blink Reformat4c46d092018-04-07 15:32:371677 console.assert(consoleMessage.isGroupStartMessage());
Tim van der Lippeb45d9a02019-11-05 17:24:411678 super(consoleMessage, linkifier, nestingLevel, onResize);
Tim van der Lippe9b2f8712020-02-12 17:46:221679 this._collapsed = consoleMessage.type === SDK.ConsoleModel.MessageType.StartGroupCollapsed;
Blink Reformat4c46d092018-04-07 15:32:371680 this._expandGroupIcon = null;
Erik Luo8ef5d0c2018-09-25 21:16:001681 this._onToggle = onToggle;
Blink Reformat4c46d092018-04-07 15:32:371682 }
1683
Jan Scheffler19cd7ec2021-02-12 14:16:301684 _setCollapsed(collapsed: boolean): void {
Blink Reformat4c46d092018-04-07 15:32:371685 this._collapsed = collapsed;
Tim van der Lippe1d6e57a2019-09-30 11:55:341686 if (this._expandGroupIcon) {
Blink Reformat4c46d092018-04-07 15:32:371687 this._expandGroupIcon.setIconType(this._collapsed ? 'smallicon-triangle-right' : 'smallicon-triangle-down');
Tim van der Lippe1d6e57a2019-09-30 11:55:341688 }
Erik Luo8ef5d0c2018-09-25 21:16:001689 this._onToggle.call(null);
Blink Reformat4c46d092018-04-07 15:32:371690 }
1691
Jan Scheffler19cd7ec2021-02-12 14:16:301692 collapsed(): boolean {
Blink Reformat4c46d092018-04-07 15:32:371693 return this._collapsed;
1694 }
1695
Jan Scheffler19cd7ec2021-02-12 14:16:301696 maybeHandleOnKeyDown(event: KeyboardEvent): boolean {
Erik Luo0b8282e2018-10-08 20:37:461697 const focusedChildIndex = this._focusedChildIndex();
1698 if (focusedChildIndex === -1) {
1699 if ((event.key === 'ArrowLeft' && !this._collapsed) || (event.key === 'ArrowRight' && this._collapsed)) {
1700 this._setCollapsed(!this._collapsed);
1701 return true;
1702 }
Erik Luo8ef5d0c2018-09-25 21:16:001703 }
1704 return super.maybeHandleOnKeyDown(event);
1705 }
1706
Jan Scheffler19cd7ec2021-02-12 14:16:301707 toMessageElement(): HTMLElement {
1708 let element: HTMLElement|null = this._element || null;
Sigurd Schneider45f32c32020-10-13 13:32:051709 if (!element) {
1710 element = super.toMessageElement();
Erik Luo8ef5d0c2018-09-25 21:16:001711 const iconType = this._collapsed ? 'smallicon-triangle-right' : 'smallicon-triangle-down';
Tim van der Lippe9b2f8712020-02-12 17:46:221712 this._expandGroupIcon = UI.Icon.Icon.create(iconType, 'expand-group-icon');
Erik Luob5bfff42018-09-20 02:52:391713 // Intercept focus to avoid highlight on click.
Sigurd Schneider45f32c32020-10-13 13:32:051714 this.contentElement().tabIndex = -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341715 if (this._repeatCountElement) {
Blink Reformat4c46d092018-04-07 15:32:371716 this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341717 } else {
Sigurd Schneider45f32c32020-10-13 13:32:051718 element.insertBefore(this._expandGroupIcon, this._contentElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:341719 }
Sigurd Schneider45f32c32020-10-13 13:32:051720 element.addEventListener('click', () => this._setCollapsed(!this._collapsed));
Blink Reformat4c46d092018-04-07 15:32:371721 }
Sigurd Schneider45f32c32020-10-13 13:32:051722 return element;
Blink Reformat4c46d092018-04-07 15:32:371723 }
1724
Jan Scheffler19cd7ec2021-02-12 14:16:301725 _showRepeatCountElement(): void {
Blink Reformat4c46d092018-04-07 15:32:371726 super._showRepeatCountElement();
Tim van der Lippe1d6e57a2019-09-30 11:55:341727 if (this._repeatCountElement && this._expandGroupIcon) {
Blink Reformat4c46d092018-04-07 15:32:371728 this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341729 }
Blink Reformat4c46d092018-04-07 15:32:371730 }
Paul Lewisbf7aa3c2019-11-20 17:03:381731}
Blink Reformat4c46d092018-04-07 15:32:371732
Sigurd Schneiderca7b4ff2020-10-14 07:45:471733export class ConsoleCommand extends ConsoleViewMessage {
Jan Scheffler19cd7ec2021-02-12 14:16:301734 _formattedCommand: HTMLElement|null;
1735
1736 constructor(
1737 consoleMessage: SDK.ConsoleModel.ConsoleMessage, linkifier: Components.Linkifier.Linkifier, nestingLevel: number,
1738 onResize: (arg0: Common.EventTarget.EventTargetEvent) => void) {
Sigurd Schneiderca7b4ff2020-10-14 07:45:471739 super(consoleMessage, linkifier, nestingLevel, onResize);
Sigurd Schneiderca7b4ff2020-10-14 07:45:471740 this._formattedCommand = null;
1741 }
1742
Jan Scheffler19cd7ec2021-02-12 14:16:301743 contentElement(): HTMLElement {
Sigurd Schneiderca7b4ff2020-10-14 07:45:471744 const contentElement = this.getContentElement();
1745 if (contentElement) {
1746 return contentElement;
1747 }
Jan Scheffler19cd7ec2021-02-12 14:16:301748 const newContentElement = (document.createElement('div') as HTMLElement);
Sigurd Schneiderca7b4ff2020-10-14 07:45:471749 this.setContentElement(newContentElement);
1750 newContentElement.classList.add('console-user-command');
1751 const icon = UI.Icon.Icon.create('smallicon-user-command', 'command-result-icon');
1752 newContentElement.appendChild(icon);
1753
1754 elementToMessage.set(newContentElement, this);
Jan Scheffler19cd7ec2021-02-12 14:16:301755 this._formattedCommand = (document.createElement('span') as HTMLElement);
Sigurd Schneiderca7b4ff2020-10-14 07:45:471756 this._formattedCommand.classList.add('source-code');
1757 this._formattedCommand.textContent = Platform.StringUtilities.replaceControlCharacters(this.text);
1758 newContentElement.appendChild(this._formattedCommand);
1759
1760 if (this._formattedCommand.textContent.length < MaxLengthToIgnoreHighlighter) {
Andres Olivaresf59e6de2021-02-18 13:10:251761 const javascriptSyntaxHighlighter = new TextEditor.SyntaxHighlighter.SyntaxHighlighter('text/javascript', true);
Sigurd Schneiderca7b4ff2020-10-14 07:45:471762 javascriptSyntaxHighlighter.syntaxHighlightNode(this._formattedCommand).then(this._updateSearch.bind(this));
1763 } else {
1764 this._updateSearch();
1765 }
1766
1767 this.updateTimestamp();
1768 return newContentElement;
1769 }
1770
Jan Scheffler19cd7ec2021-02-12 14:16:301771 _updateSearch(): void {
Sigurd Schneiderca7b4ff2020-10-14 07:45:471772 this.setSearchRegex(this.searchRegex());
1773 }
1774}
1775
1776export class ConsoleCommandResult extends ConsoleViewMessage {
Jan Scheffler19cd7ec2021-02-12 14:16:301777 contentElement(): HTMLElement {
Sigurd Schneiderca7b4ff2020-10-14 07:45:471778 const element = super.contentElement();
1779 if (!element.classList.contains('console-user-command-result')) {
1780 element.classList.add('console-user-command-result');
1781 if (this.consoleMessage().level === SDK.ConsoleModel.MessageLevel.Info) {
1782 const icon = UI.Icon.Icon.create('smallicon-command-result', 'command-result-icon');
1783 element.insertBefore(icon, element.firstChild);
1784 }
1785 }
1786 return element;
1787 }
1788}
1789
Sigurd Schneider8bfb4212020-10-27 10:27:371790export class ConsoleTableMessageView extends ConsoleViewMessage {
Jan Scheffler19cd7ec2021-02-12 14:16:301791 _dataGrid: DataGrid.SortableDataGrid.SortableDataGrid<unknown>|null;
1792
1793 constructor(
1794 consoleMessage: SDK.ConsoleModel.ConsoleMessage, linkifier: Components.Linkifier.Linkifier, nestingLevel: number,
1795 onResize: (arg0: Common.EventTarget.EventTargetEvent) => void) {
Sigurd Schneider8bfb4212020-10-27 10:27:371796 super(consoleMessage, linkifier, nestingLevel, onResize);
1797 console.assert(consoleMessage.type === SDK.ConsoleModel.MessageType.Table);
Sigurd Schneider8bfb4212020-10-27 10:27:371798 this._dataGrid = null;
1799 }
1800
Jan Scheffler19cd7ec2021-02-12 14:16:301801 wasShown(): void {
Sigurd Schneider8bfb4212020-10-27 10:27:371802 if (this._dataGrid) {
1803 this._dataGrid.updateWidths();
1804 }
1805 super.wasShown();
1806 }
1807
Jan Scheffler19cd7ec2021-02-12 14:16:301808 onResize(): void {
Sigurd Schneider8bfb4212020-10-27 10:27:371809 if (!this.isVisible()) {
1810 return;
1811 }
1812 if (this._dataGrid) {
1813 this._dataGrid.onResize();
1814 }
1815 }
1816
Jan Scheffler19cd7ec2021-02-12 14:16:301817 contentElement(): HTMLElement {
Sigurd Schneider8bfb4212020-10-27 10:27:371818 const contentElement = this.getContentElement();
1819 if (contentElement) {
1820 return contentElement;
1821 }
1822
Jan Scheffler19cd7ec2021-02-12 14:16:301823 const newContentElement = (document.createElement('div') as HTMLElement);
Sigurd Schneider8bfb4212020-10-27 10:27:371824 newContentElement.classList.add('console-message');
1825 if (this._messageLevelIcon) {
1826 newContentElement.appendChild(this._messageLevelIcon);
1827 }
1828 this.setContentElement(newContentElement);
1829
1830 newContentElement.appendChild(this._buildTableMessage());
1831 this.updateTimestamp();
1832 return newContentElement;
1833 }
1834
Jan Scheffler19cd7ec2021-02-12 14:16:301835 _buildTableMessage(): HTMLElement {
1836 const formattedMessage = (document.createElement('span') as HTMLElement);
Sigurd Schneider8bfb4212020-10-27 10:27:371837 formattedMessage.classList.add('source-code');
1838 this._anchorElement = this._buildMessageAnchor();
1839 if (this._anchorElement) {
1840 formattedMessage.appendChild(this._anchorElement);
1841 }
1842
1843 const table = this._message.parameters && this._message.parameters.length ? this._message.parameters[0] : null;
1844 if (!table) {
1845 return this._buildMessage();
1846 }
1847 const actualTable = parameterToRemoteObject(this._message.runtimeModel())(table);
1848 if (!actualTable || !actualTable.preview) {
1849 return this._buildMessage();
1850 }
1851
1852 const rawValueColumnSymbol = Symbol('rawValueColumn');
Jan Scheffler19cd7ec2021-02-12 14:16:301853 const columnNames: (string|symbol)[] = [];
Sigurd Schneider8bfb4212020-10-27 10:27:371854 const preview = actualTable.preview;
1855 const rows = [];
1856 for (let i = 0; i < preview.properties.length; ++i) {
1857 const rowProperty = preview.properties[i];
Jan Scheffler19cd7ec2021-02-12 14:16:301858 let rowSubProperties: Protocol.Runtime.PropertyPreview[];
Sigurd Schneiderb393a432020-11-06 12:08:211859 if (rowProperty.valuePreview && rowProperty.valuePreview.properties.length) {
Sigurd Schneider8bfb4212020-10-27 10:27:371860 rowSubProperties = rowProperty.valuePreview.properties;
1861 } else if (rowProperty.value) {
Jan Scheffler19cd7ec2021-02-12 14:16:301862 rowSubProperties =
1863 [{name: rawValueColumnSymbol as unknown as string, type: rowProperty.type, value: rowProperty.value}];
Sigurd Schneider8bfb4212020-10-27 10:27:371864 } else {
1865 continue;
1866 }
1867
Jan Scheffler19cd7ec2021-02-12 14:16:301868 const rowValue = new Map<string|symbol, HTMLElement>();
Sigurd Schneider8bfb4212020-10-27 10:27:371869 const maxColumnsToRender = 20;
1870 for (let j = 0; j < rowSubProperties.length; ++j) {
1871 const cellProperty = rowSubProperties[j];
Jan Scheffler19cd7ec2021-02-12 14:16:301872 let columnRendered: true|boolean = columnNames.indexOf(cellProperty.name) !== -1;
Sigurd Schneider8bfb4212020-10-27 10:27:371873 if (!columnRendered) {
1874 if (columnNames.length === maxColumnsToRender) {
1875 continue;
1876 }
1877 columnRendered = true;
1878 columnNames.push(cellProperty.name);
1879 }
1880
1881 if (columnRendered) {
1882 const cellElement =
1883 this._renderPropertyPreviewOrAccessor(actualTable, cellProperty, [rowProperty, cellProperty]);
1884 cellElement.classList.add('console-message-nowrap-below');
1885 rowValue.set(cellProperty.name, cellElement);
1886 }
1887 }
1888 rows.push({rowName: rowProperty.name, rowValue});
1889 }
1890
1891 const flatValues = [];
1892 for (const {rowName, rowValue} of rows) {
1893 flatValues.push(rowName);
1894 for (let j = 0; j < columnNames.length; ++j) {
1895 flatValues.push(rowValue.get(columnNames[j]));
1896 }
1897 }
Christy Chen9c6d8982021-02-08 02:28:311898 columnNames.unshift(i18nString(UIStrings.index));
Sigurd Schneider8bfb4212020-10-27 10:27:371899 const columnDisplayNames =
Christy Chen9c6d8982021-02-08 02:28:311900 columnNames.map(name => name === rawValueColumnSymbol ? i18nString(UIStrings.value) : name.toString());
Sigurd Schneider8bfb4212020-10-27 10:27:371901
1902 if (flatValues.length) {
Christy Chen9c6d8982021-02-08 02:28:311903 this._dataGrid = DataGrid.SortableDataGrid.SortableDataGrid.create(
1904 columnDisplayNames, flatValues, i18nString(UIStrings.console));
Sigurd Schneider8bfb4212020-10-27 10:27:371905 if (this._dataGrid) {
1906 this._dataGrid.setStriped(true);
1907 this._dataGrid.setFocusable(false);
1908
1909 const formattedResult = document.createElement('span');
1910 formattedResult.classList.add('console-message-text');
1911 const tableElement = formattedResult.createChild('div', 'console-message-formatted-table');
1912 const dataGridContainer = tableElement.createChild('span');
1913 tableElement.appendChild(this._formatParameter(actualTable, true, false));
1914 dataGridContainer.appendChild(this._dataGrid.element);
1915 formattedMessage.appendChild(formattedResult);
1916 this._dataGrid.renderInline();
1917 }
1918 }
1919 return formattedMessage;
1920 }
1921
Jan Scheffler19cd7ec2021-02-12 14:16:301922 approximateFastHeight(): number {
Sigurd Schneider8bfb4212020-10-27 10:27:371923 const table = this._message.parameters && this._message.parameters[0];
1924 if (table && typeof table !== 'string' && table.preview) {
1925 return defaultConsoleRowHeight * table.preview.properties.length;
1926 }
1927 return defaultConsoleRowHeight;
1928 }
1929}
1930
Sigurd Schneiderca7b4ff2020-10-14 07:45:471931/**
1932 * The maximum length before strings are considered too long for syntax highlighting.
1933 * @const
Sigurd Schneiderca7b4ff2020-10-14 07:45:471934 */
Jan Scheffler19cd7ec2021-02-12 14:16:301935const MaxLengthToIgnoreHighlighter: number = 10000;
Sigurd Schneiderca7b4ff2020-10-14 07:45:471936
Blink Reformat4c46d092018-04-07 15:32:371937/**
1938 * @const
Blink Reformat4c46d092018-04-07 15:32:371939 */
Jan Scheffler19cd7ec2021-02-12 14:16:301940export const MaxLengthForLinks: number = 40;
Blink Reformat4c46d092018-04-07 15:32:371941
Sigurd Schneider17c74452021-02-15 12:14:101942let maxTokenizableStringLength = 10000;
1943let longStringVisibleLength = 5000;
Sigurd Schneider8f4ac862020-10-13 13:30:111944
Jan Scheffler19cd7ec2021-02-12 14:16:301945export const getMaxTokenizableStringLength = (): number => {
Sigurd Schneider17c74452021-02-15 12:14:101946 return maxTokenizableStringLength;
Sigurd Schneider8f4ac862020-10-13 13:30:111947};
1948
Jan Scheffler19cd7ec2021-02-12 14:16:301949export const setMaxTokenizableStringLength = (length: number): void => {
Sigurd Schneider17c74452021-02-15 12:14:101950 maxTokenizableStringLength = length;
Sigurd Schneider8f4ac862020-10-13 13:30:111951};
1952
Jan Scheffler19cd7ec2021-02-12 14:16:301953export const getLongStringVisibleLength = (): number => {
Sigurd Schneider17c74452021-02-15 12:14:101954 return longStringVisibleLength;
Sigurd Schneider8f4ac862020-10-13 13:30:111955};
1956
Jan Scheffler19cd7ec2021-02-12 14:16:301957export const setLongStringVisibleLength = (length: number): void => {
Sigurd Schneider17c74452021-02-15 12:14:101958 longStringVisibleLength = length;
Sigurd Schneider8f4ac862020-10-13 13:30:111959};