From 3bb573ced14c68b6d867c199c3030fc98d002dd4 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Sat, 22 Aug 2026 13:42:26 -0400 Subject: [PATCH 1/2] treewide: fix textarea double scrolling issue In "textarea" class elements, like the syslog, depending on the browser, it is difficult to scroll if moused over or after clicking or highlighting text. The browser perceives that there is scrolling space/content within the inner element because when the height of the element is exactly the same size as text inside, the text padding or other invisible content exceeds the size of the text box and the scroll bar is kept in the window. This causes scrolling within the element with a range of just a few pixels, and the rest of the page remains static and refuses to scroll. To fix this add 1 to the dynamic size of the "textarea" boxes, and also the initial values before the dynamic size is calculated. This "+ 1" already exists in some instances of similar Javascript files. A previous attempt at fixing this used "overflow-y" styling but that causes undesirable behavior in some "textarea" use cases. In some cases "+ 1" is added to both dynamic and final sizes, this can equate to a total addition of 2 lines, which is still reasonable and proper padding, and this promotes the habit of padding the textarea elements treewide, no matter what example is used to modify or create the javascript for a new app. The aria2 application ternary check for a minimum textarea size seems to be written in reversed logic. It should likely be a minimum of 20 lines, and the exact number + 1 otherwise, so fix that while at it. Tested on Chrome 64-bit Windows 10. Ref: 755061bc9e7e ("themes: remove overflow-y property...") Signed-off-by: Michael Pratt --- .../htdocs/luci-static/resources/view/antiblock/log.js | 4 ++-- .../htdocs/luci-static/resources/view/antiblock/statistics.js | 4 ++-- .../htdocs/luci-static/resources/view/aria2/files.js | 4 ++-- .../htdocs/luci-static/resources/view/package-manager.js | 2 +- modules/luci-base/htdocs/luci-static/resources/tools/views.js | 4 ++-- modules/luci-base/htdocs/luci-static/resources/ui.js | 2 +- .../htdocs/luci-static/resources/view/status/dmesg.js | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/applications/luci-app-antiblock/htdocs/luci-static/resources/view/antiblock/log.js b/applications/luci-app-antiblock/htdocs/luci-static/resources/view/antiblock/log.js index 3918a6a80901..5721a8e05dcf 100644 --- a/applications/luci-app-antiblock/htdocs/luci-static/resources/view/antiblock/log.js +++ b/applications/luci-app-antiblock/htdocs/luci-static/resources/view/antiblock/log.js @@ -25,7 +25,7 @@ return view.extend({ if (element) { const log = await this.retrieveLog(); element.value = log.value; - element.rows = log.rows; + element.rows = log.rows + 1; } }, @@ -78,7 +78,7 @@ return view.extend({ 'style': 'font-size:12px', 'readonly': 'readonly', 'wrap': 'off', - 'rows': loglines.rows + 'rows': loglines.rows + 1 }, [loglines.value]), E('div', { 'style': 'padding-top: 20px' }, [scrollUpButton]) ]) diff --git a/applications/luci-app-antiblock/htdocs/luci-static/resources/view/antiblock/statistics.js b/applications/luci-app-antiblock/htdocs/luci-static/resources/view/antiblock/statistics.js index af95c2d8a247..2f3feef24c06 100644 --- a/applications/luci-app-antiblock/htdocs/luci-static/resources/view/antiblock/statistics.js +++ b/applications/luci-app-antiblock/htdocs/luci-static/resources/view/antiblock/statistics.js @@ -25,7 +25,7 @@ return view.extend({ if (element) { const log = await this.retrieveLog(); element.value = log.value; - element.rows = log.rows; + element.rows = log.rows + 1; } }, @@ -61,7 +61,7 @@ return view.extend({ 'style': 'font-size:12px', 'readonly': 'readonly', 'wrap': 'off', - 'rows': loglines.rows + 'rows': loglines.rows + 1 }, [loglines.value]) ]) ]); diff --git a/applications/luci-app-aria2/htdocs/luci-static/resources/view/aria2/files.js b/applications/luci-app-aria2/htdocs/luci-static/resources/view/aria2/files.js index c86c794a93c4..d41433700229 100644 --- a/applications/luci-app-aria2/htdocs/luci-static/resources/view/aria2/files.js +++ b/applications/luci-app-aria2/htdocs/luci-static/resources/view/aria2/files.js @@ -17,7 +17,7 @@ return view.extend({ res.file = res.file || ''; res.content = 'content' in res ? res.content.trim() : ''; - res.rows = res.content.split('\n', 20).length; + res.rows = res.content.split('\n', 20).length + 1; return res; }) ); @@ -35,7 +35,7 @@ return view.extend({ 'style': 'width: 100%', 'readonly': true, 'wrap': 'off', - 'rows': data.rows >= 20 ? 20 : data.rows + 1 + 'rows': data.rows >= 20 ? data.rows + 1 : 20 }, data.content) ) ]); diff --git a/applications/luci-app-package-manager/htdocs/luci-static/resources/view/package-manager.js b/applications/luci-app-package-manager/htdocs/luci-static/resources/view/package-manager.js index 5272b843f216..76bc7073a6e4 100644 --- a/applications/luci-app-package-manager/htdocs/luci-static/resources/view/package-manager.js +++ b/applications/luci-app-package-manager/htdocs/luci-static/resources/view/package-manager.js @@ -981,7 +981,7 @@ function handleConfig(ev) body.push(E('h5', {}, '%h'.format(file))); body.push(E('textarea', { 'name': file, - 'rows': Math.max(Math.min(L.toArray(conf[file].match(/\n/g)).length, 10), 3) + 'rows': Math.max(Math.min(L.toArray(conf[file].match(/\n/g)).length, 10), 3) + 1 }, '%h'.format(conf[file]))); }); diff --git a/modules/luci-base/htdocs/luci-static/resources/tools/views.js b/modules/luci-base/htdocs/luci-static/resources/tools/views.js index 8bbd9fa76a69..44217a810b59 100644 --- a/modules/luci-base/htdocs/luci-static/resources/tools/views.js +++ b/modules/luci-base/htdocs/luci-static/resources/tools/views.js @@ -140,7 +140,7 @@ var CBILogreadBox = function(logtag, name) { if (element) { const log = await this.retrieveLog(); element.value = log?.value; - element.rows = log?.rows; + element.rows = log?.rows + 1; } }, @@ -277,7 +277,7 @@ var CBILogreadBox = function(logtag, name) { 'style': 'font-size:12px', 'readonly': 'readonly', 'wrap': 'off', - 'rows': loglines?.rows, + 'rows': loglines?.rows + 1 }, [ loglines?.value ]), E('div', {'style': 'padding-bottom: 20px'}, [scrollUpButton]) ]) diff --git a/modules/luci-base/htdocs/luci-static/resources/ui.js b/modules/luci-base/htdocs/luci-static/resources/ui.js index f649904766ab..89e944914319 100644 --- a/modules/luci-base/htdocs/luci-static/resources/ui.js +++ b/modules/luci-base/htdocs/luci-static/resources/ui.js @@ -527,7 +527,7 @@ const UITextarea = UIElement.extend(/** @lends LuCI.ui.Textarea.prototype */ { 'placeholder': this.options.placeholder, 'style': style, 'cols': this.options.cols, - 'rows': this.options.rows, + 'rows': this.options.rows ? this.options.rows + 1 : this.options.rows, 'wrap': this.options.wrap ? 'soft' : 'off' }, [ value ])); diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/dmesg.js b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/dmesg.js index 315ddacd3578..eefec852a6a5 100644 --- a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/dmesg.js +++ b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/dmesg.js @@ -119,7 +119,7 @@ return view.extend({ if (element) { const log = await this.retrieveLog(); element.value = log.value; - element.rows = log.rows; + element.rows = log.rows + 1; } }, @@ -284,7 +284,7 @@ return view.extend({ 'style': 'font-size:12px', 'readonly': 'readonly', 'wrap': 'off', - 'rows': loglines.rows + 'rows': loglines.rows + 1 }, [ loglines.value ]), E('div', {'style': 'padding-bottom: 20px'}, [scrollUpButton]) ]) From 60e8555ff891efb8f826844d174522cc214990d1 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Sat, 22 Aug 2026 13:46:06 -0400 Subject: [PATCH 2/2] luci-theme-openwrt-2020: use lighter color for checkboxes When using browser extensions for automatic dark mode on pages, the background is made too dark to see whether or not the checkboxes are being toggled or their current state. Use the brighter blue color for the check in the checkbox which is suitable for either view as a light mode or dark mode, and also makes the color of the check match the progress bar color. This color change also affects "radio buttons" which likely have the same problem as checkboxes, although there are almost no "radio buttons" in LuCI at all. Signed-off-by: Michael Pratt --- .../htdocs/luci-static/openwrt2020/cascade.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/cascade.css b/themes/luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/cascade.css index d6a476e3476c..edd4d4ba9be7 100644 --- a/themes/luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/cascade.css +++ b/themes/luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/cascade.css @@ -981,7 +981,7 @@ button[disabled], button.disabled, .btn[disabled], .btn.disabled { input[type="checkbox"], input[type="radio"] { --bd-color: var(--main-dark-color); - --fg-color: var(--main-dark-color); + --fg-color: var(--main-bright-color); -webkit-appearance: none; /* nonstandard, should remove in future */ appearance: none; width: 1em;