From 63487ff845d912ca0719e6e78638c306f1e745fe Mon Sep 17 00:00:00 2001 From: Aaron Wallentine <amwalle@sandia.gov> Date: Sat, 15 Jul 2023 15:03:57 -0600 Subject: [PATCH 1/3] Some usability improvements, and grammar fixes. - The code that automatically pads the bottom of the page so that the user is still able to scroll down and see the bottom of the page even with the console expanded now works on all pages (previously was only working correctly on error pages). - Improve keyboard shortcut handling for 'Home', 'End', 'Ctrl-P', 'Ctrl-N', and 'Ctrl-E'. - 'Home' and 'End' go to beginning and end of line; 'Ctrl-E' end of line; 'Ctrl-P' and 'Ctrl-N' navigate forward and back through command history, just like up and down arrows, to match default key mappings in bash. - Add .moveToBeginning and .moveToEnd helper functions to the REPLConsole JS, and use them in key input handlers to make them easier to read. - Improve styling: font sizes and heights are in rems to adjust to font size in browser; close button is a little bigger and offset from the right margin to be more easily usable in browsers that render the scrollbar over the content. (Some widgets in Gnome shell in Ubuntu do this, maybe others also.) - Some small grammar and English usage fixes in comments and README. Details: - Add a container element around the web console so we can more easily add padding to keep it from obscuring the page - DRY the code that adds a margin to the bottom of the page so that user is still able to scroll down and see the bottom of the page even with the console expanded; make it so it works whenever the console is loaded, not just on error pages. - Remove the extra now-redundant code from the error_page.js.erb and regular_page.js.erb; it now lives in main.js.erb. - It wasn't actually working before on regular pages anyway. - Change font sizes used in console from pixels to rems so they will auto-adjust to font size used on the page. This also makes them just a little bigger by default (unless the page font size is very small). - Increase the size of the "close" button slightly so it is easier to hit with the mouse, and also move it slightly away from the right side, so that it doesn't render under the scrollbar on some browsers (usually on Linux, in my experience; the default Gnome shell scrollbars in Ubuntu 20 made it very hard to use). - Add key handling for 'Home' and 'End' keys. - Change Ctrl-E handler to move cursor to end of line, to match default bash builtin key mappings. - Add Ctrl-P and Ctrl-N handlers to navigate previous and next in command history. - Add .moveToBeginning and .moveToEnd helper functions to the REPLConsole JS, and use them in key input handlers to make them easier to read. - Fix grammar and English usage just a little bit in some comments and README. --- README.markdown | 2 +- lib/web_console/context.rb | 2 +- lib/web_console/templates/_markup.html.erb | 12 +++--- lib/web_console/templates/console.js.erb | 33 +++++++++++---- lib/web_console/templates/error_page.js.erb | 40 ++----------------- lib/web_console/templates/main.js.erb | 29 ++++++++++++++ lib/web_console/templates/regular_page.js.erb | 25 +----------- lib/web_console/templates/style.css.erb | 18 ++++++--- lib/web_console/view.rb | 6 +-- 9 files changed, 83 insertions(+), 84 deletions(-) diff --git a/README.markdown b/README.markdown index ae958bca..fe9197dc 100644 --- a/README.markdown +++ b/README.markdown @@ -67,7 +67,7 @@ By default, only requests coming from IPv4 and IPv6 localhosts are allowed. `config.web_console.permissions` lets you control which IP's have access to the console. -You can allow single IP's or whole networks. Say you want to share your +You can allow single IPs or whole networks. Say you want to share your console with `192.168.0.100`: ```ruby diff --git a/lib/web_console/context.rb b/lib/web_console/context.rb index ead093b3..af87503e 100644 --- a/lib/web_console/context.rb +++ b/lib/web_console/context.rb @@ -8,7 +8,7 @@ def initialize(binding) end # Extracts entire objects which can be called by the current session unless - # the inputs is present. + # the input is present. # # Otherwise, it extracts methods and constants of the object specified by # the input. diff --git a/lib/web_console/templates/_markup.html.erb b/lib/web_console/templates/_markup.html.erb index 96d48769..f9cf15b0 100644 --- a/lib/web_console/templates/_markup.html.erb +++ b/lib/web_console/templates/_markup.html.erb @@ -1,5 +1,7 @@ -<div id="console" - data-mount-point='<%= @mount_point %>' - data-session-id='<%= @session.id %>' - data-prompt-label='>> '> -</div> +<div id="console-container"> + <div id="console" + data-mount-point='<%= @mount_point %>' + data-session-id='<%= @session.id %>' + data-prompt-label='>> '> + </div> +</div> \ No newline at end of file diff --git a/lib/web_console/templates/console.js.erb b/lib/web_console/templates/console.js.erb index 108f91ff..8e0d308e 100644 --- a/lib/web_console/templates/console.js.erb +++ b/lib/web_console/templates/console.js.erb @@ -661,6 +661,14 @@ REPLConsole.prototype.onTabKey = function() { }); }; +REPLConsole.prototype.moveToBeginning = function() { + this.setInput(this._input, 0); +}; + +REPLConsole.prototype.moveToEnd = function() { + this.setInput(this._input, this._input.length); +}; + REPLConsole.prototype.onNavigateHistory = function(offset) { var command = this.commandStorage.navigate(offset) || ""; this.setInput(command); @@ -680,14 +688,25 @@ REPLConsole.prototype.onKeyDown = function(ev) { switch (ev.keyCode) { case 65: // Ctrl-A if (ev.ctrlKey) { - this.setInput(this._input, 0); + // this.setInput(this._input, 0); + this.moveToBeginning(); ev.preventDefault(); } break; + case 36: // 'Home' key + this.moveToBeginning(); + ev.preventDefault(); + break; + + case 35: // 'End' key + this.moveToEnd(); + ev.preventDefault(); + break; + case 69: // Ctrl-E if (ev.ctrlKey) { - this.onTabKey(); + this.moveToEnd(); ev.preventDefault(); } break; @@ -706,18 +725,16 @@ REPLConsole.prototype.onKeyDown = function(ev) { } break; - case 69: // Ctrl-E - if (ev.ctrlKey) { - this.onTabKey(); - ev.preventDefault(); - } - break; case 80: // Ctrl-P if (! ev.ctrlKey) break; + this.onNavigateHistory(-1); + break; case 78: // Ctrl-N if (! ev.ctrlKey) break; + this.onNavigateHistory(1); + break; case 9: // Tab this.onTabKey(); diff --git a/lib/web_console/templates/error_page.js.erb b/lib/web_console/templates/error_page.js.erb index 9fc91d26..293ccbc8 100644 --- a/lib/web_console/templates/error_page.js.erb +++ b/lib/web_console/templates/error_page.js.erb @@ -1,8 +1,8 @@ -// Try intercept traces links in Rails 4.2. +// Try to intercept traces links in Rails 4.2. var traceFrames = document.getElementsByClassName('trace-frames'); var selectedFrame, currentSource = document.getElementById('frame-source-0'); -// Add click listeners for all stack frames +// Add click listeners for all stack frames. for (var i = 0; i < traceFrames.length; i++) { traceFrames[i].addEventListener('click', function(e) { e.preventDefault(); @@ -17,7 +17,7 @@ for (var i = 0; i < traceFrames.length; i++) { return target.innerHTML; }); - // Change the extracted source code + // Change the extracted source code. changeSourceExtract(frameId); }); } @@ -34,36 +34,4 @@ function changeSourceExtract(frameId) { el.className = el.className.replace(" hidden", ""); currentSource = el; } -} - -// Push the error page body upwards the size of the console. -// -// While, I wouldn't like to do that on every custom page (so I don't screw -// user's layouts), I think a lot of developers want to see all of the content -// on the default Rails error page. -// -// Since it's quite special as is now, being a bit more special in the name of -// better user experience, won't hurt. -document.addEventListener('DOMContentLoaded', function() { - var consoleElement = document.getElementById('console'); - var resizerElement = consoleElement.getElementsByClassName('resizer')[0]; - var containerElement = document.getElementById('container'); - - function setContainerElementBottomMargin(pixels) { - containerElement.style.marginBottom = pixels + 'px'; - } - - var currentConsoleElementHeight = consoleElement.offsetHeight; - setContainerElementBottomMargin(currentConsoleElementHeight); - - resizerElement.addEventListener('mousedown', function(event) { - function recordConsoleElementHeight(event) { - resizerElement.removeEventListener('mouseup', recordConsoleElementHeight); - - var currentConsoleElementHeight = consoleElement.offsetHeight; - setContainerElementBottomMargin(currentConsoleElementHeight); - } - - resizerElement.addEventListener('mouseup', recordConsoleElementHeight); - }); -}); +} \ No newline at end of file diff --git a/lib/web_console/templates/main.js.erb b/lib/web_console/templates/main.js.erb index 4e4a0284..f3123f31 100644 --- a/lib/web_console/templates/main.js.erb +++ b/lib/web_console/templates/main.js.erb @@ -1 +1,30 @@ REPLConsole.installInto('console'); + +// Push the page body upwards by the size of the console +// so it doesn't obscure any of the page content. +// +// An event handler is added to adjust the size of the margin +// whenever the console is resized. +document.addEventListener('DOMContentLoaded', function() { + var consoleElement = document.getElementById('console'); + var resizerElement = consoleElement.getElementsByClassName('resizer')[0]; + var consoleContainerElement = document.getElementById('console-container'); + + function setConsoleContainerMargin(pixels) { + consoleContainerElement.style.marginTop = pixels + 'px'; + } + + var currentConsoleElementHeight = consoleElement.offsetHeight; + setConsoleContainerMargin(currentConsoleElementHeight); + + resizerElement.addEventListener('mousedown', function(event) { + function recordConsoleElementHeight(event) { + resizerElement.removeEventListener('mouseup', recordConsoleElementHeight); + + var currentConsoleElementHeight = consoleElement.offsetHeight; + setConsoleContainerMargin(currentConsoleElementHeight); + } + + resizerElement.addEventListener('mouseup', recordConsoleElementHeight); + }); +}); diff --git a/lib/web_console/templates/regular_page.js.erb b/lib/web_console/templates/regular_page.js.erb index bee20147..ee422442 100644 --- a/lib/web_console/templates/regular_page.js.erb +++ b/lib/web_console/templates/regular_page.js.erb @@ -1,24 +1 @@ -// Push the error page body upwards the size of the console. -document.addEventListener('DOMContentLoaded', function() { - var consoleElement = document.getElementById('console'); - var resizerElement = consoleElement.getElementsByClassName('resizer')[0]; - var bodyElement = document.body; - - function setBodyElementBottomMargin(pixels) { - bodyElement.style.marginBottom = pixels + 'px'; - } - - var currentConsoleElementHeight = consoleElement.offsetHeight; - setBodyElementBottomMargin(currentConsoleElementHeight); - - resizerElement.addEventListener('mousedown', function(event) { - function recordConsoleElementHeight(event) { - resizerElement.removeEventListener('mouseup', recordConsoleElementHeight); - - var currentConsoleElementHeight = consoleElement.offsetHeight; - setBodyElementBottomMargin(currentConsoleElementHeight); - } - - resizerElement.addEventListener('mouseup', recordConsoleElementHeight); - }); -}); +// Nothing here, for now \ No newline at end of file diff --git a/lib/web_console/templates/style.css.erb b/lib/web_console/templates/style.css.erb index 4e80780f..084569e9 100644 --- a/lib/web_console/templates/style.css.erb +++ b/lib/web_console/templates/style.css.erb @@ -1,3 +1,8 @@ +#console-container { + --console-initial-height: 10rem; + margin-top: var(--console-initial-height); +} + .console .pos-absolute { position: absolute; } @@ -32,7 +37,7 @@ left: 0; bottom: 0; width: 100%; - height: 148px; + height: var(--console-initial-height); padding: 0; margin: 0; background: none repeat scroll 0% 0% #333; @@ -46,7 +51,7 @@ .console .console-inner { font-family: monospace; - font-size: 11px; + font-size: 1rem; width: 100%; height: 100%; overflow: unset; @@ -124,10 +129,11 @@ cursor: pointer; border-radius: 1px; font-family: monospace; - font-size: 13px; - width: 14px; - height: 14px; - line-height: 14px; + font-size: 1.2rem; + width: 1.5rem; + height: 1.5rem; + margin-right: 1.5rem; /* allow room for scrollbar on right on some browsers */ + line-height: 1.4rem; text-align: center; color: #ccc; } diff --git a/lib/web_console/view.rb b/lib/web_console/view.rb index 57f1ad33..585cf09e 100644 --- a/lib/web_console/view.rb +++ b/lib/web_console/view.rb @@ -17,9 +17,9 @@ def only_on_regular_page(*args) # Render JavaScript inside a script tag and a closure. # - # This one lets write JavaScript that will automatically get wrapped in a - # script tag and enclosed in a closure, so you don't have to worry for - # leaking globals, unless you explicitly want to. + # Allows writing JavaScript that will automatically get wrapped in + # a script tag and enclosed in a closure, so we don't have to worry about + # leaking globals, unless we explicitly want to. def render_javascript(template) assign(template: template) assign(nonce: @env["action_dispatch.content_security_policy_nonce"]) From c6f0a6503b38708bbb59795f827829a66932d026 Mon Sep 17 00:00:00 2001 From: Aaron Wallentine <amwalle@sandia.gov> Date: Sat, 15 Jul 2023 15:29:20 -0600 Subject: [PATCH 2/3] Fix test to accommodate for markup changes. --- test/web_console/middleware_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/web_console/middleware_test.rb b/test/web_console/middleware_test.rb index b545e78c..fcc364f3 100644 --- a/test/web_console/middleware_test.rb +++ b/test/web_console/middleware_test.rb @@ -64,7 +64,7 @@ def headers get "/", params: nil - assert_select "body > #console" + assert_select "body > #console-container > #console" end test "render error_page.js from web_console.exception" do From 4058663fe79117047660589b308af83dcd2fd948 Mon Sep 17 00:00:00 2001 From: Aaron Wallentine <amwalle@sandia.gov> Date: Sat, 15 Jul 2023 16:12:28 -0600 Subject: [PATCH 3/3] Bump version --- lib/web_console/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web_console/version.rb b/lib/web_console/version.rb index 7178afa1..66e31769 100644 --- a/lib/web_console/version.rb +++ b/lib/web_console/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module WebConsole - VERSION = "4.2.0" + VERSION = "4.2.1" end