Refine site rule toggle and override UI

This commit is contained in:
2026-04-07 14:31:41 -04:00
parent 0cb13905ff
commit 6efe92a036
5 changed files with 363 additions and 190 deletions
+119 -16
View File
@@ -7,6 +7,17 @@
--text: #17191c;
--muted: #626b76;
--accent: #111827;
--switch-track-off: #c1cad6;
--switch-track-off-border: #aeb8c5;
--switch-track-on: #111827;
--switch-track-on-border: #111827;
--switch-thumb-off: #ffffff;
--switch-thumb-on: #ffffff;
--toggle-open-fg: #111827;
--toggle-open-bg: #eef2f6;
--toggle-open-border: #c5ccd5;
--toggle-open-hover-bg: #e4eaf1;
--toggle-open-hover-border: #b5c0cc;
--danger: #b42318;
}
@@ -210,6 +221,7 @@ button:active {
}
button:focus-visible,
input[type="checkbox"]:focus-visible,
input[type="text"]:focus,
select:focus,
textarea:focus {
@@ -247,10 +259,49 @@ textarea:focus {
}
input[type="checkbox"] {
width: 16px;
height: 16px;
margin: 2px 0 0;
accent-color: var(--accent);
appearance: none;
-webkit-appearance: none;
position: relative;
width: 46px;
min-width: 46px;
height: 28px;
margin: 0;
border: 1px solid var(--switch-track-off-border);
border-radius: 999px;
background: var(--switch-track-off);
cursor: pointer;
transition: background-color 120ms ease, border-color 120ms ease,
box-shadow 120ms ease;
flex-shrink: 0;
}
input[type="checkbox"]::before {
content: "";
position: absolute;
top: 3px;
left: 3px;
width: 20px;
height: 20px;
border-radius: 50%;
background: var(--switch-thumb-off);
box-shadow: 0 1px 2px rgba(17, 24, 39, 0.18),
inset 0 0 0 1px rgba(17, 24, 39, 0.08);
transition: transform 120ms ease, background-color 120ms ease;
}
input[type="checkbox"]:checked {
background: var(--switch-track-on);
border-color: var(--switch-track-on-border);
}
input[type="checkbox"]:checked::before {
transform: translateX(18px);
background: var(--switch-thumb-on);
}
input[type="checkbox"]:disabled {
cursor: default;
opacity: 0.7;
}
label {
@@ -322,6 +373,39 @@ label em {
.toggle-site-rule {
font-weight: 400;
color: var(--muted);
}
.toggle-site-rule:hover {
color: var(--toggle-open-fg);
background: var(--toggle-open-hover-bg);
border-color: var(--toggle-open-hover-border);
}
.toggle-site-rule .site-rule-toggle-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 18px;
height: 18px;
pointer-events: none;
}
.toggle-site-rule .site-rule-toggle-icon svg {
width: 18px;
height: 18px;
}
.site-rule:not(.collapsed) .toggle-site-rule {
color: var(--toggle-open-fg);
background: var(--toggle-open-bg);
border-color: var(--toggle-open-border);
}
.site-rule:not(.collapsed) .toggle-site-rule:hover {
color: var(--toggle-open-fg);
background: var(--toggle-open-hover-bg);
border-color: var(--toggle-open-hover-border);
}
.row {
@@ -339,7 +423,7 @@ label em {
}
.row.row-checkbox {
grid-template-columns: minmax(0, 1fr) 24px;
grid-template-columns: minmax(0, 1fr) auto;
}
.row.row-checkbox input[type="checkbox"] {
@@ -403,9 +487,9 @@ label em {
.site-override-lead {
display: grid;
grid-template-columns: minmax(0, 1fr) 24px;
grid-template-columns: minmax(0, 1fr) auto;
gap: 16px;
align-items: flex-start;
align-items: center;
font-weight: 600;
margin-bottom: 8px;
cursor: pointer;
@@ -414,7 +498,6 @@ label em {
.site-override-lead input[type="checkbox"] {
justify-self: end;
margin-top: 3px;
}
.site-override-lead span {
@@ -427,10 +510,19 @@ label em {
.site-rule-override-section .site-autohide-container,
.site-rule-override-section .site-playback-container,
.site-rule-override-section .site-opacity-container,
.site-rule-override-section .site-subtitleNudge-container {
.site-rule-override-section .site-subtitleNudge-container,
.site-controlbar-container,
.site-popup-controlbar-container,
.site-shortcuts-container {
padding-left: 4px;
}
.site-override-disabled {
opacity: 0.48;
pointer-events: none;
user-select: none;
}
.cb-editor {
display: flex;
flex-direction: column;
@@ -803,7 +895,7 @@ button.lucide-result-tile.lucide-picked {
}
.site-rule-option-checkbox {
grid-template-columns: minmax(0, 1fr) 24px;
grid-template-columns: minmax(0, 1fr) auto;
}
.site-rule-option-checkbox > input[type="checkbox"] {
@@ -833,7 +925,7 @@ button.lucide-result-tile.lucide-picked {
.site-rule-split-label {
display: grid;
grid-template-columns: minmax(0, 1fr) 24px;
grid-template-columns: minmax(0, 1fr) auto;
gap: 16px;
align-items: flex-start;
width: 100%;
@@ -845,7 +937,7 @@ button.lucide-result-tile.lucide-picked {
.site-rule-split-label input[type="checkbox"] {
justify-self: end;
margin-top: 3px;
margin-top: 0;
}
.site-rule-option-checkbox > .site-rule-split-label {
@@ -889,8 +981,8 @@ button.lucide-result-tile.lucide-picked {
.force-label {
display: flex;
align-items: flex-start;
gap: 8px;
align-items: center;
gap: 10px;
width: auto;
margin: 0;
color: var(--muted);
@@ -898,7 +990,7 @@ button.lucide-result-tile.lucide-picked {
}
.force-label input {
margin-top: 2px;
margin-top: 0;
}
.action-row {
@@ -956,7 +1048,7 @@ button.lucide-result-tile.lucide-picked {
}
.site-override-lead {
grid-template-columns: minmax(0, 1fr) 24px;
grid-template-columns: minmax(0, 1fr) auto;
}
.action-row button,
@@ -1005,6 +1097,17 @@ button.lucide-result-tile.lucide-picked {
--text: #f2f4f6;
--muted: #a0a8b2;
--accent: #f2f4f6;
--switch-track-off: #374151;
--switch-track-off-border: #4b5563;
--switch-track-on: #aab7c6;
--switch-track-on-border: #aab7c6;
--switch-thumb-off: #f8fafc;
--switch-thumb-on: #111315;
--toggle-open-fg: #f2f4f6;
--toggle-open-bg: #2b3138;
--toggle-open-border: #4b5563;
--toggle-open-hover-bg: #374151;
--toggle-open-hover-border: #64748b;
--danger: #ff8a80;
}
+18 -10
View File
@@ -483,7 +483,15 @@
<template id="siteRuleTemplate">
<div class="site-rule">
<div class="site-rule-header">
<button type="button" class="toggle-site-rule" title="Expand/Collapse">&plus;</button>
<button
type="button"
class="toggle-site-rule"
title="Expand site rule"
aria-label="Expand site rule"
aria-expanded="false"
>
<span class="site-rule-toggle-icon" aria-hidden="true">&hellip;</span>
</button>
<input
type="text"
class="site-pattern"
@@ -504,7 +512,7 @@
<span>Override placement for this site</span>
<input type="checkbox" class="override-placement" />
</label>
<div class="site-placement-container" style="display: none">
<div class="site-placement-container">
<div class="site-rule-option site-rule-option-field">
<label>Default controller location:</label>
<select class="site-controllerLocation">
@@ -542,7 +550,7 @@
<span>Override hide-by-default for this site</span>
<input type="checkbox" class="override-visibility" />
</label>
<div class="site-visibility-container" style="display: none">
<div class="site-visibility-container">
<div class="site-rule-option site-rule-option-checkbox">
<label>Hide controller by default:</label>
<input type="checkbox" class="site-startHidden" />
@@ -554,7 +562,7 @@
<span>Override auto-hide for this site</span>
<input type="checkbox" class="override-autohide" />
</label>
<div class="site-autohide-container" style="display: none">
<div class="site-autohide-container">
<div class="site-rule-option site-rule-option-checkbox">
<label class="site-rule-split-label">
<span>Hide with controls (idle-based)</span>
@@ -572,7 +580,7 @@
<span>Override playback for this site</span>
<input type="checkbox" class="override-playback" />
</label>
<div class="site-playback-container" style="display: none">
<div class="site-playback-container">
<div class="site-rule-option site-rule-option-checkbox">
<label>Remember playback speed:</label>
<input type="checkbox" class="site-rememberSpeed" />
@@ -592,7 +600,7 @@
<span>Override opacity for this site</span>
<input type="checkbox" class="override-opacity" />
</label>
<div class="site-opacity-container" style="display: none">
<div class="site-opacity-container">
<div class="site-rule-option site-rule-option-field">
<label>Controller opacity:</label>
<input type="text" class="site-controllerOpacity" />
@@ -604,7 +612,7 @@
<span>Override subtitle nudge for this site</span>
<input type="checkbox" class="override-subtitleNudge" />
</label>
<div class="site-subtitleNudge-container" style="display: none">
<div class="site-subtitleNudge-container">
<div class="site-rule-option site-rule-option-checkbox">
<label>Enable subtitle nudge:</label>
<input type="checkbox" class="site-enableSubtitleNudge" />
@@ -620,7 +628,7 @@
<span>Override in-player control bar for this site</span>
<input type="checkbox" class="override-controlbar" />
</label>
<div class="site-controlbar-container" style="display: none">
<div class="site-controlbar-container">
<div class="cb-editor">
<div class="cb-zone">
<div class="cb-zone-label">Active</div>
@@ -638,7 +646,7 @@
<span>Override extension popup for this site</span>
<input type="checkbox" class="override-popup-controlbar" />
</label>
<div class="site-popup-controlbar-container" style="display: none">
<div class="site-popup-controlbar-container">
<div class="site-rule-option site-rule-option-checkbox">
<label>Show popup control bar</label>
<input type="checkbox" class="site-showPopupControlBar" />
@@ -660,7 +668,7 @@
<span>Override shortcuts for this site</span>
<input type="checkbox" class="override-shortcuts" />
</label>
<div class="site-shortcuts-container" style="display: none"></div>
<div class="site-shortcuts-container"></div>
</div>
</div>
</div>
+172 -164
View File
@@ -312,6 +312,71 @@ function parseFiniteNumberOrFallback(value, fallback) {
return Number.isFinite(numericValue) ? numericValue : fallback;
}
function updateSiteRuleToggleIcon(toggleButton, action) {
if (!toggleButton) return;
var iconEl = toggleButton.querySelector(".site-rule-toggle-icon");
if (!iconEl) return;
if (typeof vscIconSvgString === "function" && typeof vscSetSvgContent === "function") {
var svgHtml = vscIconSvgString(action, 16);
if (svgHtml && vscSetSvgContent(iconEl, svgHtml)) {
return;
}
}
iconEl.textContent = action === "chevronUp" ? "\u2212" : "\u2026";
}
function setSiteRuleExpandedState(ruleEl, expanded) {
if (!ruleEl) return;
var ruleBody = ruleEl.querySelector(".site-rule-body");
var toggleButton = ruleEl.querySelector(".toggle-site-rule");
if (ruleBody) {
ruleBody.style.display = expanded ? "block" : "none";
}
ruleEl.classList.toggle("collapsed", !expanded);
if (!toggleButton) return;
var label = expanded ? "Collapse site rule" : "Expand site rule";
toggleButton.title = label;
toggleButton.setAttribute("aria-label", label);
toggleButton.setAttribute("aria-expanded", expanded ? "true" : "false");
updateSiteRuleToggleIcon(toggleButton, expanded ? "chevronUp" : "moreHorizontal");
}
function setSiteOverrideContainerState(container, enabled) {
if (!container) return;
container.classList.toggle("site-override-disabled", !enabled);
container.setAttribute("aria-disabled", enabled ? "false" : "true");
Array.prototype.forEach.call(
container.querySelectorAll("input, select, textarea, button"),
function (control) {
control.disabled = !enabled;
}
);
Array.prototype.forEach.call(
container.querySelectorAll(".cb-block"),
function (block) {
block.draggable = enabled;
}
);
}
function applySiteRuleOverrideState(ruleEl, checkboxClass, containerClass) {
if (!ruleEl) return;
var checkbox = ruleEl.querySelector("." + checkboxClass);
var container = ruleEl.querySelector("." + containerClass);
if (!container) return;
container.style.display = "block";
setSiteOverrideContainerState(container, checkbox ? checkbox.checked : false);
}
function syncSiteRuleField(ruleEl, rule, key, isCheckbox) {
var input = ruleEl.querySelector(".site-" + key);
if (!input) return;
@@ -894,9 +959,7 @@ function createSiteRule(rule) {
ruleEl.querySelector(".site-pattern").value = pattern;
// Make the rule body collapsed by default
var ruleBody = ruleEl.querySelector(".site-rule-body");
ruleBody.style.display = "none";
ruleEl.classList.add("collapsed");
setSiteRuleExpandedState(ruleEl, false);
var enabledCheckbox = ruleEl.querySelector(".site-enabled");
var contentEl = ruleEl.querySelector(".site-rule-content");
@@ -931,114 +994,99 @@ function createSiteRule(rule) {
];
var hasPlacementOverride =
rule && placementKeys.some(function (k) { return rule[k] !== undefined; });
if (hasPlacementOverride) {
ruleEl.querySelector(".override-placement").checked = true;
ruleEl.querySelector(".site-placement-container").style.display = "block";
}
ruleEl.querySelector(".override-placement").checked = Boolean(hasPlacementOverride);
syncSiteRuleField(ruleEl, rule, "controllerLocation", false);
syncSiteRuleField(ruleEl, rule, "controllerMarginTop", false);
syncSiteRuleField(ruleEl, rule, "controllerMarginBottom", false);
applySiteRuleOverrideState(ruleEl, "override-placement", "site-placement-container");
if (rule && rule.startHidden !== undefined) {
ruleEl.querySelector(".override-visibility").checked = true;
ruleEl.querySelector(".site-visibility-container").style.display = "block";
}
ruleEl.querySelector(".override-visibility").checked = Boolean(
rule && rule.startHidden !== undefined
);
syncSiteRuleField(ruleEl, rule, "startHidden", true);
applySiteRuleOverrideState(ruleEl, "override-visibility", "site-visibility-container");
if (
var hasAutohideOverride = Boolean(
rule &&
(rule.hideWithControls !== undefined ||
rule.hideWithControlsTimer !== undefined)
) {
ruleEl.querySelector(".override-autohide").checked = true;
ruleEl.querySelector(".site-autohide-container").style.display = "block";
}
);
ruleEl.querySelector(".override-autohide").checked = hasAutohideOverride;
syncSiteRuleField(ruleEl, rule, "hideWithControls", true);
syncSiteRuleField(ruleEl, rule, "hideWithControlsTimer", false);
applySiteRuleOverrideState(ruleEl, "override-autohide", "site-autohide-container");
if (
var hasPlaybackOverride = Boolean(
rule &&
(rule.rememberSpeed !== undefined ||
rule.forceLastSavedSpeed !== undefined ||
rule.audioBoolean !== undefined)
) {
ruleEl.querySelector(".override-playback").checked = true;
ruleEl.querySelector(".site-playback-container").style.display = "block";
}
);
ruleEl.querySelector(".override-playback").checked = hasPlaybackOverride;
syncSiteRuleField(ruleEl, rule, "rememberSpeed", true);
syncSiteRuleField(ruleEl, rule, "forceLastSavedSpeed", true);
syncSiteRuleField(ruleEl, rule, "audioBoolean", true);
applySiteRuleOverrideState(ruleEl, "override-playback", "site-playback-container");
if (rule && rule.controllerOpacity !== undefined) {
ruleEl.querySelector(".override-opacity").checked = true;
ruleEl.querySelector(".site-opacity-container").style.display = "block";
}
ruleEl.querySelector(".override-opacity").checked = Boolean(
rule && rule.controllerOpacity !== undefined
);
syncSiteRuleField(ruleEl, rule, "controllerOpacity", false);
applySiteRuleOverrideState(ruleEl, "override-opacity", "site-opacity-container");
if (
var hasSubtitleNudgeOverride = Boolean(
rule &&
(rule.enableSubtitleNudge !== undefined ||
rule.subtitleNudgeInterval !== undefined)
) {
ruleEl.querySelector(".override-subtitleNudge").checked = true;
ruleEl.querySelector(".site-subtitleNudge-container").style.display =
"block";
}
);
ruleEl.querySelector(".override-subtitleNudge").checked = hasSubtitleNudgeOverride;
syncSiteRuleField(ruleEl, rule, "enableSubtitleNudge", true);
syncSiteRuleField(ruleEl, rule, "subtitleNudgeInterval", false);
applySiteRuleOverrideState(
ruleEl,
"override-subtitleNudge",
"site-subtitleNudge-container"
);
if (rule && Array.isArray(rule.controllerButtons)) {
ruleEl.querySelector(".override-controlbar").checked = true;
var cbContainer = ruleEl.querySelector(".site-controlbar-container");
cbContainer.style.display = "block";
populateControlBarZones(
ruleEl.querySelector(".site-cb-active"),
ruleEl.querySelector(".site-cb-available"),
rule.controllerButtons
);
}
var hasControlbarOverride = Boolean(rule && Array.isArray(rule.controllerButtons));
ruleEl.querySelector(".override-controlbar").checked = hasControlbarOverride;
populateControlBarZones(
ruleEl.querySelector(".site-cb-active"),
ruleEl.querySelector(".site-cb-available"),
hasControlbarOverride ? rule.controllerButtons : getControlBarOrder()
);
applySiteRuleOverrideState(ruleEl, "override-controlbar", "site-controlbar-container");
if (
var hasPopupControlbarOverride = Boolean(
rule &&
(rule.showPopupControlBar !== undefined ||
Array.isArray(rule.popupControllerButtons))
) {
ruleEl.querySelector(".override-popup-controlbar").checked = true;
var popupCbContainer = ruleEl.querySelector(".site-popup-controlbar-container");
popupCbContainer.style.display = "block";
var sitePopupActive = ruleEl.querySelector(".site-popup-cb-active");
var sitePopupAvailable = ruleEl.querySelector(".site-popup-cb-available");
if (Array.isArray(rule.popupControllerButtons)) {
populateControlBarZones(
sitePopupActive,
sitePopupAvailable,
sanitizePopupButtonOrder(rule.popupControllerButtons),
function (id) {
return !popupExcludedButtonIds.has(id);
}
);
} else if (
sitePopupActive &&
sitePopupAvailable &&
sitePopupActive.children.length === 0
) {
populateControlBarZones(
sitePopupActive,
sitePopupAvailable,
getPopupControlBarOrder(),
function (id) {
return !popupExcludedButtonIds.has(id);
}
);
);
ruleEl.querySelector(".override-popup-controlbar").checked =
hasPopupControlbarOverride;
populateControlBarZones(
ruleEl.querySelector(".site-popup-cb-active"),
ruleEl.querySelector(".site-popup-cb-available"),
hasPopupControlbarOverride && Array.isArray(rule.popupControllerButtons)
? sanitizePopupButtonOrder(rule.popupControllerButtons)
: getPopupControlBarOrder(),
function (id) {
return !popupExcludedButtonIds.has(id);
}
}
);
syncSiteRuleField(ruleEl, rule, "showPopupControlBar", true);
applySiteRuleOverrideState(
ruleEl,
"override-popup-controlbar",
"site-popup-controlbar-container"
);
if (rule && Array.isArray(rule.shortcuts) && rule.shortcuts.length > 0) {
ruleEl.querySelector(".override-shortcuts").checked = true;
var container = ruleEl.querySelector(".site-shortcuts-container");
container.style.display = "block";
var hasShortcutOverride = Boolean(
rule && Array.isArray(rule.shortcuts) && rule.shortcuts.length > 0
);
ruleEl.querySelector(".override-shortcuts").checked = hasShortcutOverride;
var container = ruleEl.querySelector(".site-shortcuts-container");
if (hasShortcutOverride) {
rule.shortcuts.forEach((shortcut) => {
addSiteRuleShortcut(
container,
@@ -1048,13 +1096,41 @@ function createSiteRule(rule) {
shortcut.force
);
});
} else {
populateDefaultSiteShortcuts(container);
}
applySiteRuleOverrideState(ruleEl, "override-shortcuts", "site-shortcuts-container");
document.getElementById("siteRulesContainer").appendChild(ruleEl);
}
function populateDefaultSiteShortcuts(container) {
tcDefaults.keyBindings.forEach((binding) => {
var bindings = [];
document.querySelectorAll("#customs .shortcut-row").forEach((row) => {
var action = row.dataset.action;
if (!action) return;
var keyInput = row.querySelector(".customKey");
var binding = normalizeStoredBinding(keyInput && keyInput.vscBinding);
if (!binding) return;
var valueInput = row.querySelector(".customValue");
bindings.push({
action: action,
code: binding.code,
disabled: binding.disabled === true,
value: customActionsNoValues.includes(action)
? 0
: Number(valueInput && valueInput.value),
force: false
});
});
if (bindings.length === 0) {
bindings = tcDefaults.keyBindings.slice();
}
bindings.forEach((binding) => {
addSiteRuleShortcut(container, binding.action, binding, binding.value, false);
});
}
@@ -1626,29 +1702,26 @@ document.addEventListener("DOMContentLoaded", function () {
eventCaller(event, "customKey", recordKeyPress)
);
document.addEventListener("click", (event) => {
if (event.target.classList.contains("removeParent")) {
event.target.parentNode.remove();
var target = event.target;
var targetEl = target && target.closest ? target : target.parentElement;
if (!targetEl) return;
var removeParentButton = targetEl.closest(".removeParent");
if (removeParentButton) {
removeParentButton.parentNode.remove();
refreshAddShortcutSelector();
return;
}
if (event.target.classList.contains("remove-site-rule")) {
event.target.closest(".site-rule").remove();
var removeSiteRuleButton = targetEl.closest(".remove-site-rule");
if (removeSiteRuleButton) {
removeSiteRuleButton.closest(".site-rule").remove();
return;
}
if (event.target.classList.contains("toggle-site-rule")) {
var ruleEl = event.target.closest(".site-rule");
var ruleBody = ruleEl.querySelector(".site-rule-body");
var toggleButton = targetEl.closest(".toggle-site-rule");
if (toggleButton) {
var ruleEl = toggleButton.closest(".site-rule");
var isCollapsed = ruleEl.classList.contains("collapsed");
if (isCollapsed) {
ruleBody.style.display = "block";
ruleEl.classList.remove("collapsed");
event.target.textContent = "\u2212";
} else {
ruleBody.style.display = "none";
ruleEl.classList.add("collapsed");
event.target.textContent = "\u002b";
}
setSiteRuleExpandedState(ruleEl, isCollapsed);
return;
}
});
@@ -1670,7 +1743,10 @@ document.addEventListener("DOMContentLoaded", function () {
"override-autohide": "site-autohide-container",
"override-playback": "site-playback-container",
"override-opacity": "site-opacity-container",
"override-subtitleNudge": "site-subtitleNudge-container"
"override-subtitleNudge": "site-subtitleNudge-container",
"override-controlbar": "site-controlbar-container",
"override-popup-controlbar": "site-popup-controlbar-container",
"override-shortcuts": "site-shortcuts-container"
};
for (var ocb in siteOverrideContainers) {
if (event.target.classList.contains(ocb)) {
@@ -1679,78 +1755,10 @@ document.addEventListener("DOMContentLoaded", function () {
"." + siteOverrideContainers[ocb]
);
if (targetBox) {
targetBox.style.display = event.target.checked ? "block" : "none";
setSiteOverrideContainerState(targetBox, event.target.checked);
}
return;
}
}
// Handle site rule override checkboxes
if (event.target.classList.contains("override-shortcuts")) {
var container = event.target
.closest(".site-rule-shortcuts")
.querySelector(".site-shortcuts-container");
if (event.target.checked) {
container.style.display = "block";
if (container.children.length === 0) {
populateDefaultSiteShortcuts(container);
}
} else {
container.style.display = "none";
}
}
if (event.target.classList.contains("override-controlbar")) {
var cbContainer = event.target
.closest(".site-rule-controlbar")
.querySelector(".site-controlbar-container");
if (event.target.checked) {
cbContainer.style.display = "block";
var activeZone = cbContainer.querySelector(".site-cb-active");
var availableZone = cbContainer.querySelector(".site-cb-available");
if (
activeZone &&
availableZone &&
activeZone.children.length === 0 &&
availableZone.children.length === 0
) {
populateControlBarZones(
activeZone,
availableZone,
getControlBarOrder()
);
}
} else {
cbContainer.style.display = "none";
}
}
if (event.target.classList.contains("override-popup-controlbar")) {
var popupCbContainer = event.target
.closest(".site-rule-controlbar")
.querySelector(".site-popup-controlbar-container");
if (event.target.checked) {
popupCbContainer.style.display = "block";
var popupActiveZone = popupCbContainer.querySelector(".site-popup-cb-active");
var popupAvailableZone = popupCbContainer.querySelector(".site-popup-cb-available");
if (
popupActiveZone &&
popupAvailableZone &&
popupActiveZone.children.length === 0 &&
popupAvailableZone.children.length === 0
) {
populateControlBarZones(
popupActiveZone,
popupAvailableZone,
getPopupControlBarOrder(),
function (id) {
return !popupExcludedButtonIds.has(id);
}
);
}
} else {
popupCbContainer.style.display = "none";
}
}
});
});
+51
View File
@@ -73,6 +73,57 @@ describe("options page", () => {
expect(chrome.storage.sync.set).not.toHaveBeenCalled();
});
it("shows a more-menu trigger for collapsed site rules and a collapse trigger when open", async () => {
await setupOptions({ sync: { siteRules: [] } });
globalThis.createSiteRule({ pattern: "youtube.com" });
const rule = document.getElementById("siteRulesContainer").lastElementChild;
const toggle = rule.querySelector(".toggle-site-rule");
const body = rule.querySelector(".site-rule-body");
expect(rule.classList.contains("collapsed")).toBe(true);
expect(body.style.display).toBe("none");
expect(toggle.getAttribute("aria-expanded")).toBe("false");
expect(toggle.getAttribute("aria-label")).toBe("Expand site rule");
expect(toggle.querySelector("svg")).not.toBeNull();
globalThis.setSiteRuleExpandedState(rule, true);
expect(rule.classList.contains("collapsed")).toBe(false);
expect(body.style.display).toBe("block");
expect(toggle.getAttribute("aria-expanded")).toBe("true");
expect(toggle.getAttribute("aria-label")).toBe("Collapse site rule");
});
it("keeps site override settings visible but disabled until enabled", async () => {
await setupOptions({ sync: { siteRules: [] } });
globalThis.createSiteRule({ pattern: "youtube.com" });
const rule = document.getElementById("siteRulesContainer").lastElementChild;
const playbackOverride = rule.querySelector(".override-playback");
const playbackContainer = rule.querySelector(".site-playback-container");
const rememberSpeed = rule.querySelector(".site-rememberSpeed");
expect(playbackContainer.classList.contains("site-override-disabled")).toBe(
true
);
expect(rememberSpeed.disabled).toBe(true);
playbackOverride.checked = true;
playbackOverride.dispatchEvent(
new Event("change", {
bubbles: true
})
);
expect(playbackContainer.classList.contains("site-override-disabled")).toBe(
false
);
expect(rememberSpeed.disabled).toBe(false);
});
it("saves normalized settings and sanitized popup/site-rule controls", async () => {
const chrome = await setupOptions();
+3
View File
@@ -16,6 +16,9 @@ var vscUiIconPaths = {
slower: '<line x1="5" y1="12" x2="19" y2="12"/>',
faster:
'<line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>',
moreHorizontal:
'<circle cx="6" cy="12" r="1.5"/><circle cx="12" cy="12" r="1.5"/><circle cx="18" cy="12" r="1.5"/>',
chevronUp: '<path d="m18 15-6-6-6 6"/>',
display:
'<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>',
fast: '<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/>',