mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-05-26 00:55:16 -07:00
fix: default hoverTokenBackgroundColor to transparent
- Change default from rgba(54, 58, 79, 0.84) to transparent in config, CSS, and sanitizer fallbacks - Update tests and docs to reflect new default
This commit is contained in:
@@ -378,7 +378,7 @@
|
|||||||
"text-shadow": "0 2px 6px rgba(0,0,0,0.9), 0 0 12px rgba(0,0,0,0.55)", // Text shadow setting.
|
"text-shadow": "0 2px 6px rgba(0,0,0,0.9), 0 0 12px rgba(0,0,0,0.55)", // Text shadow setting.
|
||||||
"backdrop-filter": "blur(6px)", // Backdrop filter setting.
|
"backdrop-filter": "blur(6px)", // Backdrop filter setting.
|
||||||
"--subtitle-hover-token-color": "#f4dbd6", // Subtitle hover token color setting.
|
"--subtitle-hover-token-color": "#f4dbd6", // Subtitle hover token color setting.
|
||||||
"--subtitle-hover-token-background-color": "rgba(54, 58, 79, 0.84)" // Subtitle hover token background color setting.
|
"--subtitle-hover-token-background-color": "transparent" // Subtitle hover token background color setting.
|
||||||
}, // CSS declaration object applied to primary subtitles after normal subtitle style defaults.
|
}, // CSS declaration object applied to primary subtitles after normal subtitle style defaults.
|
||||||
"enableJlpt": false, // Enable JLPT vocabulary level underlines. When disabled, JLPT tagging lookup and underlines are skipped. Values: true | false
|
"enableJlpt": false, // Enable JLPT vocabulary level underlines. When disabled, JLPT tagging lookup and underlines are skipped. Values: true | false
|
||||||
"preserveLineBreaks": false, // Preserve line breaks in visible overlay subtitle rendering. When false, line breaks are flattened to spaces for a single-line flow. Values: true | false
|
"preserveLineBreaks": false, // Preserve line breaks in visible overlay subtitle rendering. When false, line breaks are flattened to spaces for a single-line flow. Values: true | false
|
||||||
|
|||||||
@@ -390,7 +390,7 @@ See `config.example.jsonc` for detailed configuration options.
|
|||||||
| `autoPauseVideoOnHover` | boolean | Pause playback while mouse hovers subtitle text, then resume on leave (`true` by default). |
|
| `autoPauseVideoOnHover` | boolean | Pause playback while mouse hovers subtitle text, then resume on leave (`true` by default). |
|
||||||
| `autoPauseVideoOnYomitanPopup` | boolean | Pause playback while the Yomitan popup is open, then resume when the popup closes (`true` by default). |
|
| `autoPauseVideoOnYomitanPopup` | boolean | Pause playback while the Yomitan popup is open, then resume when the popup closes (`true` by default). |
|
||||||
| `hoverTokenColor` | string | Hex color used for hovered subtitle token highlight in mpv (default: catppuccin mauve) |
|
| `hoverTokenColor` | string | Hex color used for hovered subtitle token highlight in mpv (default: catppuccin mauve) |
|
||||||
| `hoverTokenBackgroundColor` | string | CSS color used for hovered subtitle token background highlight; `hoverBackground` is accepted as an alias |
|
| `hoverTokenBackgroundColor` | string | CSS color used for hovered subtitle token background highlight (default: `"transparent"`); `hoverBackground` is accepted as an alias |
|
||||||
| `nameMatchEnabled` | boolean | Enable subtitle token coloring for matches from the SubMiner character dictionary (`true` by default) |
|
| `nameMatchEnabled` | boolean | Enable subtitle token coloring for matches from the SubMiner character dictionary (`true` by default) |
|
||||||
| `nameMatchColor` | string | Hex color used for subtitle tokens matched from the SubMiner character dictionary (default: `#f5bde6`) |
|
| `nameMatchColor` | string | Hex color used for subtitle tokens matched from the SubMiner character dictionary (default: `#f5bde6`) |
|
||||||
| `knownWordColor` | string | Hex color used for known-word subtitle highlights (default: `#a6da95`) |
|
| `knownWordColor` | string | Hex color used for known-word subtitle highlights (default: `#a6da95`) |
|
||||||
|
|||||||
@@ -378,7 +378,7 @@
|
|||||||
"text-shadow": "0 2px 6px rgba(0,0,0,0.9), 0 0 12px rgba(0,0,0,0.55)", // Text shadow setting.
|
"text-shadow": "0 2px 6px rgba(0,0,0,0.9), 0 0 12px rgba(0,0,0,0.55)", // Text shadow setting.
|
||||||
"backdrop-filter": "blur(6px)", // Backdrop filter setting.
|
"backdrop-filter": "blur(6px)", // Backdrop filter setting.
|
||||||
"--subtitle-hover-token-color": "#f4dbd6", // Subtitle hover token color setting.
|
"--subtitle-hover-token-color": "#f4dbd6", // Subtitle hover token color setting.
|
||||||
"--subtitle-hover-token-background-color": "rgba(54, 58, 79, 0.84)" // Subtitle hover token background color setting.
|
"--subtitle-hover-token-background-color": "transparent" // Subtitle hover token background color setting.
|
||||||
}, // CSS declaration object applied to primary subtitles after normal subtitle style defaults.
|
}, // CSS declaration object applied to primary subtitles after normal subtitle style defaults.
|
||||||
"enableJlpt": false, // Enable JLPT vocabulary level underlines. When disabled, JLPT tagging lookup and underlines are skipped. Values: true | false
|
"enableJlpt": false, // Enable JLPT vocabulary level underlines. When disabled, JLPT tagging lookup and underlines are skipped. Values: true | false
|
||||||
"preserveLineBreaks": false, // Preserve line breaks in visible overlay subtitle rendering. When false, line breaks are flattened to spaces for a single-line flow. Values: true | false
|
"preserveLineBreaks": false, // Preserve line breaks in visible overlay subtitle rendering. When false, line breaks are flattened to spaces for a single-line flow. Values: true | false
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ test('loads defaults when config is missing', () => {
|
|||||||
assert.equal(config.subtitleStyle.autoPauseVideoOnYomitanPopup, true);
|
assert.equal(config.subtitleStyle.autoPauseVideoOnYomitanPopup, true);
|
||||||
assert.equal(config.subtitleSidebar.enabled, true);
|
assert.equal(config.subtitleSidebar.enabled, true);
|
||||||
assert.equal(config.subtitleStyle.hoverTokenColor, '#f4dbd6');
|
assert.equal(config.subtitleStyle.hoverTokenColor, '#f4dbd6');
|
||||||
assert.equal(config.subtitleStyle.hoverTokenBackgroundColor, 'rgba(54, 58, 79, 0.84)');
|
assert.equal(config.subtitleStyle.hoverTokenBackgroundColor, 'transparent');
|
||||||
assert.equal(config.subtitleStyle.fontFamily, DEFAULT_SUBTITLE_FONT_FAMILY);
|
assert.equal(config.subtitleStyle.fontFamily, DEFAULT_SUBTITLE_FONT_FAMILY);
|
||||||
assert.equal(config.subtitleStyle.fontWeight, '600');
|
assert.equal(config.subtitleStyle.fontWeight, '600');
|
||||||
assert.equal(config.subtitleStyle.lineHeight, 1.35);
|
assert.equal(config.subtitleStyle.lineHeight, 1.35);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export const SUBTITLE_DEFAULT_CONFIG: Pick<ResolvedConfig, 'subtitleStyle' | 'su
|
|||||||
autoPauseVideoOnHover: true,
|
autoPauseVideoOnHover: true,
|
||||||
autoPauseVideoOnYomitanPopup: true,
|
autoPauseVideoOnYomitanPopup: true,
|
||||||
hoverTokenColor: '#f4dbd6',
|
hoverTokenColor: '#f4dbd6',
|
||||||
hoverTokenBackgroundColor: 'rgba(54, 58, 79, 0.84)',
|
hoverTokenBackgroundColor: 'transparent',
|
||||||
nameMatchEnabled: true,
|
nameMatchEnabled: true,
|
||||||
nameMatchColor: '#f5bde6',
|
nameMatchColor: '#f5bde6',
|
||||||
fontFamily: 'Hiragino Sans, M PLUS 1, Source Han Sans JP, Noto Sans CJK JP',
|
fontFamily: 'Hiragino Sans, M PLUS 1, Source Han Sans JP, Noto Sans CJK JP',
|
||||||
|
|||||||
@@ -660,7 +660,7 @@ body.subtitle-sidebar-embedded-open #subtitleContainer {
|
|||||||
--subtitle-jlpt-n4-color: #a6e3a1;
|
--subtitle-jlpt-n4-color: #a6e3a1;
|
||||||
--subtitle-jlpt-n5-color: #8aadf4;
|
--subtitle-jlpt-n5-color: #8aadf4;
|
||||||
--subtitle-hover-token-color: #f4dbd6;
|
--subtitle-hover-token-color: #f4dbd6;
|
||||||
--subtitle-hover-token-background-color: rgba(54, 58, 79, 0.84);
|
--subtitle-hover-token-background-color: transparent;
|
||||||
--subtitle-frequency-single-color: #f5a97f;
|
--subtitle-frequency-single-color: #f5a97f;
|
||||||
--subtitle-frequency-band-1-color: #ed8796;
|
--subtitle-frequency-band-1-color: #ed8796;
|
||||||
--subtitle-frequency-band-2-color: #f5a97f;
|
--subtitle-frequency-band-2-color: #f5a97f;
|
||||||
@@ -719,7 +719,7 @@ body.settings-modal-open [data-subminer-yomitan-popup-host='true'] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#subtitleRoot .c:hover {
|
#subtitleRoot .c:hover {
|
||||||
background: var(--subtitle-hover-token-background-color, rgba(54, 58, 79, 0.84));
|
background: var(--subtitle-hover-token-background-color, transparent);
|
||||||
color: var(--subtitle-hover-token-color, #f4dbd6) !important;
|
color: var(--subtitle-hover-token-color, #f4dbd6) !important;
|
||||||
-webkit-text-fill-color: var(--subtitle-hover-token-color, #f4dbd6) !important;
|
-webkit-text-fill-color: var(--subtitle-hover-token-color, #f4dbd6) !important;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
@@ -884,7 +884,7 @@ body.settings-modal-open [data-subminer-yomitan-popup-host='true'] {
|
|||||||
):not(.word-frequency-band-1):not(.word-frequency-band-2):not(.word-frequency-band-3):not(
|
):not(.word-frequency-band-1):not(.word-frequency-band-2):not(.word-frequency-band-3):not(
|
||||||
.word-frequency-band-4
|
.word-frequency-band-4
|
||||||
):not(.word-frequency-band-5):hover {
|
):not(.word-frequency-band-5):hover {
|
||||||
background: var(--subtitle-hover-token-background-color, rgba(54, 58, 79, 0.84));
|
background: var(--subtitle-hover-token-background-color, transparent);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
color: var(--subtitle-hover-token-color, #f4dbd6) !important;
|
color: var(--subtitle-hover-token-color, #f4dbd6) !important;
|
||||||
-webkit-text-fill-color: var(--subtitle-hover-token-color, #f4dbd6) !important;
|
-webkit-text-fill-color: var(--subtitle-hover-token-color, #f4dbd6) !important;
|
||||||
@@ -899,7 +899,7 @@ body.settings-modal-open [data-subminer-yomitan-popup-host='true'] {
|
|||||||
#subtitleRoot .word.word-frequency-band-3:hover,
|
#subtitleRoot .word.word-frequency-band-3:hover,
|
||||||
#subtitleRoot .word.word-frequency-band-4:hover,
|
#subtitleRoot .word.word-frequency-band-4:hover,
|
||||||
#subtitleRoot .word.word-frequency-band-5:hover {
|
#subtitleRoot .word.word-frequency-band-5:hover {
|
||||||
background: var(--subtitle-hover-token-background-color, rgba(54, 58, 79, 0.84));
|
background: var(--subtitle-hover-token-background-color, transparent);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
filter: brightness(1.18) saturate(1.08);
|
filter: brightness(1.18) saturate(1.08);
|
||||||
}
|
}
|
||||||
@@ -933,13 +933,13 @@ body.settings-modal-open [data-subminer-yomitan-popup-host='true'] {
|
|||||||
#subtitleRoot::selection,
|
#subtitleRoot::selection,
|
||||||
#subtitleRoot .word::selection,
|
#subtitleRoot .word::selection,
|
||||||
#subtitleRoot .c::selection {
|
#subtitleRoot .c::selection {
|
||||||
background: var(--subtitle-hover-token-background-color, rgba(54, 58, 79, 0.84));
|
background: var(--subtitle-hover-token-background-color, transparent);
|
||||||
color: var(--subtitle-hover-token-color, #f4dbd6) !important;
|
color: var(--subtitle-hover-token-color, #f4dbd6) !important;
|
||||||
-webkit-text-fill-color: var(--subtitle-hover-token-color, #f4dbd6) !important;
|
-webkit-text-fill-color: var(--subtitle-hover-token-color, #f4dbd6) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#subtitleRoot *::selection {
|
#subtitleRoot *::selection {
|
||||||
background: var(--subtitle-hover-token-background-color, rgba(54, 58, 79, 0.84)) !important;
|
background: var(--subtitle-hover-token-background-color, transparent) !important;
|
||||||
color: var(--subtitle-hover-token-color, #f4dbd6) !important;
|
color: var(--subtitle-hover-token-color, #f4dbd6) !important;
|
||||||
-webkit-text-fill-color: var(--subtitle-hover-token-color, #f4dbd6) !important;
|
-webkit-text-fill-color: var(--subtitle-hover-token-color, #f4dbd6) !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1066,10 +1066,7 @@ test('subtitle annotation CSS underlines JLPT tokens without changing token colo
|
|||||||
|
|
||||||
const subtitleRootBlock = extractClassBlock(cssText, '#subtitleRoot');
|
const subtitleRootBlock = extractClassBlock(cssText, '#subtitleRoot');
|
||||||
assert.match(subtitleRootBlock, /--subtitle-hover-token-color:\s*#f4dbd6;/);
|
assert.match(subtitleRootBlock, /--subtitle-hover-token-color:\s*#f4dbd6;/);
|
||||||
assert.match(
|
assert.match(subtitleRootBlock, /--subtitle-hover-token-background-color:\s*transparent;/);
|
||||||
subtitleRootBlock,
|
|
||||||
/--subtitle-hover-token-background-color:\s*rgba\(54,\s*58,\s*79,\s*0\.84\);/,
|
|
||||||
);
|
|
||||||
assert.match(subtitleRootBlock, /-webkit-text-fill-color:\s*currentColor;/);
|
assert.match(subtitleRootBlock, /-webkit-text-fill-color:\s*currentColor;/);
|
||||||
|
|
||||||
const charBlock = extractClassBlock(cssText, '#subtitleRoot .c');
|
const charBlock = extractClassBlock(cssText, '#subtitleRoot .c');
|
||||||
@@ -1123,7 +1120,7 @@ test('subtitle annotation CSS underlines JLPT tokens without changing token colo
|
|||||||
);
|
);
|
||||||
assert.match(
|
assert.match(
|
||||||
plainWordHoverBlock,
|
plainWordHoverBlock,
|
||||||
/background:\s*var\(--subtitle-hover-token-background-color,\s*rgba\(54,\s*58,\s*79,\s*0\.84\)\);/,
|
/background:\s*var\(--subtitle-hover-token-background-color,\s*transparent\);/,
|
||||||
);
|
);
|
||||||
assert.match(
|
assert.match(
|
||||||
plainWordHoverBlock,
|
plainWordHoverBlock,
|
||||||
@@ -1137,7 +1134,7 @@ test('subtitle annotation CSS underlines JLPT tokens without changing token colo
|
|||||||
const coloredWordHoverBlock = extractClassBlock(cssText, '#subtitleRoot .word.word-known:hover');
|
const coloredWordHoverBlock = extractClassBlock(cssText, '#subtitleRoot .word.word-known:hover');
|
||||||
assert.match(
|
assert.match(
|
||||||
coloredWordHoverBlock,
|
coloredWordHoverBlock,
|
||||||
/background:\s*var\(--subtitle-hover-token-background-color,\s*rgba\(54,\s*58,\s*79,\s*0\.84\)\);/,
|
/background:\s*var\(--subtitle-hover-token-background-color,\s*transparent\);/,
|
||||||
);
|
);
|
||||||
assert.match(coloredWordHoverBlock, /border-radius:\s*3px;/);
|
assert.match(coloredWordHoverBlock, /border-radius:\s*3px;/);
|
||||||
assert.match(coloredWordHoverBlock, /filter:\s*brightness\(1\.18\) saturate\(1\.08\);/);
|
assert.match(coloredWordHoverBlock, /filter:\s*brightness\(1\.18\) saturate\(1\.08\);/);
|
||||||
@@ -1246,7 +1243,7 @@ test('subtitle annotation CSS underlines JLPT tokens without changing token colo
|
|||||||
const selectionBlock = extractClassBlock(cssText, '#subtitleRoot::selection');
|
const selectionBlock = extractClassBlock(cssText, '#subtitleRoot::selection');
|
||||||
assert.match(
|
assert.match(
|
||||||
selectionBlock,
|
selectionBlock,
|
||||||
/background:\s*var\(--subtitle-hover-token-background-color,\s*rgba\(54,\s*58,\s*79,\s*0\.84\)\);/,
|
/background:\s*var\(--subtitle-hover-token-background-color,\s*transparent\);/,
|
||||||
);
|
);
|
||||||
assert.match(
|
assert.match(
|
||||||
selectionBlock,
|
selectionBlock,
|
||||||
@@ -1260,7 +1257,7 @@ test('subtitle annotation CSS underlines JLPT tokens without changing token colo
|
|||||||
const descendantSelectionBlock = extractClassBlock(cssText, '#subtitleRoot *::selection');
|
const descendantSelectionBlock = extractClassBlock(cssText, '#subtitleRoot *::selection');
|
||||||
assert.match(
|
assert.match(
|
||||||
descendantSelectionBlock,
|
descendantSelectionBlock,
|
||||||
/background:\s*var\(--subtitle-hover-token-background-color,\s*rgba\(54,\s*58,\s*79,\s*0\.84\)\)\s*!important;/,
|
/background:\s*var\(--subtitle-hover-token-background-color,\s*transparent\)\s*!important;/,
|
||||||
);
|
);
|
||||||
assert.match(
|
assert.match(
|
||||||
descendantSelectionBlock,
|
descendantSelectionBlock,
|
||||||
|
|||||||
@@ -80,12 +80,10 @@ export function sanitizeSubtitleHoverTokenColor(value: unknown): string {
|
|||||||
|
|
||||||
function sanitizeSubtitleHoverTokenBackgroundColor(value: unknown): string {
|
function sanitizeSubtitleHoverTokenBackgroundColor(value: unknown): string {
|
||||||
if (typeof value !== 'string') {
|
if (typeof value !== 'string') {
|
||||||
return 'rgba(54, 58, 79, 0.84)';
|
return 'transparent';
|
||||||
}
|
}
|
||||||
const trimmed = value.trim();
|
const trimmed = value.trim();
|
||||||
return trimmed.length > 0 && SAFE_CSS_COLOR_PATTERN.test(trimmed)
|
return trimmed.length > 0 && SAFE_CSS_COLOR_PATTERN.test(trimmed) ? trimmed : 'transparent';
|
||||||
? trimmed
|
|
||||||
: 'rgba(54, 58, 79, 0.84)';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_FREQUENCY_RENDER_SETTINGS: FrequencyRenderSettings = {
|
const DEFAULT_FREQUENCY_RENDER_SETTINGS: FrequencyRenderSettings = {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ test('serializeSubtitleCssDeclarations builds primary CSS from all managed appea
|
|||||||
'subtitleStyle.fontColor': '#cad3f5',
|
'subtitleStyle.fontColor': '#cad3f5',
|
||||||
'subtitleStyle.backgroundColor': 'transparent',
|
'subtitleStyle.backgroundColor': 'transparent',
|
||||||
'subtitleStyle.hoverTokenColor': '#f4dbd6',
|
'subtitleStyle.hoverTokenColor': '#f4dbd6',
|
||||||
'subtitleStyle.hoverTokenBackgroundColor': 'rgba(54, 58, 79, 0.84)',
|
'subtitleStyle.hoverTokenBackgroundColor': 'transparent',
|
||||||
'subtitleStyle.paintOrder': 'stroke fill',
|
'subtitleStyle.paintOrder': 'stroke fill',
|
||||||
'subtitleStyle.WebkitTextStroke': '1.5px #000',
|
'subtitleStyle.WebkitTextStroke': '1.5px #000',
|
||||||
'subtitleStyle.textShadow': '0 2px 6px rgba(0,0,0,0.9)',
|
'subtitleStyle.textShadow': '0 2px 6px rgba(0,0,0,0.9)',
|
||||||
@@ -29,7 +29,7 @@ test('serializeSubtitleCssDeclarations builds primary CSS from all managed appea
|
|||||||
assert.match(css, /color: #cad3f5;/);
|
assert.match(css, /color: #cad3f5;/);
|
||||||
assert.match(css, /background-color: transparent;/);
|
assert.match(css, /background-color: transparent;/);
|
||||||
assert.match(css, /--subtitle-hover-token-color: #f4dbd6;/);
|
assert.match(css, /--subtitle-hover-token-color: #f4dbd6;/);
|
||||||
assert.match(css, /--subtitle-hover-token-background-color: rgba\(54, 58, 79, 0.84\);/);
|
assert.match(css, /--subtitle-hover-token-background-color: transparent;/);
|
||||||
assert.match(css, /paint-order: stroke fill;/);
|
assert.match(css, /paint-order: stroke fill;/);
|
||||||
assert.match(css, /-webkit-text-stroke: 1.5px #000;/);
|
assert.match(css, /-webkit-text-stroke: 1.5px #000;/);
|
||||||
assert.doesNotMatch(css, /--subtitle-known-word-color:/);
|
assert.doesNotMatch(css, /--subtitle-known-word-color:/);
|
||||||
|
|||||||
Reference in New Issue
Block a user