mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 09:15:35 +00:00
Bug 1534938 - Don't scroll to bottom when opening a group. r=Honza.
The heuristic to scroll the console output to the bottom was to only look if new messages were visible. But it can happen that such case is triggered by only opening a closed group. This patch tweaks the heuristic a bit to exclude the case where we open a group, while making sure that we still scroll to bottom if there are new, opened, group messages. A test is added to ensure this works as expected. Differential Revision: https://phabricator.services.mozilla.com/D23996 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
02fae301d6
commit
5fe7229262
@ -108,23 +108,31 @@ class ConsoleOutput extends Component {
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to scroll to the bottom if:
|
||||
// - we are reacting to "initialize" action, and we are already scrolled to the bottom
|
||||
// - the number of messages displayed changed and we are already scrolled to the
|
||||
// bottom, but not if we are reacting to a group opening.
|
||||
// - the number of messages in the store changed and the new message is an evaluation
|
||||
// result.
|
||||
|
||||
const lastChild = outputNode.lastChild;
|
||||
const visibleMessagesDelta =
|
||||
nextProps.visibleMessages.length - this.props.visibleMessages.length;
|
||||
const messagesDelta =
|
||||
nextProps.messages.size - this.props.messages.size;
|
||||
|
||||
// We need to scroll to the bottom if:
|
||||
// - we are reacting to the "initialize" action,
|
||||
// and we are already scrolled to the bottom
|
||||
// - the number of messages displayed changed
|
||||
// and we are already scrolled to the bottom
|
||||
// - the number of messages in the store changed
|
||||
// and the new message is an evaluation result.
|
||||
const isNewMessageEvaluationResult = messagesDelta > 0 &&
|
||||
[...nextProps.messages.values()][nextProps.messages.size - 1].type
|
||||
=== MESSAGE_TYPE.RESULT;
|
||||
|
||||
const messagesUiDelta =
|
||||
nextProps.messagesUi.length - this.props.messagesUi.length;
|
||||
const isOpeningGroup = messagesUiDelta > 0 &&
|
||||
nextProps.messagesUi.some(id =>
|
||||
!this.props.messagesUi.includes(id) &&
|
||||
nextProps.messagesUi.includes(id) &&
|
||||
this.props.visibleMessages.includes(id) &&
|
||||
nextProps.visibleMessages.includes(id));
|
||||
|
||||
this.shouldScrollBottom =
|
||||
(
|
||||
!this.props.initialized &&
|
||||
@ -132,7 +140,11 @@ class ConsoleOutput extends Component {
|
||||
isScrolledToBottom(lastChild, outputNode)
|
||||
) ||
|
||||
(isNewMessageEvaluationResult) ||
|
||||
(visibleMessagesDelta > 0 && isScrolledToBottom(lastChild, outputNode));
|
||||
(
|
||||
isScrolledToBottom(lastChild, outputNode) &&
|
||||
visibleMessagesDelta > 0 &&
|
||||
!isOpeningGroup
|
||||
);
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
|
@ -253,6 +253,7 @@ skip-if = true # Bug 1405250
|
||||
[browser_webconsole_console_dir.js]
|
||||
[browser_webconsole_console_dir_uninspectable.js]
|
||||
[browser_webconsole_console_error_expand_object.js]
|
||||
[browser_webconsole_console_group_open_no_scroll.js]
|
||||
[browser_webconsole_console_group.js]
|
||||
[browser_webconsole_console_logging_workers_api.js]
|
||||
skip-if = e10s # SharedWorkers console events are not received on the current process because they could run on any process.
|
||||
|
@ -0,0 +1,49 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Check that opening a group does not scroll the console output.
|
||||
|
||||
const TEST_URI = `data:text/html,<meta charset=utf8><script>
|
||||
Array.from({length: 100}, (_, i) => console.log("log-"+i));
|
||||
console.groupCollapsed("GROUP");
|
||||
console.log("in group");
|
||||
</script>`;
|
||||
|
||||
add_task(async function() {
|
||||
const hud = await openNewTabAndConsole(TEST_URI);
|
||||
const outputScroller = hud.ui.outputScroller;
|
||||
|
||||
// Let's wait until the first message and the group are displayed.
|
||||
await waitFor(() => findMessage(hud, "log-0"));
|
||||
const groupMessage = await waitFor(() => findMessage(hud, "GROUP"));
|
||||
|
||||
is(hasVerticalOverflow(outputScroller), true, "output node overflows");
|
||||
is(isScrolledToBottom(outputScroller), true, "output node is scrolled to the bottom");
|
||||
|
||||
info("Expand the group");
|
||||
groupMessage.querySelector(".arrow").click();
|
||||
await waitFor(() => findMessage(hud, "in group"));
|
||||
|
||||
is(hasVerticalOverflow(outputScroller), true, "output node overflows");
|
||||
is(isScrolledToBottom(outputScroller), false,
|
||||
"output node isn't scrolled to the bottom anymore");
|
||||
|
||||
info("Scroll to bottom");
|
||||
outputScroller.scrollTop = outputScroller.scrollHeight;
|
||||
is(isScrolledToBottom(outputScroller), true, "output node is scrolled to the bottom");
|
||||
|
||||
info("Check that adding a message on an open group when scrolled to bottom scrolls " +
|
||||
"to bottom");
|
||||
const onNewMessage = waitForMessage(hud, "new-message");
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
|
||||
content.console.group("GROUP-2");
|
||||
content.console.log("new-message");
|
||||
});
|
||||
await onNewMessage;
|
||||
is(isScrolledToBottom(outputScroller), true,
|
||||
"output node is scrolled to the bottom after adding message in group");
|
||||
});
|
@ -1161,3 +1161,26 @@ async function pauseDebugger(dbg) {
|
||||
});
|
||||
await onPaused;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the passed HTMLElement vertically overflows.
|
||||
* @param {HTMLElement} container
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
function hasVerticalOverflow(container) {
|
||||
return container.scrollHeight > container.clientHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the passed HTMLElement is scrolled to the bottom.
|
||||
* @param {HTMLElement} container
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
function isScrolledToBottom(container) {
|
||||
if (!container.lastChild) {
|
||||
return true;
|
||||
}
|
||||
const lastNodeHeight = container.lastChild.clientHeight;
|
||||
return container.scrollTop + container.clientHeight >=
|
||||
container.scrollHeight - lastNodeHeight / 2;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user