luci-theme-openwrt-2020: minor fixes - #8964
Conversation
openwrt-ai
left a comment
There was a problem hiding this comment.
Commit checks
- 5008956 "luci-theme-openwrt-2020: use lighter color for checkboxes" — the subject and body talk about checkboxes only, but the changed declaration sits in the shared
input[type="checkbox"], input[type="radio"]block andinput[type="radio"]:checked::afteralso paints withvar(--fg-color), so radio buttons are recoloured too. Either mention radios in the message or scope the override toinput[type="checkbox"].
Generated by Claude Code
| input[type="radio"] { | ||
| --bd-color: var(--main-dark-color); | ||
| --fg-color: var(--main-dark-color); | ||
| --fg-color: var(--main-bright-color); |
There was a problem hiding this comment.
This lowers the checked-state contrast in the theme's own (light) rendering. --fg-color paints the checkmark glyph via background: var(--fg-color) on :checked::after at line 1034, and the page background is white ([`body { background: var(--secondary-bright-color) }`](https://github.com/openwrt/luci/blob/500895691b08c46ab9da396a3ea3e8e4f1b0fbbd/themes/luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/cascade.css#L50-L51),`` #FFFFFF). #00B5E2 on white is roughly 2.4:1, under the 3:1 that WCAG 2.1 SC 1.4.11 asks for on non-text UI components; the current --main-dark-color (#002B49) is roughly 14.6:1.
This theme ships no prefers-color-scheme handling, so the only rendering it controls is the light one — and the commit message says the motivation is a third-party extension that inverts the page. Is trading the default rendering for that the intent? A @media (prefers-color-scheme: dark) override of --fg-color, or brightening only the ::before box outline and leaving the glyph dark, would fix the dark case without regressing the light one.
Generated by Claude Code
There was a problem hiding this comment.
maybe we should consider changing the color because of WCAG 2.1 SC 1.4.11, but thats for another day...
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. Tested on Chrome 64-bit Windows 10. Ref: 755061b ("themes: remove overflow-y property...") Signed-off-by: Michael Pratt <mcpratt@pm.me>
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 <mcpratt@pm.me>
5008956 to
32970c5
Compare
|
I see that using bumping the "rows" value also fixes the problem while not blocking a scrollbar from appearing in other contexts. I think this is ready now |
openwrt-ai
left a comment
There was a problem hiding this comment.
Re-reviewed after the force-push: the CSS overflow-y approach was replaced by a JS rows + 1 approach, so the first commit is entirely new. The previous commit-check on the checkbox commit is addressed — 32970c5 now documents the radio-button side effect.
Commit checks
- db70415 "treewide: fix textarea double scrolling issue" — the body says "add 1 to the dynamic size of the
textareaboxes", but in five of the seven files the value being incremented has already been padded by its producer, so the effective change is +2, not +1. The message also reads the pre-existing+ 1as belonging to unrelated files ("this+ 1already exists in some instances of similar Javascript files") when it is in fact the same padding, in the same files this commit touches. Either drop the duplicate hunks or state that +2 is intended. Details inline.
Generated by Claude Code
| const log = await this.retrieveLog(); | ||
| element.value = log?.value; | ||
| element.rows = log?.rows; | ||
| element.rows = log?.rows + 1; |
There was a problem hiding this comment.
retrieveLog() already returns the padded value — rows: loglines?.length + 1 at views.js:126. So log?.rows is already lines + 1, and this hunk makes the syslog box lines + 2. The commit message says "add 1 to the dynamic size", not 2, so this looks unintended — the + 1 the message notes "already exists in some instances of similar Javascript files" is this same producer-side one, not a separate concern.
| element.rows = log?.rows + 1; | |
| element.rows = log?.rows; |
The identical double-apply is in the four other log views, each of which already pads at the producer:
producer (already + 1) |
sites this PR adds a second + 1 |
|---|---|
| views.js:126 | this line, and line 280 |
| dmesg.js:109 | dmesg.js:122, dmesg.js:287 |
| antiblock/log.js:16`` | log.js:28, log.js:81 |
| antiblock/statistics.js:16`` | statistics.js:28, statistics.js:64 |
If lines + 2 really is what fixed the scrolling for you in testing, then the fix belongs in the one producer expression per file rather than in the two consumers, and the commit message should say +2.
Generated by Claude Code
| 'style': style, | ||
| 'cols': this.options.cols, | ||
| 'rows': this.options.rows, | ||
| 'rows': this.options.rows + 1, |
There was a problem hiding this comment.
rows is optional here and defaults to null — rows: null in __init__ at ui.js:511. null + 1 is 1, so every ui.Textarea constructed without an explicit rows now renders a one-line-tall textarea. Before this change the null was dropped by attr[key] == null in dom.attr() at luci.js:1503, so no rows attribute was emitted at all and the theme CSS governed the height.
The form.TextValue path is hit too but lands differently: rows: this.rows at form.js:5356 passes undefined for options that never set .rows, and Object.assign overwrites the null default with that undefined, so those get rows="NaN" — an invalid attribute value the browser discards. Affected in-tree options that never assign .rows include cloudflared config.js:62 and [keepalived peers.js:83](https://github.com/openwrt/luci/blob/32970c53fc94d6659253154812e53cbfee8f2fe0/applications/luci-app-keepalived/htdocs/luci-static/resources/view/keepalived/peers.js#L83),`` plus samba4, ksmbd, ocserv, lldpd, smartdns, clamav and nlbwmon.
Only pad when a row count was actually supplied, so the unset case keeps being omitted:
| 'rows': this.options.rows + 1, | |
| 'rows': this.options.rows != null ? this.options.rows + 1 : null, |
Generated by Claude Code
| 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; |
There was a problem hiding this comment.
Padding here misses the case that actually has the bug and over-pads the one that doesn't. The consumer already adds the row itself in its else-branch — 'rows': data.rows >= 20 ? 20 : data.rows + 1 at files.js:38.``
Because split('\n', 20) caps the array at 20 entries, res.rows maxes out at 20 before this change:
- ≥ 20 lines (the case that double-scrolls):
res.rowsbecomes 21, still>= 20, so the ternary still yields exactly20rows for 20 displayed lines. Unchanged — and still buggy. - ≤ 18 lines: now
lines + 2instead oflines + 1. - 19 lines:
res.rowsbecomes 20, which now trips the>= 20branch, so the cap boundary moves one line earlier.
It also makes res.rows no longer mean "number of lines", which is what line 38 reads it as. Revert this line:
| res.rows = res.content.split('\n', 20).length + 1; | |
| res.rows = res.content.split('\n', 20).length; |
and fix the capped branch at line 38 instead — 'rows': Math.min(data.rows, 20) + 1 gives 21 rows for the capped case and keeps lines + 1 everywhere below it.
Generated by Claude Code
Pull request details
Tested on
Web browser(s): Win 10 64-bit Chrome 151.0.7922.169