Skip to content

Commit 01e62d3

Browse files
Harden settings CSS for theme engine compatibility
1 parent 7b35642 commit 01e62d3

6 files changed

Lines changed: 52 additions & 8 deletions

File tree

13.9 MB
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
273d3f7c702197fe62a61e4ca05617e6dcfdf256c5ed7c6e785b9e517cd92d08 folderview.plus-2026.03.08.06.txz

folderview.plus.plg

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,20 @@
66
<!ENTITY launch "Settings/FolderViewPlus">
77
<!ENTITY plugdir "/usr/local/emhttp/plugins/&name;">
88
<!ENTITY pluginURL "https://raw.githubusercontent.com/&github;/main/folderview.plus.plg">
9-
<!ENTITY version "2026.03.08.05">
10-
<!ENTITY md5 "0a80435be4ea2e2e2b4a03c3ebf1d8da">
9+
<!ENTITY version "2026.03.08.06">
10+
<!ENTITY md5 "9a7c8551c73f86995494c5a99c64ef72">
1111
]>
1212

1313
<PLUGIN name="&name;" author="&author;" version="&version;" launch="&launch;" pluginURL="&pluginURL;" icon="folder-icon.png" support="https://github.com/alexphillips-dev/FolderView-Plus/issues" min="7.0.0">
1414
<CHANGES>
1515

16+
###2026.03.08.06
17+
- Theme compatibility hardening: scoped settings-page focus styling to plugin root container only.
18+
- Theme compatibility hardening: replaced global `body` bottom-padding rule with plugin-root scoped padding.
19+
- UX safety: wrapped settings content in `#fv-settings-root` to isolate styling from external theme engines.
20+
- Regression guard: added automated tests for theme-safe CSS selector scoping.
21+
22+
1623
###2026.03.08.05
1724
- Bug fix: hardened first-install behavior when no prior folder JSON data exists.
1825
- Reliability: sanitize error-shaped API responses before rendering folder/state tables.

src/folderview.plus/usr/local/emhttp/plugins/folderview.plus/FolderViewPlus.page

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ emitRequestTokenMetaTag();
1919
</script>
2020
<link rel="stylesheet" href="<?=autov('/plugins/folderview.plus/styles/folderviewplus.css')?>">
2121

22+
<div id="fv-settings-root" class="fv-theme-safe">
2223
<div id="fv-settings-topbar"></div>
2324
<div id="fv-update-notes-panel" class="fv-update-notes-panel" style="display:none"></div>
2425

@@ -702,6 +703,7 @@ emitRequestTokenMetaTag();
702703
</div>
703704

704705
<div id="fv-settings-action-bar"></div>
706+
</div>
705707

706708
<script src="<?=autov('/plugins/folderview.plus/scripts/folderviewplus.utils.js')?>"></script>
707709
<script src="<?=autov('/plugins/folderview.plus/scripts/folderviewplus.request.js')?>"></script>

src/folderview.plus/usr/local/emhttp/plugins/folderview.plus/styles/folderviewplus.css

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,11 +1594,11 @@ h2[data-fv-advanced="1"] + .template-grid .rules-panel {
15941594
}
15951595
}
15961596

1597-
button:focus-visible,
1598-
input:focus-visible,
1599-
select:focus-visible,
1600-
textarea:focus-visible,
1601-
a:focus-visible {
1597+
#fv-settings-root button:focus-visible,
1598+
#fv-settings-root input:focus-visible,
1599+
#fv-settings-root select:focus-visible,
1600+
#fv-settings-root textarea:focus-visible,
1601+
#fv-settings-root a:focus-visible {
16021602
outline: 2px solid #4da3ff;
16031603
outline-offset: 2px;
16041604
}
@@ -2710,7 +2710,7 @@ h2[data-fv-section].fv-search-match {
27102710
font-size: 1.03rem;
27112711
}
27122712

2713-
body {
2713+
#fv-settings-root {
27142714
padding-bottom: calc(64px + var(--fv-unraid-bottom-bar-offset) + env(safe-area-inset-bottom, 0px));
27152715
}
27162716

tests/theme-compatibility.test.mjs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import test from 'node:test';
2+
import assert from 'node:assert/strict';
3+
import fs from 'node:fs';
4+
import path from 'node:path';
5+
6+
const repoRoot = path.resolve(process.cwd());
7+
const settingsPagePath = path.join(
8+
repoRoot,
9+
'src/folderview.plus/usr/local/emhttp/plugins/folderview.plus/FolderViewPlus.page'
10+
);
11+
const settingsCssPath = path.join(
12+
repoRoot,
13+
'src/folderview.plus/usr/local/emhttp/plugins/folderview.plus/styles/folderviewplus.css'
14+
);
15+
16+
const settingsPage = fs.readFileSync(settingsPagePath, 'utf8');
17+
const settingsCss = fs.readFileSync(settingsCssPath, 'utf8');
18+
19+
test('settings page wraps plugin UI in a theme-safe root container', () => {
20+
assert.match(settingsPage, /<div id="fv-settings-root" class="fv-theme-safe">/);
21+
assert.match(settingsPage, /<div id="fv-settings-topbar"><\/div>/);
22+
assert.match(settingsPage, /<div id="fv-settings-action-bar"><\/div>/);
23+
});
24+
25+
test('theme compatibility: global focus and body selectors are scoped to plugin root', () => {
26+
assert.match(settingsCss, /#fv-settings-root\s*\{\s*[\s\S]*padding-bottom:\s*calc\(64px\s*\+\s*var\(--fv-unraid-bottom-bar-offset\)\s*\+\s*env\(safe-area-inset-bottom,\s*0px\)\)/);
27+
assert.match(settingsCss, /#fv-settings-root button:focus-visible/);
28+
assert.match(settingsCss, /#fv-settings-root input:focus-visible/);
29+
assert.match(settingsCss, /#fv-settings-root select:focus-visible/);
30+
assert.match(settingsCss, /#fv-settings-root textarea:focus-visible/);
31+
assert.match(settingsCss, /#fv-settings-root a:focus-visible/);
32+
assert.doesNotMatch(settingsCss, /\nbody\s*\{/);
33+
assert.doesNotMatch(settingsCss, /\nbutton:focus-visible,\s*\ninput:focus-visible,/);
34+
});

0 commit comments

Comments
 (0)