Bug 1399242 - Prevent console react updates while console isn't visible. r=nchevobbe

MozReview-Commit-ID: A6NGLbiuyTE

--HG--
extra : rebase_source : 9f58d6e2ed6be3fb31de276e536158efa4cdd5ce
This commit is contained in:
Alexandre Poirot 2017-10-09 20:14:34 +02:00
parent fb08f4c098
commit 3d64658419
8 changed files with 189 additions and 4 deletions

View File

@ -1763,6 +1763,10 @@ Toolbox.prototype = {
let iframe = node.querySelector(".toolbox-panel-iframe");
if (iframe) {
let visible = node.id == id;
// Prevents hiding the split-console if it is currently enabled
if (node == this.webconsolePanel && this.splitConsole) {
visible = true;
}
this.setIframeVisible(iframe, visible);
}
});
@ -1907,6 +1911,12 @@ Toolbox.prototype = {
Services.prefs.setBoolPref(SPLITCONSOLE_ENABLED_PREF, true);
this._refreshConsoleDisplay();
// Ensure split console is visible if console was already loaded in background
let iframe = this.webconsolePanel.querySelector(".toolbox-panel-iframe");
if (iframe) {
this.setIframeVisible(iframe, true);
}
return this.loadTool("webconsole").then(() => {
this.emit("split-console");
this.focusConsoleInput();

View File

@ -0,0 +1,47 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* Helper class to disable panel rendering when it is in background.
*
* Toolbox code hides the iframes when switching to another panel
* and triggers `visibilitychange` events.
*
* See devtools/client/framework/toolbox.js:setIframeVisible().
*/
const {
createClass,
} = require("devtools/client/shared/vendor/react");
const VisibilityHandler = createClass({
displayName: "VisiblityHandler",
shouldComponentUpdate() {
return document.visibilityState == "visible";
},
onVisibilityChange() {
if (document.visibilityState == "visible") {
this.forceUpdate();
}
},
componentDidMount() {
window.addEventListener("visibilitychange", this.onVisibilityChange);
},
componentWillUnmount() {
window.removeEventListener("visibilitychange", this.onVisibilityChange);
},
render() {
return this.props.children;
}
});
module.exports = VisibilityHandler;

View File

@ -22,6 +22,7 @@ DevToolsModules(
'SidebarToggle.js',
'StackTrace.js',
'Tree.js',
'VisibilityHandler.js',
)
MOCHITEST_CHROME_MANIFESTS += ['test/mochitest/chrome.ini']

View File

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { Component, createFactory } = require("devtools/client/shared/vendor/react");
const { Component, createElement, createFactory } = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { connect } = require("devtools/client/shared/vendor/react-redux");
@ -18,6 +18,7 @@ const {
getAllRepeatById,
} = require("devtools/client/webconsole/new-console-output/selectors/messages");
const MessageContainer = createFactory(require("devtools/client/webconsole/new-console-output/components/MessageContainer").MessageContainer);
const VisibilityHandler = createFactory(require("devtools/client/shared/components/VisibilityHandler"));
const {
MESSAGE_TYPE,
} = require("devtools/client/webconsole/new-console-output/constants");
@ -190,4 +191,9 @@ function mapStateToProps(state, props) {
};
}
module.exports = connect(mapStateToProps)(ConsoleOutput);
module.exports = connect(mapStateToProps)(props =>
VisibilityHandler(
null,
createElement(ConsoleOutput, props)
)
);

View File

@ -209,7 +209,8 @@ NewConsoleOutputWrapper.prototype = {
// be removed once it's not needed anymore.
// Can only wait for response if the action contains a valid message.
let promise;
if (waitForResponse) {
// Also, do not expect any update while the panel is in background.
if (waitForResponse && document.visibilityState === "visible") {
promise = new Promise(resolve => {
let jsterm = this.jsterm;
jsterm.hud.on("new-messages", function onThisMessage(e, messages) {

View File

@ -440,6 +440,7 @@ skip-if = true # Bug 1403205
[browser_webconsole_violation.js]
skip-if = true # Bug 1405245
# old console skip-if = e10s && (os == 'win') # Bug 1264955
[browser_webconsole_visibility_messages.js]
[browser_webconsole_warn_about_replaced_api.js]
[browser_webconsole_websocket.js]
skip-if = true # Bug 1408950
skip-if = true # Bug 1408950

View File

@ -35,6 +35,9 @@ add_task(async function() {
await togglePref(optionsPanel, observer);
observer.destroy();
// Switch back to the console as it won't update when it is in background
await toolbox.selectTool("webconsole");
await testChangedPref(hud);
Services.prefs.clearUserPref(PREF_MESSAGE_TIMESTAMP);

View File

@ -0,0 +1,116 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
// Check messages logged when console not visible are displayed when
// the user show the console again.
const HTML = `
<!DOCTYPE html>
<html>
<body>
<h1>Test console visibility update</h1>
<script>
function log(str) {
console.log(str);
}
</script>
</body>
</html>
`;
const TEST_URI = "data:text/html;charset=utf-8," + encodeURI(HTML);
const MESSAGES_COUNT = 10;
add_task(async function () {
const hud = await openNewTabAndConsole(TEST_URI);
const toolbox = gDevTools.getToolbox(hud.target);
info("Log one message in the console");
ContentTask.spawn(gBrowser.selectedBrowser, null, () => {
content.wrappedJSObject.log("in-console log");
});
await waitFor(() => findMessage(hud, "in-console log"));
info("select the inspector");
await toolbox.selectTool("inspector");
info("Wait for console to be hidden");
const { document } = hud.iframeWindow;
await waitFor(() => (document.visibilityState == "hidden"));
const onAllMessagesInStore = new Promise(done => {
const store = hud.ui.newConsoleOutput.getStore();
store.subscribe(() => {
const messages = store.getState().messages.messagesById.size;
// Also consider the "in-console log" message
if (messages == MESSAGES_COUNT+1) {
done();
}
});
});
await ContentTask.spawn(gBrowser.selectedBrowser, [MESSAGES_COUNT], (count) => {
for (let i = 1; i <= count; i++) {
content.wrappedJSObject.log("in-inspector log " + i);
}
});
info("Waiting for all messages to be logged into the store");
await onAllMessagesInStore;
const count = await findMessages(hud, "in-inspector");
is(count, 0, "No messages from the inspector actually appear in the console");
info("select back the console");
await toolbox.selectTool("webconsole");
info("And wait for all messages to be visible");
let waitForMessagePromises = [];
for (let j = 1; j <= MESSAGES_COUNT; j++) {
waitForMessagePromises.push(waitFor(() => findMessage(hud, "in-inspector log " + j)));
}
await Promise.all(waitForMessagePromises);
ok(true, "All the messages logged when the console was hidden were displayed.");
});
// Similar scenario, but with the split console on the inspector panel.
// Here, the messages should still be logged.
add_task(async function () {
const hud = await openNewTabAndConsole(TEST_URI);
const toolbox = gDevTools.getToolbox(hud.target);
info("Log one message in the console");
ContentTask.spawn(gBrowser.selectedBrowser, null, () => {
content.wrappedJSObject.log("in-console log");
});
await waitFor(() => findMessage(hud, "in-console log"));
info("select the inspector");
await toolbox.selectTool("inspector");
info("Wait for console to be hidden");
const { document } = hud.iframeWindow;
await waitFor(() => (document.visibilityState == "hidden"));
await toolbox.openSplitConsole();
await ContentTask.spawn(gBrowser.selectedBrowser, [MESSAGES_COUNT], (count) => {
for (let i = 1; i <= count; i++) {
content.wrappedJSObject.log("in-inspector log " + i);
}
});
info("Wait for all messages to be visible in the split console");
let waitForMessagePromises = [];
for (let j = 1; j <= MESSAGES_COUNT; j++) {
waitForMessagePromises.push(waitFor(() => findMessage(hud, "in-inspector log " + j)));
}
await Promise.all(waitForMessagePromises);
ok(true, "All the messages logged when we are using the split console");
await toolbox.closeSplitConsole();
});