Bug 1304328 - Stop using XUL in webconsole/jsterm.js; r=nchevobbe
MozReview-Commit-ID: ChyHBETlYOn
--- a/devtools/client/themes/webconsole.css
+++ b/devtools/client/themes/webconsole.css
@@ -413,50 +413,81 @@ html #webconsole-notificationbox {
background-color: #fff;
border-top-color: #e0e0e0;
}
.theme-firebug .jsterm-input-container {
border-top: 1px solid #ccc;
}
-.jsterm-input-node,
+html .jsterm-stack-node {
+ position: relative;
+}
+
+html .jsterm-input-node,
+html .jsterm-complete-node {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100vw;
+ border: none;
+ margin: 0;
+ -moz-appearance: none;
+ background-color: transparent;
+ resize: none;
+ font-size: var(--theme-toolbar-font-size);
+ line-height: 16px;
+ overflow-x: hidden;
+ /* Set padding for console input on textarea to make sure it is included in
+ scrollHeight that is used when resizing JSTerminal's input. */
+ padding: 4px 0;
+ padding-inline-start: 20px;
+}
+
.jsterm-complete-node {
+ color: var(--theme-comment);
+}
+
+/* Focused attribute based selector can be removed as soon as the old
+ Console UI is removed. See bug: 1381834 */
+textbox.jsterm-input-node[focused="true"],
+html .jsterm-input-node:focus {
+ background-image: var(--theme-command-line-image-focus);
+ box-shadow: none;
+}
+
+/* This entire selector + rules can be removed as soon as the old
+ Console UI is removed. See bug: 1381834 */
+textbox.jsterm-input-node,
+textbox.jsterm-complete-node {
border: none;
padding: 0;
padding-inline-start: 20px;
margin: 0;
-moz-appearance: none;
background-color: transparent;
}
-.jsterm-input-node[focused="true"] {
- background-image: var(--theme-command-line-image-focus);
- box-shadow: none;
-}
-
-.jsterm-complete-node {
- color: var(--theme-comment);
-}
-
.jsterm-input-node {
/* Always allow scrolling on input - it auto expands in js by setting height,
but don't want it to get bigger than the window. 24px = toolbar height. */
max-height: calc(90vh - 24px);
background-image: var(--theme-command-line-image);
background-repeat: no-repeat;
background-size: 16px 16px;
background-position: 4px 50%;
color: var(--theme-content-color1);
}
-:-moz-any(.jsterm-input-node,
- .jsterm-complete-node) > .textbox-input-box > .textbox-textarea {
+/* This entire selector + rules can be removed as soon as the old
+ Console UI is removed. See bug: 1381834 */
+:-moz-any(textbox.jsterm-input-node,
+ textbox.jsterm-complete-node) > .textbox-input-box > .textbox-textarea {
overflow-x: hidden;
- /* Set padding for console input on textbox to make sure it is inlcuded in
+ /* Set padding for console input on textbox to make sure it is included in
scrollHeight that is used when resizing JSTerminal's input. Note: textbox
default style has important already */
padding: 4px 0 !important;
}
.inlined-variables-view .message-body {
display: flex;
flex-direction: column;
@@ -1093,27 +1124,28 @@ a.learn-more-link.webconsole-learn-more-
overflow: auto;
-moz-user-select: text;
position: relative;
}
html,
body,
#app-wrapper {
- height: 100%;
margin: 0;
padding: 0;
}
body {
overflow: hidden;
}
#app-wrapper {
- height: 100%;
+ /* The content wrapper take entire vertical space of the panel
+ except of the command line. */
+ height: calc(100% - 24px);
display: flex;
flex-direction: column;
}
body #output-container {
flex: 1;
overflow: hidden;
}
--- a/devtools/client/webconsole/jsterm.js
+++ b/devtools/client/webconsole/jsterm.js
@@ -1001,19 +1001,26 @@ JSTerm.prototype = {
resizeInput: function () {
let inputNode = this.inputNode;
// Reset the height so that scrollHeight will reflect the natural height of
// the contents of the input field.
inputNode.style.height = "auto";
// Now resize the input field to fit its contents.
- let scrollHeight = inputNode.inputField.scrollHeight;
+ // TODO: remove `inputNode.inputField.scrollHeight` when the old
+ // console UI is removed. See bug 1381834
+ let scrollHeight = inputNode.inputField ?
+ inputNode.inputField.scrollHeight : inputNode.scrollHeight;
+
if (scrollHeight > 0) {
inputNode.style.height = scrollHeight + "px";
+
+ let appWrapper = inputNode.ownerDocument.querySelector("#app-wrapper");
+ appWrapper.style.height = `calc(100% - ${scrollHeight}px)`;
}
},
/**
* Sets the value of the input field (command line), and resizes the field to
* fit its contents. This method is preferred over setting "inputNode.value"
* directly, because it correctly resizes the field.
*
--- a/devtools/client/webconsole/new-console-output/new-console-output-wrapper.js
+++ b/devtools/client/webconsole/new-console-output/new-console-output-wrapper.js
@@ -55,17 +55,18 @@ NewConsoleOutputWrapper.prototype = {
}
// Do not focus if an input field was clicked
if (target.closest("input")) {
return;
}
// Do not focus if something other than the output region was clicked
- if (!target.closest(".webconsole-output")) {
+ // (including e.g. the clear messages button in toolbar)
+ if (!target.closest(".webconsole-output-wrapper")) {
return;
}
// Do not focus if something is selected
let selection = this.document.defaultView.getSelection();
if (selection && !selection.isCollapsed) {
return;
}
--- a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_input_focus.js
+++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_input_focus.js
@@ -13,48 +13,43 @@ const TEST_URI =
console.log("console message 1");
</script>`;
add_task(function* () {
let hud = yield openNewTabAndConsole(TEST_URI);
hud.jsterm.clearOutput();
let inputNode = hud.jsterm.inputNode;
- ok(inputNode.getAttribute("focused"), "input node is focused after output is cleared");
+ ok(hasFocus(inputNode), "input node is focused after output is cleared");
info("Focus during message logging");
ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
content.wrappedJSObject.console.log("console message 2");
});
let msg = yield waitFor(() => findMessage(hud, "console message 2"));
- ok(inputNode.getAttribute("focused"), "input node is focused, first time");
+ ok(hasFocus(inputNode, "input node is focused, first time"));
info("Focus after clicking in the output area");
yield waitForBlurredInput(hud);
EventUtils.sendMouseEvent({type: "click"}, msg);
- ok(inputNode.getAttribute("focused"), "input node is focused, second time");
+ ok(hasFocus(inputNode), "input node is focused, second time");
info("Setting a text selection and making sure a click does not re-focus");
yield waitForBlurredInput(hud);
let selection = hud.iframeWindow.getSelection();
selection.selectAllChildren(msg.querySelector(".message-body"));
EventUtils.sendMouseEvent({type: "click"}, msg);
- ok(!inputNode.getAttribute("focused"),
- "input node not focused after text is selected");
+ ok(!hasFocus(inputNode), "input node not focused after text is selected");
});
function waitForBlurredInput(hud) {
let inputNode = hud.jsterm.inputNode;
return new Promise(resolve => {
let lostFocus = () => {
- ok(!inputNode.getAttribute("focused"), "input node is not focused");
+ ok(!hasFocus(inputNode), "input node is not focused");
resolve();
};
inputNode.addEventListener("blur", lostFocus, { once: true });
- // Clicking on a DOM Node outside of the webconsole document. The 'blur' event fires
- // if we click on something in this document (like the filter box), but the 'focus'
- // event won't re-fire on the textbox XBL binding when it's clicked on again.
- // Bug 1304328 is tracking removal of XUL for jsterm, we should be able to click on
- // the filter textbox instead of the url bar after that.
- document.getElementById("urlbar").click();
+ // The 'blur' event fires if we focus e.g. the filter box.
+ inputNode.ownerDocument.querySelector("input.text-filter").focus();
});
}
--- a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_keyboard_accessibility.js
+++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_keyboard_accessibility.js
@@ -49,17 +49,17 @@ add_task(function* () {
let clearShortcut;
if (Services.appinfo.OS === "Darwin") {
clearShortcut = WCUL10n.getStr("webconsole.clear.keyOSX");
} else {
clearShortcut = WCUL10n.getStr("webconsole.clear.key");
}
synthesizeKeyShortcut(clearShortcut);
yield waitFor(() => findMessages(hud, "").length == 0);
- is(hud.jsterm.inputNode.getAttribute("focused"), "true", "jsterm input is focused");
+ ok(hasFocus(hud.jsterm.inputNode), "jsterm input is focused");
// Focus filter
info("try ctrl-f to focus filter");
synthesizeKeyShortcut(WCUL10n.getStr("webconsole.find.key"));
- ok(!hud.jsterm.inputNode.getAttribute("focused"), "jsterm input is not focused");
+ ok(!hasFocus(hud.jsterm.inputNode), "jsterm input is not focused");
is(hud.ui.filterBox, outputScroller.ownerDocument.activeElement,
"filter input is focused");
});
--- a/devtools/client/webconsole/new-console-output/test/mochitest/head.js
+++ b/devtools/client/webconsole/new-console-output/test/mochitest/head.js
@@ -1,15 +1,15 @@
/* -*- 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/ */
/* import-globals-from ../../../../framework/test/shared-head.js */
/* exported WCUL10n, openNewTabAndConsole, waitForMessages, waitFor, findMessage,
- openContextMenu, hideContextMenu, loadDocument,
+ openContextMenu, hideContextMenu, loadDocument, hasFocus,
waitForNodeMutation, testOpenInDebugger, checkClickOnNode */
"use strict";
// shared-head.js handles imports, constants, and utility functions
// Load the shared-head file first.
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js",
@@ -248,8 +248,15 @@ function* checkClickOnNode(hud, toolbox,
let dbg = toolbox.getPanel("jsdebugger");
is(
dbg._selectors.getSelectedSource(dbg._getState()).get("url"),
url,
"expected source url"
);
}
+
+/**
+ * Returns true if the give node is currently focused.
+ */
+function hasFocus(node) {
+ return node.ownerDocument.activeElement == node;
+}
--- a/devtools/client/webconsole/webconsole.xhtml
+++ b/devtools/client/webconsole/webconsole.xhtml
@@ -18,23 +18,23 @@
<script src="chrome://devtools/content/shared/theme-switching.js"></script>
<script type="application/javascript"
src="resource://devtools/client/webconsole/new-console-output/main.js"></script>
</head>
<body class="theme-sidebar" role="application">
<div id="app-wrapper" class="theme-body">
<div id="output-container" role="document" aria-live="polite"/>
<div id="jsterm-wrapper">
- <xul:notificationbox id="webconsole-notificationbox">
+ <div id="webconsole-notificationbox">
<div class="jsterm-input-container" style="direction:ltr">
- <xul:stack class="jsterm-stack-node" flex="1">
- <xul:textbox class="jsterm-complete-node devtools-monospace"
+ <div class="jsterm-stack-node" flex="1">
+ <textarea class="jsterm-complete-node devtools-monospace"
multiline="true" rows="1" tabindex="-1"/>
- <xul:textbox class="jsterm-input-node devtools-monospace"
+ <textarea class="jsterm-input-node devtools-monospace"
multiline="true" rows="1" tabindex="0"
aria-autocomplete="list"/>
- </xul:stack>
+ </div>
</div>
- </xul:notificationbox>
+ </div>
</div>
</div>
</body>
</html>