blob: 12a508c063e372a88f4e22c4d451dfaa42eb2882 [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371/*
2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
4 * Copyright (C) 2009 Joseph Pecoraro
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30/**
31 * @implements {Console.ConsoleViewportElement}
32 * @unrestricted
33 */
Paul Lewisbf7aa3c2019-11-20 17:03:3834export default class ConsoleViewMessage {
Blink Reformat4c46d092018-04-07 15:32:3735 /**
36 * @param {!SDK.ConsoleMessage} consoleMessage
37 * @param {!Components.Linkifier} linkifier
Blink Reformat4c46d092018-04-07 15:32:3738 * @param {number} nestingLevel
Erik Luo840be6b2018-12-03 20:54:2739 * @param {function(!Common.Event)} onResize
Blink Reformat4c46d092018-04-07 15:32:3740 */
Tim van der Lippeb45d9a02019-11-05 17:24:4141 constructor(consoleMessage, linkifier, nestingLevel, onResize) {
Blink Reformat4c46d092018-04-07 15:32:3742 this._message = consoleMessage;
43 this._linkifier = linkifier;
Blink Reformat4c46d092018-04-07 15:32:3744 this._repeatCount = 1;
45 this._closeGroupDecorationCount = 0;
46 this._nestingLevel = nestingLevel;
Erik Luo31c21f62018-12-13 03:39:3947 /** @type {!Array<{element: !Element, forceSelect: function()}>} */
Erik Luo383f21d2018-11-07 23:16:3748 this._selectableChildren = [];
Erik Luo840be6b2018-12-03 20:54:2749 this._messageResized = onResize;
Blink Reformat4c46d092018-04-07 15:32:3750
51 /** @type {?DataGrid.DataGrid} */
52 this._dataGrid = null;
53 this._previewFormatter = new ObjectUI.RemoteObjectPreviewFormatter();
54 this._searchRegex = null;
55 /** @type {?UI.Icon} */
56 this._messageLevelIcon = null;
Erik Luo8ef5d0c2018-09-25 21:16:0057 this._traceExpanded = false;
58 /** @type {?function(boolean)} */
59 this._expandTrace = null;
John Emaubb2897a2019-10-04 17:37:3260 /** @type {?Element} */
61 this._anchorElement = null;
Blink Reformat4c46d092018-04-07 15:32:3762 }
63
64 /**
65 * @override
66 * @return {!Element}
67 */
68 element() {
69 return this.toMessageElement();
70 }
71
72 /**
Blink Reformat4c46d092018-04-07 15:32:3773 * @override
74 */
75 wasShown() {
Tim van der Lippe1d6e57a2019-09-30 11:55:3476 if (this._dataGrid) {
Blink Reformat4c46d092018-04-07 15:32:3777 this._dataGrid.updateWidths();
Tim van der Lippe1d6e57a2019-09-30 11:55:3478 }
Blink Reformat4c46d092018-04-07 15:32:3779 this._isVisible = true;
80 }
81
82 onResize() {
Tim van der Lippe1d6e57a2019-09-30 11:55:3483 if (!this._isVisible) {
Blink Reformat4c46d092018-04-07 15:32:3784 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:3485 }
86 if (this._dataGrid) {
Blink Reformat4c46d092018-04-07 15:32:3787 this._dataGrid.onResize();
Tim van der Lippe1d6e57a2019-09-30 11:55:3488 }
Blink Reformat4c46d092018-04-07 15:32:3789 }
90
91 /**
92 * @override
93 */
94 willHide() {
95 this._isVisible = false;
Erik Luo4b002322018-07-30 21:23:3196 this._cachedHeight = this.element().offsetHeight;
Blink Reformat4c46d092018-04-07 15:32:3797 }
98
99 /**
100 * @return {number}
101 */
102 fastHeight() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34103 if (this._cachedHeight) {
Blink Reformat4c46d092018-04-07 15:32:37104 return this._cachedHeight;
Tim van der Lippe1d6e57a2019-09-30 11:55:34105 }
Blink Reformat4c46d092018-04-07 15:32:37106 // This value reflects the 18px min-height of .console-message, plus the
107 // 1px border of .console-message-wrapper. Keep in sync with consoleView.css.
108 const defaultConsoleRowHeight = 19;
109 if (this._message.type === SDK.ConsoleMessage.MessageType.Table) {
110 const table = this._message.parameters[0];
Tim van der Lippe1d6e57a2019-09-30 11:55:34111 if (table && table.preview) {
Blink Reformat4c46d092018-04-07 15:32:37112 return defaultConsoleRowHeight * table.preview.properties.length;
Tim van der Lippe1d6e57a2019-09-30 11:55:34113 }
Blink Reformat4c46d092018-04-07 15:32:37114 }
115 return defaultConsoleRowHeight;
116 }
117
118 /**
119 * @return {!SDK.ConsoleMessage}
120 */
121 consoleMessage() {
122 return this._message;
123 }
124
125 /**
126 * @return {!Element}
127 */
128 _buildTableMessage() {
129 const formattedMessage = createElementWithClass('span', 'source-code');
Erik Luo5976c8c2018-07-24 02:03:09130 this._anchorElement = this._buildMessageAnchor();
Tim van der Lippe1d6e57a2019-09-30 11:55:34131 if (this._anchorElement) {
Erik Luo5976c8c2018-07-24 02:03:09132 formattedMessage.appendChild(this._anchorElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34133 }
Blink Reformat4c46d092018-04-07 15:32:37134
135 let table = this._message.parameters && this._message.parameters.length ? this._message.parameters[0] : null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34136 if (table) {
Blink Reformat4c46d092018-04-07 15:32:37137 table = this._parameterToRemoteObject(table);
Tim van der Lippe1d6e57a2019-09-30 11:55:34138 }
139 if (!table || !table.preview) {
Erik Luo16e3e382018-11-09 02:56:01140 return this._buildMessage();
Tim van der Lippe1d6e57a2019-09-30 11:55:34141 }
Blink Reformat4c46d092018-04-07 15:32:37142
143 const rawValueColumnSymbol = Symbol('rawValueColumn');
144 const columnNames = [];
145 const preview = table.preview;
146 const rows = [];
147 for (let i = 0; i < preview.properties.length; ++i) {
148 const rowProperty = preview.properties[i];
149 let rowSubProperties;
Tim van der Lippe1d6e57a2019-09-30 11:55:34150 if (rowProperty.valuePreview) {
Blink Reformat4c46d092018-04-07 15:32:37151 rowSubProperties = rowProperty.valuePreview.properties;
Tim van der Lippe1d6e57a2019-09-30 11:55:34152 } else if (rowProperty.value) {
Blink Reformat4c46d092018-04-07 15:32:37153 rowSubProperties = [{name: rawValueColumnSymbol, type: rowProperty.type, value: rowProperty.value}];
Tim van der Lippe1d6e57a2019-09-30 11:55:34154 } else {
Blink Reformat4c46d092018-04-07 15:32:37155 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34156 }
Blink Reformat4c46d092018-04-07 15:32:37157
158 const rowValue = {};
159 const maxColumnsToRender = 20;
160 for (let j = 0; j < rowSubProperties.length; ++j) {
161 const cellProperty = rowSubProperties[j];
162 let columnRendered = columnNames.indexOf(cellProperty.name) !== -1;
163 if (!columnRendered) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34164 if (columnNames.length === maxColumnsToRender) {
Blink Reformat4c46d092018-04-07 15:32:37165 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34166 }
Blink Reformat4c46d092018-04-07 15:32:37167 columnRendered = true;
168 columnNames.push(cellProperty.name);
169 }
170
171 if (columnRendered) {
172 const cellElement = this._renderPropertyPreviewOrAccessor(table, [rowProperty, cellProperty]);
173 cellElement.classList.add('console-message-nowrap-below');
174 rowValue[cellProperty.name] = cellElement;
175 }
176 }
177 rows.push([rowProperty.name, rowValue]);
178 }
179
180 const flatValues = [];
181 for (let i = 0; i < rows.length; ++i) {
182 const rowName = rows[i][0];
183 const rowValue = rows[i][1];
184 flatValues.push(rowName);
Tim van der Lippe1d6e57a2019-09-30 11:55:34185 for (let j = 0; j < columnNames.length; ++j) {
Blink Reformat4c46d092018-04-07 15:32:37186 flatValues.push(rowValue[columnNames[j]]);
Tim van der Lippe1d6e57a2019-09-30 11:55:34187 }
Blink Reformat4c46d092018-04-07 15:32:37188 }
189 columnNames.unshift(Common.UIString('(index)'));
190 const columnDisplayNames = columnNames.map(name => name === rawValueColumnSymbol ? Common.UIString('Value') : name);
191
192 if (flatValues.length) {
Michael Liao18769f22019-12-12 19:01:25193 this._dataGrid = DataGrid.SortableDataGrid.create(columnDisplayNames, flatValues, ls`Console`);
Blink Reformat4c46d092018-04-07 15:32:37194 this._dataGrid.setStriped(true);
Anubha Mathurfbacf4e2019-10-28 19:08:03195 this._dataGrid.setFocusable(false);
Blink Reformat4c46d092018-04-07 15:32:37196
197 const formattedResult = createElementWithClass('span', 'console-message-text');
198 const tableElement = formattedResult.createChild('div', 'console-message-formatted-table');
199 const dataGridContainer = tableElement.createChild('span');
200 tableElement.appendChild(this._formatParameter(table, true, false));
201 dataGridContainer.appendChild(this._dataGrid.element);
202 formattedMessage.appendChild(formattedResult);
203 this._dataGrid.renderInline();
204 }
205 return formattedMessage;
206 }
207
208 /**
209 * @return {!Element}
210 */
211 _buildMessage() {
212 let messageElement;
213 let messageText = this._message.messageText;
214 if (this._message.source === SDK.ConsoleMessage.MessageSource.ConsoleAPI) {
215 switch (this._message.type) {
216 case SDK.ConsoleMessage.MessageType.Trace:
217 messageElement = this._format(this._message.parameters || ['console.trace']);
218 break;
219 case SDK.ConsoleMessage.MessageType.Clear:
220 messageElement = createElementWithClass('span', 'console-info');
Tim van der Lippe1d6e57a2019-09-30 11:55:34221 if (Common.moduleSetting('preserveConsoleLog').get()) {
Blink Reformat4c46d092018-04-07 15:32:37222 messageElement.textContent = Common.UIString('console.clear() was prevented due to \'Preserve log\'');
Tim van der Lippe1d6e57a2019-09-30 11:55:34223 } else {
Blink Reformat4c46d092018-04-07 15:32:37224 messageElement.textContent = Common.UIString('Console was cleared');
Tim van der Lippe1d6e57a2019-09-30 11:55:34225 }
Blink Reformat4c46d092018-04-07 15:32:37226 messageElement.title =
Lorne Mitchell81a1a972019-03-06 18:13:13227 ls`Clear all messages with ${UI.shortcutRegistry.shortcutTitleForAction('console.clear')}`;
Blink Reformat4c46d092018-04-07 15:32:37228 break;
Blink Reformat4c46d092018-04-07 15:32:37229 case SDK.ConsoleMessage.MessageType.Dir: {
230 const obj = this._message.parameters ? this._message.parameters[0] : undefined;
231 const args = ['%O', obj];
232 messageElement = this._format(args);
233 break;
234 }
235 case SDK.ConsoleMessage.MessageType.Profile:
236 case SDK.ConsoleMessage.MessageType.ProfileEnd:
237 messageElement = this._format([messageText]);
238 break;
Pavel Feldman9f0f0a32018-12-18 02:09:13239 case SDK.ConsoleMessage.MessageType.Assert:
240 this._messagePrefix = ls`Assertion failed: `;
241 // Fall through.
Blink Reformat4c46d092018-04-07 15:32:37242 default: {
243 if (this._message.parameters && this._message.parameters.length === 1 &&
Tim van der Lippe1d6e57a2019-09-30 11:55:34244 this._message.parameters[0].type === 'string') {
Blink Reformat4c46d092018-04-07 15:32:37245 messageElement = this._tryFormatAsError(/** @type {string} */ (this._message.parameters[0].value));
Tim van der Lippe1d6e57a2019-09-30 11:55:34246 }
Blink Reformat4c46d092018-04-07 15:32:37247 const args = this._message.parameters || [messageText];
248 messageElement = messageElement || this._format(args);
249 }
250 }
251 } else {
Erik Luofc2214f2018-11-21 19:54:58252 if (this._message.source === SDK.ConsoleMessage.MessageSource.Network) {
253 messageElement = this._formatAsNetworkRequest() || this._format([messageText]);
254 } else {
Blink Reformat4c46d092018-04-07 15:32:37255 const messageInParameters =
256 this._message.parameters && messageText === /** @type {string} */ (this._message.parameters[0]);
Tim van der Lippe1d6e57a2019-09-30 11:55:34257 if (this._message.source === SDK.ConsoleMessage.MessageSource.Violation) {
Blink Reformat4c46d092018-04-07 15:32:37258 messageText = Common.UIString('[Violation] %s', messageText);
Tim van der Lippe1d6e57a2019-09-30 11:55:34259 } else if (this._message.source === SDK.ConsoleMessage.MessageSource.Intervention) {
Blink Reformat4c46d092018-04-07 15:32:37260 messageText = Common.UIString('[Intervention] %s', messageText);
Tim van der Lippe1d6e57a2019-09-30 11:55:34261 } else if (this._message.source === SDK.ConsoleMessage.MessageSource.Deprecation) {
Blink Reformat4c46d092018-04-07 15:32:37262 messageText = Common.UIString('[Deprecation] %s', messageText);
Tim van der Lippe1d6e57a2019-09-30 11:55:34263 }
Blink Reformat4c46d092018-04-07 15:32:37264 const args = this._message.parameters || [messageText];
Tim van der Lippe1d6e57a2019-09-30 11:55:34265 if (messageInParameters) {
Blink Reformat4c46d092018-04-07 15:32:37266 args[0] = messageText;
Tim van der Lippe1d6e57a2019-09-30 11:55:34267 }
Blink Reformat4c46d092018-04-07 15:32:37268 messageElement = this._format(args);
269 }
270 }
271 messageElement.classList.add('console-message-text');
272
273 const formattedMessage = createElementWithClass('span', 'source-code');
Erik Luo5976c8c2018-07-24 02:03:09274 this._anchorElement = this._buildMessageAnchor();
Tim van der Lippe1d6e57a2019-09-30 11:55:34275 if (this._anchorElement) {
Erik Luo5976c8c2018-07-24 02:03:09276 formattedMessage.appendChild(this._anchorElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34277 }
Blink Reformat4c46d092018-04-07 15:32:37278 formattedMessage.appendChild(messageElement);
279 return formattedMessage;
280 }
281
282 /**
283 * @return {?Element}
284 */
Erik Luofc2214f2018-11-21 19:54:58285 _formatAsNetworkRequest() {
286 const request = SDK.NetworkLog.requestForConsoleMessage(this._message);
Tim van der Lippe1d6e57a2019-09-30 11:55:34287 if (!request) {
Erik Luofc2214f2018-11-21 19:54:58288 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34289 }
Erik Luofc2214f2018-11-21 19:54:58290 const messageElement = createElement('span');
291 if (this._message.level === SDK.ConsoleMessage.MessageLevel.Error) {
292 messageElement.createTextChild(request.requestMethod + ' ');
Erik Luo182bece2018-11-29 03:15:22293 const linkElement = Components.Linkifier.linkifyRevealable(request, request.url(), request.url());
294 // Focus is handled by the viewport.
295 linkElement.tabIndex = -1;
Erik Luo31c21f62018-12-13 03:39:39296 this._selectableChildren.push({element: linkElement, forceSelect: () => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22297 messageElement.appendChild(linkElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34298 if (request.failed) {
Erik Luofc2214f2018-11-21 19:54:58299 messageElement.createTextChildren(' ', request.localizedFailDescription);
Tim van der Lippe1d6e57a2019-09-30 11:55:34300 }
301 if (request.statusCode !== 0) {
Erik Luofc2214f2018-11-21 19:54:58302 messageElement.createTextChildren(' ', String(request.statusCode));
Tim van der Lippe1d6e57a2019-09-30 11:55:34303 }
304 if (request.statusText) {
Erik Luofc2214f2018-11-21 19:54:58305 messageElement.createTextChildren(' (', request.statusText, ')');
Tim van der Lippe1d6e57a2019-09-30 11:55:34306 }
Erik Luofc2214f2018-11-21 19:54:58307 } else {
Erik Luoad5f3942019-03-26 20:53:44308 const messageText = this._message.messageText;
309 const fragment = this._linkifyWithCustomLinkifier(messageText, (text, url, lineNumber, columnNumber) => {
310 let linkElement;
311 if (url === request.url()) {
312 linkElement = Components.Linkifier.linkifyRevealable(
313 /** @type {!SDK.NetworkRequest} */ (request), url, request.url());
314 } else {
315 linkElement = Components.Linkifier.linkifyURL(url, {text, lineNumber, columnNumber});
316 }
Erik Luo182bece2018-11-29 03:15:22317 linkElement.tabIndex = -1;
Erik Luo31c21f62018-12-13 03:39:39318 this._selectableChildren.push({element: linkElement, forceSelect: () => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22319 return linkElement;
320 });
Erik Luofc2214f2018-11-21 19:54:58321 messageElement.appendChild(fragment);
322 }
323 return messageElement;
324 }
325
326 /**
327 * @return {?Element}
328 */
Blink Reformat4c46d092018-04-07 15:32:37329 _buildMessageAnchor() {
330 let anchorElement = null;
331 if (this._message.scriptId) {
332 anchorElement = this._linkifyScriptId(
333 this._message.scriptId, this._message.url || '', this._message.line, this._message.column);
334 } else if (this._message.stackTrace && this._message.stackTrace.callFrames.length) {
335 anchorElement = this._linkifyStackTraceTopFrame(this._message.stackTrace);
336 } else if (this._message.url && this._message.url !== 'undefined') {
337 anchorElement = this._linkifyLocation(this._message.url, this._message.line, this._message.column);
338 }
339
340 // Append a space to prevent the anchor text from being glued to the console message when the user selects and copies the console messages.
341 if (anchorElement) {
John Emauf7e30fb2019-10-04 19:12:32342 anchorElement.tabIndex = -1;
343 this._selectableChildren.push({
344 element: anchorElement,
345 forceSelect: () => anchorElement.focus(),
346 });
Blink Reformat4c46d092018-04-07 15:32:37347 const anchorWrapperElement = createElementWithClass('span', 'console-message-anchor');
348 anchorWrapperElement.appendChild(anchorElement);
349 anchorWrapperElement.createTextChild(' ');
350 return anchorWrapperElement;
351 }
352 return null;
353 }
354
355 /**
Blink Reformat4c46d092018-04-07 15:32:37356 * @return {!Element}
357 */
358 _buildMessageWithStackTrace() {
359 const toggleElement = createElementWithClass('div', 'console-message-stack-trace-toggle');
360 const contentElement = toggleElement.createChild('div', 'console-message-stack-trace-wrapper');
361
362 const messageElement = this._buildMessage();
363 const icon = UI.Icon.create('smallicon-triangle-right', 'console-message-expand-icon');
364 const clickableElement = contentElement.createChild('div');
365 clickableElement.appendChild(icon);
Erik Luob5bfff42018-09-20 02:52:39366 // Intercept focus to avoid highlight on click.
367 clickableElement.tabIndex = -1;
Blink Reformat4c46d092018-04-07 15:32:37368
369 clickableElement.appendChild(messageElement);
370 const stackTraceElement = contentElement.createChild('div');
371 const stackTracePreview = Components.JSPresentationUtils.buildStackTracePreviewContents(
372 this._message.runtimeModel().target(), this._linkifier, this._message.stackTrace);
Erik Luo182bece2018-11-29 03:15:22373 stackTraceElement.appendChild(stackTracePreview.element);
374 for (const linkElement of stackTracePreview.links) {
375 linkElement.tabIndex = -1;
Erik Luo31c21f62018-12-13 03:39:39376 this._selectableChildren.push({element: linkElement, forceSelect: () => linkElement.focus()});
Erik Luo182bece2018-11-29 03:15:22377 }
Blink Reformat4c46d092018-04-07 15:32:37378 stackTraceElement.classList.add('hidden');
Brandon Goddard04a5a762019-12-10 16:45:53379 UI.ARIAUtils.markAsTreeitem(this.element());
380 UI.ARIAUtils.setExpanded(this.element(), false);
Erik Luo8ef5d0c2018-09-25 21:16:00381 this._expandTrace = expand => {
Blink Reformat4c46d092018-04-07 15:32:37382 icon.setIconType(expand ? 'smallicon-triangle-down' : 'smallicon-triangle-right');
383 stackTraceElement.classList.toggle('hidden', !expand);
Brandon Goddard04a5a762019-12-10 16:45:53384 UI.ARIAUtils.setExpanded(this.element(), expand);
Erik Luo8ef5d0c2018-09-25 21:16:00385 this._traceExpanded = expand;
386 };
Blink Reformat4c46d092018-04-07 15:32:37387
388 /**
Erik Luo8ef5d0c2018-09-25 21:16:00389 * @this {!Console.ConsoleViewMessage}
Blink Reformat4c46d092018-04-07 15:32:37390 * @param {?Event} event
391 */
392 function toggleStackTrace(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34393 if (UI.isEditing() || contentElement.hasSelection()) {
Blink Reformat4c46d092018-04-07 15:32:37394 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34395 }
Erik Luo8ef5d0c2018-09-25 21:16:00396 this._expandTrace(stackTraceElement.classList.contains('hidden'));
Blink Reformat4c46d092018-04-07 15:32:37397 event.consume();
398 }
399
Erik Luo8ef5d0c2018-09-25 21:16:00400 clickableElement.addEventListener('click', toggleStackTrace.bind(this), false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34401 if (this._message.type === SDK.ConsoleMessage.MessageType.Trace) {
Erik Luo8ef5d0c2018-09-25 21:16:00402 this._expandTrace(true);
Tim van der Lippe1d6e57a2019-09-30 11:55:34403 }
Blink Reformat4c46d092018-04-07 15:32:37404
Erik Luo8ef5d0c2018-09-25 21:16:00405 toggleElement._expandStackTraceForTest = this._expandTrace.bind(this, true);
Blink Reformat4c46d092018-04-07 15:32:37406 return toggleElement;
407 }
408
409 /**
410 * @param {string} url
411 * @param {number} lineNumber
412 * @param {number} columnNumber
413 * @return {?Element}
414 */
415 _linkifyLocation(url, lineNumber, columnNumber) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34416 if (!this._message.runtimeModel()) {
Blink Reformat4c46d092018-04-07 15:32:37417 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34418 }
Blink Reformat4c46d092018-04-07 15:32:37419 return this._linkifier.linkifyScriptLocation(
420 this._message.runtimeModel().target(), null, url, lineNumber, columnNumber);
421 }
422
423 /**
424 * @param {!Protocol.Runtime.StackTrace} stackTrace
425 * @return {?Element}
426 */
427 _linkifyStackTraceTopFrame(stackTrace) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34428 if (!this._message.runtimeModel()) {
Blink Reformat4c46d092018-04-07 15:32:37429 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34430 }
Blink Reformat4c46d092018-04-07 15:32:37431 return this._linkifier.linkifyStackTraceTopFrame(this._message.runtimeModel().target(), stackTrace);
432 }
433
434 /**
435 * @param {string} scriptId
436 * @param {string} url
437 * @param {number} lineNumber
438 * @param {number} columnNumber
439 * @return {?Element}
440 */
441 _linkifyScriptId(scriptId, url, lineNumber, columnNumber) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34442 if (!this._message.runtimeModel()) {
Blink Reformat4c46d092018-04-07 15:32:37443 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34444 }
Blink Reformat4c46d092018-04-07 15:32:37445 return this._linkifier.linkifyScriptLocation(
446 this._message.runtimeModel().target(), scriptId, url, lineNumber, columnNumber);
447 }
448
449 /**
450 * @param {!SDK.RemoteObject|!Protocol.Runtime.RemoteObject|string} parameter
451 * @return {!SDK.RemoteObject}
452 */
453 _parameterToRemoteObject(parameter) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34454 if (parameter instanceof SDK.RemoteObject) {
Blink Reformat4c46d092018-04-07 15:32:37455 return parameter;
Tim van der Lippe1d6e57a2019-09-30 11:55:34456 }
Blink Reformat4c46d092018-04-07 15:32:37457 const runtimeModel = this._message.runtimeModel();
Tim van der Lippe1d6e57a2019-09-30 11:55:34458 if (!runtimeModel) {
Blink Reformat4c46d092018-04-07 15:32:37459 return SDK.RemoteObject.fromLocalObject(parameter);
Tim van der Lippe1d6e57a2019-09-30 11:55:34460 }
461 if (typeof parameter === 'object') {
Blink Reformat4c46d092018-04-07 15:32:37462 return runtimeModel.createRemoteObject(parameter);
Tim van der Lippe1d6e57a2019-09-30 11:55:34463 }
Blink Reformat4c46d092018-04-07 15:32:37464 return runtimeModel.createRemoteObjectFromPrimitiveValue(parameter);
465 }
466
467 /**
468 * @param {!Array.<!SDK.RemoteObject|string>} rawParameters
469 * @return {!Element}
470 */
471 _format(rawParameters) {
472 // This node is used like a Builder. Values are continually appended onto it.
473 const formattedResult = createElement('span');
Tim van der Lippe1d6e57a2019-09-30 11:55:34474 if (this._messagePrefix) {
Pavel Feldman9f0f0a32018-12-18 02:09:13475 formattedResult.createChild('span').textContent = this._messagePrefix;
Tim van der Lippe1d6e57a2019-09-30 11:55:34476 }
477 if (!rawParameters.length) {
Blink Reformat4c46d092018-04-07 15:32:37478 return formattedResult;
Tim van der Lippe1d6e57a2019-09-30 11:55:34479 }
Blink Reformat4c46d092018-04-07 15:32:37480
481 // Formatting code below assumes that parameters are all wrappers whereas frontend console
482 // API allows passing arbitrary values as messages (strings, numbers, etc.). Wrap them here.
483 // FIXME: Only pass runtime wrappers here.
484 let parameters = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:34485 for (let i = 0; i < rawParameters.length; ++i) {
Blink Reformat4c46d092018-04-07 15:32:37486 parameters[i] = this._parameterToRemoteObject(rawParameters[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:34487 }
Blink Reformat4c46d092018-04-07 15:32:37488
489 // There can be string log and string eval result. We distinguish between them based on message type.
490 const shouldFormatMessage =
491 SDK.RemoteObject.type((/** @type {!Array.<!SDK.RemoteObject>} **/ (parameters))[0]) === 'string' &&
492 (this._message.type !== SDK.ConsoleMessage.MessageType.Result ||
493 this._message.level === SDK.ConsoleMessage.MessageLevel.Error);
494
495 // Multiple parameters with the first being a format string. Save unused substitutions.
496 if (shouldFormatMessage) {
497 const result = this._formatWithSubstitutionString(
498 /** @type {string} **/ (parameters[0].description), parameters.slice(1), formattedResult);
499 parameters = result.unusedSubstitutions;
Tim van der Lippe1d6e57a2019-09-30 11:55:34500 if (parameters.length) {
Blink Reformat4c46d092018-04-07 15:32:37501 formattedResult.createTextChild(' ');
Tim van der Lippe1d6e57a2019-09-30 11:55:34502 }
Blink Reformat4c46d092018-04-07 15:32:37503 }
504
505 // Single parameter, or unused substitutions from above.
506 for (let i = 0; i < parameters.length; ++i) {
507 // Inline strings when formatting.
Tim van der Lippe1d6e57a2019-09-30 11:55:34508 if (shouldFormatMessage && parameters[i].type === 'string') {
Erik Luo383f21d2018-11-07 23:16:37509 formattedResult.appendChild(this._linkifyStringAsFragment(parameters[i].description));
Tim van der Lippe1d6e57a2019-09-30 11:55:34510 } else {
Blink Reformat4c46d092018-04-07 15:32:37511 formattedResult.appendChild(this._formatParameter(parameters[i], false, true));
Tim van der Lippe1d6e57a2019-09-30 11:55:34512 }
513 if (i < parameters.length - 1) {
Blink Reformat4c46d092018-04-07 15:32:37514 formattedResult.createTextChild(' ');
Tim van der Lippe1d6e57a2019-09-30 11:55:34515 }
Blink Reformat4c46d092018-04-07 15:32:37516 }
517 return formattedResult;
518 }
519
520 /**
521 * @param {!SDK.RemoteObject} output
522 * @param {boolean=} forceObjectFormat
523 * @param {boolean=} includePreview
524 * @return {!Element}
525 */
526 _formatParameter(output, forceObjectFormat, includePreview) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34527 if (output.customPreview()) {
Blink Reformat4c46d092018-04-07 15:32:37528 return (new ObjectUI.CustomPreviewComponent(output)).element;
Tim van der Lippe1d6e57a2019-09-30 11:55:34529 }
Blink Reformat4c46d092018-04-07 15:32:37530
531 const type = forceObjectFormat ? 'object' : (output.subtype || output.type);
532 let element;
533 switch (type) {
534 case 'error':
535 element = this._formatParameterAsError(output);
536 break;
537 case 'function':
538 element = this._formatParameterAsFunction(output, includePreview);
539 break;
540 case 'array':
541 case 'arraybuffer':
542 case 'blob':
543 case 'dataview':
544 case 'generator':
545 case 'iterator':
546 case 'map':
547 case 'object':
548 case 'promise':
549 case 'proxy':
550 case 'set':
551 case 'typedarray':
552 case 'weakmap':
553 case 'weakset':
554 element = this._formatParameterAsObject(output, includePreview);
555 break;
556 case 'node':
557 element = output.isNode() ? this._formatParameterAsNode(output) : this._formatParameterAsObject(output, false);
558 break;
559 case 'string':
560 element = this._formatParameterAsString(output);
561 break;
562 case 'boolean':
563 case 'date':
564 case 'null':
565 case 'number':
566 case 'regexp':
567 case 'symbol':
568 case 'undefined':
569 case 'bigint':
570 element = this._formatParameterAsValue(output);
571 break;
572 default:
573 element = this._formatParameterAsValue(output);
574 console.error('Tried to format remote object of unknown type.');
575 }
576 element.classList.add('object-value-' + type);
577 element.classList.add('source-code');
578 return element;
579 }
580
581 /**
582 * @param {!SDK.RemoteObject} obj
583 * @return {!Element}
584 */
585 _formatParameterAsValue(obj) {
586 const result = createElement('span');
587 const description = obj.description || '';
Tim van der Lippe1d6e57a2019-09-30 11:55:34588 if (description.length > Console.ConsoleViewMessage._MaxTokenizableStringLength) {
Connor Moody1a5c0d32019-12-19 07:23:36589 const propertyValue = new ObjectUI.ExpandableTextPropertyValue(
590 createElement('span'), description, Console.ConsoleViewMessage._LongStringVisibleLength);
591 result.appendChild(propertyValue.element);
Tim van der Lippe1d6e57a2019-09-30 11:55:34592 } else {
Blink Reformat4c46d092018-04-07 15:32:37593 result.createTextChild(description);
Tim van der Lippe1d6e57a2019-09-30 11:55:34594 }
595 if (obj.objectId) {
Blink Reformat4c46d092018-04-07 15:32:37596 result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, obj), false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34597 }
Blink Reformat4c46d092018-04-07 15:32:37598 return result;
599 }
600
601 /**
602 * @param {!SDK.RemoteObject} obj
603 * @param {boolean=} includePreview
604 * @return {!Element}
605 */
606 _formatParameterAsObject(obj, includePreview) {
607 const titleElement = createElementWithClass('span', 'console-object');
608 if (includePreview && obj.preview) {
609 titleElement.classList.add('console-object-preview');
610 this._previewFormatter.appendObjectPreview(titleElement, obj.preview, false /* isEntry */);
611 } else if (obj.type === 'function') {
612 const functionElement = titleElement.createChild('span');
613 ObjectUI.ObjectPropertiesSection.formatObjectAsFunction(obj, functionElement, false);
614 titleElement.classList.add('object-value-function');
615 } else {
616 titleElement.createTextChild(obj.description || '');
617 }
618
Tim van der Lippe1d6e57a2019-09-30 11:55:34619 if (!obj.hasChildren || obj.customPreview()) {
Blink Reformat4c46d092018-04-07 15:32:37620 return titleElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:34621 }
Blink Reformat4c46d092018-04-07 15:32:37622
623 const note = titleElement.createChild('span', 'object-state-note info-note');
Tim van der Lippe1d6e57a2019-09-30 11:55:34624 if (this._message.type === SDK.ConsoleMessage.MessageType.QueryObjectResult) {
Blink Reformat4c46d092018-04-07 15:32:37625 note.title = ls`This value will not be collected until console is cleared.`;
Tim van der Lippe1d6e57a2019-09-30 11:55:34626 } else {
Blink Reformat4c46d092018-04-07 15:32:37627 note.title = ls`Value below was evaluated just now.`;
Tim van der Lippe1d6e57a2019-09-30 11:55:34628 }
Blink Reformat4c46d092018-04-07 15:32:37629
630 const section = new ObjectUI.ObjectPropertiesSection(obj, titleElement, this._linkifier);
631 section.element.classList.add('console-view-object-properties-section');
632 section.enableContextMenu();
Erik Luocc14b812018-11-03 01:33:09633 section.setShowSelectionOnKeyboardFocus(true, true);
Erik Luo383f21d2018-11-07 23:16:37634 this._selectableChildren.push(section);
Erik Luo840be6b2018-12-03 20:54:27635 section.addEventListener(UI.TreeOutline.Events.ElementAttached, this._messageResized);
636 section.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._messageResized);
637 section.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._messageResized);
Blink Reformat4c46d092018-04-07 15:32:37638 return section.element;
639 }
640
641 /**
642 * @param {!SDK.RemoteObject} func
643 * @param {boolean=} includePreview
644 * @return {!Element}
645 */
646 _formatParameterAsFunction(func, includePreview) {
647 const result = createElement('span');
648 SDK.RemoteFunction.objectAsFunction(func).targetFunction().then(formatTargetFunction.bind(this));
649 return result;
650
651 /**
652 * @param {!SDK.RemoteObject} targetFunction
653 * @this {Console.ConsoleViewMessage}
654 */
655 function formatTargetFunction(targetFunction) {
656 const functionElement = createElement('span');
Joey Arhard78a58f2018-12-05 01:59:45657 const promise = ObjectUI.ObjectPropertiesSection.formatObjectAsFunction(
658 targetFunction, functionElement, true, includePreview);
Blink Reformat4c46d092018-04-07 15:32:37659 result.appendChild(functionElement);
660 if (targetFunction !== func) {
661 const note = result.createChild('span', 'object-info-state-note');
662 note.title = Common.UIString('Function was resolved from bound function.');
663 }
664 result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, targetFunction), false);
Joey Arhard78a58f2018-12-05 01:59:45665 promise.then(() => this._formattedParameterAsFunctionForTest());
Blink Reformat4c46d092018-04-07 15:32:37666 }
667 }
668
Joey Arhard78a58f2018-12-05 01:59:45669 _formattedParameterAsFunctionForTest() {
670 }
671
Blink Reformat4c46d092018-04-07 15:32:37672 /**
673 * @param {!SDK.RemoteObject} obj
674 * @param {!Event} event
675 */
676 _contextMenuEventFired(obj, event) {
677 const contextMenu = new UI.ContextMenu(event);
678 contextMenu.appendApplicableItems(obj);
679 contextMenu.show();
680 }
681
682 /**
683 * @param {?SDK.RemoteObject} object
684 * @param {!Array.<!Protocol.Runtime.PropertyPreview>} propertyPath
685 * @return {!Element}
686 */
687 _renderPropertyPreviewOrAccessor(object, propertyPath) {
688 const property = propertyPath.peekLast();
Tim van der Lippe1d6e57a2019-09-30 11:55:34689 if (property.type === 'accessor') {
Blink Reformat4c46d092018-04-07 15:32:37690 return this._formatAsAccessorProperty(object, propertyPath.map(property => property.name), false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34691 }
Blink Reformat4c46d092018-04-07 15:32:37692 return this._previewFormatter.renderPropertyPreview(
693 property.type, /** @type {string} */ (property.subtype), property.value);
694 }
695
696 /**
697 * @param {!SDK.RemoteObject} remoteObject
698 * @return {!Element}
699 */
700 _formatParameterAsNode(remoteObject) {
701 const result = createElement('span');
702
703 const domModel = remoteObject.runtimeModel().target().model(SDK.DOMModel);
Tim van der Lippe1d6e57a2019-09-30 11:55:34704 if (!domModel) {
Blink Reformat4c46d092018-04-07 15:32:37705 return result;
Tim van der Lippe1d6e57a2019-09-30 11:55:34706 }
Erik Luo54fdd912018-11-01 17:57:01707 domModel.pushObjectAsNodeToFrontend(remoteObject).then(async node => {
Blink Reformat4c46d092018-04-07 15:32:37708 if (!node) {
709 result.appendChild(this._formatParameterAsObject(remoteObject, false));
710 return;
711 }
Erik Luo54fdd912018-11-01 17:57:01712 const renderResult = await UI.Renderer.render(/** @type {!Object} */ (node));
Erik Luofc6a6302018-11-02 06:48:52713 if (renderResult) {
Erik Luo840be6b2018-12-03 20:54:27714 if (renderResult.tree) {
Erik Luo383f21d2018-11-07 23:16:37715 this._selectableChildren.push(renderResult.tree);
Erik Luo840be6b2018-12-03 20:54:27716 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementAttached, this._messageResized);
717 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._messageResized);
718 renderResult.tree.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._messageResized);
719 }
Erik Luofc6a6302018-11-02 06:48:52720 result.appendChild(renderResult.node);
721 } else {
722 result.appendChild(this._formatParameterAsObject(remoteObject, false));
723 }
Erik Luo54fdd912018-11-01 17:57:01724 this._formattedParameterAsNodeForTest();
Blink Reformat4c46d092018-04-07 15:32:37725 });
726
727 return result;
728 }
729
730 _formattedParameterAsNodeForTest() {
731 }
732
733 /**
734 * @param {!SDK.RemoteObject} output
735 * @return {!Element}
736 */
737 _formatParameterAsString(output) {
738 const span = createElement('span');
Erik Luo383f21d2018-11-07 23:16:37739 span.appendChild(this._linkifyStringAsFragment(output.description || ''));
Blink Reformat4c46d092018-04-07 15:32:37740
741 const result = createElement('span');
742 result.createChild('span', 'object-value-string-quote').textContent = '"';
743 result.appendChild(span);
744 result.createChild('span', 'object-value-string-quote').textContent = '"';
745 return result;
746 }
747
748 /**
749 * @param {!SDK.RemoteObject} output
750 * @return {!Element}
751 */
752 _formatParameterAsError(output) {
753 const result = createElement('span');
754 const errorSpan = this._tryFormatAsError(output.description || '');
Erik Luo383f21d2018-11-07 23:16:37755 result.appendChild(errorSpan ? errorSpan : this._linkifyStringAsFragment(output.description || ''));
Blink Reformat4c46d092018-04-07 15:32:37756 return result;
757 }
758
759 /**
760 * @param {!SDK.RemoteObject} output
761 * @return {!Element}
762 */
763 _formatAsArrayEntry(output) {
764 return this._previewFormatter.renderPropertyPreview(output.type, output.subtype, output.description);
765 }
766
767 /**
768 * @param {?SDK.RemoteObject} object
769 * @param {!Array.<string>} propertyPath
770 * @param {boolean} isArrayEntry
771 * @return {!Element}
772 */
773 _formatAsAccessorProperty(object, propertyPath, isArrayEntry) {
774 const rootElement = ObjectUI.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan(
775 object, propertyPath, onInvokeGetterClick.bind(this));
776
777 /**
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18778 * @param {!SDK.CallFunctionResult} result
Blink Reformat4c46d092018-04-07 15:32:37779 * @this {Console.ConsoleViewMessage}
780 */
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18781 function onInvokeGetterClick(result) {
782 const wasThrown = result.wasThrown;
783 const object = result.object;
Tim van der Lippe1d6e57a2019-09-30 11:55:34784 if (!object) {
Blink Reformat4c46d092018-04-07 15:32:37785 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34786 }
Blink Reformat4c46d092018-04-07 15:32:37787 rootElement.removeChildren();
788 if (wasThrown) {
789 const element = rootElement.createChild('span');
790 element.textContent = Common.UIString('<exception>');
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18791 element.title = /** @type {string} */ (object.description);
Blink Reformat4c46d092018-04-07 15:32:37792 } else if (isArrayEntry) {
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18793 rootElement.appendChild(this._formatAsArrayEntry(object));
Blink Reformat4c46d092018-04-07 15:32:37794 } else {
795 // Make a PropertyPreview from the RemoteObject similar to the backend logic.
796 const maxLength = 100;
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18797 const type = object.type;
798 const subtype = object.subtype;
Blink Reformat4c46d092018-04-07 15:32:37799 let description = '';
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18800 if (type !== 'function' && object.description) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34801 if (type === 'string' || subtype === 'regexp') {
Alexey Kozyatinskiy330bffb2018-09-21 19:20:18802 description = object.description.trimMiddle(maxLength);
Tim van der Lippe1d6e57a2019-09-30 11:55:34803 } else {
Tim van der Lippeffa78622019-09-16 12:07:12804 description = object.description.trimEndWithMaxLength(maxLength);
Tim van der Lippe1d6e57a2019-09-30 11:55:34805 }
Blink Reformat4c46d092018-04-07 15:32:37806 }
807 rootElement.appendChild(this._previewFormatter.renderPropertyPreview(type, subtype, description));
808 }
809 }
810
811 return rootElement;
812 }
813
814 /**
815 * @param {string} format
816 * @param {!Array.<!SDK.RemoteObject>} parameters
817 * @param {!Element} formattedResult
818 */
819 _formatWithSubstitutionString(format, parameters, formattedResult) {
820 const formatters = {};
821
822 /**
823 * @param {boolean} force
824 * @param {boolean} includePreview
825 * @param {!SDK.RemoteObject} obj
826 * @return {!Element}
827 * @this {Console.ConsoleViewMessage}
828 */
829 function parameterFormatter(force, includePreview, obj) {
830 return this._formatParameter(obj, force, includePreview);
831 }
832
833 function stringFormatter(obj) {
834 return obj.description;
835 }
836
837 function floatFormatter(obj) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34838 if (typeof obj.value !== 'number') {
Blink Reformat4c46d092018-04-07 15:32:37839 return 'NaN';
Tim van der Lippe1d6e57a2019-09-30 11:55:34840 }
Blink Reformat4c46d092018-04-07 15:32:37841 return obj.value;
842 }
843
844 function integerFormatter(obj) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34845 if (obj.type === 'bigint') {
Alexey Kozyatinskiybeb38de2018-08-10 18:54:19846 return obj.description;
Tim van der Lippe1d6e57a2019-09-30 11:55:34847 }
848 if (typeof obj.value !== 'number') {
Blink Reformat4c46d092018-04-07 15:32:37849 return 'NaN';
Tim van der Lippe1d6e57a2019-09-30 11:55:34850 }
Blink Reformat4c46d092018-04-07 15:32:37851 return Math.floor(obj.value);
852 }
853
854 function bypassFormatter(obj) {
855 return (obj instanceof Node) ? obj : '';
856 }
857
858 let currentStyle = null;
859 function styleFormatter(obj) {
860 currentStyle = {};
861 const buffer = createElement('span');
862 buffer.setAttribute('style', obj.description);
863 for (let i = 0; i < buffer.style.length; i++) {
864 const property = buffer.style[i];
Tim van der Lippe1d6e57a2019-09-30 11:55:34865 if (isWhitelistedProperty(property)) {
Blink Reformat4c46d092018-04-07 15:32:37866 currentStyle[property] = buffer.style[property];
Tim van der Lippe1d6e57a2019-09-30 11:55:34867 }
Blink Reformat4c46d092018-04-07 15:32:37868 }
869 }
870
871 function isWhitelistedProperty(property) {
872 // Make sure that allowed properties do not interfere with link visibility.
873 const prefixes = [
874 'background', 'border', 'color', 'font', 'line', 'margin', 'padding', 'text', '-webkit-background',
875 '-webkit-border', '-webkit-font', '-webkit-margin', '-webkit-padding', '-webkit-text'
876 ];
877 for (let i = 0; i < prefixes.length; i++) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34878 if (property.startsWith(prefixes[i])) {
Blink Reformat4c46d092018-04-07 15:32:37879 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:34880 }
Blink Reformat4c46d092018-04-07 15:32:37881 }
882 return false;
883 }
884
885 // Firebug uses %o for formatting objects.
886 formatters.o = parameterFormatter.bind(this, false /* force */, true /* includePreview */);
887 formatters.s = stringFormatter;
888 formatters.f = floatFormatter;
889 // Firebug allows both %i and %d for formatting integers.
890 formatters.i = integerFormatter;
891 formatters.d = integerFormatter;
892
893 // Firebug uses %c for styling the message.
894 formatters.c = styleFormatter;
895
896 // Support %O to force object formatting, instead of the type-based %o formatting.
897 formatters.O = parameterFormatter.bind(this, true /* force */, false /* includePreview */);
898
899 formatters._ = bypassFormatter;
900
901 /**
902 * @param {!Element} a
903 * @param {*} b
904 * @this {!Console.ConsoleViewMessage}
Erik Luo17926392018-05-17 22:06:12905 * @return {!Element}
Blink Reformat4c46d092018-04-07 15:32:37906 */
907 function append(a, b) {
908 if (b instanceof Node) {
909 a.appendChild(b);
Erik Luo17926392018-05-17 22:06:12910 return a;
911 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34912 if (typeof b === 'undefined') {
Erik Luo17926392018-05-17 22:06:12913 return a;
Tim van der Lippe1d6e57a2019-09-30 11:55:34914 }
Erik Luo17926392018-05-17 22:06:12915 if (!currentStyle) {
Erik Luo383f21d2018-11-07 23:16:37916 a.appendChild(this._linkifyStringAsFragment(String(b)));
Erik Luo17926392018-05-17 22:06:12917 return a;
918 }
919 const lines = String(b).split('\n');
920 for (let i = 0; i < lines.length; i++) {
921 const line = lines[i];
Erik Luo383f21d2018-11-07 23:16:37922 const lineFragment = this._linkifyStringAsFragment(line);
Erik Luo17926392018-05-17 22:06:12923 const wrapper = createElement('span');
924 wrapper.style.setProperty('contain', 'paint');
925 wrapper.style.setProperty('display', 'inline-block');
926 wrapper.style.setProperty('max-width', '100%');
927 wrapper.appendChild(lineFragment);
928 applyCurrentStyle(wrapper);
929 for (const child of wrapper.children) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34930 if (child.classList.contains('devtools-link')) {
Erik Luo17926392018-05-17 22:06:12931 this._applyForcedVisibleStyle(child);
Tim van der Lippe1d6e57a2019-09-30 11:55:34932 }
Blink Reformat4c46d092018-04-07 15:32:37933 }
Erik Luo17926392018-05-17 22:06:12934 a.appendChild(wrapper);
Tim van der Lippe1d6e57a2019-09-30 11:55:34935 if (i < lines.length - 1) {
Erik Luo17926392018-05-17 22:06:12936 a.appendChild(createElement('br'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34937 }
Blink Reformat4c46d092018-04-07 15:32:37938 }
939 return a;
940 }
941
942 /**
943 * @param {!Element} element
944 */
945 function applyCurrentStyle(element) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34946 for (const key in currentStyle) {
Blink Reformat4c46d092018-04-07 15:32:37947 element.style[key] = currentStyle[key];
Tim van der Lippe1d6e57a2019-09-30 11:55:34948 }
Blink Reformat4c46d092018-04-07 15:32:37949 }
950
951 // String.format does treat formattedResult like a Builder, result is an object.
952 return String.format(format, parameters, formatters, formattedResult, append.bind(this));
953 }
954
955 /**
956 * @param {!Element} element
957 */
958 _applyForcedVisibleStyle(element) {
959 element.style.setProperty('-webkit-text-stroke', '0', 'important');
960 element.style.setProperty('text-decoration', 'underline', 'important');
961
962 const themedColor = UI.themeSupport.patchColorText('rgb(33%, 33%, 33%)', UI.ThemeSupport.ColorUsage.Foreground);
963 element.style.setProperty('color', themedColor, 'important');
964
965 let backgroundColor = 'hsl(0, 0%, 100%)';
Tim van der Lippe1d6e57a2019-09-30 11:55:34966 if (this._message.level === SDK.ConsoleMessage.MessageLevel.Error) {
Blink Reformat4c46d092018-04-07 15:32:37967 backgroundColor = 'hsl(0, 100%, 97%)';
Tim van der Lippe1d6e57a2019-09-30 11:55:34968 } else if (this._message.level === SDK.ConsoleMessage.MessageLevel.Warning || this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:37969 backgroundColor = 'hsl(50, 100%, 95%)';
Tim van der Lippe1d6e57a2019-09-30 11:55:34970 }
Blink Reformat4c46d092018-04-07 15:32:37971 const themedBackgroundColor =
972 UI.themeSupport.patchColorText(backgroundColor, UI.ThemeSupport.ColorUsage.Background);
973 element.style.setProperty('background-color', themedBackgroundColor, 'important');
974 }
975
976 /**
977 * @return {boolean}
978 */
979 matchesFilterRegex(regexObject) {
980 regexObject.lastIndex = 0;
Erik Luo5976c8c2018-07-24 02:03:09981 const contentElement = this.contentElement();
982 const anchorText = this._anchorElement ? this._anchorElement.deepTextContent() : '';
983 return (anchorText && regexObject.test(anchorText.trim())) ||
984 regexObject.test(contentElement.deepTextContent().slice(anchorText.length));
Blink Reformat4c46d092018-04-07 15:32:37985 }
986
987 /**
988 * @param {string} filter
989 * @return {boolean}
990 */
991 matchesFilterText(filter) {
992 const text = this.contentElement().deepTextContent();
993 return text.toLowerCase().includes(filter.toLowerCase());
994 }
995
996 updateTimestamp() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34997 if (!this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:37998 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34999 }
Blink Reformat4c46d092018-04-07 15:32:371000
1001 if (Common.moduleSetting('consoleTimestampsEnabled').get()) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341002 if (!this._timestampElement) {
Blink Reformat4c46d092018-04-07 15:32:371003 this._timestampElement = createElementWithClass('span', 'console-timestamp');
Tim van der Lippe1d6e57a2019-09-30 11:55:341004 }
Rayan Kansoaca06e72019-03-27 11:57:061005 this._timestampElement.textContent = UI.formatTimestamp(this._message.timestamp, false) + ' ';
1006 this._timestampElement.title = UI.formatTimestamp(this._message.timestamp, true);
Blink Reformat4c46d092018-04-07 15:32:371007 this._contentElement.insertBefore(this._timestampElement, this._contentElement.firstChild);
1008 } else if (this._timestampElement) {
1009 this._timestampElement.remove();
1010 delete this._timestampElement;
1011 }
Blink Reformat4c46d092018-04-07 15:32:371012 }
1013
1014 /**
1015 * @return {number}
1016 */
1017 nestingLevel() {
1018 return this._nestingLevel;
1019 }
1020
1021 /**
1022 * @param {boolean} inSimilarGroup
1023 * @param {boolean=} isLast
1024 */
1025 setInSimilarGroup(inSimilarGroup, isLast) {
1026 this._inSimilarGroup = inSimilarGroup;
1027 this._lastInSimilarGroup = inSimilarGroup && !!isLast;
1028 if (this._similarGroupMarker && !inSimilarGroup) {
1029 this._similarGroupMarker.remove();
1030 this._similarGroupMarker = null;
1031 } else if (this._element && !this._similarGroupMarker && inSimilarGroup) {
1032 this._similarGroupMarker = createElementWithClass('div', 'nesting-level-marker');
1033 this._element.insertBefore(this._similarGroupMarker, this._element.firstChild);
1034 this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
1035 }
1036 }
1037
1038 /**
1039 * @return {boolean}
1040 */
1041 isLastInSimilarGroup() {
1042 return this._inSimilarGroup && this._lastInSimilarGroup;
1043 }
1044
1045 resetCloseGroupDecorationCount() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341046 if (!this._closeGroupDecorationCount) {
Blink Reformat4c46d092018-04-07 15:32:371047 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341048 }
Blink Reformat4c46d092018-04-07 15:32:371049 this._closeGroupDecorationCount = 0;
1050 this._updateCloseGroupDecorations();
1051 }
1052
1053 incrementCloseGroupDecorationCount() {
1054 ++this._closeGroupDecorationCount;
1055 this._updateCloseGroupDecorations();
1056 }
1057
1058 _updateCloseGroupDecorations() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341059 if (!this._nestingLevelMarkers) {
Blink Reformat4c46d092018-04-07 15:32:371060 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341061 }
Blink Reformat4c46d092018-04-07 15:32:371062 for (let i = 0, n = this._nestingLevelMarkers.length; i < n; ++i) {
1063 const marker = this._nestingLevelMarkers[i];
1064 marker.classList.toggle('group-closed', n - i <= this._closeGroupDecorationCount);
1065 }
1066 }
1067
1068 /**
Erik Luo0b8282e2018-10-08 20:37:461069 * @return {number}
1070 */
1071 _focusedChildIndex() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341072 if (!this._selectableChildren.length) {
Erik Luo0b8282e2018-10-08 20:37:461073 return -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341074 }
Erik Luo383f21d2018-11-07 23:16:371075 return this._selectableChildren.findIndex(child => child.element.hasFocus());
Erik Luo0b8282e2018-10-08 20:37:461076 }
1077
1078 /**
Erik Luo8ef5d0c2018-09-25 21:16:001079 * @param {!Event} event
1080 */
1081 _onKeyDown(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341082 if (UI.isEditing() || !this._element.hasFocus() || this._element.hasSelection()) {
Erik Luo8ef5d0c2018-09-25 21:16:001083 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341084 }
1085 if (this.maybeHandleOnKeyDown(event)) {
Erik Luo8ef5d0c2018-09-25 21:16:001086 event.consume(true);
Tim van der Lippe1d6e57a2019-09-30 11:55:341087 }
Erik Luo8ef5d0c2018-09-25 21:16:001088 }
1089
1090 /**
1091 * @protected
1092 * @param {!Event} event
1093 */
1094 maybeHandleOnKeyDown(event) {
1095 // Handle trace expansion.
Erik Luo0b8282e2018-10-08 20:37:461096 const focusedChildIndex = this._focusedChildIndex();
1097 const isWrapperFocused = focusedChildIndex === -1;
1098 if (this._expandTrace && isWrapperFocused) {
Erik Luo8ef5d0c2018-09-25 21:16:001099 if ((event.key === 'ArrowLeft' && this._traceExpanded) || (event.key === 'ArrowRight' && !this._traceExpanded)) {
1100 this._expandTrace(!this._traceExpanded);
1101 return true;
1102 }
1103 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341104 if (!this._selectableChildren.length) {
Erik Luo0b8282e2018-10-08 20:37:461105 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341106 }
Erik Luo0b8282e2018-10-08 20:37:461107
1108 if (event.key === 'ArrowLeft') {
1109 this._element.focus();
1110 return true;
1111 }
1112 if (event.key === 'ArrowRight') {
Tim van der Lippe1d6e57a2019-09-30 11:55:341113 if (isWrapperFocused && this._selectNearestVisibleChild(0)) {
Erik Luo0b8282e2018-10-08 20:37:461114 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341115 }
Erik Luo0b8282e2018-10-08 20:37:461116 }
1117 if (event.key === 'ArrowUp') {
Erik Luo182bece2018-11-29 03:15:221118 const firstVisibleChild = this._nearestVisibleChild(0);
1119 if (this._selectableChildren[focusedChildIndex] === firstVisibleChild && firstVisibleChild) {
Erik Luo0b8282e2018-10-08 20:37:461120 this._element.focus();
1121 return true;
Erik Luo182bece2018-11-29 03:15:221122 } else if (this._selectNearestVisibleChild(focusedChildIndex - 1, true /* backwards */)) {
Erik Luo0b8282e2018-10-08 20:37:461123 return true;
1124 }
1125 }
1126 if (event.key === 'ArrowDown') {
Tim van der Lippe1d6e57a2019-09-30 11:55:341127 if (isWrapperFocused && this._selectNearestVisibleChild(0)) {
Erik Luo0b8282e2018-10-08 20:37:461128 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341129 }
1130 if (!isWrapperFocused && this._selectNearestVisibleChild(focusedChildIndex + 1)) {
Erik Luo0b8282e2018-10-08 20:37:461131 return true;
Tim van der Lippe1d6e57a2019-09-30 11:55:341132 }
Erik Luo0b8282e2018-10-08 20:37:461133 }
Erik Luo8ef5d0c2018-09-25 21:16:001134 return false;
1135 }
1136
Erik Luo182bece2018-11-29 03:15:221137 /**
1138 * @param {number} fromIndex
1139 * @param {boolean=} backwards
1140 * @return {boolean}
1141 */
1142 _selectNearestVisibleChild(fromIndex, backwards) {
1143 const nearestChild = this._nearestVisibleChild(fromIndex, backwards);
1144 if (nearestChild) {
Erik Luo31c21f62018-12-13 03:39:391145 nearestChild.forceSelect();
Erik Luo182bece2018-11-29 03:15:221146 return true;
1147 }
1148 return false;
1149 }
1150
1151 /**
1152 * @param {number} fromIndex
1153 * @param {boolean=} backwards
Erik Luo31c21f62018-12-13 03:39:391154 * @return {?{element: !Element, forceSelect: function()}}
Erik Luo182bece2018-11-29 03:15:221155 */
1156 _nearestVisibleChild(fromIndex, backwards) {
1157 const childCount = this._selectableChildren.length;
Tim van der Lippe1d6e57a2019-09-30 11:55:341158 if (fromIndex < 0 || fromIndex >= childCount) {
Erik Luo182bece2018-11-29 03:15:221159 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341160 }
Erik Luo182bece2018-11-29 03:15:221161 const direction = backwards ? -1 : 1;
1162 let index = fromIndex;
1163
1164 while (!this._selectableChildren[index].element.offsetParent) {
1165 index += direction;
Tim van der Lippe1d6e57a2019-09-30 11:55:341166 if (index < 0 || index >= childCount) {
Erik Luo182bece2018-11-29 03:15:221167 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341168 }
Erik Luo182bece2018-11-29 03:15:221169 }
1170 return this._selectableChildren[index];
1171 }
1172
Erik Luo0b8282e2018-10-08 20:37:461173 focusLastChildOrSelf() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341174 if (this._element && !this._selectNearestVisibleChild(this._selectableChildren.length - 1, true /* backwards */)) {
Erik Luo0b8282e2018-10-08 20:37:461175 this._element.focus();
Tim van der Lippe1d6e57a2019-09-30 11:55:341176 }
Erik Luo0b8282e2018-10-08 20:37:461177 }
1178
1179 /**
Blink Reformat4c46d092018-04-07 15:32:371180 * @return {!Element}
1181 */
1182 contentElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341183 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371184 return this._contentElement;
Tim van der Lippe1d6e57a2019-09-30 11:55:341185 }
Blink Reformat4c46d092018-04-07 15:32:371186
1187 const contentElement = createElementWithClass('div', 'console-message');
Tim van der Lippe1d6e57a2019-09-30 11:55:341188 if (this._messageLevelIcon) {
Blink Reformat4c46d092018-04-07 15:32:371189 contentElement.appendChild(this._messageLevelIcon);
Tim van der Lippe1d6e57a2019-09-30 11:55:341190 }
Blink Reformat4c46d092018-04-07 15:32:371191 this._contentElement = contentElement;
1192
1193 let formattedMessage;
1194 const shouldIncludeTrace = !!this._message.stackTrace &&
1195 (this._message.source === SDK.ConsoleMessage.MessageSource.Network ||
1196 this._message.source === SDK.ConsoleMessage.MessageSource.Violation ||
1197 this._message.level === SDK.ConsoleMessage.MessageLevel.Error ||
1198 this._message.level === SDK.ConsoleMessage.MessageLevel.Warning ||
1199 this._message.type === SDK.ConsoleMessage.MessageType.Trace);
Tim van der Lippe1d6e57a2019-09-30 11:55:341200 if (this._message.runtimeModel() && shouldIncludeTrace) {
Blink Reformat4c46d092018-04-07 15:32:371201 formattedMessage = this._buildMessageWithStackTrace();
Tim van der Lippe1d6e57a2019-09-30 11:55:341202 } else if (this._message.type === SDK.ConsoleMessage.MessageType.Table) {
Blink Reformat4c46d092018-04-07 15:32:371203 formattedMessage = this._buildTableMessage();
Tim van der Lippe1d6e57a2019-09-30 11:55:341204 } else {
Blink Reformat4c46d092018-04-07 15:32:371205 formattedMessage = this._buildMessage();
Tim van der Lippe1d6e57a2019-09-30 11:55:341206 }
Blink Reformat4c46d092018-04-07 15:32:371207 contentElement.appendChild(formattedMessage);
1208
1209 this.updateTimestamp();
1210 return this._contentElement;
1211 }
1212
1213 /**
1214 * @return {!Element}
1215 */
1216 toMessageElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341217 if (this._element) {
Blink Reformat4c46d092018-04-07 15:32:371218 return this._element;
Tim van der Lippe1d6e57a2019-09-30 11:55:341219 }
Blink Reformat4c46d092018-04-07 15:32:371220
1221 this._element = createElement('div');
Pavel Feldmandb310912019-01-30 00:31:201222 this._element.tabIndex = -1;
1223 this._element.addEventListener('keydown', this._onKeyDown.bind(this));
Blink Reformat4c46d092018-04-07 15:32:371224 this.updateMessageElement();
1225 return this._element;
1226 }
1227
1228 updateMessageElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341229 if (!this._element) {
Blink Reformat4c46d092018-04-07 15:32:371230 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341231 }
Blink Reformat4c46d092018-04-07 15:32:371232
1233 this._element.className = 'console-message-wrapper';
1234 this._element.removeChildren();
Tim van der Lippe1d6e57a2019-09-30 11:55:341235 if (this._message.isGroupStartMessage()) {
Blink Reformat4c46d092018-04-07 15:32:371236 this._element.classList.add('console-group-title');
Tim van der Lippe1d6e57a2019-09-30 11:55:341237 }
1238 if (this._message.source === SDK.ConsoleMessage.MessageSource.ConsoleAPI) {
Blink Reformat4c46d092018-04-07 15:32:371239 this._element.classList.add('console-from-api');
Tim van der Lippe1d6e57a2019-09-30 11:55:341240 }
Blink Reformat4c46d092018-04-07 15:32:371241 if (this._inSimilarGroup) {
1242 this._similarGroupMarker = this._element.createChild('div', 'nesting-level-marker');
1243 this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
1244 }
1245
1246 this._nestingLevelMarkers = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341247 for (let i = 0; i < this._nestingLevel; ++i) {
Blink Reformat4c46d092018-04-07 15:32:371248 this._nestingLevelMarkers.push(this._element.createChild('div', 'nesting-level-marker'));
Tim van der Lippe1d6e57a2019-09-30 11:55:341249 }
Blink Reformat4c46d092018-04-07 15:32:371250 this._updateCloseGroupDecorations();
1251 this._element.message = this;
1252
1253 switch (this._message.level) {
1254 case SDK.ConsoleMessage.MessageLevel.Verbose:
1255 this._element.classList.add('console-verbose-level');
Blink Reformat4c46d092018-04-07 15:32:371256 break;
1257 case SDK.ConsoleMessage.MessageLevel.Info:
1258 this._element.classList.add('console-info-level');
Tim van der Lippe1d6e57a2019-09-30 11:55:341259 if (this._message.type === SDK.ConsoleMessage.MessageType.System) {
Blink Reformat4c46d092018-04-07 15:32:371260 this._element.classList.add('console-system-type');
Tim van der Lippe1d6e57a2019-09-30 11:55:341261 }
Blink Reformat4c46d092018-04-07 15:32:371262 break;
1263 case SDK.ConsoleMessage.MessageLevel.Warning:
1264 this._element.classList.add('console-warning-level');
Blink Reformat4c46d092018-04-07 15:32:371265 break;
1266 case SDK.ConsoleMessage.MessageLevel.Error:
1267 this._element.classList.add('console-error-level');
Blink Reformat4c46d092018-04-07 15:32:371268 break;
1269 }
Erik Luofd3e7d42018-09-25 02:12:351270 this._updateMessageLevelIcon();
Tim van der Lippe1d6e57a2019-09-30 11:55:341271 if (this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371272 this._element.classList.add('console-warning-level');
Tim van der Lippe1d6e57a2019-09-30 11:55:341273 }
Blink Reformat4c46d092018-04-07 15:32:371274
1275 this._element.appendChild(this.contentElement());
Tim van der Lippe1d6e57a2019-09-30 11:55:341276 if (this._repeatCount > 1) {
Blink Reformat4c46d092018-04-07 15:32:371277 this._showRepeatCountElement();
Tim van der Lippe1d6e57a2019-09-30 11:55:341278 }
Blink Reformat4c46d092018-04-07 15:32:371279 }
1280
1281 /**
1282 * @return {boolean}
1283 */
1284 _shouldRenderAsWarning() {
1285 return (this._message.level === SDK.ConsoleMessage.MessageLevel.Verbose ||
1286 this._message.level === SDK.ConsoleMessage.MessageLevel.Info) &&
1287 (this._message.source === SDK.ConsoleMessage.MessageSource.Violation ||
1288 this._message.source === SDK.ConsoleMessage.MessageSource.Deprecation ||
1289 this._message.source === SDK.ConsoleMessage.MessageSource.Intervention ||
1290 this._message.source === SDK.ConsoleMessage.MessageSource.Recommendation);
1291 }
1292
Erik Luofd3e7d42018-09-25 02:12:351293 _updateMessageLevelIcon() {
1294 let iconType = '';
1295 let accessibleName = '';
1296 if (this._message.level === SDK.ConsoleMessage.MessageLevel.Warning) {
1297 iconType = 'smallicon-warning';
1298 accessibleName = ls`Warning`;
1299 } else if (this._message.level === SDK.ConsoleMessage.MessageLevel.Error) {
1300 iconType = 'smallicon-error';
1301 accessibleName = ls`Error`;
1302 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341303 if (!iconType && !this._messageLevelIcon) {
Blink Reformat4c46d092018-04-07 15:32:371304 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341305 }
Blink Reformat4c46d092018-04-07 15:32:371306 if (iconType && !this._messageLevelIcon) {
1307 this._messageLevelIcon = UI.Icon.create('', 'message-level-icon');
Tim van der Lippe1d6e57a2019-09-30 11:55:341308 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371309 this._contentElement.insertBefore(this._messageLevelIcon, this._contentElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341310 }
Blink Reformat4c46d092018-04-07 15:32:371311 }
1312 this._messageLevelIcon.setIconType(iconType);
Erik Luofd3e7d42018-09-25 02:12:351313 UI.ARIAUtils.setAccessibleName(this._messageLevelIcon, accessibleName);
Blink Reformat4c46d092018-04-07 15:32:371314 }
1315
1316 /**
1317 * @return {number}
1318 */
1319 repeatCount() {
1320 return this._repeatCount || 1;
1321 }
1322
1323 resetIncrementRepeatCount() {
1324 this._repeatCount = 1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341325 if (!this._repeatCountElement) {
Blink Reformat4c46d092018-04-07 15:32:371326 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341327 }
Blink Reformat4c46d092018-04-07 15:32:371328
1329 this._repeatCountElement.remove();
Tim van der Lippe1d6e57a2019-09-30 11:55:341330 if (this._contentElement) {
Blink Reformat4c46d092018-04-07 15:32:371331 this._contentElement.classList.remove('repeated-message');
Tim van der Lippe1d6e57a2019-09-30 11:55:341332 }
Blink Reformat4c46d092018-04-07 15:32:371333 delete this._repeatCountElement;
1334 }
1335
1336 incrementRepeatCount() {
1337 this._repeatCount++;
1338 this._showRepeatCountElement();
1339 }
1340
1341 /**
1342 * @param {number} repeatCount
1343 */
1344 setRepeatCount(repeatCount) {
1345 this._repeatCount = repeatCount;
1346 this._showRepeatCountElement();
1347 }
1348
1349 _showRepeatCountElement() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341350 if (!this._element) {
Blink Reformat4c46d092018-04-07 15:32:371351 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341352 }
Blink Reformat4c46d092018-04-07 15:32:371353
1354 if (!this._repeatCountElement) {
Joel Einbinder7fbe24c2019-01-24 05:19:011355 this._repeatCountElement = createElementWithClass('span', 'console-message-repeat-count', 'dt-small-bubble');
Blink Reformat4c46d092018-04-07 15:32:371356 switch (this._message.level) {
1357 case SDK.ConsoleMessage.MessageLevel.Warning:
1358 this._repeatCountElement.type = 'warning';
1359 break;
1360 case SDK.ConsoleMessage.MessageLevel.Error:
1361 this._repeatCountElement.type = 'error';
1362 break;
1363 case SDK.ConsoleMessage.MessageLevel.Verbose:
1364 this._repeatCountElement.type = 'verbose';
1365 break;
1366 default:
1367 this._repeatCountElement.type = 'info';
1368 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341369 if (this._shouldRenderAsWarning()) {
Blink Reformat4c46d092018-04-07 15:32:371370 this._repeatCountElement.type = 'warning';
Tim van der Lippe1d6e57a2019-09-30 11:55:341371 }
Blink Reformat4c46d092018-04-07 15:32:371372
1373 this._element.insertBefore(this._repeatCountElement, this._contentElement);
1374 this._contentElement.classList.add('repeated-message');
1375 }
1376 this._repeatCountElement.textContent = this._repeatCount;
Erik Luofd3e7d42018-09-25 02:12:351377 let accessibleName = ls`Repeat ${this._repeatCount}`;
Tim van der Lippe1d6e57a2019-09-30 11:55:341378 if (this._message.level === SDK.ConsoleMessage.MessageLevel.Warning) {
Erik Luofd3e7d42018-09-25 02:12:351379 accessibleName = ls`Warning ${accessibleName}`;
Tim van der Lippe1d6e57a2019-09-30 11:55:341380 } else if (this._message.level === SDK.ConsoleMessage.MessageLevel.Error) {
Erik Luofd3e7d42018-09-25 02:12:351381 accessibleName = ls`Error ${accessibleName}`;
Tim van der Lippe1d6e57a2019-09-30 11:55:341382 }
Erik Luofd3e7d42018-09-25 02:12:351383 UI.ARIAUtils.setAccessibleName(this._repeatCountElement, accessibleName);
Blink Reformat4c46d092018-04-07 15:32:371384 }
1385
1386 get text() {
1387 return this._message.messageText;
1388 }
1389
1390 /**
1391 * @return {string}
1392 */
1393 toExportString() {
1394 const lines = [];
1395 const nodes = this.contentElement().childTextNodes();
1396 const messageContent = nodes.map(Components.Linkifier.untruncatedNodeText).join('');
Tim van der Lippe1d6e57a2019-09-30 11:55:341397 for (let i = 0; i < this.repeatCount(); ++i) {
Blink Reformat4c46d092018-04-07 15:32:371398 lines.push(messageContent);
Tim van der Lippe1d6e57a2019-09-30 11:55:341399 }
Blink Reformat4c46d092018-04-07 15:32:371400 return lines.join('\n');
1401 }
1402
1403 /**
1404 * @param {?RegExp} regex
1405 */
1406 setSearchRegex(regex) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341407 if (this._searchHiglightNodeChanges && this._searchHiglightNodeChanges.length) {
Blink Reformat4c46d092018-04-07 15:32:371408 UI.revertDomChanges(this._searchHiglightNodeChanges);
Tim van der Lippe1d6e57a2019-09-30 11:55:341409 }
Blink Reformat4c46d092018-04-07 15:32:371410 this._searchRegex = regex;
1411 this._searchHighlightNodes = [];
1412 this._searchHiglightNodeChanges = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341413 if (!this._searchRegex) {
Blink Reformat4c46d092018-04-07 15:32:371414 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341415 }
Blink Reformat4c46d092018-04-07 15:32:371416
1417 const text = this.contentElement().deepTextContent();
1418 let match;
1419 this._searchRegex.lastIndex = 0;
1420 const sourceRanges = [];
Tim van der Lippe1d6e57a2019-09-30 11:55:341421 while ((match = this._searchRegex.exec(text)) && match[0]) {
Blink Reformat4c46d092018-04-07 15:32:371422 sourceRanges.push(new TextUtils.SourceRange(match.index, match[0].length));
Tim van der Lippe1d6e57a2019-09-30 11:55:341423 }
Blink Reformat4c46d092018-04-07 15:32:371424
1425 if (sourceRanges.length) {
1426 this._searchHighlightNodes =
1427 UI.highlightSearchResults(this.contentElement(), sourceRanges, this._searchHiglightNodeChanges);
1428 }
1429 }
1430
1431 /**
1432 * @return {?RegExp}
1433 */
1434 searchRegex() {
1435 return this._searchRegex;
1436 }
1437
1438 /**
1439 * @return {number}
1440 */
1441 searchCount() {
1442 return this._searchHighlightNodes.length;
1443 }
1444
1445 /**
1446 * @return {!Element}
1447 */
1448 searchHighlightNode(index) {
1449 return this._searchHighlightNodes[index];
1450 }
1451
1452 /**
1453 * @param {string} string
1454 * @return {?Element}
1455 */
1456 _tryFormatAsError(string) {
1457 /**
1458 * @param {string} prefix
1459 */
1460 function startsWith(prefix) {
1461 return string.startsWith(prefix);
1462 }
1463
1464 const errorPrefixes =
1465 ['EvalError', 'ReferenceError', 'SyntaxError', 'TypeError', 'RangeError', 'Error', 'URIError'];
Tim van der Lippe1d6e57a2019-09-30 11:55:341466 if (!this._message.runtimeModel() || !errorPrefixes.some(startsWith)) {
Blink Reformat4c46d092018-04-07 15:32:371467 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341468 }
Blink Reformat4c46d092018-04-07 15:32:371469 const debuggerModel = this._message.runtimeModel().debuggerModel();
1470 const baseURL = this._message.runtimeModel().target().inspectedURL();
1471
1472 const lines = string.split('\n');
1473 const links = [];
1474 let position = 0;
1475 for (let i = 0; i < lines.length; ++i) {
1476 position += i > 0 ? lines[i - 1].length + 1 : 0;
1477 const isCallFrameLine = /^\s*at\s/.test(lines[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:341478 if (!isCallFrameLine && links.length) {
Blink Reformat4c46d092018-04-07 15:32:371479 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341480 }
Blink Reformat4c46d092018-04-07 15:32:371481
Tim van der Lippe1d6e57a2019-09-30 11:55:341482 if (!isCallFrameLine) {
Blink Reformat4c46d092018-04-07 15:32:371483 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341484 }
Blink Reformat4c46d092018-04-07 15:32:371485
1486 let openBracketIndex = -1;
1487 let closeBracketIndex = -1;
Yang Guo39256bd2019-07-18 06:02:251488 const inBracketsWithLineAndColumn = /\([^\)\(]+:\d+:\d+\)/g;
1489 const inBrackets = /\([^\)\(]+\)/g;
1490 let lastMatch = null;
1491 let currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341492 while ((currentMatch = inBracketsWithLineAndColumn.exec(lines[i]))) {
Yang Guo39256bd2019-07-18 06:02:251493 lastMatch = currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341494 }
Yang Guo39256bd2019-07-18 06:02:251495 if (!lastMatch) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341496 while ((currentMatch = inBrackets.exec(lines[i]))) {
Yang Guo39256bd2019-07-18 06:02:251497 lastMatch = currentMatch;
Tim van der Lippe1d6e57a2019-09-30 11:55:341498 }
Yang Guo39256bd2019-07-18 06:02:251499 }
1500 if (lastMatch) {
1501 openBracketIndex = lastMatch.index;
1502 closeBracketIndex = lastMatch.index + lastMatch[0].length - 1;
Blink Reformat4c46d092018-04-07 15:32:371503 }
1504 const hasOpenBracket = openBracketIndex !== -1;
1505 const left = hasOpenBracket ? openBracketIndex + 1 : lines[i].indexOf('at') + 3;
1506 const right = hasOpenBracket ? closeBracketIndex : lines[i].length;
1507 const linkCandidate = lines[i].substring(left, right);
1508 const splitResult = Common.ParsedURL.splitLineAndColumn(linkCandidate);
Tim van der Lippe1d6e57a2019-09-30 11:55:341509 if (!splitResult) {
Blink Reformat4c46d092018-04-07 15:32:371510 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341511 }
Blink Reformat4c46d092018-04-07 15:32:371512
Tim van der Lippe1d6e57a2019-09-30 11:55:341513 if (splitResult.url === '<anonymous>') {
Blink Reformat4c46d092018-04-07 15:32:371514 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341515 }
Blink Reformat4c46d092018-04-07 15:32:371516 let url = parseOrScriptMatch(splitResult.url);
Tim van der Lippe1d6e57a2019-09-30 11:55:341517 if (!url && Common.ParsedURL.isRelativeURL(splitResult.url)) {
Blink Reformat4c46d092018-04-07 15:32:371518 url = parseOrScriptMatch(Common.ParsedURL.completeURL(baseURL, splitResult.url));
Tim van der Lippe1d6e57a2019-09-30 11:55:341519 }
1520 if (!url) {
Blink Reformat4c46d092018-04-07 15:32:371521 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341522 }
Blink Reformat4c46d092018-04-07 15:32:371523
1524 links.push({
1525 url: url,
1526 positionLeft: position + left,
1527 positionRight: position + right,
1528 lineNumber: splitResult.lineNumber,
1529 columnNumber: splitResult.columnNumber
1530 });
1531 }
1532
Tim van der Lippe1d6e57a2019-09-30 11:55:341533 if (!links.length) {
Blink Reformat4c46d092018-04-07 15:32:371534 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341535 }
Blink Reformat4c46d092018-04-07 15:32:371536
1537 const formattedResult = createElement('span');
1538 let start = 0;
1539 for (let i = 0; i < links.length; ++i) {
Erik Luo383f21d2018-11-07 23:16:371540 formattedResult.appendChild(this._linkifyStringAsFragment(string.substring(start, links[i].positionLeft)));
Erik Luo182bece2018-11-29 03:15:221541 const scriptLocationLink = this._linkifier.linkifyScriptLocation(
1542 debuggerModel.target(), null, links[i].url, links[i].lineNumber, links[i].columnNumber);
1543 scriptLocationLink.tabIndex = -1;
Erik Luo31c21f62018-12-13 03:39:391544 this._selectableChildren.push({element: scriptLocationLink, forceSelect: () => scriptLocationLink.focus()});
Erik Luo182bece2018-11-29 03:15:221545 formattedResult.appendChild(scriptLocationLink);
Blink Reformat4c46d092018-04-07 15:32:371546 start = links[i].positionRight;
1547 }
1548
Tim van der Lippe1d6e57a2019-09-30 11:55:341549 if (start !== string.length) {
Erik Luo383f21d2018-11-07 23:16:371550 formattedResult.appendChild(this._linkifyStringAsFragment(string.substring(start)));
Tim van der Lippe1d6e57a2019-09-30 11:55:341551 }
Blink Reformat4c46d092018-04-07 15:32:371552
1553 return formattedResult;
1554
1555 /**
1556 * @param {?string} url
1557 * @return {?string}
1558 */
1559 function parseOrScriptMatch(url) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341560 if (!url) {
Blink Reformat4c46d092018-04-07 15:32:371561 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341562 }
Peter Marshall3e4e5692019-12-09 16:48:041563 const parsedURL = Common.ParsedURL.fromString(url);
Tim van der Lippe1d6e57a2019-09-30 11:55:341564 if (parsedURL) {
Blink Reformat4c46d092018-04-07 15:32:371565 return parsedURL.url;
Tim van der Lippe1d6e57a2019-09-30 11:55:341566 }
1567 if (debuggerModel.scriptsForSourceURL(url).length) {
Blink Reformat4c46d092018-04-07 15:32:371568 return url;
Tim van der Lippe1d6e57a2019-09-30 11:55:341569 }
Blink Reformat4c46d092018-04-07 15:32:371570 return null;
1571 }
1572 }
1573
1574 /**
1575 * @param {string} string
1576 * @param {function(string,string,number=,number=):!Node} linkifier
1577 * @return {!DocumentFragment}
1578 */
Erik Luofc2214f2018-11-21 19:54:581579 _linkifyWithCustomLinkifier(string, linkifier) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341580 if (string.length > Console.ConsoleViewMessage._MaxTokenizableStringLength) {
Connor Moody1a5c0d32019-12-19 07:23:361581 const propertyValue = new ObjectUI.ExpandableTextPropertyValue(
1582 createElement('span'), string, Console.ConsoleViewMessage._LongStringVisibleLength);
1583 const fragment = createDocumentFragment();
1584 fragment.appendChild(propertyValue.element);
1585 return fragment;
Tim van der Lippe1d6e57a2019-09-30 11:55:341586 }
Blink Reformat4c46d092018-04-07 15:32:371587 const container = createDocumentFragment();
Erik Luofc2214f2018-11-21 19:54:581588 const tokens = Console.ConsoleViewMessage._tokenizeMessageText(string);
Blink Reformat4c46d092018-04-07 15:32:371589 for (const token of tokens) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341590 if (!token.text) {
Erik Luofc2214f2018-11-21 19:54:581591 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341592 }
Blink Reformat4c46d092018-04-07 15:32:371593 switch (token.type) {
1594 case 'url': {
1595 const realURL = (token.text.startsWith('www.') ? 'http://' + token.text : token.text);
1596 const splitResult = Common.ParsedURL.splitLineAndColumn(realURL);
1597 let linkNode;
Tim van der Lippe1d6e57a2019-09-30 11:55:341598 if (splitResult) {
Blink Reformat4c46d092018-04-07 15:32:371599 linkNode = linkifier(token.text, splitResult.url, splitResult.lineNumber, splitResult.columnNumber);
Tim van der Lippe1d6e57a2019-09-30 11:55:341600 } else {
Blink Reformat4c46d092018-04-07 15:32:371601 linkNode = linkifier(token.text, token.value);
Tim van der Lippe1d6e57a2019-09-30 11:55:341602 }
Blink Reformat4c46d092018-04-07 15:32:371603 container.appendChild(linkNode);
1604 break;
1605 }
1606 default:
1607 container.appendChild(createTextNode(token.text));
1608 break;
1609 }
1610 }
1611 return container;
1612 }
1613
1614 /**
Blink Reformat4c46d092018-04-07 15:32:371615 * @param {string} string
1616 * @return {!DocumentFragment}
1617 */
Erik Luo383f21d2018-11-07 23:16:371618 _linkifyStringAsFragment(string) {
Erik Luofc2214f2018-11-21 19:54:581619 return this._linkifyWithCustomLinkifier(string, (text, url, lineNumber, columnNumber) => {
Erik Luo383f21d2018-11-07 23:16:371620 const linkElement = Components.Linkifier.linkifyURL(url, {text, lineNumber, columnNumber});
1621 linkElement.tabIndex = -1;
Erik Luo31c21f62018-12-13 03:39:391622 this._selectableChildren.push({element: linkElement, forceSelect: () => linkElement.focus()});
Erik Luo383f21d2018-11-07 23:16:371623 return linkElement;
Blink Reformat4c46d092018-04-07 15:32:371624 });
1625 }
1626
1627 /**
1628 * @param {string} string
1629 * @return {!Array<{type: string, text: (string|undefined)}>}
1630 */
1631 static _tokenizeMessageText(string) {
1632 if (!Console.ConsoleViewMessage._tokenizerRegexes) {
1633 const controlCodes = '\\u0000-\\u0020\\u007f-\\u009f';
1634 const linkStringRegex = new RegExp(
1635 '(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\\/\\/|data:|www\\.)[^\\s' + controlCodes + '"]{2,}[^\\s' + controlCodes +
1636 '"\')}\\],:;.!?]',
1637 'u');
1638 const pathLineRegex = /(?:\/[\w\.-]*)+\:[\d]+/;
1639 const timeRegex = /took [\d]+ms/;
1640 const eventRegex = /'\w+' event/;
1641 const milestoneRegex = /\sM[6-7]\d/;
1642 const autofillRegex = /\(suggested: \"[\w-]+\"\)/;
1643 const handlers = new Map();
1644 handlers.set(linkStringRegex, 'url');
1645 handlers.set(pathLineRegex, 'url');
1646 handlers.set(timeRegex, 'time');
1647 handlers.set(eventRegex, 'event');
1648 handlers.set(milestoneRegex, 'milestone');
1649 handlers.set(autofillRegex, 'autofill');
1650 Console.ConsoleViewMessage._tokenizerRegexes = Array.from(handlers.keys());
1651 Console.ConsoleViewMessage._tokenizerTypes = Array.from(handlers.values());
1652 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341653 if (string.length > Console.ConsoleViewMessage._MaxTokenizableStringLength) {
Blink Reformat4c46d092018-04-07 15:32:371654 return [{text: string, type: undefined}];
Tim van der Lippe1d6e57a2019-09-30 11:55:341655 }
Blink Reformat4c46d092018-04-07 15:32:371656 const results = TextUtils.TextUtils.splitStringByRegexes(string, Console.ConsoleViewMessage._tokenizerRegexes);
1657 return results.map(
1658 result => ({text: result.value, type: Console.ConsoleViewMessage._tokenizerTypes[result.regexIndex]}));
1659 }
1660
1661 /**
1662 * @return {string}
1663 */
1664 groupKey() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341665 if (!this._groupKey) {
Blink Reformat4c46d092018-04-07 15:32:371666 this._groupKey = this._message.groupCategoryKey() + ':' + this.groupTitle();
Tim van der Lippe1d6e57a2019-09-30 11:55:341667 }
Blink Reformat4c46d092018-04-07 15:32:371668 return this._groupKey;
1669 }
1670
1671 /**
1672 * @return {string}
1673 */
1674 groupTitle() {
1675 const tokens = Console.ConsoleViewMessage._tokenizeMessageText(this._message.messageText);
1676 const result = tokens.reduce((acc, token) => {
1677 let text = token.text;
Tim van der Lippe1d6e57a2019-09-30 11:55:341678 if (token.type === 'url') {
Blink Reformat4c46d092018-04-07 15:32:371679 text = Common.UIString('<URL>');
Tim van der Lippe1d6e57a2019-09-30 11:55:341680 } else if (token.type === 'time') {
Blink Reformat4c46d092018-04-07 15:32:371681 text = Common.UIString('took <N>ms');
Tim van der Lippe1d6e57a2019-09-30 11:55:341682 } else if (token.type === 'event') {
Blink Reformat4c46d092018-04-07 15:32:371683 text = Common.UIString('<some> event');
Tim van der Lippe1d6e57a2019-09-30 11:55:341684 } else if (token.type === 'milestone') {
Blink Reformat4c46d092018-04-07 15:32:371685 text = Common.UIString(' M<XX>');
Tim van der Lippe1d6e57a2019-09-30 11:55:341686 } else if (token.type === 'autofill') {
Blink Reformat4c46d092018-04-07 15:32:371687 text = Common.UIString('<attribute>');
Tim van der Lippe1d6e57a2019-09-30 11:55:341688 }
Blink Reformat4c46d092018-04-07 15:32:371689 return acc + text;
1690 }, '');
1691 return result.replace(/[%]o/g, '');
1692 }
Paul Lewisbf7aa3c2019-11-20 17:03:381693}
Blink Reformat4c46d092018-04-07 15:32:371694
1695/**
1696 * @unrestricted
1697 */
Paul Lewisbf7aa3c2019-11-20 17:03:381698export class ConsoleGroupViewMessage extends ConsoleViewMessage {
Blink Reformat4c46d092018-04-07 15:32:371699 /**
1700 * @param {!SDK.ConsoleMessage} consoleMessage
1701 * @param {!Components.Linkifier} linkifier
Blink Reformat4c46d092018-04-07 15:32:371702 * @param {number} nestingLevel
Erik Luo8ef5d0c2018-09-25 21:16:001703 * @param {function()} onToggle
Erik Luo840be6b2018-12-03 20:54:271704 * @param {function(!Common.Event)} onResize
Blink Reformat4c46d092018-04-07 15:32:371705 */
Tim van der Lippeb45d9a02019-11-05 17:24:411706 constructor(consoleMessage, linkifier, nestingLevel, onToggle, onResize) {
Blink Reformat4c46d092018-04-07 15:32:371707 console.assert(consoleMessage.isGroupStartMessage());
Tim van der Lippeb45d9a02019-11-05 17:24:411708 super(consoleMessage, linkifier, nestingLevel, onResize);
Blink Reformat4c46d092018-04-07 15:32:371709 this._collapsed = consoleMessage.type === SDK.ConsoleMessage.MessageType.StartGroupCollapsed;
1710 /** @type {?UI.Icon} */
1711 this._expandGroupIcon = null;
Erik Luo8ef5d0c2018-09-25 21:16:001712 this._onToggle = onToggle;
Blink Reformat4c46d092018-04-07 15:32:371713 }
1714
1715 /**
1716 * @param {boolean} collapsed
1717 */
Erik Luo8ef5d0c2018-09-25 21:16:001718 _setCollapsed(collapsed) {
Blink Reformat4c46d092018-04-07 15:32:371719 this._collapsed = collapsed;
Tim van der Lippe1d6e57a2019-09-30 11:55:341720 if (this._expandGroupIcon) {
Blink Reformat4c46d092018-04-07 15:32:371721 this._expandGroupIcon.setIconType(this._collapsed ? 'smallicon-triangle-right' : 'smallicon-triangle-down');
Tim van der Lippe1d6e57a2019-09-30 11:55:341722 }
Erik Luo8ef5d0c2018-09-25 21:16:001723 this._onToggle.call(null);
Blink Reformat4c46d092018-04-07 15:32:371724 }
1725
1726 /**
1727 * @return {boolean}
1728 */
1729 collapsed() {
1730 return this._collapsed;
1731 }
1732
1733 /**
1734 * @override
Erik Luo8ef5d0c2018-09-25 21:16:001735 * @param {!Event} event
1736 */
1737 maybeHandleOnKeyDown(event) {
Erik Luo0b8282e2018-10-08 20:37:461738 const focusedChildIndex = this._focusedChildIndex();
1739 if (focusedChildIndex === -1) {
1740 if ((event.key === 'ArrowLeft' && !this._collapsed) || (event.key === 'ArrowRight' && this._collapsed)) {
1741 this._setCollapsed(!this._collapsed);
1742 return true;
1743 }
Erik Luo8ef5d0c2018-09-25 21:16:001744 }
1745 return super.maybeHandleOnKeyDown(event);
1746 }
1747
1748 /**
1749 * @override
Blink Reformat4c46d092018-04-07 15:32:371750 * @return {!Element}
1751 */
1752 toMessageElement() {
1753 if (!this._element) {
1754 super.toMessageElement();
Erik Luo8ef5d0c2018-09-25 21:16:001755 const iconType = this._collapsed ? 'smallicon-triangle-right' : 'smallicon-triangle-down';
1756 this._expandGroupIcon = UI.Icon.create(iconType, 'expand-group-icon');
Erik Luob5bfff42018-09-20 02:52:391757 // Intercept focus to avoid highlight on click.
1758 this._contentElement.tabIndex = -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:341759 if (this._repeatCountElement) {
Blink Reformat4c46d092018-04-07 15:32:371760 this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341761 } else {
Blink Reformat4c46d092018-04-07 15:32:371762 this._element.insertBefore(this._expandGroupIcon, this._contentElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:341763 }
Erik Luo8ef5d0c2018-09-25 21:16:001764 this._element.addEventListener('click', () => this._setCollapsed(!this._collapsed));
Blink Reformat4c46d092018-04-07 15:32:371765 }
1766 return this._element;
1767 }
1768
1769 /**
1770 * @override
1771 */
1772 _showRepeatCountElement() {
1773 super._showRepeatCountElement();
Tim van der Lippe1d6e57a2019-09-30 11:55:341774 if (this._repeatCountElement && this._expandGroupIcon) {
Blink Reformat4c46d092018-04-07 15:32:371775 this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
Tim van der Lippe1d6e57a2019-09-30 11:55:341776 }
Blink Reformat4c46d092018-04-07 15:32:371777 }
Paul Lewisbf7aa3c2019-11-20 17:03:381778}
Blink Reformat4c46d092018-04-07 15:32:371779
1780/**
1781 * @const
1782 * @type {number}
1783 */
Paul Lewisbf7aa3c2019-11-20 17:03:381784export const MaxLengthForLinks = 40;
Blink Reformat4c46d092018-04-07 15:32:371785
Paul Lewisbf7aa3c2019-11-20 17:03:381786export const _MaxTokenizableStringLength = 10000;
1787export const _LongStringVisibleLength = 5000;
Blink Reformat4c46d092018-04-07 15:32:371788
Paul Lewisbf7aa3c2019-11-20 17:03:381789/* Legacy exported object */
1790self.Console = self.Console || {};
1791
1792/* Legacy exported object */
1793Console = Console || {};
1794
1795/**
1796 * @implements {Console.ConsoleViewportElement}
1797 * @unrestricted
1798 * @constructor
1799 */
1800Console.ConsoleViewMessage = ConsoleViewMessage;
1801
1802/**
1803 * @constructor
1804 */
1805Console.ConsoleGroupViewMessage = ConsoleGroupViewMessage;
1806
1807/**
1808 * @const
1809 * @type {number}
1810 */
1811Console.ConsoleViewMessage.MaxLengthForLinks = MaxLengthForLinks;
1812Console.ConsoleViewMessage._MaxTokenizableStringLength = _MaxTokenizableStringLength;
1813Console.ConsoleViewMessage._LongStringVisibleLength = _LongStringVisibleLength;