Compare commits

..

6 Commits

Author SHA1 Message Date
joshpatra b3707c0803 Release v5.1.4 2026-04-02 18:07:09 -04:00
joshpatra fb25c56230 Merge beta 2026-04-01 15:33:11 -04:00
joshpatra 4efc3e0acc Merge beta 2026-04-01 11:29:16 -04:00
joshpatra 7c0a188cd3 Merge beta 2026-04-01 11:19:08 -04:00
joshpatra d7ce1fd000 Merge beta 2026-03-31 15:04:56 -04:00
joshpatra 313832015b Merge beta 2026-03-31 15:01:18 -04:00
6 changed files with 124 additions and 19 deletions
+11 -1
View File
@@ -121,7 +121,7 @@ var controllerButtonDefs = {
faster: { label: "", className: "" },
advance: { label: "", className: "rw" },
display: { label: "", className: "hideButton" },
reset: { label: "", className: "" },
reset: { label: "\u21BB", className: "" },
fast: { label: "", className: "" },
settings: { label: "", className: "" },
pause: { label: "", className: "" },
@@ -778,6 +778,15 @@ function setSubtitleNudgeEnabledForVideo(video, enabled) {
function subtitleNudgeIconMarkup(isEnabled) {
var action = isEnabled ? "subtitleNudgeOn" : "subtitleNudgeOff";
var custom =
tc.settings.customButtonIcons &&
tc.settings.customButtonIcons[action] &&
tc.settings.customButtonIcons[action].svg;
if (custom) {
return (
'<span class="vsc-btn-icon" aria-hidden="true">' + custom + "</span>"
);
}
if (typeof vscIconSvgString !== "function") {
return isEnabled ? "✓" : "×";
}
@@ -1367,6 +1376,7 @@ chrome.storage.sync.get(tc.settings, function (storage) {
btn.textContent = (cdf2 && cdf2.label) || "?";
}
});
updateSubtitleNudgeIndicator(video);
});
}
});
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "Speeder",
"short_name": "Speeder",
"version": "5.1.2",
"version": "5.1.4",
"manifest_version": 2,
"description": "Speed up, slow down, advance and rewind HTML5 audio/video with shortcuts (New and improved version of \"Video Speed Controller\")",
"homepage_url": "https://github.com/SoPat712/speeder",
+45
View File
@@ -545,6 +545,51 @@ label em {
flex-shrink: 0;
}
.cb-icon.cb-icon-nudge-pair {
width: auto;
min-width: 0;
padding: 0 4px;
gap: 4px;
background: transparent;
border: none;
}
.cb-nudge-chip {
display: inline-flex;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
border-radius: 6px;
flex-shrink: 0;
color: #fff;
}
.cb-nudge-chip[data-nudge-state="on"] {
background: #4b9135;
border: 1px solid #6ec754;
}
.cb-nudge-chip[data-nudge-state="off"] {
background: #943e3e;
border: 1px solid #c06060;
}
.cb-nudge-chip .vsc-btn-icon svg,
.cb-nudge-chip svg {
width: 14px;
height: 14px;
flex-shrink: 0;
}
.cb-nudge-sep {
font-size: 11px;
font-weight: 600;
opacity: 0.45;
color: var(--text);
flex-shrink: 0;
}
.row-lucide-pair select {
justify-self: end;
}
+16 -14
View File
@@ -382,9 +382,11 @@
rel="noopener noreferrer"
>Lucide</a
>
set (fetched from jsDelivr). Chosen SVGs are cached in local
storage and included in settings export.
<strong>Reset speed</strong> stays numeric text only.
set (fetched from jsDelivr). Custom icons are cached in local
storage and included when you export settings. Subtitle nudge
icons use two menu entries (enabled and disabled), not the bar
block id
<code>nudge</code>.
</p>
</div>
<div class="row row-lucide-pair">
@@ -676,6 +678,17 @@
<div id="status" role="status" aria-live="polite"></div>
</section>
<section id="faq" class="settings-card info-card">
<h4>Extension controls not appearing?</h4>
<p>
This extension only works with HTML5 audio and video. If the
controls never appear, you may be looking at Flash content instead.
Right-click the player to check: if the menu mentions Flash, that
is the issue. Most sites will fall back to HTML5 when Flash is not
available, so disabling Flash in the browser can help.
</p>
</section>
<footer class="support-footer settings-card">
<p>
If Speeder has been useful, consider supporting its development via
@@ -694,17 +707,6 @@
>.
</p>
</footer>
<section id="faq" class="settings-card info-card">
<h4>Extension controls not appearing?</h4>
<p>
This extension only works with HTML5 audio and video. If the
controls never appear, you may be looking at Flash content instead.
Right-click the player to check: if the menu mentions Flash, that
is the issue. Most sites will fall back to HTML5 when Flash is not
available, so disabling Flash in the browser can help.
</p>
</section>
</main>
</div>
</body>
+50 -2
View File
@@ -138,7 +138,7 @@ var controllerButtonDefs = {
faster: { icon: "+", name: "Increase speed" },
advance: { icon: "\u00BB", name: "Advance" },
display: { icon: "\u00D7", name: "Close controller" },
reset: { icon: "", name: "Reset speed" },
reset: { icon: "\u21BB", name: "Reset speed" },
fast: { icon: "\u2605", name: "Preferred speed" },
nudge: { icon: "\u2713", name: "Subtitle nudge" },
settings: { icon: "\u2699", name: "Settings" },
@@ -149,6 +149,12 @@ var controllerButtonDefs = {
};
var popupExcludedButtonIds = new Set(["settings"]);
/** Lucide picker only — not control-bar blocks (chip uses subtitleNudgeOn/Off). */
var lucideSubtitleNudgeActionLabels = {
subtitleNudgeOn: "Subtitle nudge — enabled",
subtitleNudgeOff: "Subtitle nudge — disabled"
};
function sanitizePopupButtonOrder(buttonIds) {
if (!Array.isArray(buttonIds)) return [];
var seen = new Set();
@@ -166,6 +172,39 @@ var customButtonIconsLive = {};
function fillControlBarIconElement(icon, buttonId) {
if (!icon || !buttonId) return;
if (buttonId === "nudge") {
icon.innerHTML = "";
icon.className = "cb-icon cb-icon-nudge-pair";
function nudgeChipMarkup(action) {
var c = customButtonIconsLive[action];
if (c && c.svg) return c.svg;
if (typeof vscIconSvgString === "function") {
return vscIconSvgString(action, 14) || "";
}
return "";
}
function appendChip(action, stateKey) {
var sp = document.createElement("span");
sp.className = "cb-nudge-chip";
sp.setAttribute("data-nudge-state", stateKey);
var inner = nudgeChipMarkup(action);
if (inner) {
var wrap = document.createElement("span");
wrap.className = "vsc-btn-icon";
wrap.innerHTML = inner;
sp.appendChild(wrap);
}
icon.appendChild(sp);
}
appendChip("subtitleNudgeOn", "on");
var sep = document.createElement("span");
sep.className = "cb-nudge-sep";
sep.textContent = "/";
icon.appendChild(sep);
appendChip("subtitleNudgeOff", "off");
return;
}
icon.className = "cb-icon";
var custom = customButtonIconsLive[buttonId];
if (custom && custom.svg) {
icon.innerHTML = custom.svg;
@@ -1357,7 +1396,16 @@ function initLucideButtonIconsUI() {
actionSel.dataset.lucideInit = "1";
actionSel.innerHTML = "";
Object.keys(controllerButtonDefs).forEach(function (aid) {
if (aid === "reset") return;
if (aid === "nudge") {
Object.keys(lucideSubtitleNudgeActionLabels).forEach(function (subId) {
var o2 = document.createElement("option");
o2.value = subId;
o2.textContent =
lucideSubtitleNudgeActionLabels[subId] + " (" + subId + ")";
actionSel.appendChild(o2);
});
return;
}
var o = document.createElement("option");
o.value = aid;
o.textContent =
+1 -1
View File
@@ -8,7 +8,7 @@ document.addEventListener("DOMContentLoaded", function () {
faster: { label: "", className: "" },
advance: { label: "", className: "rw" },
display: { label: "", className: "hideButton" },
reset: { label: "", className: "" },
reset: { label: "\u21BB", className: "" },
fast: { label: "", className: "" },
nudge: { label: "", className: "" },
settings: { label: "", className: "" },