Commit 75dc9ac6 authored by Erik Luo's avatar Erik Luo Committed by Commit Bot

DevTools: hide super long console text behind expandable button

Rendering console logs with lots of text can stall DevTools. In this CL,
very long text will get truncated. A 'Show N more' button reveals the
full text and a 'Copy' button copies the full text to clipboard.

Screenshot: https://imgur.com/a/0dHJI

Bug: 658525
Change-Id: Ic27e4836b8aaf9069f7ff0643b39ded4a83ce91f
Reviewed-on: https://chromium-review.googlesource.com/597012
Commit-Queue: Erik Luo <luoe@chromium.org>
Reviewed-by: default avatarDmitry Gozman <dgozman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#521869}
parent 4f6bce25
Tests that console logging large messages will be truncated.
Setting max length to: 40
Setting long string visible length to: 20
Message: 0, length: 14, "a".repeat(80)
Message: 1, length: 22, "aaaaaaaaaaaaaaaaaaaa"
Message: 2, length: 20, aaaaaaaaaaaaaaaaaaaa
Message: 3, length: 41, aaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbb
Message: 4, length: 20, aaaaaaaaaaaaaaaaaaaa
Message: 5, length: 22, "aaaaaaaaaaaaaaaaaaaa"
Message: 6, length: 20, aaaaaaaaaaaaaaaaaaaa
Message: 7, length: 35, foo aaaaaaaaaaaaaaaaaaaa {a: 1} bar
Message: 8, length: 36, {a: 1} "aaaaaaaaaaaaaaaaaaaa" {b: 1}
Link: https://chromium.org
Message: 9, length: 41, aaaaaaaaaaaaaaaaaaaa https://chromium.org
Link: https://chromium.org
Message: 10, length: 41, https://chromium.org aaaaaaaaaaaaaaaaaaaa
Expanding hidden texts
Message: 0, length: 14, "a".repeat(80)
Message: 1, length: 82, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Message: 2, length: 80, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Message: 3, length: 161, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
Message: 4, length: 80, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Message: 5, length: 82, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Message: 6, length: 80, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Message: 7, length: 95, foo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa {a: 1} bar
Message: 8, length: 96, {a: 1} "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" {b: 1}
Link: https://chromium.org
Message: 9, length: 101, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa https://chromium.org
Link: https://chromium.org
Message: 10, length: 101, https://chromium.org aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
(async function() {
TestRunner.addResult('Tests that console logging large messages will be truncated.\n');
await TestRunner.loadModule('console_test_runner');
await TestRunner.showPanel('console');
var consoleView = Console.ConsoleView.instance();
var maxLength = Console.ConsoleViewMessage._MaxTokenizableStringLength = 40;
var visibleLength = Console.ConsoleViewMessage._LongStringVisibleLength = 20;
var overMaxLength = maxLength * 2;
TestRunner.addResult(`Setting max length to: ${maxLength}`);
TestRunner.addResult(`Setting long string visible length to: ${visibleLength}`);
await ConsoleTestRunner.evaluateInConsolePromise(`"a".repeat(${overMaxLength})`);
await TestRunner.evaluateInPagePromise(`console.log("a".repeat(${overMaxLength}))`);
await TestRunner.evaluateInPagePromise(`console.log("a".repeat(${overMaxLength}), "b".repeat(${overMaxLength}))`);
await TestRunner.evaluateInPagePromise(`console.log("%s", "a".repeat(${overMaxLength}))`);
await TestRunner.evaluateInPagePromise(`console.log("%o", "a".repeat(${overMaxLength}))`);
await TestRunner.evaluateInPagePromise(`console.log("%c" + "a".repeat(${overMaxLength}), "color: green")`);
await TestRunner.evaluateInPagePromise(`console.log("foo %s %o bar", "a".repeat(${overMaxLength}), {a: 1})`);
await TestRunner.evaluateInPagePromise(`console.log({a: 1}, "a".repeat(${overMaxLength}), {b: 1})`);
await TestRunner.evaluateInPagePromise(`console.log("a".repeat(${overMaxLength}), "https://chromium.org")`);
await TestRunner.evaluateInPagePromise(`console.log("https://chromium.org", "a".repeat(${overMaxLength}))`);
dumpMessageLengths();
TestRunner.addResult('\nExpanding hidden texts');
consoleView._visibleViewMessages.forEach(message => {
message.element().querySelectorAll('.console-inline-button').forEach(button => button.click());
});
dumpMessageLengths();
TestRunner.completeTest();
function dumpMessageLengths() {
consoleView._visibleViewMessages.forEach((message, index) => {
var text = consoleMessageText(index);
TestRunner.addResult(`Message: ${index}, length: ${text.length}, ${text}`);
});
function consoleMessageText(index) {
var messageElement = consoleView._visibleViewMessages[index].element();
var anchor = messageElement.querySelector('.console-message-anchor');
if (anchor)
anchor.remove();
var links = messageElement.querySelectorAll('.devtools-link');
for (var link of links)
TestRunner.addResult(`Link: ${link.textContent}`);
return messageElement.deepTextContent();
}
}
})();
......@@ -1300,6 +1300,8 @@ Console.ConsoleViewMessage = class {
* @return {!DocumentFragment}
*/
static _linkifyWithCustomLinkifier(string, linkifier) {
if (string.length > Console.ConsoleViewMessage._MaxTokenizableStringLength)
return createExpandableFragment(string);
var container = createDocumentFragment();
var tokens = this._tokenizeMessageText(string);
for (var token of tokens) {
......@@ -1321,6 +1323,31 @@ Console.ConsoleViewMessage = class {
}
}
return container;
/**
* @param {string} text
* @return {!DocumentFragment}
*/
function createExpandableFragment(text) {
var fragment = createDocumentFragment();
fragment.textContent = text.slice(0, Console.ConsoleViewMessage._LongStringVisibleLength);
var hiddenText = text.slice(Console.ConsoleViewMessage._LongStringVisibleLength);
var expandButton = fragment.createChild('span', 'console-inline-button');
expandButton.setAttribute('data-text', ls`Show ${Number.withThousandsSeparator(hiddenText.length)} more`);
expandButton.addEventListener('click', () => {
if (expandButton.parentElement)
expandButton.parentElement.insertBefore(createTextNode(hiddenText), expandButton);
expandButton.remove();
});
var copyButton = fragment.createChild('span', 'console-inline-button');
copyButton.setAttribute('data-text', ls`Copy`);
copyButton.addEventListener('click', () => {
InspectorFrontendHost.copyText(text);
});
return fragment;
}
}
/**
......@@ -1463,3 +1490,5 @@ Console.ConsoleGroupViewMessage = class extends Console.ConsoleViewMessage {
Console.ConsoleViewMessage.MaxLengthForLinks = 40;
Console.ConsoleViewMessage._MaxTokenizableStringLength = 10000;
Console.ConsoleViewMessage._LongStringVisibleLength = 5000;
......@@ -406,4 +406,25 @@
.console-message-expand-icon {
margin-bottom: -2px;
}
\ No newline at end of file
}
.console-inline-button {
background-color: #dedede;
padding: 2px 4px;
margin: 0 2px;
color: #333;
cursor: pointer;
border-radius: 3px;
font-size: 12px;
font-family: sans-serif;
white-space: nowrap;
display: inline-block;
}
.console-inline-button::after {
content: attr(data-text);
}
.console-inline-button:hover {
background-color: #d5d5d5;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment