blob: ee9958f40b69c43a45dc0d49c01e297405f67d3b [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 Lippe9b2f8712020-02-12 17:46:2237import * as Common from '../common/common.js';
38import * as Components from '../components/components.js';
39import * as DataGrid from '../data_grid/data_grid.js';
Christy Chen9c6d8982021-02-08 02:28:3140import * as i18n from '../i18n/i18n.js';
Tim van der Lippe9b2f8712020-02-12 17:46:2241import * as ObjectUI from '../object_ui/object_ui.js';
Tim van der Lippe93b57c32020-02-20 17:38:4442import * as Platform from '../platform/platform.js';
Tim van der Lippe9b2f8712020-02-12 17:46:2243import * as SDK from '../sdk/sdk.js';
44import * as TextUtils from '../text_utils/text_utils.js';
Paul Lewisca569a52020-09-09 16:11:5145import * as ThemeSupport from '../theme_support/theme_support.js';
Tim van der Lippe9b2f8712020-02-12 17:46:2246import * as UI from '../ui/ui.js';
47
Tim van der Lippeeaacb722020-01-10 12:16:0048import {ConsoleViewportElement} from './ConsoleViewport.js'; // eslint-disable-line no-unused-vars
49
Christy Chen9c6d8982021-02-08 02:28:3150export const UIStrings = {
51 /**
52 *@description Message element text content in Console View Message of the Console panel
53 */
54 consoleclearWasPreventedDueTo: '`console.clear()` was prevented due to \'Preserve log\'',
55 /**
56 *@description Message element text content in Console View Message of the Console panel
57 */
58 consoleWasCleared: 'Console was cleared',
59 /**
60 *@description Message element title in Console View Message of the Console panel
61 *@example {Ctrl+L} PH1
62 */
63 clearAllMessagesWithS: 'Clear all messages with {PH1}',
64 /**
65 *@description Message prefix in Console View Message of the Console panel
66 */
67 assertionFailed: 'Assertion failed: ',
68 /**
69 *@description Message text in Console View Message of the Console panel
70 *@example {console.log(1)} PH1
71 */
72 violationS: '[Violation] {PH1}',
73 /**
74 *@description Message text in Console View Message of the Console panel
75 *@example {console.log(1)} PH1
76 */
77 interventionS: '[Intervention] {PH1}',
78 /**
79 *@description Message text in Console View Message of the Console panel
80 *@example {console.log(1)} PH1
81 */
82 deprecationS: '[Deprecation] {PH1}',
83 /**
84 *@description Note title in Console View Message of the Console panel
85 */
86 thisValueWillNotBeCollectedUntil: 'This value will not be collected until console is cleared.',
87 /**
88 *@description Note title in Console View Message of the Console panel
89 */
90 thisValueWasEvaluatedUponFirst: 'This value was evaluated upon first expanding. It may have changed since then.',
91 /**
92 *@description Note title in Console View Message of the Console panel
93 */
94 functionWasResolvedFromBound: 'Function was resolved from bound function.',
95 /**
96 *@description Element text content in Console View Message of the Console panel
97 */
98 exception: '<exception>',
99 /**
100 *@description Text to indicate an item is a warning
101 */
102 warning: 'Warning',
103 /**
104 *@description Text for errors
105 */
106 error: 'Error',
107 /**
Tim van der Lippee4b96c62021-02-17 12:43:16108 *@description Tooltip text for how often this particular console message was reported
Christy Chen9c6d8982021-02-08 02:28:31109 *@example {3} PH1
110 */
111 repeatS: 'Repeat {PH1}',
112 /**
113 *@description Accessible name in Console View Message of the Console panel
114 *@example {Repeat 4} PH1
115 */
116 warningS: 'Warning {PH1}',
117 /**
118 *@description Accessible name in Console View Message of the Console panel
119 *@example {Repeat 4} PH1
120 */
121 errorS: 'Error {PH1}',
122 /**
Tim van der Lippee4b96c62021-02-17 12:43:16123 *@description Text appended to grouped console messages that are related to URL requests
Christy Chen9c6d8982021-02-08 02:28:31124 */
125 url: '<URL>',
126 /**
Tim van der Lippee4b96c62021-02-17 12:43:16127 *@description Text appended to grouped console messages about tasks that took longer than N ms
Christy Chen9c6d8982021-02-08 02:28:31128 */
129 tookNms: 'took <N>ms',
130 /**
Tim van der Lippee4b96c62021-02-17 12:43:16131 *@description Text appended to grouped console messages about tasks that are related to some DOM event
Christy Chen9c6d8982021-02-08 02:28:31132 */
133 someEvent: '<some> event',
134 /**
Tim van der Lippee4b96c62021-02-17 12:43:16135 *@description Text appended to grouped console messages about tasks that are related to a particular milestone
Christy Chen9c6d8982021-02-08 02:28:31136 */
137 Mxx: ' M<XX>',
138 /**
Tim van der Lippee4b96c62021-02-17 12:43:16139 *@description Text appended to grouped console messages about tasks that are related to autofill completions
Christy Chen9c6d8982021-02-08 02:28:31140 */
141 attribute: '<attribute>',
142 /**
143 *@description Text for the index of something
144 */
145 index: '(index)',
146 /**
147 *@description Text for the value of something
148 */
149 value: 'Value',
150 /**
151 *@description Title of the Console tool
152 */
153 console: 'Console',
154};
Jan Scheffler19cd7ec2021-02-12 14:16:30155const str_ = i18n.i18n.registerUIStrings('console/ConsoleViewMessage.ts', UIStrings);
Christy Chen9c6d8982021-02-08 02:28:31156const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
Jan Scheffler19cd7ec2021-02-12 14:16:30157const elementToMessage = new WeakMap<Element, ConsoleViewMessage>();
Sigurd Schneiderca7b4ff2020-10-14 07:45:47158
Jan Scheffler19cd7ec2021-02-12 14:16:30159export const getMessageForElement = (element: Element): ConsoleViewMessage|undefined => {
Sigurd Schneiderca7b4ff2020-10-14 07:45:47160 return elementToMessage.get(element);
161};
162
Sigurd Schneider8bfb4212020-10-27 10:27:37163// This value reflects the 18px min-height of .console-message, plus the
164// 1px border of .console-message-wrapper. Keep in sync with consoleView.css.
165const defaultConsoleRowHeight = 19;
166
Jan Scheffler19cd7ec2021-02-12 14:16:30167const parameterToRemoteObject = (runtimeModel: SDK.RuntimeModel.RuntimeModel|null): (
168 parameter?: SDK.RemoteObject.RemoteObject|Protocol.Runtime.RemoteObject|string) => SDK.RemoteObject.RemoteObject =>
169 (parameter?: string|SDK.RemoteObject.RemoteObject|Protocol.Runtime.RemoteObject): SDK.RemoteObject.RemoteObject => {
Sigurd Schneider8bfb4212020-10-27 10:27:37170 if (parameter instanceof SDK.RemoteObject.RemoteObject) {
171 return parameter;
172 }
173 if (!runtimeModel) {
174 return SDK.RemoteObject.RemoteObject.fromLocalObject(parameter);
175 }
176 if (typeof parameter === 'object') {
177 return runtimeModel.createRemoteObject(parameter);
178 }
179 return runtimeModel.createRemoteObjectFromPrimitiveValue(parameter);
180 };
181
Jan Scheffler19cd7ec2021-02-12 14:16:30182export class ConsoleViewMessage implements ConsoleViewportElement {
183 _message: SDK.ConsoleModel.ConsoleMessage;
184 _linkifier: Components.Linkifier.Linkifier;
185 _repeatCount: number;
186 _closeGroupDecorationCount: number;
187 _nestingLevel: number;
188 _selectableChildren: {
189 element: HTMLElement,
190 forceSelect: () => void,
191 }[];
192 _messageResized: (arg0: Common.EventTarget.EventTargetEvent) => void;
193 _element: HTMLElement|null;
194 _previewFormatter: ObjectUI.RemoteObjectPreviewFormatter.RemoteObjectPreviewFormatter;
195 _searchRegex: RegExp|null;
196 _messageLevelIcon: UI.Icon.Icon|null;
197 _traceExpanded: boolean;
198 _expandTrace: ((arg0: boolean) => void)|null;
199 _anchorElement: HTMLElement|null;
200 _contentElement: HTMLElement|null;
201 _nestingLevelMarkers: HTMLElement[]|null;
202 _searchHighlightNodes: Element[];
203 _searchHighlightNodeChanges: UI.UIUtils.HighlightChange[];
204 _isVisible: boolean;
205 _cachedHeight: number;
206 _messagePrefix: string;
207 _timestampElement: HTMLElement|null;
208 _inSimilarGroup: boolean;
209 _similarGroupMarker: HTMLElement|null;
210 _lastInSimilarGroup: boolean;
211 _groupKey: string;
212 _repeatCountElement: UI.UIUtils.DevToolsSmallBubble|null;
213
214 constructor(
215 consoleMessage: SDK.ConsoleModel.ConsoleMessage, linkifier: Components.Linkifier.Linkifier, nestingLevel: number,
216 onResize: (arg0: Common.EventTarget.EventTargetEvent) => void) {
Blink Reformat4c46d092018-04-07 15:32:37217 this._message = consoleMessage;
218 this._linkifier = linkifier;
Blink Reformat4c46d092018-04-07 15:32:37219 this._repeatCount = 1;
220 this._closeGroupDecorationCount = 0;
221 this._nestingLevel = nestingLevel;
Erik Luo383f21d2018-11-07 23:16:37222 this._selectableChildren = [];
Erik Luo840be6b2018-12-03 20:54:27223 this._messageResized = onResize;
Sigurd Schneider53e98632020-10-26 15:29:50224 this._element = null;
Blink Reformat4c46d092018-04-07 15:32:37225
Tim van der Lippe9b2f8712020-02-12 17:46:22226 this._previewFormatter = new ObjectUI.RemoteObjectPreviewFormatter.RemoteObjectPreviewFormatter();
Blink Reformat4c46d092018-04-07 15:32:37227 this._searchRegex = null;
Blink Reformat4c46d092018-04-07 15:32:37228 this._messageLevelIcon = null;
Erik Luo8ef5d0c2018-09-25 21:16:00229 this._traceExpanded = false;
Erik Luo8ef5d0c2018-09-25 21:16:00230 this._expandTrace = null;
John Emaubb2897a2019-10-04 17:37:32231 this._anchorElement = null;
Sigurd Schneider45f32c32020-10-13 13:32:05232 this._contentElement = null;
Sigurd Schneider45f32c32020-10-13 13:32:05233 this._nestingLevelMarkers = null;
Sigurd Schneider45f32c32020-10-13 13:32:05234 this._searchHighlightNodes = [];
Sigurd Schneidere8e75cf2020-10-13 08:17:52235 this._searchHighlightNodeChanges = [];
Sigurd Schneider53e98632020-10-26 15:29:50236 this._isVisible = false;
237 this._cachedHeight = 0;
238 this._messagePrefix = '';
Sigurd Schneider53e98632020-10-26 15:29:50239 this._timestampElement = null;
240 this._inSimilarGroup = false;
Sigurd Schneider53e98632020-10-26 15:29:50241 this._similarGroupMarker = null;
242 this._lastInSimilarGroup = false;
243 this._groupKey = '';
Sigurd Schneider53e98632020-10-26 15:29:50244 this._repeatCountElement = null;
Blink Reformat4c46d092018-04-07 15:32:37245 }
246
Jan Scheffler19cd7ec2021-02-12 14:16:30247 element(): HTMLElement {
Blink Reformat4c46d092018-04-07 15:32:37248 return this.toMessageElement();
249 }
250
Jan Scheffler19cd7ec2021-02-12 14:16:30251 wasShown(): void {
Blink Reformat4c46d092018-04-07 15:32:37252 this._isVisible = true;
253 }
254
Jan Scheffler19cd7ec2021-02-12 14:16:30255 onResize(): void {
Blink Reformat4c46d092018-04-07 15:32:37256 }
257
Jan Scheffler19cd7ec2021-02-12 14:16:30258 willHide(): void {
Blink Reformat4c46d092018-04-07 15:32:37259 this._isVisible = false;
Erik Luo4b002322018-07-30 21:23:31260 this._cachedHeight = this.element().offsetHeight;
Blink Reformat4c46d092018-04-07 15:32:37261 }
262
Jan Scheffler19cd7ec2021-02-12 14:16:30263 isVisible(): boolean {
Sigurd Schneider8bfb4212020-10-27 10:27:37264 return this._isVisible;
265 }
266
Jan Scheffler19cd7ec2021-02-12 14:16:30267 fastHeight(): number {
Tim van der Lippe1d6e57a2019-09-30 11:55:34268 if (this._cachedHeight) {
Blink Reformat4c46d092018-04-07 15:32:37269 return this._cachedHeight;
Tim van der Lippe1d6e57a2019-09-30 11:55:34270 }
Sigurd Schneider8bfb4212020-10-27 10:27:37271 return this.approximateFastHeight();
272 }
273
Jan Scheffler19cd7ec2021-02-12 14:16:30274 approximateFastHeight(): number {
Blink Reformat4c46d092018-04-07 15:32:37275 return defaultConsoleRowHeight;
276 }
277
Jan Scheffler19cd7ec2021-02-12 14:16:30278 consoleMessage(): SDK.ConsoleModel.ConsoleMessage {
Blink Reformat4c46d092018-04-07 15:32:37279 return this._message;
280 }
281
Jan Scheffler19cd7ec2021-02-12 14:16:30282 _buildMessage(): HTMLElement {
Blink Reformat4c46d092018-04-07 15:32:37283 let messageElement;
Jan Scheffler19cd7ec2021-02-12 14:16:30284 let messageText: Common.UIString.LocalizedString|string = this._message.messageText;
Tim van der Lippe9b2f8712020-02-12 17:46:22285 if (this._message.source === SDK.ConsoleModel.MessageSource.ConsoleAPI) {
Blink Reformat4c46d092018-04-07 15:32:37286 switch (this._message.type) {
Tim van der Lippe9b2f8712020-02-12 17:46:22287 case SDK.ConsoleModel.MessageType.Trace:
Blink Reformat4c46d092018-04-07 15:32:37288 messageElement = this._format(this._message.parameters || ['console.trace']);
289 break;
Tim van der Lippe9b2f8712020-02-12 17:46:22290 case SDK.ConsoleModel.MessageType.Clear:
Tim van der Lippef49e2322020-05-01 15:03:09291 messageElement = document.createElement('span');
292 messageElement.classList.add('console-info');
Paul Lewis2d7d65c2020-03-16 17:26:30293 if (Common.Settings.Settings.instance().moduleSetting('preserveConsoleLog').get()) {
Christy Chen9c6d8982021-02-08 02:28:31294 messageElement.textContent = i18nString(UIStrings.consoleclearWasPreventedDueTo);
Tim van der Lippe1d6e57a2019-09-30 11:55:34295 } else {
Christy Chen9c6d8982021-02-08 02:28:31296 messageElement.textContent = i18nString(UIStrings.consoleWasCleared);
Tim van der Lippe1d6e57a2019-09-30 11:55:34297 }
Tim van der Lippe420e5e32020-11-23 16:58:46298 UI.Tooltip.Tooltip.install(
Christy Chen9c6d8982021-02-08 02:28:31299 messageElement, i18nString(UIStrings.clearAllMessagesWithS, {
Jan Scheffler19cd7ec2021-02-12 14:16:30300 PH1: UI.ShortcutRegistry.ShortcutRegistry.instance().shortcutTitleForAction('console.clear'),
Christy Chen9c6d8982021-02-08 02:28:31301 }));
Blink Reformat4c46d092018-04-07 15:32:37302 break;
Tim van der Lippe9b2f8712020-02-12 17:46:22303 case SDK.ConsoleModel.MessageType.Dir: {
Blink Reformat4c46d092018-04-07 15:32:37304 const obj = this._message.parameters ? this._message.parameters[0] : undefined;
305 const args = ['%O', obj];
306 messageElement = this._format(args);
307 break;
308 }
Tim van der Lippe9b2f8712020-02-12 17:46:22309 case SDK.ConsoleModel.MessageType.Profile:
310 case SDK.ConsoleModel.MessageType.ProfileEnd:
Blink Reformat4c46d092018-04-07 15:32:37311 messageElement = this._format([messageText]);
312 break;
313 default: {
Sigurd Schneider45f32c32020-10-13 13:32:05314 if (this._message.type === SDK.ConsoleModel.MessageType.Assert) {
Christy Chen9c6d8982021-02-08 02:28:31315 this._messagePrefix = i18nString(UIStrings.assertionFailed);
Sigurd Schneider45f32c32020-10-13 13:32:05316 }
317 if (this._message.parameters && this._message.parameters.length === 1) {
318 const parameter = this._message.parameters[0];
319 if (typeof parameter !== 'string' && parameter.type === 'string') {
Jan Scheffler19cd7ec2021-02-12 14:16:30320 messageElement = this._tryFormatAsError((parameter.value as string));
Sigurd Schneider45f32c32020-10-13 13:32:05321 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34322 }
Blink Reformat4c46d092018-04-07 15:32:37323 const args = this._message.parameters || [messageText];
324 messageElement = messageElement || this._format(args);
325 }
326 }
327 } else {
Tim van der Lippe9b2f8712020-02-12 17:46:22328 if (this._message.source === SDK.ConsoleModel.MessageSource.Network) {
Erik Luofc2214f2018-11-21 19:54:58329 messageElement = this._formatAsNetworkRequest() || this._format([messageText]);
330 } else {
Jan Scheffler19cd7ec2021-02-12 14:16:30331 const messageInParameters = this._message.parameters && messageText === (this._message.parameters[0] as string);
Tim van der Lippe9b2f8712020-02-12 17:46:22332 if (this._message.source === SDK.ConsoleModel.MessageSource.Violation) {
Christy Chen9c6d8982021-02-08 02:28:31333 messageText = i18nString(UIStrings.violationS, {PH1: messageText});
Tim van der Lippe9b2f8712020-02-12 17:46:22334 } else if (this._message.source === SDK.ConsoleModel.MessageSource.Intervention) {
Christy Chen9c6d8982021-02-08 02:28:31335 messageText = i18nString(UIStrings.interventionS, {PH1: messageText});
Tim van der Lippe9b2f8712020-02-12 17:46:22336 } else if (this._message.source === SDK.ConsoleModel.MessageSource.Deprecation) {
Christy Chen9c6d8982021-02-08 02:28:31337 messageText = i18nString(UIStrings.deprecationS, {PH1: messageText});
Tim van der Lippe1d6e57a2019-09-30 11:55:34338 }
Blink Reformat4c46d092018-04-07 15:32:37339 const args = this._message.parameters || [messageText];
Tim van der Lippe1d6e57a2019-09-30 11:55:34340 if (messageInParameters) {
Blink Reformat4c46d092018-04-07 15:32:37341 args[0] = messageText;
Tim van der Lippe1d6e57a2019-09-30 11:55:34342 }
Blink Reformat4c46d092018-04-07 15:32:37343 messageElement = this._format(args);
344 }
345 }
346 messageElement.classList.add('console-message-text');
347
Jan Scheffler19cd7ec2021-02-12 14:16:30348 const formattedMessage = (document.createElement('span') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:09349 formattedMessage.classList.add('source-code');
Erik Luo5976c8c2018-07-24 02:03:09350 this._anchorElement = this._buildMessageAnchor();
Tim van der Lippe1d6e57a2019-09-30 11:55:34351 if (this._anchorElement) {
Erik Luo5976c8c2018-07-24 02:03:09352 formattedMessage.appendChild(this._anchorElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34353 }
Blink Reformat4c46d092018-04-07 15:32:37354 formattedMessage.appendChild(messageElement);
355 return formattedMessage;
356 }
357
Jan Scheffler19cd7ec2021-02-12 14:16:30358 _formatAsNetworkRequest(): HTMLElement|null {
Tim van der Lippe9b2f8712020-02-12 17:46:22359 const request = SDK.NetworkLog.NetworkLog.requestForConsoleMessage(this._message);
Tim van der Lippe1d6e57a2019-09-30 11:55:34360 if (!request) {
Erik Luofc2214f2018-11-21 19:54:58361 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34362 }
Jan Scheffler19cd7ec2021-02-12 14:16:30363 const messageElement = (document.createElement('span') as HTMLElement);
Tim van der Lippe9b2f8712020-02-12 17:46:22364 if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Sigurd Schneider23c52972020-10-13 09:31:14365 UI.UIUtils.createTextChild(messageElement, request.requestMethod + ' ');
Tim van der Lippe9b2f8712020-02-12 17:46:22366 const linkElement = Components.Linkifier.Linkifier.linkifyRevealable(request, request.url(), request.url());
Erik Luo182bece2018-11-29 03:15:22367 // Focus is handled by the viewport.
368 linkElement.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:30369 this._selectableChildren.push({element: linkElement, forceSelect: (): void => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22370 messageElement.appendChild(linkElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34371 if (request.failed) {
Sigurd Schneider23c52972020-10-13 09:31:14372 UI.UIUtils.createTextChildren(messageElement, ' ', request.localizedFailDescription || '');
Tim van der Lippe1d6e57a2019-09-30 11:55:34373 }
374 if (request.statusCode !== 0) {
Sigurd Schneider23c52972020-10-13 09:31:14375 UI.UIUtils.createTextChildren(messageElement, ' ', String(request.statusCode));
Tim van der Lippe1d6e57a2019-09-30 11:55:34376 }
377 if (request.statusText) {
Sigurd Schneider23c52972020-10-13 09:31:14378 UI.UIUtils.createTextChildren(messageElement, ' (', request.statusText, ')');
Tim van der Lippe1d6e57a2019-09-30 11:55:34379 }
Erik Luofc2214f2018-11-21 19:54:58380 } else {
Erik Luoad5f3942019-03-26 20:53:44381 const messageText = this._message.messageText;
382 const fragment = this._linkifyWithCustomLinkifier(messageText, (text, url, lineNumber, columnNumber) => {
Sigurd Schneider45f32c32020-10-13 13:32:05383 const linkElement = url === request.url() ?
384 Components.Linkifier.Linkifier.linkifyRevealable(
Jan Scheffler19cd7ec2021-02-12 14:16:30385 (request as SDK.NetworkRequest.NetworkRequest), url, request.url()) :
Sigurd Schneider45f32c32020-10-13 13:32:05386 Components.Linkifier.Linkifier.linkifyURL(
Jan Scheffler19cd7ec2021-02-12 14:16:30387 url, ({text, lineNumber, columnNumber} as Components.Linkifier.LinkifyURLOptions));
Erik Luo182bece2018-11-29 03:15:22388 linkElement.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:30389 this._selectableChildren.push({element: linkElement, forceSelect: (): void => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22390 return linkElement;
391 });
Erik Luofc2214f2018-11-21 19:54:58392 messageElement.appendChild(fragment);
393 }
394 return messageElement;
395 }
396
Jan Scheffler19cd7ec2021-02-12 14:16:30397 _buildMessageAnchor(): HTMLElement|null {
398 const linkify = (message: SDK.ConsoleModel.ConsoleMessage): HTMLElement|null => {
Sigurd Schneider45f32c32020-10-13 13:32:05399 if (message.scriptId) {
400 return this._linkifyScriptId(message.scriptId, message.url || '', message.line, message.column);
401 }
402 if (message.stackTrace && message.stackTrace.callFrames.length) {
403 return this._linkifyStackTraceTopFrame(message.stackTrace);
404 }
405 if (message.url && message.url !== 'undefined') {
406 return this._linkifyLocation(message.url, message.line, message.column);
407 }
408 return null;
409 };
410 const anchorElement = linkify(this._message);
Blink Reformat4c46d092018-04-07 15:32:37411 // Append a space to prevent the anchor text from being glued to the console message when the user selects and copies the console messages.
412 if (anchorElement) {
John Emauf7e30fb2019-10-04 19:12:32413 anchorElement.tabIndex = -1;
414 this._selectableChildren.push({
415 element: anchorElement,
Jan Scheffler19cd7ec2021-02-12 14:16:30416 forceSelect: (): void => anchorElement.focus(),
John Emauf7e30fb2019-10-04 19:12:32417 });
Jan Scheffler19cd7ec2021-02-12 14:16:30418 const anchorWrapperElement = (document.createElement('span') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:09419 anchorWrapperElement.classList.add('console-message-anchor');
Blink Reformat4c46d092018-04-07 15:32:37420 anchorWrapperElement.appendChild(anchorElement);
Sigurd Schneider23c52972020-10-13 09:31:14421 UI.UIUtils.createTextChild(anchorWrapperElement, ' ');
Blink Reformat4c46d092018-04-07 15:32:37422 return anchorWrapperElement;
423 }
424 return null;
425 }
426
Jan Scheffler19cd7ec2021-02-12 14:16:30427 _buildMessageWithStackTrace(runtimeModel: SDK.RuntimeModel.RuntimeModel): HTMLElement {
428 const toggleElement = (document.createElement('div') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:09429 toggleElement.classList.add('console-message-stack-trace-toggle');
Blink Reformat4c46d092018-04-07 15:32:37430 const contentElement = toggleElement.createChild('div', 'console-message-stack-trace-wrapper');
431
432 const messageElement = this._buildMessage();
Tim van der Lippe9b2f8712020-02-12 17:46:22433 const icon = UI.Icon.Icon.create('smallicon-triangle-right', 'console-message-expand-icon');
Blink Reformat4c46d092018-04-07 15:32:37434 const clickableElement = contentElement.createChild('div');
435 clickableElement.appendChild(icon);
Erik Luob5bfff42018-09-20 02:52:39436 // Intercept focus to avoid highlight on click.
437 clickableElement.tabIndex = -1;
Blink Reformat4c46d092018-04-07 15:32:37438 clickableElement.appendChild(messageElement);
439 const stackTraceElement = contentElement.createChild('div');
440 const stackTracePreview = Components.JSPresentationUtils.buildStackTracePreviewContents(
Sigurd Schneider45f32c32020-10-13 13:32:05441 runtimeModel.target(), this._linkifier,
442 {stackTrace: this._message.stackTrace, contentUpdated: undefined, tabStops: undefined});
Erik Luo182bece2018-11-29 03:15:22443 stackTraceElement.appendChild(stackTracePreview.element);
444 for (const linkElement of stackTracePreview.links) {
Jan Scheffler19cd7ec2021-02-12 14:16:30445 this._selectableChildren.push({element: linkElement, forceSelect: (): void => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22446 }
Blink Reformat4c46d092018-04-07 15:32:37447 stackTraceElement.classList.add('hidden');
Brandon Goddard04a5a762019-12-10 16:45:53448 UI.ARIAUtils.markAsTreeitem(this.element());
449 UI.ARIAUtils.setExpanded(this.element(), false);
Jan Scheffler19cd7ec2021-02-12 14:16:30450 this._expandTrace = (expand: boolean): void => {
Blink Reformat4c46d092018-04-07 15:32:37451 icon.setIconType(expand ? 'smallicon-triangle-down' : 'smallicon-triangle-right');
452 stackTraceElement.classList.toggle('hidden', !expand);
Brandon Goddard04a5a762019-12-10 16:45:53453 UI.ARIAUtils.setExpanded(this.element(), expand);
Erik Luo8ef5d0c2018-09-25 21:16:00454 this._traceExpanded = expand;
455 };
Blink Reformat4c46d092018-04-07 15:32:37456
Jan Scheffler19cd7ec2021-02-12 14:16:30457 const toggleStackTrace = (event: Event): void => {
Tim van der Lippe9b2f8712020-02-12 17:46:22458 if (UI.UIUtils.isEditing() || contentElement.hasSelection()) {
Blink Reformat4c46d092018-04-07 15:32:37459 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34460 }
Sigurd Schneider45f32c32020-10-13 13:32:05461 this._expandTrace && this._expandTrace(stackTraceElement.classList.contains('hidden'));
Blink Reformat4c46d092018-04-07 15:32:37462 event.consume();
Sigurd Schneider45f32c32020-10-13 13:32:05463 };
Blink Reformat4c46d092018-04-07 15:32:37464
Sigurd Schneider45f32c32020-10-13 13:32:05465 clickableElement.addEventListener('click', toggleStackTrace, false);
Tim van der Lippe9b2f8712020-02-12 17:46:22466 if (this._message.type === SDK.ConsoleModel.MessageType.Trace) {
Erik Luo8ef5d0c2018-09-25 21:16:00467 this._expandTrace(true);
Tim van der Lippe1d6e57a2019-09-30 11:55:34468 }
Blink Reformat4c46d092018-04-07 15:32:37469
Sigurd Schneider45f32c32020-10-13 13:32:05470 // @ts-ignore
Erik Luo8ef5d0c2018-09-25 21:16:00471 toggleElement._expandStackTraceForTest = this._expandTrace.bind(this, true);
Blink Reformat4c46d092018-04-07 15:32:37472 return toggleElement;
473 }
474
Jan Scheffler19cd7ec2021-02-12 14:16:30475 _linkifyLocation(url: string, lineNumber: number, columnNumber: number): HTMLElement|null {
Sigurd Schneider45f32c32020-10-13 13:32:05476 const runtimeModel = this._message.runtimeModel();
477 if (!runtimeModel) {
Blink Reformat4c46d092018-04-07 15:32:37478 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34479 }
Blink Reformat4c46d092018-04-07 15:32:37480 return this._linkifier.linkifyScriptLocation(
Sigurd Schneider45f32c32020-10-13 13:32:05481 runtimeModel.target(), /* scriptId */ null, url, lineNumber,
482 {columnNumber, className: undefined, tabStop: undefined});
Blink Reformat4c46d092018-04-07 15:32:37483 }
484
Jan Scheffler19cd7ec2021-02-12 14:16:30485 _linkifyStackTraceTopFrame(stackTrace: Protocol.Runtime.StackTrace): HTMLElement|null {
Sigurd Schneider45f32c32020-10-13 13:32:05486 const runtimeModel = this._message.runtimeModel();
487 if (!runtimeModel) {
Blink Reformat4c46d092018-04-07 15:32:37488 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34489 }
Sigurd Schneider45f32c32020-10-13 13:32:05490 return this._linkifier.linkifyStackTraceTopFrame(runtimeModel.target(), stackTrace);
Blink Reformat4c46d092018-04-07 15:32:37491 }
492
Jan Scheffler19cd7ec2021-02-12 14:16:30493 _linkifyScriptId(scriptId: string, url: string, lineNumber: number, columnNumber: number): HTMLElement|null {
Sigurd Schneider45f32c32020-10-13 13:32:05494 const runtimeModel = this._message.runtimeModel();
495 if (!runtimeModel) {
Blink Reformat4c46d092018-04-07 15:32:37496 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34497 }
Blink Reformat4c46d092018-04-07 15:32:37498 return this._linkifier.linkifyScriptLocation(
Sigurd Schneider45f32c32020-10-13 13:32:05499 runtimeModel.target(), scriptId, url, lineNumber, {columnNumber, className: undefined, tabStop: undefined});
Blink Reformat4c46d092018-04-07 15:32:37500 }
501
Jan Scheffler19cd7ec2021-02-12 14:16:30502 _format(rawParameters: (string|SDK.RemoteObject.RemoteObject|Protocol.Runtime.RemoteObject|undefined)[]):
503 HTMLElement {
Blink Reformat4c46d092018-04-07 15:32:37504 // This node is used like a Builder. Values are continually appended onto it.
Jan Scheffler19cd7ec2021-02-12 14:16:30505 const formattedResult = (document.createElement('span') as HTMLElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34506 if (this._messagePrefix) {
Pavel Feldman9f0f0a32018-12-18 02:09:13507 formattedResult.createChild('span').textContent = this._messagePrefix;
Tim van der Lippe1d6e57a2019-09-30 11:55:34508 }
509 if (!rawParameters.length) {
Blink Reformat4c46d092018-04-07 15:32:37510 return formattedResult;
Tim van der Lippe1d6e57a2019-09-30 11:55:34511 }
Blink Reformat4c46d092018-04-07 15:32:37512
513 // Formatting code below assumes that parameters are all wrappers whereas frontend console
514 // API allows passing arbitrary values as messages (strings, numbers, etc.). Wrap them here.
515 // FIXME: Only pass runtime wrappers here.
Sigurd Schneider8bfb4212020-10-27 10:27:37516 let parameters = rawParameters.map(parameterToRemoteObject(this._message.runtimeModel()));
Blink Reformat4c46d092018-04-07 15:32:37517
518 // There can be string log and string eval result. We distinguish between them based on message type.
519 const shouldFormatMessage =
Jan Scheffler19cd7ec2021-02-12 14:16:30520 SDK.RemoteObject.RemoteObject.type((parameters as SDK.RemoteObject.RemoteObject[])[0]) === 'string' &&
Tim van der Lippe9b2f8712020-02-12 17:46:22521 (this._message.type !== SDK.ConsoleModel.MessageType.Result ||
522 this._message.level === SDK.ConsoleModel.MessageLevel.Error);
Blink Reformat4c46d092018-04-07 15:32:37523
524 // Multiple parameters with the first being a format string. Save unused substitutions.
525 if (shouldFormatMessage) {
526 const result = this._formatWithSubstitutionString(
Jan Scheffler19cd7ec2021-02-12 14:16:30527 (parameters[0].description as string), parameters.slice(1), formattedResult);
Sigurd Schneider45f32c32020-10-13 13:32:05528 parameters = Array.from(result.unusedSubstitutions || []);
Tim van der Lippe1d6e57a2019-09-30 11:55:34529 if (parameters.length) {
Sigurd Schneider23c52972020-10-13 09:31:14530 UI.UIUtils.createTextChild(formattedResult, ' ');
Tim van der Lippe1d6e57a2019-09-30 11:55:34531 }
Blink Reformat4c46d092018-04-07 15:32:37532 }
533
534 // Single parameter, or unused substitutions from above.
535 for (let i = 0; i < parameters.length; ++i) {
536 // Inline strings when formatting.
Tim van der Lippe1d6e57a2019-09-30 11:55:34537 if (shouldFormatMessage && parameters[i].type === 'string') {
Sigurd Schneider45f32c32020-10-13 13:32:05538 formattedResult.appendChild(this._linkifyStringAsFragment(parameters[i].description || ''));
Tim van der Lippe1d6e57a2019-09-30 11:55:34539 } else {
Blink Reformat4c46d092018-04-07 15:32:37540 formattedResult.appendChild(this._formatParameter(parameters[i], false, true));
Tim van der Lippe1d6e57a2019-09-30 11:55:34541 }
542 if (i < parameters.length - 1) {
Sigurd Schneider23c52972020-10-13 09:31:14543 UI.UIUtils.createTextChild(formattedResult, ' ');
Tim van der Lippe1d6e57a2019-09-30 11:55:34544 }
Blink Reformat4c46d092018-04-07 15:32:37545 }
546 return formattedResult;
547 }
548
Jan Scheffler19cd7ec2021-02-12 14:16:30549 _formatParameter(output: SDK.RemoteObject.RemoteObject, forceObjectFormat?: boolean, includePreview?: boolean):
550 HTMLElement {
Tim van der Lippe1d6e57a2019-09-30 11:55:34551 if (output.customPreview()) {
Jan Scheffler19cd7ec2021-02-12 14:16:30552 return new ObjectUI.CustomPreviewComponent.CustomPreviewComponent(output).element as HTMLElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:34553 }
Blink Reformat4c46d092018-04-07 15:32:37554
Alfonso Castaño20d22cd2020-10-28 16:23:58555 const outputType = forceObjectFormat ? 'object' : (output.subtype || output.type);
Blink Reformat4c46d092018-04-07 15:32:37556 let element;
Alfonso Castaño20d22cd2020-10-28 16:23:58557 switch (outputType) {
Blink Reformat4c46d092018-04-07 15:32:37558 case 'error':
559 element = this._formatParameterAsError(output);
560 break;
561 case 'function':
562 element = this._formatParameterAsFunction(output, includePreview);
563 break;
564 case 'array':
565 case 'arraybuffer':
566 case 'blob':
567 case 'dataview':
568 case 'generator':
569 case 'iterator':
570 case 'map':
571 case 'object':
572 case 'promise':
573 case 'proxy':
574 case 'set':
575 case 'typedarray':
576 case 'weakmap':
577 case 'weakset':
Benedikt Meurerdead3152020-12-07 08:43:40578 case 'webassemblymemory':
Blink Reformat4c46d092018-04-07 15:32:37579 element = this._formatParameterAsObject(output, includePreview);
580 break;
581 case 'node':
582 element = output.isNode() ? this._formatParameterAsNode(output) : this._formatParameterAsObject(output, false);
583 break;
Alfonso Castaño20d22cd2020-10-28 16:23:58584 case 'trustedtype':
585 element = this._formatParameterAsObject(output, false);
586 break;
Blink Reformat4c46d092018-04-07 15:32:37587 case 'string':
588 element = this._formatParameterAsString(output);
589 break;
590 case 'boolean':
591 case 'date':
592 case 'null':
593 case 'number':
594 case 'regexp':
595 case 'symbol':
596 case 'undefined':
597 case 'bigint':
598 element = this._formatParameterAsValue(output);
599 break;
600 default:
601 element = this._formatParameterAsValue(output);
Alfonso Castaño20d22cd2020-10-28 16:23:58602 console.error(`Tried to format remote object of unknown type ${outputType}.`);
Blink Reformat4c46d092018-04-07 15:32:37603 }
Alfonso Castaño20d22cd2020-10-28 16:23:58604 element.classList.add(`object-value-${outputType}`);
Blink Reformat4c46d092018-04-07 15:32:37605 element.classList.add('source-code');
606 return element;
607 }
608
Jan Scheffler19cd7ec2021-02-12 14:16:30609 _formatParameterAsValue(obj: SDK.RemoteObject.RemoteObject): HTMLElement {
610 const result = (document.createElement('span') as HTMLElement);
Blink Reformat4c46d092018-04-07 15:32:37611 const description = obj.description || '';
Sigurd Schneider8f4ac862020-10-13 13:30:11612 if (description.length > getMaxTokenizableStringLength()) {
Tim van der Lippe9b2f8712020-02-12 17:46:22613 const propertyValue = new ObjectUI.ObjectPropertiesSection.ExpandableTextPropertyValue(
Sigurd Schneider8f4ac862020-10-13 13:30:11614 document.createElement('span'), description, getLongStringVisibleLength());
Connor Moody1a5c0d32019-12-19 07:23:36615 result.appendChild(propertyValue.element);
Tim van der Lippe1d6e57a2019-09-30 11:55:34616 } else {
Sigurd Schneider23c52972020-10-13 09:31:14617 UI.UIUtils.createTextChild(result, description);
Tim van der Lippe1d6e57a2019-09-30 11:55:34618 }
619 if (obj.objectId) {
Blink Reformat4c46d092018-04-07 15:32:37620 result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, obj), false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34621 }
Blink Reformat4c46d092018-04-07 15:32:37622 return result;
623 }
624
Jan Scheffler19cd7ec2021-02-12 14:16:30625 _formatParameterAsTrustedType(obj: SDK.RemoteObject.RemoteObject): HTMLElement {
626 const result = (document.createElement('span') as HTMLElement);
Alfonso Castaño20d22cd2020-10-28 16:23:58627 const trustedContentSpan = document.createElement('span');
628 trustedContentSpan.appendChild(this._formatParameterAsString(obj));
629 trustedContentSpan.classList.add('object-value-string');
Alfonso Castañodfe8ca32020-10-29 13:03:09630 UI.UIUtils.createTextChild(result, `${obj.className} `);
Alfonso Castaño20d22cd2020-10-28 16:23:58631 result.appendChild(trustedContentSpan);
Alfonso Castaño20d22cd2020-10-28 16:23:58632 return result;
633 }
634
Jan Scheffler19cd7ec2021-02-12 14:16:30635 _formatParameterAsObject(obj: SDK.RemoteObject.RemoteObject, includePreview?: boolean): HTMLElement {
636 const titleElement = (document.createElement('span') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:09637 titleElement.classList.add('console-object');
Blink Reformat4c46d092018-04-07 15:32:37638 if (includePreview && obj.preview) {
639 titleElement.classList.add('console-object-preview');
640 this._previewFormatter.appendObjectPreview(titleElement, obj.preview, false /* isEntry */);
641 } else if (obj.type === 'function') {
642 const functionElement = titleElement.createChild('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22643 ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection.formatObjectAsFunction(obj, functionElement, false);
Blink Reformat4c46d092018-04-07 15:32:37644 titleElement.classList.add('object-value-function');
Alfonso Castaño20d22cd2020-10-28 16:23:58645 } else if (obj.subtype === 'trustedtype') {
646 titleElement.appendChild(this._formatParameterAsTrustedType(obj));
Blink Reformat4c46d092018-04-07 15:32:37647 } else {
Sigurd Schneider23c52972020-10-13 09:31:14648 UI.UIUtils.createTextChild(titleElement, obj.description || '');
Blink Reformat4c46d092018-04-07 15:32:37649 }
650
Tim van der Lippe1d6e57a2019-09-30 11:55:34651 if (!obj.hasChildren || obj.customPreview()) {
Blink Reformat4c46d092018-04-07 15:32:37652 return titleElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:34653 }
Blink Reformat4c46d092018-04-07 15:32:37654
655 const note = titleElement.createChild('span', 'object-state-note info-note');
Tim van der Lippe9b2f8712020-02-12 17:46:22656 if (this._message.type === SDK.ConsoleModel.MessageType.QueryObjectResult) {
Christy Chen9c6d8982021-02-08 02:28:31657 UI.Tooltip.Tooltip.install(note, i18nString(UIStrings.thisValueWillNotBeCollectedUntil));
Tim van der Lippe1d6e57a2019-09-30 11:55:34658 } else {
Christy Chen9c6d8982021-02-08 02:28:31659 UI.Tooltip.Tooltip.install(note, i18nString(UIStrings.thisValueWasEvaluatedUponFirst));
Tim van der Lippe1d6e57a2019-09-30 11:55:34660 }
Blink Reformat4c46d092018-04-07 15:32:37661
Tim van der Lippe9b2f8712020-02-12 17:46:22662 const section = new ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection(obj, titleElement, this._linkifier);
Blink Reformat4c46d092018-04-07 15:32:37663 section.element.classList.add('console-view-object-properties-section');
664 section.enableContextMenu();
Erik Luocc14b812018-11-03 01:33:09665 section.setShowSelectionOnKeyboardFocus(true, true);
Erik Luo383f21d2018-11-07 23:16:37666 this._selectableChildren.push(section);
Erik Luo840be6b2018-12-03 20:54:27667 section.addEventListener(UI.TreeOutline.Events.ElementAttached, this._messageResized);
668 section.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._messageResized);
669 section.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._messageResized);
Blink Reformat4c46d092018-04-07 15:32:37670 return section.element;
671 }
672
Jan Scheffler19cd7ec2021-02-12 14:16:30673 _formatParameterAsFunction(func: SDK.RemoteObject.RemoteObject, includePreview?: boolean): HTMLElement {
674 const result = (document.createElement('span') as HTMLElement);
Tim van der Lippe9b2f8712020-02-12 17:46:22675 SDK.RemoteObject.RemoteFunction.objectAsFunction(func).targetFunction().then(formatTargetFunction.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37676 return result;
677
Jan Scheffler19cd7ec2021-02-12 14:16:30678 function formatTargetFunction(this: ConsoleViewMessage, targetFunction: SDK.RemoteObject.RemoteObject): void {
Sigurd Schneider53f33522020-10-08 15:00:49679 const functionElement = document.createElement('span');
Tim van der Lippe9b2f8712020-02-12 17:46:22680 const promise = ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection.formatObjectAsFunction(
Joey Arhard78a58f2018-12-05 01:59:45681 targetFunction, functionElement, true, includePreview);
Blink Reformat4c46d092018-04-07 15:32:37682 result.appendChild(functionElement);
683 if (targetFunction !== func) {
684 const note = result.createChild('span', 'object-info-state-note');
Christy Chen9c6d8982021-02-08 02:28:31685 UI.Tooltip.Tooltip.install(note, i18nString(UIStrings.functionWasResolvedFromBound));
Blink Reformat4c46d092018-04-07 15:32:37686 }
687 result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, targetFunction), false);
Joey Arhard78a58f2018-12-05 01:59:45688 promise.then(() => this._formattedParameterAsFunctionForTest());
Blink Reformat4c46d092018-04-07 15:32:37689 }
690 }
691
Jan Scheffler19cd7ec2021-02-12 14:16:30692 _formattedParameterAsFunctionForTest(): void {
Joey Arhard78a58f2018-12-05 01:59:45693 }
694
Jan Scheffler19cd7ec2021-02-12 14:16:30695 _contextMenuEventFired(obj: SDK.RemoteObject.RemoteObject, event: Event): void {
Tim van der Lippe9b2f8712020-02-12 17:46:22696 const contextMenu = new UI.ContextMenu.ContextMenu(event);
Blink Reformat4c46d092018-04-07 15:32:37697 contextMenu.appendApplicableItems(obj);
698 contextMenu.show();
699 }
700
Jan Scheffler19cd7ec2021-02-12 14:16:30701 _renderPropertyPreviewOrAccessor(
702 object: SDK.RemoteObject.RemoteObject|null, property: Protocol.Runtime.PropertyPreview, propertyPath: {
703 name: (string|symbol),
704 }[]): HTMLElement {
Tim van der Lippe1d6e57a2019-09-30 11:55:34705 if (property.type === 'accessor') {
Sigurd Schneider45f32c32020-10-13 13:32:05706 return this._formatAsAccessorProperty(object, propertyPath.map(property => property.name.toString()), false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34707 }
Blink Reformat4c46d092018-04-07 15:32:37708 return this._previewFormatter.renderPropertyPreview(
Alfonso Castaño20d22cd2020-10-28 16:23:58709 property.type, 'subtype' in property ? property.subtype : undefined, null, property.value);
Blink Reformat4c46d092018-04-07 15:32:37710 }
711
Jan Scheffler19cd7ec2021-02-12 14:16:30712 _formatParameterAsNode(remoteObject: SDK.RemoteObject.RemoteObject): HTMLElement {
713 const result = document.createElement('span');
Blink Reformat4c46d092018-04-07 15:32:37714
Tim van der Lippe9b2f8712020-02-12 17:46:22715 const domModel = remoteObject.runtimeModel().target().model(SDK.DOMModel.DOMModel);
Tim van der Lippe1d6e57a2019-09-30 11:55:34716 if (!domModel) {
Blink Reformat4c46d092018-04-07 15:32:37717 return result;
Tim van der Lippe1d6e57a2019-09-30 11:55:34718 }
Jan Scheffler19cd7ec2021-02-12 14:16:30719 domModel.pushObjectAsNodeToFrontend(remoteObject).then(async (node: SDK.DOMModel.DOMNode|null) => {
Blink Reformat4c46d092018-04-07 15:32:37720 if (!node) {
721 result.appendChild(this._formatParameterAsObject(remoteObject, false));
722 return;
723 }
Jan Scheffler19cd7ec2021-02-12 14:16:30724 const renderResult = await UI.UIUtils.Renderer.render((node as Object));
Erik Luofc6a6302018-11-02 06:48:52725 if (renderResult) {
Erik Luo840be6b2018-12-03 20:54:27726 if (renderResult.tree) {
Erik Luo383f21d2018-11-07 23:16:37727 this._selectableChildren.push(renderResult.tree);
Erik Luo840be6b2018-12-03 20:54:27728 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementAttached, this._messageResized);
729 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._messageResized);
730 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._messageResized);
731 }
Erik Luofc6a6302018-11-02 06:48:52732 result.appendChild(renderResult.node);
733 } else {
734 result.appendChild(this._formatParameterAsObject(remoteObject, false));
735 }
Erik Luo54fdd912018-11-01 17:57:01736 this._formattedParameterAsNodeForTest();
Blink Reformat4c46d092018-04-07 15:32:37737 });
738
739 return result;
740 }
741
Jan Scheffler19cd7ec2021-02-12 14:16:30742 _formattedParameterAsNodeForTest(): void {
Blink Reformat4c46d092018-04-07 15:32:37743 }
744
Jan Scheffler19cd7ec2021-02-12 14:16:30745 _formatParameterAsString(output: SDK.RemoteObject.RemoteObject): HTMLElement {
746 const span = (document.createElement('span') as HTMLElement);
Alex Rudenko2f57b452021-02-17 07:02:09747 span.appendChild(this._linkifyStringAsFragment(output.description || ''));
Blink Reformat4c46d092018-04-07 15:32:37748
Jan Scheffler19cd7ec2021-02-12 14:16:30749 const result = (document.createElement('span') as HTMLElement);
Blink Reformat4c46d092018-04-07 15:32:37750 result.createChild('span', 'object-value-string-quote').textContent = '"';
751 result.appendChild(span);
752 result.createChild('span', 'object-value-string-quote').textContent = '"';
753 return result;
754 }
755
Jan Scheffler19cd7ec2021-02-12 14:16:30756 _formatParameterAsError(output: SDK.RemoteObject.RemoteObject): HTMLElement {
757 const result = (document.createElement('span') as HTMLElement);
Blink Reformat4c46d092018-04-07 15:32:37758 const errorSpan = this._tryFormatAsError(output.description || '');
Erik Luo383f21d2018-11-07 23:16:37759 result.appendChild(errorSpan ? errorSpan : this._linkifyStringAsFragment(output.description || ''));
Blink Reformat4c46d092018-04-07 15:32:37760 return result;
761 }
762
Jan Scheffler19cd7ec2021-02-12 14:16:30763 _formatAsArrayEntry(output: SDK.RemoteObject.RemoteObject): HTMLElement {
Alfonso Castaño20d22cd2020-10-28 16:23:58764 return this._previewFormatter.renderPropertyPreview(
765 output.type, output.subtype, output.className, output.description);
Blink Reformat4c46d092018-04-07 15:32:37766 }
767
Jan Scheffler19cd7ec2021-02-12 14:16:30768 _formatAsAccessorProperty(object: SDK.RemoteObject.RemoteObject|null, propertyPath: string[], isArrayEntry: boolean):
769 HTMLElement {
Tim van der Lippe9b2f8712020-02-12 17:46:22770 const rootElement =
771 ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan(
772 object, propertyPath, onInvokeGetterClick.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37773
Jan Scheffler19cd7ec2021-02-12 14:16:30774 function onInvokeGetterClick(this: ConsoleViewMessage, result: SDK.RemoteObject.CallFunctionResult): void {
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18775 const wasThrown = result.wasThrown;
776 const object = result.object;
Tim van der Lippe1d6e57a2019-09-30 11:55:34777 if (!object) {
Blink Reformat4c46d092018-04-07 15:32:37778 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34779 }
Blink Reformat4c46d092018-04-07 15:32:37780 rootElement.removeChildren();
781 if (wasThrown) {
782 const element = rootElement.createChild('span');
Christy Chen9c6d8982021-02-08 02:28:31783 element.textContent = i18nString(UIStrings.exception);
Jan Scheffler19cd7ec2021-02-12 14:16:30784 UI.Tooltip.Tooltip.install(element, (object.description as string));
Blink Reformat4c46d092018-04-07 15:32:37785 } else if (isArrayEntry) {
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18786 rootElement.appendChild(this._formatAsArrayEntry(object));
Blink Reformat4c46d092018-04-07 15:32:37787 } else {
788 // Make a PropertyPreview from the RemoteObject similar to the backend logic.
789 const maxLength = 100;
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18790 const type = object.type;
791 const subtype = object.subtype;
Blink Reformat4c46d092018-04-07 15:32:37792 let description = '';
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18793 if (type !== 'function' && object.description) {
Alfonso Castaño20d22cd2020-10-28 16:23:58794 if (type === 'string' || subtype === 'regexp' || subtype === 'trustedtype') {
Tim van der Lippe213266c2021-01-18 15:48:31795 description = Platform.StringUtilities.trimMiddle(object.description, maxLength);
Tim van der Lippe1d6e57a2019-09-30 11:55:34796 } else {
Tim van der Lippe3cc3af32021-01-19 14:25:26797 description = Platform.StringUtilities.trimEndWithMaxLength(object.description, maxLength);
Tim van der Lippe1d6e57a2019-09-30 11:55:34798 }
Blink Reformat4c46d092018-04-07 15:32:37799 }
Alfonso Castaño20d22cd2020-10-28 16:23:58800 rootElement.appendChild(
801 this._previewFormatter.renderPropertyPreview(type, subtype, object.className, description));
Blink Reformat4c46d092018-04-07 15:32:37802 }
803 }
804
805 return rootElement;
806 }
807
Jan Scheffler19cd7ec2021-02-12 14:16:30808 _formatWithSubstitutionString(
809 format: string, parameters: SDK.RemoteObject.RemoteObject[], formattedResult: HTMLElement): {
810 formattedResult: Element,
811 unusedSubstitutions: ArrayLike<SDK.RemoteObject.RemoteObject>|null,
812 } {
813 function parameterFormatter(
814 this: ConsoleViewMessage, force: boolean, includePreview: boolean,
815 obj?: string|SDK.RemoteObject.RemoteObject): string|HTMLElement|undefined {
Sigurd Schneider45f32c32020-10-13 13:32:05816 if (obj instanceof SDK.RemoteObject.RemoteObject) {
817 return this._formatParameter(obj, force, includePreview);
818 }
819 return stringFormatter(obj);
Blink Reformat4c46d092018-04-07 15:32:37820 }
821
Jan Scheffler19cd7ec2021-02-12 14:16:30822 function stringFormatter(obj?: string|SDK.RemoteObject.RemoteObject): string|undefined {
Sigurd Schneider45f32c32020-10-13 13:32:05823 if (obj === undefined) {
824 return undefined;
825 }
826 if (typeof obj === 'string') {
827 return obj;
828 }
Blink Reformat4c46d092018-04-07 15:32:37829 return obj.description;
830 }
831
Jan Scheffler19cd7ec2021-02-12 14:16:30832 function floatFormatter(obj?: string|SDK.RemoteObject.RemoteObject): number|string|undefined {
Sigurd Schneider45f32c32020-10-13 13:32:05833 if (obj instanceof SDK.RemoteObject.RemoteObject) {
834 if (typeof obj.value !== 'number') {
835 return 'NaN';
836 }
837 return obj.value;
Tim van der Lippe1d6e57a2019-09-30 11:55:34838 }
Sigurd Schneider45f32c32020-10-13 13:32:05839 return undefined;
Blink Reformat4c46d092018-04-07 15:32:37840 }
841
Jan Scheffler19cd7ec2021-02-12 14:16:30842 function integerFormatter(obj?: string|SDK.RemoteObject.RemoteObject): string|number|undefined {
Sigurd Schneider45f32c32020-10-13 13:32:05843 if (obj instanceof SDK.RemoteObject.RemoteObject) {
844 if (obj.type === 'bigint') {
845 return obj.description;
846 }
847 if (typeof obj.value !== 'number') {
848 return 'NaN';
849 }
850 return Math.floor(obj.value);
Tim van der Lippe1d6e57a2019-09-30 11:55:34851 }
Sigurd Schneider45f32c32020-10-13 13:32:05852 return undefined;
Blink Reformat4c46d092018-04-07 15:32:37853 }
854
Jan Scheffler19cd7ec2021-02-12 14:16:30855 function bypassFormatter(obj?: string|SDK.RemoteObject.RemoteObject): Node|string {
Blink Reformat4c46d092018-04-07 15:32:37856 return (obj instanceof Node) ? obj : '';
857 }
858
Jan Scheffler19cd7ec2021-02-12 14:16:30859 let currentStyle: Map<string, {value: string, priority: string}>|null = null;
860 function styleFormatter(obj?: string|SDK.RemoteObject.RemoteObject): void {
Sigurd Schneider45f32c32020-10-13 13:32:05861 currentStyle = new Map();
Sigurd Schneider53f33522020-10-08 15:00:49862 const buffer = document.createElement('span');
Sigurd Schneider45f32c32020-10-13 13:32:05863 if (obj === undefined) {
864 return;
865 }
866 if (typeof obj === 'string' || !obj.description) {
867 return;
868 }
Blink Reformat4c46d092018-04-07 15:32:37869 buffer.setAttribute('style', obj.description);
Sigurd Schneider45f32c32020-10-13 13:32:05870 for (const property of buffer.style) {
Mathias Bynens5165a7a2020-06-10 05:51:43871 if (isAllowedProperty(property)) {
Sigurd Schneider45f32c32020-10-13 13:32:05872 const info = {
873 value: buffer.style.getPropertyValue(property),
Jan Scheffler19cd7ec2021-02-12 14:16:30874 priority: buffer.style.getPropertyPriority(property),
Sigurd Schneider45f32c32020-10-13 13:32:05875 };
876 currentStyle.set(property, info);
Tim van der Lippe1d6e57a2019-09-30 11:55:34877 }
Blink Reformat4c46d092018-04-07 15:32:37878 }
879 }
880
Jan Scheffler19cd7ec2021-02-12 14:16:30881 function isAllowedProperty(property: string): boolean {
Blink Reformat4c46d092018-04-07 15:32:37882 // Make sure that allowed properties do not interfere with link visibility.
883 const prefixes = [
Jan Scheffler19cd7ec2021-02-12 14:16:30884 'background',
885 'border',
886 'color',
887 'font',
888 'line',
889 'margin',
890 'padding',
891 'text',
892 '-webkit-background',
893 '-webkit-border',
894 '-webkit-font',
895 '-webkit-margin',
896 '-webkit-padding',
897 '-webkit-text',
Blink Reformat4c46d092018-04-07 15:32:37898 ];
Sigurd Schneider45f32c32020-10-13 13:32:05899 for (const prefix of prefixes) {
900 if (property.startsWith(prefix)) {
Blink Reformat4c46d092018-04-07 15:32:37901 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:34902 }
Blink Reformat4c46d092018-04-07 15:32:37903 }
904 return false;
905 }
906
Jan Scheffler19cd7ec2021-02-12 14:16:30907 // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
908 // eslint-disable-next-line @typescript-eslint/no-explicit-any
909 const formatters: Record<string, Platform.StringUtilities.FormatterFunction<any>> = {};
Blink Reformat4c46d092018-04-07 15:32:37910 // Firebug uses %o for formatting objects.
911 formatters.o = parameterFormatter.bind(this, false /* force */, true /* includePreview */);
912 formatters.s = stringFormatter;
913 formatters.f = floatFormatter;
914 // Firebug allows both %i and %d for formatting integers.
915 formatters.i = integerFormatter;
916 formatters.d = integerFormatter;
917
918 // Firebug uses %c for styling the message.
919 formatters.c = styleFormatter;
920
921 // Support %O to force object formatting, instead of the type-based %o formatting.
922 formatters.O = parameterFormatter.bind(this, true /* force */, false /* includePreview */);
923
924 formatters._ = bypassFormatter;
925
Jan Scheffler19cd7ec2021-02-12 14:16:30926 function append(this: ConsoleViewMessage, a: HTMLElement, b?: string|Node): HTMLElement {
Blink Reformat4c46d092018-04-07 15:32:37927 if (b instanceof Node) {
928 a.appendChild(b);
Erik Luo17926392018-05-17 22:06:12929 return a;
930 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34931 if (typeof b === 'undefined') {
Erik Luo17926392018-05-17 22:06:12932 return a;
Tim van der Lippe1d6e57a2019-09-30 11:55:34933 }
Erik Luo17926392018-05-17 22:06:12934 if (!currentStyle) {
Erik Luo383f21d2018-11-07 23:16:37935 a.appendChild(this._linkifyStringAsFragment(String(b)));
Erik Luo17926392018-05-17 22:06:12936 return a;
937 }
938 const lines = String(b).split('\n');
939 for (let i = 0; i < lines.length; i++) {
940 const line = lines[i];
Erik Luo383f21d2018-11-07 23:16:37941 const lineFragment = this._linkifyStringAsFragment(line);
Jan Scheffler19cd7ec2021-02-12 14:16:30942 const wrapper = (document.createElement('span') as HTMLElement);
Erik Luo17926392018-05-17 22:06:12943 wrapper.style.setProperty('contain', 'paint');
944 wrapper.style.setProperty('display', 'inline-block');
945 wrapper.style.setProperty('max-width', '100%');
946 wrapper.appendChild(lineFragment);
947 applyCurrentStyle(wrapper);
948 for (const child of wrapper.children) {
Sigurd Schneider53f33522020-10-08 15:00:49949 if (child.classList.contains('devtools-link') && child instanceof HTMLElement) {
Erik Luo17926392018-05-17 22:06:12950 this._applyForcedVisibleStyle(child);
Tim van der Lippe1d6e57a2019-09-30 11:55:34951 }
Blink Reformat4c46d092018-04-07 15:32:37952 }
Erik Luo17926392018-05-17 22:06:12953 a.appendChild(wrapper);
Tim van der Lippe1d6e57a2019-09-30 11:55:34954 if (i < lines.length - 1) {
Sigurd Schneider53f33522020-10-08 15:00:49955 a.appendChild(document.createElement('br'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34956 }
Blink Reformat4c46d092018-04-07 15:32:37957 }
958 return a;
959 }
960
Jan Scheffler19cd7ec2021-02-12 14:16:30961 function applyCurrentStyle(element: HTMLElement): void {
Sigurd Schneider45f32c32020-10-13 13:32:05962 if (!currentStyle) {
963 return;
964 }
965 for (const [property, {value, priority}] of currentStyle.entries()) {
Jan Scheffler19cd7ec2021-02-12 14:16:30966 element.style.setProperty((property as string), value, priority);
Tim van der Lippe1d6e57a2019-09-30 11:55:34967 }
Blink Reformat4c46d092018-04-07 15:32:37968 }
969
Tim van der Lippe93b57c32020-02-20 17:38:44970 // Platform.StringUtilities.format does treat formattedResult like a Builder, result is an object.
971 return Platform.StringUtilities.format(format, parameters, formatters, formattedResult, append.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37972 }
973
Jan Scheffler19cd7ec2021-02-12 14:16:30974 _applyForcedVisibleStyle(element: HTMLElement): void {
Blink Reformat4c46d092018-04-07 15:32:37975 element.style.setProperty('-webkit-text-stroke', '0', 'important');
976 element.style.setProperty('text-decoration', 'underline', 'important');
977
Paul Lewisca569a52020-09-09 16:11:51978 const themedColor = ThemeSupport.ThemeSupport.instance().patchColorText(
979 'rgb(33%, 33%, 33%)', ThemeSupport.ThemeSupport.ColorUsage.Foreground);
Blink Reformat4c46d092018-04-07 15:32:37980 element.style.setProperty('color', themedColor, 'important');
981
982 let backgroundColor = 'hsl(0, 0%, 100%)';
Tim van der Lippe9b2f8712020-02-12 17:46:22983 if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Blink Reformat4c46d092018-04-07 15:32:37984 backgroundColor = 'hsl(0, 100%, 97%)';
Tim van der Lippe9b2f8712020-02-12 17:46:22985 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning || this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:37986 backgroundColor = 'hsl(50, 100%, 95%)';
Tim van der Lippe1d6e57a2019-09-30 11:55:34987 }
Paul Lewisca569a52020-09-09 16:11:51988 const themedBackgroundColor = ThemeSupport.ThemeSupport.instance().patchColorText(
989 backgroundColor, ThemeSupport.ThemeSupport.ColorUsage.Background);
Blink Reformat4c46d092018-04-07 15:32:37990 element.style.setProperty('background-color', themedBackgroundColor, 'important');
991 }
992
Jan Scheffler19cd7ec2021-02-12 14:16:30993 matchesFilterRegex(regexObject: RegExp): boolean {
Blink Reformat4c46d092018-04-07 15:32:37994 regexObject.lastIndex = 0;
Erik Luo5976c8c2018-07-24 02:03:09995 const contentElement = this.contentElement();
996 const anchorText = this._anchorElement ? this._anchorElement.deepTextContent() : '';
Tim van der Lipped7cfd142021-01-07 12:17:24997 return (Boolean(anchorText) && regexObject.test(anchorText.trim())) ||
Erik Luo5976c8c2018-07-24 02:03:09998 regexObject.test(contentElement.deepTextContent().slice(anchorText.length));
Blink Reformat4c46d092018-04-07 15:32:37999 }
1000
Jan Scheffler19cd7ec2021-02-12 14:16:301001 matchesFilterText(filter: string): boolean {
Blink Reformat4c46d092018-04-07 15:32:371002 const text = this.contentElement().deepTextContent();
1003 return text.toLowerCase().includes(filter.toLowerCase());
1004 }
1005
Jan Scheffler19cd7ec2021-02-12 14:16:301006 updateTimestamp(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341007 if (!this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371008 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341009 }
Blink Reformat4c46d092018-04-07 15:32:371010
Paul Lewis2d7d65c2020-03-16 17:26:301011 if (Common.Settings.Settings.instance().moduleSetting('consoleTimestampsEnabled').get()) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341012 if (!this._timestampElement) {
Jan Scheffler19cd7ec2021-02-12 14:16:301013 this._timestampElement = (document.createElement('span') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:091014 this._timestampElement.classList.add('console-timestamp');
Tim van der Lippe1d6e57a2019-09-30 11:55:341015 }
Tim van der Lippe9b2f8712020-02-12 17:46:221016 this._timestampElement.textContent = UI.UIUtils.formatTimestamp(this._message.timestamp, false) + ' ';
Tim van der Lippe70842f32020-11-23 16:56:571017 UI.Tooltip.Tooltip.install(this._timestampElement, UI.UIUtils.formatTimestamp(this._message.timestamp, true));
Blink Reformat4c46d092018-04-07 15:32:371018 this._contentElement.insertBefore(this._timestampElement, this._contentElement.firstChild);
1019 } else if (this._timestampElement) {
1020 this._timestampElement.remove();
Sigurd Schneider53e98632020-10-26 15:29:501021 this._timestampElement = null;
Blink Reformat4c46d092018-04-07 15:32:371022 }
Blink Reformat4c46d092018-04-07 15:32:371023 }
1024
Jan Scheffler19cd7ec2021-02-12 14:16:301025 nestingLevel(): number {
Blink Reformat4c46d092018-04-07 15:32:371026 return this._nestingLevel;
1027 }
1028
Jan Scheffler19cd7ec2021-02-12 14:16:301029 setInSimilarGroup(inSimilarGroup: boolean, isLast?: boolean): void {
Blink Reformat4c46d092018-04-07 15:32:371030 this._inSimilarGroup = inSimilarGroup;
Tim van der Lipped7cfd142021-01-07 12:17:241031 this._lastInSimilarGroup = inSimilarGroup && Boolean(isLast);
Blink Reformat4c46d092018-04-07 15:32:371032 if (this._similarGroupMarker && !inSimilarGroup) {
1033 this._similarGroupMarker.remove();
1034 this._similarGroupMarker = null;
1035 } else if (this._element && !this._similarGroupMarker && inSimilarGroup) {
Jan Scheffler19cd7ec2021-02-12 14:16:301036 this._similarGroupMarker = (document.createElement('div') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:091037 this._similarGroupMarker.classList.add('nesting-level-marker');
Blink Reformat4c46d092018-04-07 15:32:371038 this._element.insertBefore(this._similarGroupMarker, this._element.firstChild);
1039 this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
1040 }
1041 }
1042
Jan Scheffler19cd7ec2021-02-12 14:16:301043 isLastInSimilarGroup(): boolean {
Tim van der Lipped7cfd142021-01-07 12:17:241044 return Boolean(this._inSimilarGroup) && Boolean(this._lastInSimilarGroup);
Blink Reformat4c46d092018-04-07 15:32:371045 }
1046
Jan Scheffler19cd7ec2021-02-12 14:16:301047 resetCloseGroupDecorationCount(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341048 if (!this._closeGroupDecorationCount) {
Blink Reformat4c46d092018-04-07 15:32:371049 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341050 }
Blink Reformat4c46d092018-04-07 15:32:371051 this._closeGroupDecorationCount = 0;
1052 this._updateCloseGroupDecorations();
1053 }
1054
Jan Scheffler19cd7ec2021-02-12 14:16:301055 incrementCloseGroupDecorationCount(): void {
Blink Reformat4c46d092018-04-07 15:32:371056 ++this._closeGroupDecorationCount;
1057 this._updateCloseGroupDecorations();
1058 }
1059
Jan Scheffler19cd7ec2021-02-12 14:16:301060 _updateCloseGroupDecorations(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341061 if (!this._nestingLevelMarkers) {
Blink Reformat4c46d092018-04-07 15:32:371062 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341063 }
Blink Reformat4c46d092018-04-07 15:32:371064 for (let i = 0, n = this._nestingLevelMarkers.length; i < n; ++i) {
1065 const marker = this._nestingLevelMarkers[i];
1066 marker.classList.toggle('group-closed', n - i <= this._closeGroupDecorationCount);
1067 }
1068 }
1069
Jan Scheffler19cd7ec2021-02-12 14:16:301070 _focusedChildIndex(): number {
Tim van der Lippe1d6e57a2019-09-30 11:55:341071 if (!this._selectableChildren.length) {
Erik Luo0b8282e2018-10-08 20:37:461072 return -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341073 }
Erik Luo383f21d2018-11-07 23:16:371074 return this._selectableChildren.findIndex(child => child.element.hasFocus());
Erik Luo0b8282e2018-10-08 20:37:461075 }
1076
Jan Scheffler19cd7ec2021-02-12 14:16:301077 _onKeyDown(event: KeyboardEvent): void {
Sigurd Schneider45f32c32020-10-13 13:32:051078 if (UI.UIUtils.isEditing() || !this._element || !this._element.hasFocus() || this._element.hasSelection()) {
Erik Luo8ef5d0c2018-09-25 21:16:001079 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341080 }
1081 if (this.maybeHandleOnKeyDown(event)) {
Erik Luo8ef5d0c2018-09-25 21:16:001082 event.consume(true);
Tim van der Lippe1d6e57a2019-09-30 11:55:341083 }
Erik Luo8ef5d0c2018-09-25 21:16:001084 }
1085
Jan Scheffler19cd7ec2021-02-12 14:16:301086 maybeHandleOnKeyDown(event: KeyboardEvent): boolean {
Erik Luo8ef5d0c2018-09-25 21:16:001087 // Handle trace expansion.
Erik Luo0b8282e2018-10-08 20:37:461088 const focusedChildIndex = this._focusedChildIndex();
1089 const isWrapperFocused = focusedChildIndex === -1;
1090 if (this._expandTrace && isWrapperFocused) {
Erik Luo8ef5d0c2018-09-25 21:16:001091 if ((event.key === 'ArrowLeft' && this._traceExpanded) || (event.key === 'ArrowRight' && !this._traceExpanded)) {
1092 this._expandTrace(!this._traceExpanded);
1093 return true;
1094 }
1095 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341096 if (!this._selectableChildren.length) {
Erik Luo0b8282e2018-10-08 20:37:461097 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341098 }
Erik Luo0b8282e2018-10-08 20:37:461099
1100 if (event.key === 'ArrowLeft') {
Sigurd Schneider45f32c32020-10-13 13:32:051101 this._element && this._element.focus();
Erik Luo0b8282e2018-10-08 20:37:461102 return true;
1103 }
1104 if (event.key === 'ArrowRight') {
Tim van der Lippe1d6e57a2019-09-30 11:55:341105 if (isWrapperFocused && this._selectNearestVisibleChild(0)) {
Erik Luo0b8282e2018-10-08 20:37:461106 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341107 }
Erik Luo0b8282e2018-10-08 20:37:461108 }
1109 if (event.key === 'ArrowUp') {
Erik Luo182bece2018-11-29 03:15:221110 const firstVisibleChild = this._nearestVisibleChild(0);
1111 if (this._selectableChildren[focusedChildIndex] === firstVisibleChild && firstVisibleChild) {
Sigurd Schneider45f32c32020-10-13 13:32:051112 this._element && this._element.focus();
Erik Luo0b8282e2018-10-08 20:37:461113 return true;
Mathias Bynensf06e8c02020-02-28 13:58:281114 }
1115 if (this._selectNearestVisibleChild(focusedChildIndex - 1, true /* backwards */)) {
Erik Luo0b8282e2018-10-08 20:37:461116 return true;
1117 }
1118 }
1119 if (event.key === 'ArrowDown') {
Tim van der Lippe1d6e57a2019-09-30 11:55:341120 if (isWrapperFocused && this._selectNearestVisibleChild(0)) {
Erik Luo0b8282e2018-10-08 20:37:461121 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341122 }
1123 if (!isWrapperFocused && this._selectNearestVisibleChild(focusedChildIndex + 1)) {
Erik Luo0b8282e2018-10-08 20:37:461124 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341125 }
Erik Luo0b8282e2018-10-08 20:37:461126 }
Erik Luo8ef5d0c2018-09-25 21:16:001127 return false;
1128 }
1129
Jan Scheffler19cd7ec2021-02-12 14:16:301130 _selectNearestVisibleChild(fromIndex: number, backwards?: boolean): boolean {
Erik Luo182bece2018-11-29 03:15:221131 const nearestChild = this._nearestVisibleChild(fromIndex, backwards);
1132 if (nearestChild) {
Erik Luo31c21f62018-12-13 03:39:391133 nearestChild.forceSelect();
Erik Luo182bece2018-11-29 03:15:221134 return true;
1135 }
1136 return false;
1137 }
1138
Jan Scheffler19cd7ec2021-02-12 14:16:301139 _nearestVisibleChild(fromIndex: number, backwards?: boolean): {
1140 element: Element,
1141 forceSelect: () => void,
1142 }|null {
Erik Luo182bece2018-11-29 03:15:221143 const childCount = this._selectableChildren.length;
Tim van der Lippe1d6e57a2019-09-30 11:55:341144 if (fromIndex < 0 || fromIndex >= childCount) {
Erik Luo182bece2018-11-29 03:15:221145 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341146 }
Erik Luo182bece2018-11-29 03:15:221147 const direction = backwards ? -1 : 1;
1148 let index = fromIndex;
1149
1150 while (!this._selectableChildren[index].element.offsetParent) {
1151 index += direction;
Tim van der Lippe1d6e57a2019-09-30 11:55:341152 if (index < 0 || index >= childCount) {
Erik Luo182bece2018-11-29 03:15:221153 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341154 }
Erik Luo182bece2018-11-29 03:15:221155 }
1156 return this._selectableChildren[index];
1157 }
1158
Jan Scheffler19cd7ec2021-02-12 14:16:301159 focusLastChildOrSelf(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341160 if (this._element && !this._selectNearestVisibleChild(this._selectableChildren.length - 1, true /* backwards */)) {
Erik Luo0b8282e2018-10-08 20:37:461161 this._element.focus();
Tim van der Lippe1d6e57a2019-09-30 11:55:341162 }
Erik Luo0b8282e2018-10-08 20:37:461163 }
1164
Jan Scheffler19cd7ec2021-02-12 14:16:301165 setContentElement(element: HTMLElement): void {
Sigurd Schneiderb2953b22020-10-09 09:30:151166 console.assert(!this._contentElement, 'Cannot set content element twice');
1167 this._contentElement = element;
1168 }
1169
Jan Scheffler19cd7ec2021-02-12 14:16:301170 getContentElement(): HTMLElement|null {
Sigurd Schneiderb2953b22020-10-09 09:30:151171 return this._contentElement;
1172 }
1173
Jan Scheffler19cd7ec2021-02-12 14:16:301174 contentElement(): HTMLElement {
Tim van der Lippe1d6e57a2019-09-30 11:55:341175 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371176 return this._contentElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:341177 }
Blink Reformat4c46d092018-04-07 15:32:371178
Jan Scheffler19cd7ec2021-02-12 14:16:301179 const contentElement = (document.createElement('div') as HTMLElement);
Tim van der Lippef49e2322020-05-01 15:03:091180 contentElement.classList.add('console-message');
Tim van der Lippe1d6e57a2019-09-30 11:55:341181 if (this._messageLevelIcon) {
Blink Reformat4c46d092018-04-07 15:32:371182 contentElement.appendChild(this._messageLevelIcon);
Tim van der Lippe1d6e57a2019-09-30 11:55:341183 }
Blink Reformat4c46d092018-04-07 15:32:371184 this._contentElement = contentElement;
1185
Sigurd Schneider45f32c32020-10-13 13:32:051186 const runtimeModel = this._message.runtimeModel();
Blink Reformat4c46d092018-04-07 15:32:371187 let formattedMessage;
Tim van der Lipped7cfd142021-01-07 12:17:241188 const shouldIncludeTrace = Boolean(this._message.stackTrace) &&
Tim van der Lippe9b2f8712020-02-12 17:46:221189 (this._message.source === SDK.ConsoleModel.MessageSource.Network ||
1190 this._message.source === SDK.ConsoleModel.MessageSource.Violation ||
1191 this._message.level === SDK.ConsoleModel.MessageLevel.Error ||
1192 this._message.level === SDK.ConsoleModel.MessageLevel.Warning ||
1193 this._message.type === SDK.ConsoleModel.MessageType.Trace);
Sigurd Schneider45f32c32020-10-13 13:32:051194 if (runtimeModel && shouldIncludeTrace) {
1195 formattedMessage = this._buildMessageWithStackTrace(runtimeModel);
Tim van der Lippe1d6e57a2019-09-30 11:55:341196 } else {
Blink Reformat4c46d092018-04-07 15:32:371197 formattedMessage = this._buildMessage();
Tim van der Lippe1d6e57a2019-09-30 11:55:341198 }
Blink Reformat4c46d092018-04-07 15:32:371199 contentElement.appendChild(formattedMessage);
1200
1201 this.updateTimestamp();
1202 return this._contentElement;
1203 }
1204
Jan Scheffler19cd7ec2021-02-12 14:16:301205 toMessageElement(): HTMLElement {
Tim van der Lippe1d6e57a2019-09-30 11:55:341206 if (this._element) {
Blink Reformat4c46d092018-04-07 15:32:371207 return this._element;
Tim van der Lippe1d6e57a2019-09-30 11:55:341208 }
Jan Scheffler19cd7ec2021-02-12 14:16:301209 this._element = (document.createElement('div') as HTMLElement);
Pavel Feldmandb310912019-01-30 00:31:201210 this._element.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:301211 this._element.addEventListener('keydown', (this._onKeyDown.bind(this) as EventListener));
Blink Reformat4c46d092018-04-07 15:32:371212 this.updateMessageElement();
1213 return this._element;
1214 }
1215
Jan Scheffler19cd7ec2021-02-12 14:16:301216 updateMessageElement(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341217 if (!this._element) {
Blink Reformat4c46d092018-04-07 15:32:371218 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341219 }
Blink Reformat4c46d092018-04-07 15:32:371220
1221 this._element.className = 'console-message-wrapper';
1222 this._element.removeChildren();
Tim van der Lippe1d6e57a2019-09-30 11:55:341223 if (this._message.isGroupStartMessage()) {
Blink Reformat4c46d092018-04-07 15:32:371224 this._element.classList.add('console-group-title');
Tim van der Lippe1d6e57a2019-09-30 11:55:341225 }
Tim van der Lippe9b2f8712020-02-12 17:46:221226 if (this._message.source === SDK.ConsoleModel.MessageSource.ConsoleAPI) {
Blink Reformat4c46d092018-04-07 15:32:371227 this._element.classList.add('console-from-api');
Tim van der Lippe1d6e57a2019-09-30 11:55:341228 }
Blink Reformat4c46d092018-04-07 15:32:371229 if (this._inSimilarGroup) {
Jan Scheffler19cd7ec2021-02-12 14:16:301230 this._similarGroupMarker = (this._element.createChild('div', 'nesting-level-marker') as HTMLElement);
Blink Reformat4c46d092018-04-07 15:32:371231 this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
1232 }
1233
1234 this._nestingLevelMarkers = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341235 for (let i = 0; i < this._nestingLevel; ++i) {
Blink Reformat4c46d092018-04-07 15:32:371236 this._nestingLevelMarkers.push(this._element.createChild('div', 'nesting-level-marker'));
Tim van der Lippe1d6e57a2019-09-30 11:55:341237 }
Blink Reformat4c46d092018-04-07 15:32:371238 this._updateCloseGroupDecorations();
Sigurd Schneiderca7b4ff2020-10-14 07:45:471239 elementToMessage.set(this._element, this);
Blink Reformat4c46d092018-04-07 15:32:371240
1241 switch (this._message.level) {
Tim van der Lippe9b2f8712020-02-12 17:46:221242 case SDK.ConsoleModel.MessageLevel.Verbose:
Blink Reformat4c46d092018-04-07 15:32:371243 this._element.classList.add('console-verbose-level');
Blink Reformat4c46d092018-04-07 15:32:371244 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221245 case SDK.ConsoleModel.MessageLevel.Info:
Blink Reformat4c46d092018-04-07 15:32:371246 this._element.classList.add('console-info-level');
Tim van der Lippe9b2f8712020-02-12 17:46:221247 if (this._message.type === SDK.ConsoleModel.MessageType.System) {
Blink Reformat4c46d092018-04-07 15:32:371248 this._element.classList.add('console-system-type');
Tim van der Lippe1d6e57a2019-09-30 11:55:341249 }
Blink Reformat4c46d092018-04-07 15:32:371250 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221251 case SDK.ConsoleModel.MessageLevel.Warning:
Blink Reformat4c46d092018-04-07 15:32:371252 this._element.classList.add('console-warning-level');
Blink Reformat4c46d092018-04-07 15:32:371253 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221254 case SDK.ConsoleModel.MessageLevel.Error:
Blink Reformat4c46d092018-04-07 15:32:371255 this._element.classList.add('console-error-level');
Blink Reformat4c46d092018-04-07 15:32:371256 break;
1257 }
Erik Luofd3e7d42018-09-25 02:12:351258 this._updateMessageLevelIcon();
Tim van der Lippe1d6e57a2019-09-30 11:55:341259 if (this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371260 this._element.classList.add('console-warning-level');
Tim van der Lippe1d6e57a2019-09-30 11:55:341261 }
Blink Reformat4c46d092018-04-07 15:32:371262
1263 this._element.appendChild(this.contentElement());
Tim van der Lippe1d6e57a2019-09-30 11:55:341264 if (this._repeatCount > 1) {
Blink Reformat4c46d092018-04-07 15:32:371265 this._showRepeatCountElement();
Tim van der Lippe1d6e57a2019-09-30 11:55:341266 }
Blink Reformat4c46d092018-04-07 15:32:371267 }
1268
Jan Scheffler19cd7ec2021-02-12 14:16:301269 _shouldRenderAsWarning(): boolean {
Tim van der Lippe9b2f8712020-02-12 17:46:221270 return (this._message.level === SDK.ConsoleModel.MessageLevel.Verbose ||
1271 this._message.level === SDK.ConsoleModel.MessageLevel.Info) &&
1272 (this._message.source === SDK.ConsoleModel.MessageSource.Violation ||
1273 this._message.source === SDK.ConsoleModel.MessageSource.Deprecation ||
1274 this._message.source === SDK.ConsoleModel.MessageSource.Intervention ||
1275 this._message.source === SDK.ConsoleModel.MessageSource.Recommendation);
Blink Reformat4c46d092018-04-07 15:32:371276 }
1277
Jan Scheffler19cd7ec2021-02-12 14:16:301278 _updateMessageLevelIcon(): void {
Erik Luofd3e7d42018-09-25 02:12:351279 let iconType = '';
1280 let accessibleName = '';
Tim van der Lippe9b2f8712020-02-12 17:46:221281 if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning) {
Erik Luofd3e7d42018-09-25 02:12:351282 iconType = 'smallicon-warning';
Christy Chen9c6d8982021-02-08 02:28:311283 accessibleName = i18nString(UIStrings.warning);
Tim van der Lippe9b2f8712020-02-12 17:46:221284 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Erik Luofd3e7d42018-09-25 02:12:351285 iconType = 'smallicon-error';
Christy Chen9c6d8982021-02-08 02:28:311286 accessibleName = i18nString(UIStrings.error);
Erik Luofd3e7d42018-09-25 02:12:351287 }
Sigurd Schneider45f32c32020-10-13 13:32:051288 if (!this._messageLevelIcon) {
1289 if (!iconType) {
1290 return;
1291 }
Tim van der Lippe9b2f8712020-02-12 17:46:221292 this._messageLevelIcon = UI.Icon.Icon.create('', 'message-level-icon');
Tim van der Lippe1d6e57a2019-09-30 11:55:341293 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371294 this._contentElement.insertBefore(this._messageLevelIcon, this._contentElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341295 }
Blink Reformat4c46d092018-04-07 15:32:371296 }
1297 this._messageLevelIcon.setIconType(iconType);
Erik Luofd3e7d42018-09-25 02:12:351298 UI.ARIAUtils.setAccessibleName(this._messageLevelIcon, accessibleName);
Blink Reformat4c46d092018-04-07 15:32:371299 }
1300
Jan Scheffler19cd7ec2021-02-12 14:16:301301 repeatCount(): number {
Blink Reformat4c46d092018-04-07 15:32:371302 return this._repeatCount || 1;
1303 }
1304
Jan Scheffler19cd7ec2021-02-12 14:16:301305 resetIncrementRepeatCount(): void {
Blink Reformat4c46d092018-04-07 15:32:371306 this._repeatCount = 1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341307 if (!this._repeatCountElement) {
Blink Reformat4c46d092018-04-07 15:32:371308 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341309 }
Blink Reformat4c46d092018-04-07 15:32:371310
1311 this._repeatCountElement.remove();
Tim van der Lippe1d6e57a2019-09-30 11:55:341312 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371313 this._contentElement.classList.remove('repeated-message');
Tim van der Lippe1d6e57a2019-09-30 11:55:341314 }
Sigurd Schneider53e98632020-10-26 15:29:501315 this._repeatCountElement = null;
Blink Reformat4c46d092018-04-07 15:32:371316 }
1317
Jan Scheffler19cd7ec2021-02-12 14:16:301318 incrementRepeatCount(): void {
Blink Reformat4c46d092018-04-07 15:32:371319 this._repeatCount++;
1320 this._showRepeatCountElement();
1321 }
1322
Jan Scheffler19cd7ec2021-02-12 14:16:301323 setRepeatCount(repeatCount: number): void {
Blink Reformat4c46d092018-04-07 15:32:371324 this._repeatCount = repeatCount;
1325 this._showRepeatCountElement();
1326 }
Jan Scheffler19cd7ec2021-02-12 14:16:301327 _showRepeatCountElement(): void {
Tim van der Lippe1d6e57a2019-09-30 11:55:341328 if (!this._element) {
Blink Reformat4c46d092018-04-07 15:32:371329 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341330 }
Blink Reformat4c46d092018-04-07 15:32:371331
1332 if (!this._repeatCountElement) {
Sigurd Schneider45f32c32020-10-13 13:32:051333 this._repeatCountElement =
Jan Scheffler19cd7ec2021-02-12 14:16:301334 (document.createElement('span', {is: 'dt-small-bubble'}) as UI.UIUtils.DevToolsSmallBubble);
Tim van der Lippeee954d42020-05-04 10:35:571335 this._repeatCountElement.classList.add('console-message-repeat-count');
Blink Reformat4c46d092018-04-07 15:32:371336 switch (this._message.level) {
Tim van der Lippe9b2f8712020-02-12 17:46:221337 case SDK.ConsoleModel.MessageLevel.Warning:
Blink Reformat4c46d092018-04-07 15:32:371338 this._repeatCountElement.type = 'warning';
1339 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221340 case SDK.ConsoleModel.MessageLevel.Error:
Blink Reformat4c46d092018-04-07 15:32:371341 this._repeatCountElement.type = 'error';
1342 break;
Tim van der Lippe9b2f8712020-02-12 17:46:221343 case SDK.ConsoleModel.MessageLevel.Verbose:
Blink Reformat4c46d092018-04-07 15:32:371344 this._repeatCountElement.type = 'verbose';
1345 break;
1346 default:
1347 this._repeatCountElement.type = 'info';
1348 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341349 if (this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371350 this._repeatCountElement.type = 'warning';
Tim van der Lippe1d6e57a2019-09-30 11:55:341351 }
Blink Reformat4c46d092018-04-07 15:32:371352
1353 this._element.insertBefore(this._repeatCountElement, this._contentElement);
Sigurd Schneider45f32c32020-10-13 13:32:051354 this.contentElement().classList.add('repeated-message');
Blink Reformat4c46d092018-04-07 15:32:371355 }
Sigurd Schneider45f32c32020-10-13 13:32:051356 this._repeatCountElement.textContent = `${this._repeatCount}`;
Christy Chen9c6d8982021-02-08 02:28:311357 let accessibleName = i18nString(UIStrings.repeatS, {PH1: this._repeatCount});
Tim van der Lippe9b2f8712020-02-12 17:46:221358 if (this._message.level === SDK.ConsoleModel.MessageLevel.Warning) {
Christy Chen9c6d8982021-02-08 02:28:311359 accessibleName = i18nString(UIStrings.warningS, {PH1: accessibleName});
Tim van der Lippe9b2f8712020-02-12 17:46:221360 } else if (this._message.level === SDK.ConsoleModel.MessageLevel.Error) {
Christy Chen9c6d8982021-02-08 02:28:311361 accessibleName = i18nString(UIStrings.errorS, {PH1: accessibleName});
Tim van der Lippe1d6e57a2019-09-30 11:55:341362 }
Erik Luofd3e7d42018-09-25 02:12:351363 UI.ARIAUtils.setAccessibleName(this._repeatCountElement, accessibleName);
Blink Reformat4c46d092018-04-07 15:32:371364 }
1365
Jan Scheffler19cd7ec2021-02-12 14:16:301366 get text(): string {
Blink Reformat4c46d092018-04-07 15:32:371367 return this._message.messageText;
1368 }
1369
Jan Scheffler19cd7ec2021-02-12 14:16:301370 toExportString(): string {
Blink Reformat4c46d092018-04-07 15:32:371371 const lines = [];
1372 const nodes = this.contentElement().childTextNodes();
Tim van der Lippe9b2f8712020-02-12 17:46:221373 const messageContent = nodes.map(Components.Linkifier.Linkifier.untruncatedNodeText).join('');
Tim van der Lippe1d6e57a2019-09-30 11:55:341374 for (let i = 0; i < this.repeatCount(); ++i) {
Blink Reformat4c46d092018-04-07 15:32:371375 lines.push(messageContent);
Tim van der Lippe1d6e57a2019-09-30 11:55:341376 }
Blink Reformat4c46d092018-04-07 15:32:371377 return lines.join('\n');
1378 }
1379
Jan Scheffler19cd7ec2021-02-12 14:16:301380 setSearchRegex(regex: RegExp|null): void {
Sigurd Schneidere8e75cf2020-10-13 08:17:521381 if (this._searchHighlightNodeChanges && this._searchHighlightNodeChanges.length) {
1382 UI.UIUtils.revertDomChanges(this._searchHighlightNodeChanges);
Tim van der Lippe1d6e57a2019-09-30 11:55:341383 }
Blink Reformat4c46d092018-04-07 15:32:371384 this._searchRegex = regex;
1385 this._searchHighlightNodes = [];
Sigurd Schneidere8e75cf2020-10-13 08:17:521386 this._searchHighlightNodeChanges = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341387 if (!this._searchRegex) {
Blink Reformat4c46d092018-04-07 15:32:371388 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341389 }
Blink Reformat4c46d092018-04-07 15:32:371390
1391 const text = this.contentElement().deepTextContent();
1392 let match;
1393 this._searchRegex.lastIndex = 0;
1394 const sourceRanges = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341395 while ((match = this._searchRegex.exec(text)) && match[0]) {
Tim van der Lippe9b2f8712020-02-12 17:46:221396 sourceRanges.push(new TextUtils.TextRange.SourceRange(match.index, match[0].length));
Tim van der Lippe1d6e57a2019-09-30 11:55:341397 }
Blink Reformat4c46d092018-04-07 15:32:371398
1399 if (sourceRanges.length) {
1400 this._searchHighlightNodes =
Sigurd Schneidere8e75cf2020-10-13 08:17:521401 UI.UIUtils.highlightSearchResults(this.contentElement(), sourceRanges, this._searchHighlightNodeChanges);
Blink Reformat4c46d092018-04-07 15:32:371402 }
1403 }
1404
Jan Scheffler19cd7ec2021-02-12 14:16:301405 searchRegex(): RegExp|null {
Blink Reformat4c46d092018-04-07 15:32:371406 return this._searchRegex;
1407 }
1408
Jan Scheffler19cd7ec2021-02-12 14:16:301409 searchCount(): number {
Blink Reformat4c46d092018-04-07 15:32:371410 return this._searchHighlightNodes.length;
1411 }
1412
Jan Scheffler19cd7ec2021-02-12 14:16:301413 searchHighlightNode(index: number): Element {
Blink Reformat4c46d092018-04-07 15:32:371414 return this._searchHighlightNodes[index];
1415 }
1416
Jan Scheffler19cd7ec2021-02-12 14:16:301417 _tryFormatAsError(string: string): HTMLElement|null {
1418 function startsWith(prefix: string): boolean {
Blink Reformat4c46d092018-04-07 15:32:371419 return string.startsWith(prefix);
1420 }
1421
Sigurd Schneider45f32c32020-10-13 13:32:051422 const runtimeModel = this._message.runtimeModel();
Blink Reformat4c46d092018-04-07 15:32:371423 const errorPrefixes =
1424 ['EvalError', 'ReferenceError', 'SyntaxError', 'TypeError', 'RangeError', 'Error', 'URIError'];
Sigurd Schneider45f32c32020-10-13 13:32:051425 if (!runtimeModel || !errorPrefixes.some(startsWith)) {
Blink Reformat4c46d092018-04-07 15:32:371426 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341427 }
Sigurd Schneider45f32c32020-10-13 13:32:051428 const debuggerModel = runtimeModel.debuggerModel();
1429 const baseURL = runtimeModel.target().inspectedURL();
Blink Reformat4c46d092018-04-07 15:32:371430
1431 const lines = string.split('\n');
1432 const links = [];
1433 let position = 0;
1434 for (let i = 0; i < lines.length; ++i) {
1435 position += i > 0 ? lines[i - 1].length + 1 : 0;
1436 const isCallFrameLine = /^\s*at\s/.test(lines[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:341437 if (!isCallFrameLine && links.length) {
Blink Reformat4c46d092018-04-07 15:32:371438 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341439 }
Blink Reformat4c46d092018-04-07 15:32:371440
Tim van der Lippe1d6e57a2019-09-30 11:55:341441 if (!isCallFrameLine) {
Blink Reformat4c46d092018-04-07 15:32:371442 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341443 }
Blink Reformat4c46d092018-04-07 15:32:371444
1445 let openBracketIndex = -1;
1446 let closeBracketIndex = -1;
Yang Guo39256bd2019-07-18 06:02:251447 const inBracketsWithLineAndColumn = /\([^\)\(]+:\d+:\d+\)/g;
1448 const inBrackets = /\([^\)\(]+\)/g;
Jan Scheffler19cd7ec2021-02-12 14:16:301449 let lastMatch: RegExpExecArray|null = null;
Yang Guo39256bd2019-07-18 06:02:251450 let currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341451 while ((currentMatch = inBracketsWithLineAndColumn.exec(lines[i]))) {
Yang Guo39256bd2019-07-18 06:02:251452 lastMatch = currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341453 }
Yang Guo39256bd2019-07-18 06:02:251454 if (!lastMatch) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341455 while ((currentMatch = inBrackets.exec(lines[i]))) {
Yang Guo39256bd2019-07-18 06:02:251456 lastMatch = currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341457 }
Yang Guo39256bd2019-07-18 06:02:251458 }
1459 if (lastMatch) {
1460 openBracketIndex = lastMatch.index;
1461 closeBracketIndex = lastMatch.index + lastMatch[0].length - 1;
Blink Reformat4c46d092018-04-07 15:32:371462 }
1463 const hasOpenBracket = openBracketIndex !== -1;
1464 const left = hasOpenBracket ? openBracketIndex + 1 : lines[i].indexOf('at') + 3;
1465 const right = hasOpenBracket ? closeBracketIndex : lines[i].length;
1466 const linkCandidate = lines[i].substring(left, right);
Tim van der Lippe9b2f8712020-02-12 17:46:221467 const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(linkCandidate);
Tim van der Lippe1d6e57a2019-09-30 11:55:341468 if (!splitResult) {
Blink Reformat4c46d092018-04-07 15:32:371469 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341470 }
Blink Reformat4c46d092018-04-07 15:32:371471
Tim van der Lippe1d6e57a2019-09-30 11:55:341472 if (splitResult.url === '<anonymous>') {
Blink Reformat4c46d092018-04-07 15:32:371473 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341474 }
Blink Reformat4c46d092018-04-07 15:32:371475 let url = parseOrScriptMatch(splitResult.url);
Tim van der Lippe9b2f8712020-02-12 17:46:221476 if (!url && Common.ParsedURL.ParsedURL.isRelativeURL(splitResult.url)) {
1477 url = parseOrScriptMatch(Common.ParsedURL.ParsedURL.completeURL(baseURL, splitResult.url));
Tim van der Lippe1d6e57a2019-09-30 11:55:341478 }
1479 if (!url) {
Blink Reformat4c46d092018-04-07 15:32:371480 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341481 }
Blink Reformat4c46d092018-04-07 15:32:371482
1483 links.push({
1484 url: url,
1485 positionLeft: position + left,
1486 positionRight: position + right,
1487 lineNumber: splitResult.lineNumber,
Jan Scheffler19cd7ec2021-02-12 14:16:301488 columnNumber: splitResult.columnNumber,
Blink Reformat4c46d092018-04-07 15:32:371489 });
1490 }
1491
Tim van der Lippe1d6e57a2019-09-30 11:55:341492 if (!links.length) {
Blink Reformat4c46d092018-04-07 15:32:371493 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341494 }
Blink Reformat4c46d092018-04-07 15:32:371495
Jan Scheffler19cd7ec2021-02-12 14:16:301496 const formattedResult = document.createElement('span');
Blink Reformat4c46d092018-04-07 15:32:371497 let start = 0;
1498 for (let i = 0; i < links.length; ++i) {
Erik Luo383f21d2018-11-07 23:16:371499 formattedResult.appendChild(this._linkifyStringAsFragment(string.substring(start, links[i].positionLeft)));
Erik Luo182bece2018-11-29 03:15:221500 const scriptLocationLink = this._linkifier.linkifyScriptLocation(
Sigurd Schneider45f32c32020-10-13 13:32:051501 debuggerModel.target(), null, links[i].url, links[i].lineNumber,
1502 {columnNumber: links[i].columnNumber, className: undefined, tabStop: undefined});
Erik Luo182bece2018-11-29 03:15:221503 scriptLocationLink.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:301504 this._selectableChildren.push({element: scriptLocationLink, forceSelect: (): void => scriptLocationLink.focus()});
Erik Luo182bece2018-11-29 03:15:221505 formattedResult.appendChild(scriptLocationLink);
Blink Reformat4c46d092018-04-07 15:32:371506 start = links[i].positionRight;
1507 }
1508
Tim van der Lippe1d6e57a2019-09-30 11:55:341509 if (start !== string.length) {
Erik Luo383f21d2018-11-07 23:16:371510 formattedResult.appendChild(this._linkifyStringAsFragment(string.substring(start)));
Tim van der Lippe1d6e57a2019-09-30 11:55:341511 }
Blink Reformat4c46d092018-04-07 15:32:371512
1513 return formattedResult;
1514
Jan Scheffler19cd7ec2021-02-12 14:16:301515 function parseOrScriptMatch(url: string|null): string|null {
Tim van der Lippe1d6e57a2019-09-30 11:55:341516 if (!url) {
Blink Reformat4c46d092018-04-07 15:32:371517 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341518 }
Tim van der Lippe9b2f8712020-02-12 17:46:221519 const parsedURL = Common.ParsedURL.ParsedURL.fromString(url);
Tim van der Lippe1d6e57a2019-09-30 11:55:341520 if (parsedURL) {
Blink Reformat4c46d092018-04-07 15:32:371521 return parsedURL.url;
Tim van der Lippe1d6e57a2019-09-30 11:55:341522 }
1523 if (debuggerModel.scriptsForSourceURL(url).length) {
Blink Reformat4c46d092018-04-07 15:32:371524 return url;
Tim van der Lippe1d6e57a2019-09-30 11:55:341525 }
Blink Reformat4c46d092018-04-07 15:32:371526 return null;
1527 }
1528 }
1529
Jan Scheffler19cd7ec2021-02-12 14:16:301530 _linkifyWithCustomLinkifier(
1531 string: string, linkifier: (arg0: string, arg1: string, arg2?: number, arg3?: number) => Node): DocumentFragment {
Sigurd Schneider8f4ac862020-10-13 13:30:111532 if (string.length > getMaxTokenizableStringLength()) {
Tim van der Lippe9b2f8712020-02-12 17:46:221533 const propertyValue = new ObjectUI.ObjectPropertiesSection.ExpandableTextPropertyValue(
Sigurd Schneider8f4ac862020-10-13 13:30:111534 document.createElement('span'), string, getLongStringVisibleLength());
Sigurd Schneider45f32c32020-10-13 13:32:051535 const fragment = document.createDocumentFragment();
Connor Moody1a5c0d32019-12-19 07:23:361536 fragment.appendChild(propertyValue.element);
1537 return fragment;
Tim van der Lippe1d6e57a2019-09-30 11:55:341538 }
Sigurd Schneider45f32c32020-10-13 13:32:051539 const container = document.createDocumentFragment();
Tim van der Lippeeaacb722020-01-10 12:16:001540 const tokens = ConsoleViewMessage._tokenizeMessageText(string);
Blink Reformat4c46d092018-04-07 15:32:371541 for (const token of tokens) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341542 if (!token.text) {
Erik Luofc2214f2018-11-21 19:54:581543 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341544 }
Blink Reformat4c46d092018-04-07 15:32:371545 switch (token.type) {
1546 case 'url': {
1547 const realURL = (token.text.startsWith('www.') ? 'http://' + token.text : token.text);
Tim van der Lippe9b2f8712020-02-12 17:46:221548 const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(realURL);
Kim-Anh Tran9e49a452020-02-17 09:46:101549 const sourceURL = Common.ParsedURL.ParsedURL.removeWasmFunctionInfoFromURL(splitResult.url);
Blink Reformat4c46d092018-04-07 15:32:371550 let linkNode;
Tim van der Lippe1d6e57a2019-09-30 11:55:341551 if (splitResult) {
Kim-Anh Tran9e49a452020-02-17 09:46:101552 linkNode = linkifier(token.text, sourceURL, splitResult.lineNumber, splitResult.columnNumber);
Tim van der Lippe1d6e57a2019-09-30 11:55:341553 } else {
Sigurd Schneider45f32c32020-10-13 13:32:051554 linkNode = linkifier(token.text, '');
Tim van der Lippe1d6e57a2019-09-30 11:55:341555 }
Blink Reformat4c46d092018-04-07 15:32:371556 container.appendChild(linkNode);
1557 break;
1558 }
1559 default:
Sigurd Schneider45f32c32020-10-13 13:32:051560 container.appendChild(document.createTextNode(token.text));
Blink Reformat4c46d092018-04-07 15:32:371561 break;
1562 }
1563 }
1564 return container;
1565 }
1566
Jan Scheffler19cd7ec2021-02-12 14:16:301567 _linkifyStringAsFragment(string: string): DocumentFragment {
Erik Luofc2214f2018-11-21 19:54:581568 return this._linkifyWithCustomLinkifier(string, (text, url, lineNumber, columnNumber) => {
Sigurd Schneider45f32c32020-10-13 13:32:051569 const options = {text, lineNumber, columnNumber};
Jan Scheffler19cd7ec2021-02-12 14:16:301570 const linkElement =
1571 Components.Linkifier.Linkifier.linkifyURL(url, (options as Components.Linkifier.LinkifyURLOptions));
Erik Luo383f21d2018-11-07 23:16:371572 linkElement.tabIndex = -1;
Jan Scheffler19cd7ec2021-02-12 14:16:301573 this._selectableChildren.push({element: linkElement, forceSelect: (): void => linkElement.focus()});
Erik Luo383f21d2018-11-07 23:16:371574 return linkElement;
Blink Reformat4c46d092018-04-07 15:32:371575 });
1576 }
1577
Jan Scheffler19cd7ec2021-02-12 14:16:301578 static _tokenizeMessageText(string: string): {
1579 type?: string, text: string,
1580 }[] {
Sigurd Schneider30ac3dd2020-10-13 09:06:391581 const {tokenizerRegexes, tokenizerTypes} = getOrCreateTokenizers();
Sigurd Schneider8f4ac862020-10-13 13:30:111582 if (string.length > getMaxTokenizableStringLength()) {
Blink Reformat4c46d092018-04-07 15:32:371583 return [{text: string, type: undefined}];
Tim van der Lippe1d6e57a2019-09-30 11:55:341584 }
Sigurd Schneider30ac3dd2020-10-13 09:06:391585 const results = TextUtils.TextUtils.Utils.splitStringByRegexes(string, tokenizerRegexes);
1586 return results.map(result => ({text: result.value, type: tokenizerTypes[result.regexIndex]}));
Blink Reformat4c46d092018-04-07 15:32:371587 }
1588
Jan Scheffler19cd7ec2021-02-12 14:16:301589 groupKey(): string {
Tim van der Lippe1d6e57a2019-09-30 11:55:341590 if (!this._groupKey) {
Blink Reformat4c46d092018-04-07 15:32:371591 this._groupKey = this._message.groupCategoryKey() + ':' + this.groupTitle();
Tim van der Lippe1d6e57a2019-09-30 11:55:341592 }
Blink Reformat4c46d092018-04-07 15:32:371593 return this._groupKey;
1594 }
1595
Jan Scheffler19cd7ec2021-02-12 14:16:301596 groupTitle(): string {
Tim van der Lippeeaacb722020-01-10 12:16:001597 const tokens = ConsoleViewMessage._tokenizeMessageText(this._message.messageText);
Blink Reformat4c46d092018-04-07 15:32:371598 const result = tokens.reduce((acc, token) => {
Jan Scheffler19cd7ec2021-02-12 14:16:301599 let text: Common.UIString.LocalizedString|string = token.text;
Tim van der Lippe1d6e57a2019-09-30 11:55:341600 if (token.type === 'url') {
Christy Chen9c6d8982021-02-08 02:28:311601 text = i18nString(UIStrings.url);
Tim van der Lippe1d6e57a2019-09-30 11:55:341602 } else if (token.type === 'time') {
Christy Chen9c6d8982021-02-08 02:28:311603 text = i18nString(UIStrings.tookNms);
Tim van der Lippe1d6e57a2019-09-30 11:55:341604 } else if (token.type === 'event') {
Christy Chen9c6d8982021-02-08 02:28:311605 text = i18nString(UIStrings.someEvent);
Tim van der Lippe1d6e57a2019-09-30 11:55:341606 } else if (token.type === 'milestone') {
Christy Chen9c6d8982021-02-08 02:28:311607 text = i18nString(UIStrings.Mxx);
Tim van der Lippe1d6e57a2019-09-30 11:55:341608 } else if (token.type === 'autofill') {
Christy Chen9c6d8982021-02-08 02:28:311609 text = i18nString(UIStrings.attribute);
Tim van der Lippe1d6e57a2019-09-30 11:55:341610 }
Blink Reformat4c46d092018-04-07 15:32:371611 return acc + text;
1612 }, '');
1613 return result.replace(/[%]o/g, '');
1614 }
Paul Lewisbf7aa3c2019-11-20 17:03:381615}
Blink Reformat4c46d092018-04-07 15:32:371616
Jan Scheffler19cd7ec2021-02-12 14:16:301617let tokenizerRegexes: RegExp[]|null = null;
1618let tokenizerTypes: string[]|null = null;
Sigurd Schneider30ac3dd2020-10-13 09:06:391619
Jan Scheffler19cd7ec2021-02-12 14:16:301620function getOrCreateTokenizers(): {
1621 tokenizerRegexes: Array<RegExp>,
1622 tokenizerTypes: Array<string>,
1623} {
Sigurd Schneider30ac3dd2020-10-13 09:06:391624 if (!tokenizerRegexes || !tokenizerTypes) {
1625 const controlCodes = '\\u0000-\\u0020\\u007f-\\u009f';
1626 const linkStringRegex = new RegExp(
1627 '(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\\/\\/|data:|www\\.)[^\\s' + controlCodes + '"]{2,}[^\\s' + controlCodes +
1628 '"\')}\\],:;.!?]',
1629 'u');
1630 const pathLineRegex = /(?:\/[\w\.-]*)+\:[\d]+/;
1631 const timeRegex = /took [\d]+ms/;
1632 const eventRegex = /'\w+' event/;
1633 const milestoneRegex = /\sM[6-7]\d/;
1634 const autofillRegex = /\(suggested: \"[\w-]+\"\)/;
Jan Scheffler19cd7ec2021-02-12 14:16:301635 const handlers = new Map<RegExp, string>();
Sigurd Schneider30ac3dd2020-10-13 09:06:391636 handlers.set(linkStringRegex, 'url');
1637 handlers.set(pathLineRegex, 'url');
1638 handlers.set(timeRegex, 'time');
1639 handlers.set(eventRegex, 'event');
1640 handlers.set(milestoneRegex, 'milestone');
1641 handlers.set(autofillRegex, 'autofill');
1642 tokenizerRegexes = Array.from(handlers.keys());
1643 tokenizerTypes = Array.from(handlers.values());
1644 return {tokenizerRegexes, tokenizerTypes};
1645 }
1646 return {tokenizerRegexes, tokenizerTypes};
1647}
1648
Paul Lewisbf7aa3c2019-11-20 17:03:381649export class ConsoleGroupViewMessage extends ConsoleViewMessage {
Jan Scheffler19cd7ec2021-02-12 14:16:301650 _collapsed: boolean;
1651 _expandGroupIcon: UI.Icon.Icon|null;
1652 _onToggle: () => void;
1653
1654 constructor(
1655 consoleMessage: SDK.ConsoleModel.ConsoleMessage, linkifier: Components.Linkifier.Linkifier, nestingLevel: number,
1656 onToggle: () => void, onResize: (arg0: Common.EventTarget.EventTargetEvent) => void) {
Blink Reformat4c46d092018-04-07 15:32:371657 console.assert(consoleMessage.isGroupStartMessage());
Tim van der Lippeb45d9a02019-11-05 17:24:411658 super(consoleMessage, linkifier, nestingLevel, onResize);
Tim van der Lippe9b2f8712020-02-12 17:46:221659 this._collapsed = consoleMessage.type === SDK.ConsoleModel.MessageType.StartGroupCollapsed;
Blink Reformat4c46d092018-04-07 15:32:371660 this._expandGroupIcon = null;
Erik Luo8ef5d0c2018-09-25 21:16:001661 this._onToggle = onToggle;
Blink Reformat4c46d092018-04-07 15:32:371662 }
1663
Jan Scheffler19cd7ec2021-02-12 14:16:301664 _setCollapsed(collapsed: boolean): void {
Blink Reformat4c46d092018-04-07 15:32:371665 this._collapsed = collapsed;
Tim van der Lippe1d6e57a2019-09-30 11:55:341666 if (this._expandGroupIcon) {
Blink Reformat4c46d092018-04-07 15:32:371667 this._expandGroupIcon.setIconType(this._collapsed ? 'smallicon-triangle-right' : 'smallicon-triangle-down');
Tim van der Lippe1d6e57a2019-09-30 11:55:341668 }
Erik Luo8ef5d0c2018-09-25 21:16:001669 this._onToggle.call(null);
Blink Reformat4c46d092018-04-07 15:32:371670 }
1671
Jan Scheffler19cd7ec2021-02-12 14:16:301672 collapsed(): boolean {
Blink Reformat4c46d092018-04-07 15:32:371673 return this._collapsed;
1674 }
1675
Jan Scheffler19cd7ec2021-02-12 14:16:301676 maybeHandleOnKeyDown(event: KeyboardEvent): boolean {
Erik Luo0b8282e2018-10-08 20:37:461677 const focusedChildIndex = this._focusedChildIndex();
1678 if (focusedChildIndex === -1) {
1679 if ((event.key === 'ArrowLeft' && !this._collapsed) || (event.key === 'ArrowRight' && this._collapsed)) {
1680 this._setCollapsed(!this._collapsed);
1681 return true;
1682 }
Erik Luo8ef5d0c2018-09-25 21:16:001683 }
1684 return super.maybeHandleOnKeyDown(event);
1685 }
1686
Jan Scheffler19cd7ec2021-02-12 14:16:301687 toMessageElement(): HTMLElement {
1688 let element: HTMLElement|null = this._element || null;
Sigurd Schneider45f32c32020-10-13 13:32:051689 if (!element) {
1690 element = super.toMessageElement();
Erik Luo8ef5d0c2018-09-25 21:16:001691 const iconType = this._collapsed ? 'smallicon-triangle-right' : 'smallicon-triangle-down';
Tim van der Lippe9b2f8712020-02-12 17:46:221692 this._expandGroupIcon = UI.Icon.Icon.create(iconType, 'expand-group-icon');
Erik Luob5bfff42018-09-20 02:52:391693 // Intercept focus to avoid highlight on click.
Sigurd Schneider45f32c32020-10-13 13:32:051694 this.contentElement().tabIndex = -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341695 if (this._repeatCountElement) {
Blink Reformat4c46d092018-04-07 15:32:371696 this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341697 } else {
Sigurd Schneider45f32c32020-10-13 13:32:051698 element.insertBefore(this._expandGroupIcon, this._contentElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:341699 }
Sigurd Schneider45f32c32020-10-13 13:32:051700 element.addEventListener('click', () => this._setCollapsed(!this._collapsed));
Blink Reformat4c46d092018-04-07 15:32:371701 }
Sigurd Schneider45f32c32020-10-13 13:32:051702 return element;
Blink Reformat4c46d092018-04-07 15:32:371703 }
1704
Jan Scheffler19cd7ec2021-02-12 14:16:301705 _showRepeatCountElement(): void {
Blink Reformat4c46d092018-04-07 15:32:371706 super._showRepeatCountElement();
Tim van der Lippe1d6e57a2019-09-30 11:55:341707 if (this._repeatCountElement && this._expandGroupIcon) {
Blink Reformat4c46d092018-04-07 15:32:371708 this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341709 }
Blink Reformat4c46d092018-04-07 15:32:371710 }
Paul Lewisbf7aa3c2019-11-20 17:03:381711}
Blink Reformat4c46d092018-04-07 15:32:371712
Sigurd Schneiderca7b4ff2020-10-14 07:45:471713export class ConsoleCommand extends ConsoleViewMessage {
Jan Scheffler19cd7ec2021-02-12 14:16:301714 _formattedCommand: HTMLElement|null;
1715
1716 constructor(
1717 consoleMessage: SDK.ConsoleModel.ConsoleMessage, linkifier: Components.Linkifier.Linkifier, nestingLevel: number,
1718 onResize: (arg0: Common.EventTarget.EventTargetEvent) => void) {
Sigurd Schneiderca7b4ff2020-10-14 07:45:471719 super(consoleMessage, linkifier, nestingLevel, onResize);
Sigurd Schneiderca7b4ff2020-10-14 07:45:471720 this._formattedCommand = null;
1721 }
1722
Jan Scheffler19cd7ec2021-02-12 14:16:301723 contentElement(): HTMLElement {
Sigurd Schneiderca7b4ff2020-10-14 07:45:471724 const contentElement = this.getContentElement();
1725 if (contentElement) {
1726 return contentElement;
1727 }
Jan Scheffler19cd7ec2021-02-12 14:16:301728 const newContentElement = (document.createElement('div') as HTMLElement);
Sigurd Schneiderca7b4ff2020-10-14 07:45:471729 this.setContentElement(newContentElement);
1730 newContentElement.classList.add('console-user-command');
1731 const icon = UI.Icon.Icon.create('smallicon-user-command', 'command-result-icon');
1732 newContentElement.appendChild(icon);
1733
1734 elementToMessage.set(newContentElement, this);
Jan Scheffler19cd7ec2021-02-12 14:16:301735 this._formattedCommand = (document.createElement('span') as HTMLElement);
Sigurd Schneiderca7b4ff2020-10-14 07:45:471736 this._formattedCommand.classList.add('source-code');
1737 this._formattedCommand.textContent = Platform.StringUtilities.replaceControlCharacters(this.text);
1738 newContentElement.appendChild(this._formattedCommand);
1739
1740 if (this._formattedCommand.textContent.length < MaxLengthToIgnoreHighlighter) {
1741 const javascriptSyntaxHighlighter = new UI.SyntaxHighlighter.SyntaxHighlighter('text/javascript', true);
1742 javascriptSyntaxHighlighter.syntaxHighlightNode(this._formattedCommand).then(this._updateSearch.bind(this));
1743 } else {
1744 this._updateSearch();
1745 }
1746
1747 this.updateTimestamp();
1748 return newContentElement;
1749 }
1750
Jan Scheffler19cd7ec2021-02-12 14:16:301751 _updateSearch(): void {
Sigurd Schneiderca7b4ff2020-10-14 07:45:471752 this.setSearchRegex(this.searchRegex());
1753 }
1754}
1755
1756export class ConsoleCommandResult extends ConsoleViewMessage {
Jan Scheffler19cd7ec2021-02-12 14:16:301757 contentElement(): HTMLElement {
Sigurd Schneiderca7b4ff2020-10-14 07:45:471758 const element = super.contentElement();
1759 if (!element.classList.contains('console-user-command-result')) {
1760 element.classList.add('console-user-command-result');
1761 if (this.consoleMessage().level === SDK.ConsoleModel.MessageLevel.Info) {
1762 const icon = UI.Icon.Icon.create('smallicon-command-result', 'command-result-icon');
1763 element.insertBefore(icon, element.firstChild);
1764 }
1765 }
1766 return element;
1767 }
1768}
1769
Sigurd Schneider8bfb4212020-10-27 10:27:371770export class ConsoleTableMessageView extends ConsoleViewMessage {
Jan Scheffler19cd7ec2021-02-12 14:16:301771 _dataGrid: DataGrid.SortableDataGrid.SortableDataGrid<unknown>|null;
1772
1773 constructor(
1774 consoleMessage: SDK.ConsoleModel.ConsoleMessage, linkifier: Components.Linkifier.Linkifier, nestingLevel: number,
1775 onResize: (arg0: Common.EventTarget.EventTargetEvent) => void) {
Sigurd Schneider8bfb4212020-10-27 10:27:371776 super(consoleMessage, linkifier, nestingLevel, onResize);
1777 console.assert(consoleMessage.type === SDK.ConsoleModel.MessageType.Table);
Sigurd Schneider8bfb4212020-10-27 10:27:371778 this._dataGrid = null;
1779 }
1780
Jan Scheffler19cd7ec2021-02-12 14:16:301781 wasShown(): void {
Sigurd Schneider8bfb4212020-10-27 10:27:371782 if (this._dataGrid) {
1783 this._dataGrid.updateWidths();
1784 }
1785 super.wasShown();
1786 }
1787
Jan Scheffler19cd7ec2021-02-12 14:16:301788 onResize(): void {
Sigurd Schneider8bfb4212020-10-27 10:27:371789 if (!this.isVisible()) {
1790 return;
1791 }
1792 if (this._dataGrid) {
1793 this._dataGrid.onResize();
1794 }
1795 }
1796
Jan Scheffler19cd7ec2021-02-12 14:16:301797 contentElement(): HTMLElement {
Sigurd Schneider8bfb4212020-10-27 10:27:371798 const contentElement = this.getContentElement();
1799 if (contentElement) {
1800 return contentElement;
1801 }
1802
Jan Scheffler19cd7ec2021-02-12 14:16:301803 const newContentElement = (document.createElement('div') as HTMLElement);
Sigurd Schneider8bfb4212020-10-27 10:27:371804 newContentElement.classList.add('console-message');
1805 if (this._messageLevelIcon) {
1806 newContentElement.appendChild(this._messageLevelIcon);
1807 }
1808 this.setContentElement(newContentElement);
1809
1810 newContentElement.appendChild(this._buildTableMessage());
1811 this.updateTimestamp();
1812 return newContentElement;
1813 }
1814
Jan Scheffler19cd7ec2021-02-12 14:16:301815 _buildTableMessage(): HTMLElement {
1816 const formattedMessage = (document.createElement('span') as HTMLElement);
Sigurd Schneider8bfb4212020-10-27 10:27:371817 formattedMessage.classList.add('source-code');
1818 this._anchorElement = this._buildMessageAnchor();
1819 if (this._anchorElement) {
1820 formattedMessage.appendChild(this._anchorElement);
1821 }
1822
1823 const table = this._message.parameters && this._message.parameters.length ? this._message.parameters[0] : null;
1824 if (!table) {
1825 return this._buildMessage();
1826 }
1827 const actualTable = parameterToRemoteObject(this._message.runtimeModel())(table);
1828 if (!actualTable || !actualTable.preview) {
1829 return this._buildMessage();
1830 }
1831
1832 const rawValueColumnSymbol = Symbol('rawValueColumn');
Jan Scheffler19cd7ec2021-02-12 14:16:301833 const columnNames: (string|symbol)[] = [];
Sigurd Schneider8bfb4212020-10-27 10:27:371834 const preview = actualTable.preview;
1835 const rows = [];
1836 for (let i = 0; i < preview.properties.length; ++i) {
1837 const rowProperty = preview.properties[i];
Jan Scheffler19cd7ec2021-02-12 14:16:301838 let rowSubProperties: Protocol.Runtime.PropertyPreview[];
Sigurd Schneiderb393a432020-11-06 12:08:211839 if (rowProperty.valuePreview && rowProperty.valuePreview.properties.length) {
Sigurd Schneider8bfb4212020-10-27 10:27:371840 rowSubProperties = rowProperty.valuePreview.properties;
1841 } else if (rowProperty.value) {
Jan Scheffler19cd7ec2021-02-12 14:16:301842 rowSubProperties =
1843 [{name: rawValueColumnSymbol as unknown as string, type: rowProperty.type, value: rowProperty.value}];
Sigurd Schneider8bfb4212020-10-27 10:27:371844 } else {
1845 continue;
1846 }
1847
Jan Scheffler19cd7ec2021-02-12 14:16:301848 const rowValue = new Map<string|symbol, HTMLElement>();
Sigurd Schneider8bfb4212020-10-27 10:27:371849 const maxColumnsToRender = 20;
1850 for (let j = 0; j < rowSubProperties.length; ++j) {
1851 const cellProperty = rowSubProperties[j];
Jan Scheffler19cd7ec2021-02-12 14:16:301852 let columnRendered: true|boolean = columnNames.indexOf(cellProperty.name) !== -1;
Sigurd Schneider8bfb4212020-10-27 10:27:371853 if (!columnRendered) {
1854 if (columnNames.length === maxColumnsToRender) {
1855 continue;
1856 }
1857 columnRendered = true;
1858 columnNames.push(cellProperty.name);
1859 }
1860
1861 if (columnRendered) {
1862 const cellElement =
1863 this._renderPropertyPreviewOrAccessor(actualTable, cellProperty, [rowProperty, cellProperty]);
1864 cellElement.classList.add('console-message-nowrap-below');
1865 rowValue.set(cellProperty.name, cellElement);
1866 }
1867 }
1868 rows.push({rowName: rowProperty.name, rowValue});
1869 }
1870
1871 const flatValues = [];
1872 for (const {rowName, rowValue} of rows) {
1873 flatValues.push(rowName);
1874 for (let j = 0; j < columnNames.length; ++j) {
1875 flatValues.push(rowValue.get(columnNames[j]));
1876 }
1877 }
Christy Chen9c6d8982021-02-08 02:28:311878 columnNames.unshift(i18nString(UIStrings.index));
Sigurd Schneider8bfb4212020-10-27 10:27:371879 const columnDisplayNames =
Christy Chen9c6d8982021-02-08 02:28:311880 columnNames.map(name => name === rawValueColumnSymbol ? i18nString(UIStrings.value) : name.toString());
Sigurd Schneider8bfb4212020-10-27 10:27:371881
1882 if (flatValues.length) {
Christy Chen9c6d8982021-02-08 02:28:311883 this._dataGrid = DataGrid.SortableDataGrid.SortableDataGrid.create(
1884 columnDisplayNames, flatValues, i18nString(UIStrings.console));
Sigurd Schneider8bfb4212020-10-27 10:27:371885 if (this._dataGrid) {
1886 this._dataGrid.setStriped(true);
1887 this._dataGrid.setFocusable(false);
1888
1889 const formattedResult = document.createElement('span');
1890 formattedResult.classList.add('console-message-text');
1891 const tableElement = formattedResult.createChild('div', 'console-message-formatted-table');
1892 const dataGridContainer = tableElement.createChild('span');
1893 tableElement.appendChild(this._formatParameter(actualTable, true, false));
1894 dataGridContainer.appendChild(this._dataGrid.element);
1895 formattedMessage.appendChild(formattedResult);
1896 this._dataGrid.renderInline();
1897 }
1898 }
1899 return formattedMessage;
1900 }
1901
Jan Scheffler19cd7ec2021-02-12 14:16:301902 approximateFastHeight(): number {
Sigurd Schneider8bfb4212020-10-27 10:27:371903 const table = this._message.parameters && this._message.parameters[0];
1904 if (table && typeof table !== 'string' && table.preview) {
1905 return defaultConsoleRowHeight * table.preview.properties.length;
1906 }
1907 return defaultConsoleRowHeight;
1908 }
1909}
1910
Sigurd Schneiderca7b4ff2020-10-14 07:45:471911/**
1912 * The maximum length before strings are considered too long for syntax highlighting.
1913 * @const
Sigurd Schneiderca7b4ff2020-10-14 07:45:471914 */
Jan Scheffler19cd7ec2021-02-12 14:16:301915const MaxLengthToIgnoreHighlighter: number = 10000;
Sigurd Schneiderca7b4ff2020-10-14 07:45:471916
Blink Reformat4c46d092018-04-07 15:32:371917/**
1918 * @const
Blink Reformat4c46d092018-04-07 15:32:371919 */
Jan Scheffler19cd7ec2021-02-12 14:16:301920export const MaxLengthForLinks: number = 40;
Blink Reformat4c46d092018-04-07 15:32:371921
Sigurd Schneider17c74452021-02-15 12:14:101922let maxTokenizableStringLength = 10000;
1923let longStringVisibleLength = 5000;
Sigurd Schneider8f4ac862020-10-13 13:30:111924
Jan Scheffler19cd7ec2021-02-12 14:16:301925export const getMaxTokenizableStringLength = (): number => {
Sigurd Schneider17c74452021-02-15 12:14:101926 return maxTokenizableStringLength;
Sigurd Schneider8f4ac862020-10-13 13:30:111927};
1928
Jan Scheffler19cd7ec2021-02-12 14:16:301929export const setMaxTokenizableStringLength = (length: number): void => {
Sigurd Schneider17c74452021-02-15 12:14:101930 maxTokenizableStringLength = length;
Sigurd Schneider8f4ac862020-10-13 13:30:111931};
1932
Jan Scheffler19cd7ec2021-02-12 14:16:301933export const getLongStringVisibleLength = (): number => {
Sigurd Schneider17c74452021-02-15 12:14:101934 return longStringVisibleLength;
Sigurd Schneider8f4ac862020-10-13 13:30:111935};
1936
Jan Scheffler19cd7ec2021-02-12 14:16:301937export const setLongStringVisibleLength = (length: number): void => {
Sigurd Schneider17c74452021-02-15 12:14:101938 longStringVisibleLength = length;
Sigurd Schneider8f4ac862020-10-13 13:30:111939};