mirror of
https://github.com/SoPat712/videospeed.git
synced 2026-04-27 06:32:52 -04:00
v5.0.2-beta.1
This commit is contained in:
@@ -46,7 +46,7 @@ jobs:
|
|||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v2
|
||||||
with:
|
with:
|
||||||
tag_name: ${{ github.ref_name }}
|
tag_name: ${{ github.ref_name }}
|
||||||
name: Beta ${{ github.ref_name }}
|
name: ${{ github.ref_name }}
|
||||||
files: ${{ steps.xpi.outputs.file }}
|
files: ${{ steps.xpi.outputs.file }}
|
||||||
prerelease: true
|
prerelease: true
|
||||||
body: |
|
body: |
|
||||||
@@ -61,7 +61,9 @@ jobs:
|
|||||||
|
|
||||||
# Stable tag (v* without -beta) → Sign & submit to public AMO listing
|
# Stable tag (v* without -beta) → Sign & submit to public AMO listing
|
||||||
- name: Sign & Submit to AMO (stable)
|
- name: Sign & Submit to AMO (stable)
|
||||||
if: startsWith(github.ref, 'refs/tags/') && !contains(github.ref_name, '-beta')
|
if:
|
||||||
|
startsWith(github.ref, 'refs/tags/') && !contains(github.ref_name,
|
||||||
|
'-beta')
|
||||||
run: |
|
run: |
|
||||||
web-ext sign \
|
web-ext sign \
|
||||||
--api-key ${{ secrets.FIREFOX_API_KEY }} \
|
--api-key ${{ secrets.FIREFOX_API_KEY }} \
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/* Runs via chrome.tabs.executeScript(allFrames) in the same isolated world as inject.js */
|
||||||
|
(function () {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
typeof getPrimaryVideoElement !== "function" ||
|
||||||
|
typeof computeResetButtonLabelForVideo !== "function"
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var v = getPrimaryVideoElement();
|
||||||
|
if (!v) return null;
|
||||||
|
return {
|
||||||
|
speed: v.playbackRate,
|
||||||
|
resetLabel: computeResetButtonLabelForVideo(v),
|
||||||
|
preferred: !v.paused
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})();
|
||||||
@@ -3,6 +3,15 @@ var regStrip = /^[\r\t\f\v ]+|[\r\t\f\v ]+$/gm;
|
|||||||
var isUserSeek = false; // Track if seek was user-initiated
|
var isUserSeek = false; // Track if seek was user-initiated
|
||||||
var lastToggleSpeed = {}; // Store last toggle speeds per video
|
var lastToggleSpeed = {}; // Store last toggle speeds per video
|
||||||
|
|
||||||
|
function getPrimaryVideoElement() {
|
||||||
|
if (!tc.mediaElements || tc.mediaElements.length === 0) return null;
|
||||||
|
for (var i = 0; i < tc.mediaElements.length; i++) {
|
||||||
|
var el = tc.mediaElements[i];
|
||||||
|
if (el && !el.paused) return el;
|
||||||
|
}
|
||||||
|
return tc.mediaElements[0];
|
||||||
|
}
|
||||||
|
|
||||||
var tc = {
|
var tc = {
|
||||||
settings: {
|
settings: {
|
||||||
lastSpeed: 1.0,
|
lastSpeed: 1.0,
|
||||||
@@ -112,7 +121,7 @@ var controllerButtonDefs = {
|
|||||||
faster: { label: "+", className: "" },
|
faster: { label: "+", className: "" },
|
||||||
advance: { label: "\u00BB", className: "rw" },
|
advance: { label: "\u00BB", className: "rw" },
|
||||||
display: { label: "\u00D7", className: "hideButton" },
|
display: { label: "\u00D7", className: "hideButton" },
|
||||||
reset: { label: "\u21BA", className: "" },
|
reset: { label: "1.00x", className: "" },
|
||||||
fast: { label: "\u2605", className: "" },
|
fast: { label: "\u2605", className: "" },
|
||||||
settings: { label: "\u2699", className: "" },
|
settings: { label: "\u2699", className: "" },
|
||||||
pause: { label: "\u23EF", className: "" },
|
pause: { label: "\u23EF", className: "" },
|
||||||
@@ -1267,36 +1276,38 @@ chrome.storage.sync.get(tc.settings, function (storage) {
|
|||||||
log("Re-scan command received from popup.", 4);
|
log("Re-scan command received from popup.", 4);
|
||||||
initializeWhenReady(document, true);
|
initializeWhenReady(document, true);
|
||||||
sendResponse({ status: "complete" });
|
sendResponse({ status: "complete" });
|
||||||
} else if (request.action === "get_speed") {
|
return false;
|
||||||
var speed = 1.0;
|
}
|
||||||
if (tc.mediaElements && tc.mediaElements.length > 0) {
|
if (request.action === "get_speed") {
|
||||||
for (var i = 0; i < tc.mediaElements.length; i++) {
|
// Do not sendResponse in frames with no media — only one response is
|
||||||
if (tc.mediaElements[i] && !tc.mediaElements[i].paused) {
|
// accepted tab-wide, and the top frame often wins before an iframe.
|
||||||
speed = tc.mediaElements[i].playbackRate;
|
var videoGs = getPrimaryVideoElement();
|
||||||
break;
|
if (!videoGs) return false;
|
||||||
}
|
sendResponse({
|
||||||
}
|
speed: videoGs.playbackRate,
|
||||||
if (speed === 1.0 && tc.mediaElements[0]) {
|
resetLabel: computeResetButtonLabelForVideo(videoGs)
|
||||||
speed = tc.mediaElements[0].playbackRate;
|
});
|
||||||
}
|
return false;
|
||||||
}
|
}
|
||||||
sendResponse({ speed: speed });
|
if (request.action === "get_page_context") {
|
||||||
} else if (request.action === "get_page_context") {
|
|
||||||
sendResponse({ url: location.href });
|
sendResponse({ url: location.href });
|
||||||
} else if (request.action === "run_action") {
|
return false;
|
||||||
|
}
|
||||||
|
if (request.action === "run_action") {
|
||||||
var value = request.value;
|
var value = request.value;
|
||||||
if (value === undefined || value === null) {
|
if (value === undefined || value === null) {
|
||||||
value = getKeyBindings(request.actionName, "value");
|
value = getKeyBindings(request.actionName, "value");
|
||||||
}
|
}
|
||||||
runAction(request.actionName, value);
|
runAction(request.actionName, value);
|
||||||
var newSpeed = 1.0;
|
var videoAfter = getPrimaryVideoElement();
|
||||||
if (tc.mediaElements && tc.mediaElements.length > 0) {
|
if (!videoAfter) return false;
|
||||||
newSpeed = tc.mediaElements[0].playbackRate;
|
sendResponse({
|
||||||
}
|
speed: videoAfter.playbackRate,
|
||||||
sendResponse({ speed: newSpeed });
|
resetLabel: computeResetButtonLabelForVideo(videoAfter)
|
||||||
|
});
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1343,6 +1354,8 @@ function defineVideoController() {
|
|||||||
this.suppressedRateChangeCount = 0;
|
this.suppressedRateChangeCount = 0;
|
||||||
this.suppressedRateChangeUntil = 0;
|
this.suppressedRateChangeUntil = 0;
|
||||||
this.visibilityResumeHandler = null;
|
this.visibilityResumeHandler = null;
|
||||||
|
this.resetToggleArmed = false;
|
||||||
|
this.resetButtonEl = null;
|
||||||
this.controllerLocation = normalizeControllerLocation(
|
this.controllerLocation = normalizeControllerLocation(
|
||||||
tc.settings.controllerLocation
|
tc.settings.controllerLocation
|
||||||
);
|
);
|
||||||
@@ -1843,6 +1856,10 @@ function defineVideoController() {
|
|||||||
this.speedIndicator = dragHandle;
|
this.speedIndicator = dragHandle;
|
||||||
this.subtitleNudgeIndicator = subtitleNudgeIndicator;
|
this.subtitleNudgeIndicator = subtitleNudgeIndicator;
|
||||||
this.nudgeFlashIndicator = nudgeFlashIndicator;
|
this.nudgeFlashIndicator = nudgeFlashIndicator;
|
||||||
|
this.resetButtonEl =
|
||||||
|
shadow.querySelector('button[data-action="reset"]') || null;
|
||||||
|
this.resetToggleArmed = false;
|
||||||
|
updateResetButtonLabel(this.video);
|
||||||
if (subtitleNudgeIndicator) {
|
if (subtitleNudgeIndicator) {
|
||||||
updateSubtitleNudgeIndicator(this.video);
|
updateSubtitleNudgeIndicator(this.video);
|
||||||
}
|
}
|
||||||
@@ -2091,8 +2108,11 @@ function shouldPreserveDesiredSpeed(video, speed) {
|
|||||||
function setupListener(root) {
|
function setupListener(root) {
|
||||||
root = root || document;
|
root = root || document;
|
||||||
if (root.vscRateListenerAttached) return;
|
if (root.vscRateListenerAttached) return;
|
||||||
function updateSpeedFromEvent(video) {
|
function updateSpeedFromEvent(video, skipResetDisarm) {
|
||||||
if (!video.vsc || !video.vsc.speedIndicator) return;
|
if (!video.vsc || !video.vsc.speedIndicator) return;
|
||||||
|
if (!skipResetDisarm) {
|
||||||
|
video.vsc.resetToggleArmed = false;
|
||||||
|
}
|
||||||
var speed = video.playbackRate; // Preserve full precision (e.g. 0.0625)
|
var speed = video.playbackRate; // Preserve full precision (e.g. 0.0625)
|
||||||
video.vsc.speedIndicator.textContent = speed.toFixed(2);
|
video.vsc.speedIndicator.textContent = speed.toFixed(2);
|
||||||
video.vsc.targetSpeed = speed;
|
video.vsc.targetSpeed = speed;
|
||||||
@@ -2107,6 +2127,7 @@ function setupListener(root) {
|
|||||||
if (speed === 1.0 || video.paused) video.vsc.stopSubtitleNudge();
|
if (speed === 1.0 || video.paused) video.vsc.stopSubtitleNudge();
|
||||||
else video.vsc.startSubtitleNudge();
|
else video.vsc.startSubtitleNudge();
|
||||||
}
|
}
|
||||||
|
updateResetButtonLabel(video);
|
||||||
}
|
}
|
||||||
root.addEventListener(
|
root.addEventListener(
|
||||||
"ratechange",
|
"ratechange",
|
||||||
@@ -2119,7 +2140,7 @@ function setupListener(root) {
|
|||||||
if (tc.settings.forceLastSavedSpeed) {
|
if (tc.settings.forceLastSavedSpeed) {
|
||||||
if (event.detail && event.detail.origin === "videoSpeed") {
|
if (event.detail && event.detail.origin === "videoSpeed") {
|
||||||
video.playbackRate = event.detail.speed;
|
video.playbackRate = event.detail.speed;
|
||||||
updateSpeedFromEvent(video);
|
updateSpeedFromEvent(video, true);
|
||||||
} else {
|
} else {
|
||||||
video.playbackRate = sanitizeSpeed(tc.settings.lastSpeed, 1.0);
|
video.playbackRate = sanitizeSpeed(tc.settings.lastSpeed, 1.0);
|
||||||
}
|
}
|
||||||
@@ -2130,7 +2151,7 @@ function setupListener(root) {
|
|||||||
var pendingRateChange = takePendingRateChange(video, currentSpeed);
|
var pendingRateChange = takePendingRateChange(video, currentSpeed);
|
||||||
|
|
||||||
if (pendingRateChange) {
|
if (pendingRateChange) {
|
||||||
updateSpeedFromEvent(video);
|
updateSpeedFromEvent(video, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2139,8 +2160,10 @@ function setupListener(root) {
|
|||||||
`Ignoring external rate change to ${currentSpeed.toFixed(4)} while preserving ${desiredSpeed.toFixed(4)}`,
|
`Ignoring external rate change to ${currentSpeed.toFixed(4)} while preserving ${desiredSpeed.toFixed(4)}`,
|
||||||
4
|
4
|
||||||
);
|
);
|
||||||
|
video.vsc.resetToggleArmed = false;
|
||||||
video.vsc.speedIndicator.textContent = desiredSpeed.toFixed(2);
|
video.vsc.speedIndicator.textContent = desiredSpeed.toFixed(2);
|
||||||
scheduleSpeedRestore(video, desiredSpeed, "pause/play or seek");
|
scheduleSpeedRestore(video, desiredSpeed, "pause/play or seek");
|
||||||
|
updateResetButtonLabel(video);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2429,7 +2452,47 @@ function initializeNow(doc, forceReinit = false) {
|
|||||||
vscInitializedDocuments.add(doc);
|
vscInitializedDocuments.add(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSpeed(video, speed, isInitialCall = false, isUserKeyPress = false) {
|
function formatSpeedWithX(speed) {
|
||||||
|
var n = Number(speed);
|
||||||
|
if (!isFinite(n)) return "?x";
|
||||||
|
return n.toFixed(2) + "x";
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeResetButtonLabelForVideo(video) {
|
||||||
|
if (!video) return "1.00x";
|
||||||
|
var rate = video.playbackRate;
|
||||||
|
var atOne = Math.abs(rate - 1.0) < 0.01;
|
||||||
|
var armed = video.vsc && video.vsc.resetToggleArmed === true;
|
||||||
|
|
||||||
|
if (atOne) {
|
||||||
|
if (armed) {
|
||||||
|
var videoId = getVideoSourceKey(video);
|
||||||
|
var lastToggle = lastToggleSpeed[videoId];
|
||||||
|
var pref = getKeyBindings("fast") || 1.8;
|
||||||
|
var speedToRestore =
|
||||||
|
lastToggle == null || Math.abs(lastToggle - 1.0) < 0.01
|
||||||
|
? pref
|
||||||
|
: lastToggle;
|
||||||
|
return formatSpeedWithX(speedToRestore);
|
||||||
|
}
|
||||||
|
return "1.00x";
|
||||||
|
}
|
||||||
|
return formatSpeedWithX(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateResetButtonLabel(video) {
|
||||||
|
if (!video || !video.vsc || !video.vsc.resetButtonEl) return;
|
||||||
|
video.vsc.resetButtonEl.textContent =
|
||||||
|
computeResetButtonLabelForVideo(video);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSpeed(
|
||||||
|
video,
|
||||||
|
speed,
|
||||||
|
isInitialCall = false,
|
||||||
|
isUserKeyPress = false,
|
||||||
|
fromResetSpeedToggle = false
|
||||||
|
) {
|
||||||
const numericSpeed = Number(speed);
|
const numericSpeed = Number(speed);
|
||||||
|
|
||||||
if (!isValidSpeed(numericSpeed)) {
|
if (!isValidSpeed(numericSpeed)) {
|
||||||
@@ -2442,6 +2505,10 @@ function setSpeed(video, speed, isInitialCall = false, isUserKeyPress = false) {
|
|||||||
|
|
||||||
if (!video || !video.vsc || !video.vsc.speedIndicator) return;
|
if (!video || !video.vsc || !video.vsc.speedIndicator) return;
|
||||||
|
|
||||||
|
if (isUserKeyPress && !fromResetSpeedToggle) {
|
||||||
|
video.vsc.resetToggleArmed = false;
|
||||||
|
}
|
||||||
|
|
||||||
log(
|
log(
|
||||||
`setSpeed: Target ${numericSpeed.toFixed(2)}. Initial: ${isInitialCall}. UserKeyPress: ${isUserKeyPress}`,
|
`setSpeed: Target ${numericSpeed.toFixed(2)}. Initial: ${isInitialCall}. UserKeyPress: ${isUserKeyPress}`,
|
||||||
4
|
4
|
||||||
@@ -2489,6 +2556,7 @@ function setSpeed(video, speed, isInitialCall = false, isUserKeyPress = false) {
|
|||||||
video.vsc.startSubtitleNudge();
|
video.vsc.startSubtitleNudge();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
updateResetButtonLabel(video);
|
||||||
}
|
}
|
||||||
|
|
||||||
function runAction(action, value, e) {
|
function runAction(action, value, e) {
|
||||||
@@ -2697,11 +2765,12 @@ function resetSpeed(v, target, isFastKey = false) {
|
|||||||
Math.abs(lastToggle - 1.0) < 0.01
|
Math.abs(lastToggle - 1.0) < 0.01
|
||||||
? getKeyBindings("fast") || 1.8
|
? getKeyBindings("fast") || 1.8
|
||||||
: lastToggle;
|
: lastToggle;
|
||||||
setSpeed(v, speedToRestore, false, true);
|
setSpeed(v, speedToRestore, false, true, true);
|
||||||
} else {
|
} else {
|
||||||
// Not at 1.0, save current as toggle speed and go to 1.0
|
// Not at 1.0, save current as toggle speed and go to 1.0
|
||||||
lastToggleSpeed[videoId] = currentSpeed;
|
lastToggleSpeed[videoId] = currentSpeed;
|
||||||
setSpeed(v, resetSpeedValue, false, true);
|
v.vsc.resetToggleArmed = true;
|
||||||
|
setSpeed(v, resetSpeedValue, false, true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Speeder",
|
"name": "Speeder",
|
||||||
"short_name": "Speeder",
|
"short_name": "Speeder",
|
||||||
"version": "5.0.2",
|
"version": "5.0.3",
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"description": "Speed up, slow down, advance and rewind HTML5 audio/video with shortcuts (New and improved version of \"Video Speed Controller\")",
|
"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",
|
"homepage_url": "https://github.com/SoPat712/speeder",
|
||||||
|
|||||||
+89
-20
@@ -299,6 +299,19 @@ label em {
|
|||||||
border-top: 1px solid var(--border);
|
border-top: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.row input[type="text"],
|
||||||
|
.row select {
|
||||||
|
justify-self: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row.row-checkbox {
|
||||||
|
grid-template-columns: minmax(0, 1fr) 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row.row-checkbox input[type="checkbox"] {
|
||||||
|
justify-self: end;
|
||||||
|
}
|
||||||
|
|
||||||
.settings-card .row:first-of-type {
|
.settings-card .row:first-of-type {
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
border-top: 0;
|
border-top: 0;
|
||||||
@@ -310,16 +323,17 @@ label em {
|
|||||||
|
|
||||||
.controller-margin-inputs {
|
.controller-margin-inputs {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
grid-template-columns: repeat(2, minmax(0, 116px));
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
width: 100%;
|
width: max-content;
|
||||||
|
justify-self: end;
|
||||||
}
|
}
|
||||||
|
|
||||||
.margin-pad-cell {
|
.margin-pad-cell {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
min-width: 0;
|
min-width: 116px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.margin-pad-mini {
|
.margin-pad-mini {
|
||||||
@@ -332,12 +346,13 @@ label em {
|
|||||||
|
|
||||||
.controller-margin-inputs input[type="text"] {
|
.controller-margin-inputs input[type="text"] {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: 0;
|
min-width: 116px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-rule-option.site-rule-margin-option {
|
.site-rule-option.site-rule-margin-option {
|
||||||
grid-template-columns: minmax(0, 1fr) minmax(0, 220px);
|
grid-template-columns: minmax(0, 1fr) minmax(0, 260px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-rule-override-section {
|
.site-rule-override-section {
|
||||||
@@ -353,19 +368,25 @@ label em {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.site-override-lead {
|
.site-override-lead {
|
||||||
display: flex;
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1fr) 24px;
|
||||||
|
gap: 16px;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
gap: 10px;
|
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: auto;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-override-lead input {
|
.site-override-lead input[type="checkbox"] {
|
||||||
|
justify-self: end;
|
||||||
margin-top: 3px;
|
margin-top: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.site-override-lead span {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.site-rule-override-section .site-override-fields,
|
.site-rule-override-section .site-override-fields,
|
||||||
.site-rule-override-section .site-placement-container,
|
.site-rule-override-section .site-placement-container,
|
||||||
.site-rule-override-section .site-visibility-container,
|
.site-rule-override-section .site-visibility-container,
|
||||||
@@ -525,24 +546,61 @@ label em {
|
|||||||
|
|
||||||
.site-rule-option {
|
.site-rule-option {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: minmax(0, 1fr) 150px;
|
grid-template-columns: minmax(0, 1fr) 160px;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
align-items: start;
|
align-items: start;
|
||||||
padding: 8px 0;
|
padding: 8px 0;
|
||||||
border-top: 1px solid var(--border);
|
border-top: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.site-rule-option-checkbox {
|
||||||
|
grid-template-columns: minmax(0, 1fr) 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-rule-option-checkbox > input[type="checkbox"] {
|
||||||
|
justify-self: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-rule-option > input[type="text"],
|
||||||
|
.site-rule-option > select {
|
||||||
|
justify-self: end;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-rule-option.site-rule-margin-option .controller-margin-inputs {
|
||||||
|
justify-self: end;
|
||||||
|
}
|
||||||
|
|
||||||
.site-rule-body > .site-rule-option:first-child,
|
.site-rule-body > .site-rule-option:first-child,
|
||||||
.site-rule-content > .site-rule-option:first-child {
|
.site-rule-content > .site-rule-option:first-child {
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
border-top: 0;
|
border-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-rule-option label {
|
.site-rule-option > label:not(.site-rule-split-label) {
|
||||||
display: flex;
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-rule-split-label {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1fr) 24px;
|
||||||
|
gap: 16px;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
gap: 10px;
|
width: 100%;
|
||||||
width: auto;
|
margin: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-rule-split-label input[type="checkbox"] {
|
||||||
|
justify-self: end;
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-rule-option-checkbox > .site-rule-split-label {
|
||||||
|
grid-column: 1 / -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-rule-controlbar,
|
.site-rule-controlbar,
|
||||||
@@ -552,12 +610,8 @@ label em {
|
|||||||
border-top: 1px solid var(--border);
|
border-top: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-rule-controlbar > label,
|
.site-rule-controlbar > label.site-override-lead,
|
||||||
.site-rule-shortcuts > label {
|
.site-rule-shortcuts > label.site-override-lead {
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
gap: 10px;
|
|
||||||
width: auto;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -639,11 +693,26 @@ label em {
|
|||||||
.shortcut-row,
|
.shortcut-row,
|
||||||
.shortcut-row.customs,
|
.shortcut-row.customs,
|
||||||
.row,
|
.row,
|
||||||
|
.row.row-checkbox,
|
||||||
.site-rule-option,
|
.site-rule-option,
|
||||||
.site-shortcuts-container .shortcut-row {
|
.site-shortcuts-container .shortcut-row {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.row input[type="text"],
|
||||||
|
.row select {
|
||||||
|
justify-self: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-rule-option > input[type="text"],
|
||||||
|
.site-rule-option > select {
|
||||||
|
justify-self: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-override-lead {
|
||||||
|
grid-template-columns: minmax(0, 1fr) 24px;
|
||||||
|
}
|
||||||
|
|
||||||
.action-row button,
|
.action-row button,
|
||||||
#addShortcutSelector {
|
#addShortcutSelector {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
+33
-33
@@ -180,11 +180,11 @@
|
|||||||
|
|
||||||
<h4 class="defaults-sub-heading">General</h4>
|
<h4 class="defaults-sub-heading">General</h4>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row row-checkbox">
|
||||||
<label for="enabled">Enable</label>
|
<label for="enabled">Enable</label>
|
||||||
<input id="enabled" type="checkbox" />
|
<input id="enabled" type="checkbox" />
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row row-checkbox">
|
||||||
<label for="audioBoolean">Work on audio</label>
|
<label for="audioBoolean">Work on audio</label>
|
||||||
<input id="audioBoolean" type="checkbox" />
|
<input id="audioBoolean" type="checkbox" />
|
||||||
</div>
|
</div>
|
||||||
@@ -192,11 +192,11 @@
|
|||||||
<div class="defaults-divider"></div>
|
<div class="defaults-divider"></div>
|
||||||
<h4 class="defaults-sub-heading">Playback</h4>
|
<h4 class="defaults-sub-heading">Playback</h4>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row row-checkbox">
|
||||||
<label for="rememberSpeed">Remember playback speed</label>
|
<label for="rememberSpeed">Remember playback speed</label>
|
||||||
<input id="rememberSpeed" type="checkbox" />
|
<input id="rememberSpeed" type="checkbox" />
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row row-checkbox">
|
||||||
<label for="forceLastSavedSpeed"
|
<label for="forceLastSavedSpeed"
|
||||||
>Force last saved speed<br />
|
>Force last saved speed<br />
|
||||||
<em
|
<em
|
||||||
@@ -210,7 +210,7 @@
|
|||||||
<div class="defaults-divider"></div>
|
<div class="defaults-divider"></div>
|
||||||
<h4 class="defaults-sub-heading">Controller</h4>
|
<h4 class="defaults-sub-heading">Controller</h4>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row row-checkbox">
|
||||||
<label for="startHidden">Hide controller by default</label>
|
<label for="startHidden">Hide controller by default</label>
|
||||||
<input id="startHidden" type="checkbox" />
|
<input id="startHidden" type="checkbox" />
|
||||||
</div>
|
</div>
|
||||||
@@ -250,7 +250,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row row-checkbox">
|
||||||
<label for="hideWithControls"
|
<label for="hideWithControls"
|
||||||
>Hide with controls<br />
|
>Hide with controls<br />
|
||||||
<em
|
<em
|
||||||
@@ -270,7 +270,7 @@
|
|||||||
</label>
|
</label>
|
||||||
<input id="hideWithControlsTimer" type="text" placeholder="2" />
|
<input id="hideWithControlsTimer" type="text" placeholder="2" />
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row row-checkbox">
|
||||||
<label for="showPopupControlBar">Show popup control bar</label>
|
<label for="showPopupControlBar">Show popup control bar</label>
|
||||||
<input id="showPopupControlBar" type="checkbox" />
|
<input id="showPopupControlBar" type="checkbox" />
|
||||||
</div>
|
</div>
|
||||||
@@ -278,7 +278,7 @@
|
|||||||
<div class="defaults-divider"></div>
|
<div class="defaults-divider"></div>
|
||||||
<h4 class="defaults-sub-heading">Subtitle sync</h4>
|
<h4 class="defaults-sub-heading">Subtitle sync</h4>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row row-checkbox">
|
||||||
<label for="enableSubtitleNudge"
|
<label for="enableSubtitleNudge"
|
||||||
>Enable subtitle nudge<br /><em
|
>Enable subtitle nudge<br /><em
|
||||||
>Makes tiny playback changes to help keep subtitles aligned.</em
|
>Makes tiny playback changes to help keep subtitles aligned.</em
|
||||||
@@ -389,20 +389,20 @@
|
|||||||
<button type="button" class="remove-site-rule">Remove</button>
|
<button type="button" class="remove-site-rule">Remove</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="site-rule-body">
|
<div class="site-rule-body">
|
||||||
<div class="site-rule-option">
|
<div class="site-rule-option site-rule-option-checkbox">
|
||||||
<label>
|
<label class="site-rule-split-label">
|
||||||
|
<span>Enable Speeder on this site</span>
|
||||||
<input type="checkbox" class="site-enabled" />
|
<input type="checkbox" class="site-enabled" />
|
||||||
Enable Speeder on this site
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="site-rule-content">
|
<div class="site-rule-content">
|
||||||
<div class="site-rule-override-section">
|
<div class="site-rule-override-section">
|
||||||
<label class="site-override-lead">
|
<label class="site-override-lead">
|
||||||
|
<span>Override placement for this site</span>
|
||||||
<input type="checkbox" class="override-placement" />
|
<input type="checkbox" class="override-placement" />
|
||||||
Override placement for this site
|
|
||||||
</label>
|
</label>
|
||||||
<div class="site-placement-container" style="display: none">
|
<div class="site-placement-container" style="display: none">
|
||||||
<div class="site-rule-option">
|
<div class="site-rule-option site-rule-option-field">
|
||||||
<label>Default controller location:</label>
|
<label>Default controller location:</label>
|
||||||
<select class="site-controllerLocation">
|
<select class="site-controllerLocation">
|
||||||
<option value="top-left">Top left</option>
|
<option value="top-left">Top left</option>
|
||||||
@@ -436,11 +436,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="site-rule-override-section">
|
<div class="site-rule-override-section">
|
||||||
<label class="site-override-lead">
|
<label class="site-override-lead">
|
||||||
|
<span>Override hide-by-default for this site</span>
|
||||||
<input type="checkbox" class="override-visibility" />
|
<input type="checkbox" class="override-visibility" />
|
||||||
Override hide-by-default for this site
|
|
||||||
</label>
|
</label>
|
||||||
<div class="site-visibility-container" style="display: none">
|
<div class="site-visibility-container" style="display: none">
|
||||||
<div class="site-rule-option">
|
<div class="site-rule-option site-rule-option-checkbox">
|
||||||
<label>Hide controller by default:</label>
|
<label>Hide controller by default:</label>
|
||||||
<input type="checkbox" class="site-startHidden" />
|
<input type="checkbox" class="site-startHidden" />
|
||||||
</div>
|
</div>
|
||||||
@@ -448,17 +448,17 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="site-rule-override-section">
|
<div class="site-rule-override-section">
|
||||||
<label class="site-override-lead">
|
<label class="site-override-lead">
|
||||||
|
<span>Override auto-hide for this site</span>
|
||||||
<input type="checkbox" class="override-autohide" />
|
<input type="checkbox" class="override-autohide" />
|
||||||
Override auto-hide for this site
|
|
||||||
</label>
|
</label>
|
||||||
<div class="site-autohide-container" style="display: none">
|
<div class="site-autohide-container" style="display: none">
|
||||||
<div class="site-rule-option">
|
<div class="site-rule-option site-rule-option-checkbox">
|
||||||
<label>
|
<label class="site-rule-split-label">
|
||||||
|
<span>Hide with controls (idle-based)</span>
|
||||||
<input type="checkbox" class="site-hideWithControls" />
|
<input type="checkbox" class="site-hideWithControls" />
|
||||||
Hide with controls (idle-based)
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="site-rule-option">
|
<div class="site-rule-option site-rule-option-field">
|
||||||
<label>Auto-hide timer (0.1–15s):</label>
|
<label>Auto-hide timer (0.1–15s):</label>
|
||||||
<input type="text" class="site-hideWithControlsTimer" />
|
<input type="text" class="site-hideWithControlsTimer" />
|
||||||
</div>
|
</div>
|
||||||
@@ -466,19 +466,19 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="site-rule-override-section">
|
<div class="site-rule-override-section">
|
||||||
<label class="site-override-lead">
|
<label class="site-override-lead">
|
||||||
|
<span>Override playback for this site</span>
|
||||||
<input type="checkbox" class="override-playback" />
|
<input type="checkbox" class="override-playback" />
|
||||||
Override playback for this site
|
|
||||||
</label>
|
</label>
|
||||||
<div class="site-playback-container" style="display: none">
|
<div class="site-playback-container" style="display: none">
|
||||||
<div class="site-rule-option">
|
<div class="site-rule-option site-rule-option-checkbox">
|
||||||
<label>Remember playback speed:</label>
|
<label>Remember playback speed:</label>
|
||||||
<input type="checkbox" class="site-rememberSpeed" />
|
<input type="checkbox" class="site-rememberSpeed" />
|
||||||
</div>
|
</div>
|
||||||
<div class="site-rule-option">
|
<div class="site-rule-option site-rule-option-checkbox">
|
||||||
<label>Force last saved speed:</label>
|
<label>Force last saved speed:</label>
|
||||||
<input type="checkbox" class="site-forceLastSavedSpeed" />
|
<input type="checkbox" class="site-forceLastSavedSpeed" />
|
||||||
</div>
|
</div>
|
||||||
<div class="site-rule-option">
|
<div class="site-rule-option site-rule-option-checkbox">
|
||||||
<label>Work on audio:</label>
|
<label>Work on audio:</label>
|
||||||
<input type="checkbox" class="site-audioBoolean" />
|
<input type="checkbox" class="site-audioBoolean" />
|
||||||
</div>
|
</div>
|
||||||
@@ -486,11 +486,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="site-rule-override-section">
|
<div class="site-rule-override-section">
|
||||||
<label class="site-override-lead">
|
<label class="site-override-lead">
|
||||||
|
<span>Override opacity for this site</span>
|
||||||
<input type="checkbox" class="override-opacity" />
|
<input type="checkbox" class="override-opacity" />
|
||||||
Override opacity for this site
|
|
||||||
</label>
|
</label>
|
||||||
<div class="site-opacity-container" style="display: none">
|
<div class="site-opacity-container" style="display: none">
|
||||||
<div class="site-rule-option">
|
<div class="site-rule-option site-rule-option-field">
|
||||||
<label>Controller opacity:</label>
|
<label>Controller opacity:</label>
|
||||||
<input type="text" class="site-controllerOpacity" />
|
<input type="text" class="site-controllerOpacity" />
|
||||||
</div>
|
</div>
|
||||||
@@ -498,15 +498,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="site-rule-override-section">
|
<div class="site-rule-override-section">
|
||||||
<label class="site-override-lead">
|
<label class="site-override-lead">
|
||||||
|
<span>Override subtitle nudge for this site</span>
|
||||||
<input type="checkbox" class="override-subtitleNudge" />
|
<input type="checkbox" class="override-subtitleNudge" />
|
||||||
Override subtitle nudge for this site
|
|
||||||
</label>
|
</label>
|
||||||
<div class="site-subtitleNudge-container" style="display: none">
|
<div class="site-subtitleNudge-container" style="display: none">
|
||||||
<div class="site-rule-option">
|
<div class="site-rule-option site-rule-option-checkbox">
|
||||||
<label>Enable subtitle nudge:</label>
|
<label>Enable subtitle nudge:</label>
|
||||||
<input type="checkbox" class="site-enableSubtitleNudge" />
|
<input type="checkbox" class="site-enableSubtitleNudge" />
|
||||||
</div>
|
</div>
|
||||||
<div class="site-rule-option">
|
<div class="site-rule-option site-rule-option-field">
|
||||||
<label>Nudge interval (10–1000ms):</label>
|
<label>Nudge interval (10–1000ms):</label>
|
||||||
<input type="text" class="site-subtitleNudgeInterval" placeholder="50" />
|
<input type="text" class="site-subtitleNudgeInterval" placeholder="50" />
|
||||||
</div>
|
</div>
|
||||||
@@ -514,8 +514,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="site-rule-controlbar">
|
<div class="site-rule-controlbar">
|
||||||
<label class="site-override-lead">
|
<label class="site-override-lead">
|
||||||
|
<span>Override in-player control bar for this site</span>
|
||||||
<input type="checkbox" class="override-controlbar" />
|
<input type="checkbox" class="override-controlbar" />
|
||||||
Override in-player control bar for this site
|
|
||||||
</label>
|
</label>
|
||||||
<div class="site-controlbar-container" style="display: none">
|
<div class="site-controlbar-container" style="display: none">
|
||||||
<div class="cb-editor">
|
<div class="cb-editor">
|
||||||
@@ -532,11 +532,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="site-rule-controlbar">
|
<div class="site-rule-controlbar">
|
||||||
<label class="site-override-lead">
|
<label class="site-override-lead">
|
||||||
|
<span>Override extension popup for this site</span>
|
||||||
<input type="checkbox" class="override-popup-controlbar" />
|
<input type="checkbox" class="override-popup-controlbar" />
|
||||||
Override extension popup for this site
|
|
||||||
</label>
|
</label>
|
||||||
<div class="site-popup-controlbar-container" style="display: none">
|
<div class="site-popup-controlbar-container" style="display: none">
|
||||||
<div class="site-rule-option">
|
<div class="site-rule-option site-rule-option-checkbox">
|
||||||
<label>Show popup control bar</label>
|
<label>Show popup control bar</label>
|
||||||
<input type="checkbox" class="site-showPopupControlBar" />
|
<input type="checkbox" class="site-showPopupControlBar" />
|
||||||
</div>
|
</div>
|
||||||
@@ -554,8 +554,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="site-rule-shortcuts">
|
<div class="site-rule-shortcuts">
|
||||||
<label class="site-override-lead">
|
<label class="site-override-lead">
|
||||||
|
<span>Override shortcuts for this site</span>
|
||||||
<input type="checkbox" class="override-shortcuts" />
|
<input type="checkbox" class="override-shortcuts" />
|
||||||
Override shortcuts for this site
|
|
||||||
</label>
|
</label>
|
||||||
<div class="site-shortcuts-container" style="display: none"></div>
|
<div class="site-shortcuts-container" style="display: none"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+19
-4
@@ -138,7 +138,7 @@ var controllerButtonDefs = {
|
|||||||
faster: { icon: "+", name: "Increase speed" },
|
faster: { icon: "+", name: "Increase speed" },
|
||||||
advance: { icon: "\u00BB", name: "Advance" },
|
advance: { icon: "\u00BB", name: "Advance" },
|
||||||
display: { icon: "\u00D7", name: "Close controller" },
|
display: { icon: "\u00D7", name: "Close controller" },
|
||||||
reset: { icon: "\u21BA", name: "Reset speed" },
|
reset: { icon: "1.00x", name: "Reset speed" },
|
||||||
fast: { icon: "\u2605", name: "Preferred speed" },
|
fast: { icon: "\u2605", name: "Preferred speed" },
|
||||||
nudge: { icon: "\u2713", name: "Subtitle nudge" },
|
nudge: { icon: "\u2713", name: "Subtitle nudge" },
|
||||||
settings: { icon: "\u2699", name: "Settings" },
|
settings: { icon: "\u2699", name: "Settings" },
|
||||||
@@ -227,6 +227,19 @@ const actionLabels = {
|
|||||||
toggleSubtitleNudge: "Toggle subtitle nudge"
|
toggleSubtitleNudge: "Toggle subtitle nudge"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const speedBindingActions = ["slower", "faster", "fast"];
|
||||||
|
|
||||||
|
function formatSpeedBindingDisplay(action, value) {
|
||||||
|
if (!speedBindingActions.includes(action)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
var n = Number(value);
|
||||||
|
if (!isFinite(n)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return n.toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
const customActionsNoValues = [
|
const customActionsNoValues = [
|
||||||
"reset",
|
"reset",
|
||||||
"display",
|
"display",
|
||||||
@@ -526,7 +539,7 @@ function add_shortcut(action, value) {
|
|||||||
valueInput.value = "N/A";
|
valueInput.value = "N/A";
|
||||||
valueInput.disabled = true;
|
valueInput.disabled = true;
|
||||||
} else {
|
} else {
|
||||||
valueInput.value = value || 0;
|
valueInput.value = formatSpeedBindingDisplay(action, value || 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
var removeButton = document.createElement("button");
|
var removeButton = document.createElement("button");
|
||||||
@@ -899,9 +912,11 @@ function addSiteRuleShortcut(container, action, binding, value, force) {
|
|||||||
valueInput.className = "customValue";
|
valueInput.className = "customValue";
|
||||||
valueInput.type = "text";
|
valueInput.type = "text";
|
||||||
valueInput.placeholder = "value (0.10)";
|
valueInput.placeholder = "value (0.10)";
|
||||||
valueInput.value = value || 0;
|
|
||||||
if (customActionsNoValues.includes(action)) {
|
if (customActionsNoValues.includes(action)) {
|
||||||
|
valueInput.value = "N/A";
|
||||||
valueInput.disabled = true;
|
valueInput.disabled = true;
|
||||||
|
} else {
|
||||||
|
valueInput.value = formatSpeedBindingDisplay(action, value || 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
var forceLabel = document.createElement("label");
|
var forceLabel = document.createElement("label");
|
||||||
@@ -1329,7 +1344,7 @@ function restore_options() {
|
|||||||
valueInput.disabled = true;
|
valueInput.disabled = true;
|
||||||
}
|
}
|
||||||
} else if (valueInput) {
|
} else if (valueInput) {
|
||||||
valueInput.value = item.value;
|
valueInput.value = formatSpeedBindingDisplay(item.action, item.value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
faster: { label: "+", className: "" },
|
faster: { label: "+", className: "" },
|
||||||
advance: { label: "\u00BB", className: "rw" },
|
advance: { label: "\u00BB", className: "rw" },
|
||||||
display: { label: "\u00D7", className: "hideButton" },
|
display: { label: "\u00D7", className: "hideButton" },
|
||||||
reset: { label: "\u21BA", className: "" },
|
reset: { label: "1.00x", className: "" },
|
||||||
fast: { label: "\u2605", className: "" },
|
fast: { label: "\u2605", className: "" },
|
||||||
settings: { label: "\u2699", className: "" },
|
settings: { label: "\u2699", className: "" },
|
||||||
pause: { label: "\u23EF", className: "" },
|
pause: { label: "\u23EF", className: "" },
|
||||||
@@ -171,11 +171,76 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
if (el) el.textContent = (speed != null ? Number(speed) : 1).toFixed(2);
|
if (el) el.textContent = (speed != null ? Number(speed) : 1).toFixed(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
function querySpeed() {
|
function updatePopupResetLabel(resetLabel) {
|
||||||
sendToActiveTab({ action: "get_speed" }, function (response) {
|
var bar = document.getElementById("popupControlBar");
|
||||||
if (response && response.speed != null) {
|
if (!bar || typeof resetLabel !== "string") return;
|
||||||
updateSpeedDisplay(response.speed);
|
var btn = bar.querySelector('button[data-action="reset"]');
|
||||||
|
if (btn) btn.textContent = resetLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
function applySpeedAndResetFromResponse(response) {
|
||||||
|
if (response && response.speed != null) {
|
||||||
|
updateSpeedDisplay(response.speed);
|
||||||
|
}
|
||||||
|
if (response && response.resetLabel != null) {
|
||||||
|
updatePopupResetLabel(response.resetLabel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function pickBestFrameSpeedResult(results) {
|
||||||
|
if (!results || !results.length) return null;
|
||||||
|
var i;
|
||||||
|
var r;
|
||||||
|
var fallback = null;
|
||||||
|
for (i = 0; i < results.length; i++) {
|
||||||
|
r = results[i];
|
||||||
|
if (
|
||||||
|
!r ||
|
||||||
|
typeof r.speed !== "number" ||
|
||||||
|
typeof r.resetLabel !== "string"
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
if (r.preferred) {
|
||||||
|
return { speed: r.speed, resetLabel: r.resetLabel };
|
||||||
|
}
|
||||||
|
if (!fallback) {
|
||||||
|
fallback = { speed: r.speed, resetLabel: r.resetLabel };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
function querySpeed() {
|
||||||
|
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
|
||||||
|
if (!tabs[0] || tabs[0].id == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var tabId = tabs[0].id;
|
||||||
|
chrome.tabs.executeScript(
|
||||||
|
tabId,
|
||||||
|
{ allFrames: true, file: "frameSpeedSnapshot.js" },
|
||||||
|
function (results) {
|
||||||
|
if (chrome.runtime.lastError) {
|
||||||
|
sendToActiveTab({ action: "get_speed" }, function (response) {
|
||||||
|
applySpeedAndResetFromResponse(
|
||||||
|
response || { speed: 1, resetLabel: "1.00x" }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var best = pickBestFrameSpeedResult(results);
|
||||||
|
if (best) {
|
||||||
|
applySpeedAndResetFromResponse(best);
|
||||||
|
} else {
|
||||||
|
sendToActiveTab({ action: "get_speed" }, function (response) {
|
||||||
|
applySpeedAndResetFromResponse(
|
||||||
|
response || { speed: 1, resetLabel: "1.00x" }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,10 +269,8 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
}
|
}
|
||||||
sendToActiveTab(
|
sendToActiveTab(
|
||||||
{ action: "run_action", actionName: btnId },
|
{ action: "run_action", actionName: btnId },
|
||||||
function (response) {
|
function () {
|
||||||
if (response && response.speed != null) {
|
querySpeed();
|
||||||
updateSpeedDisplay(response.speed);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -297,12 +360,14 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
if (blacklisted) {
|
if (blacklisted) {
|
||||||
setStatusMessage("Site is blacklisted.");
|
setStatusMessage("Site is blacklisted.");
|
||||||
updateSpeedDisplay(1);
|
updateSpeedDisplay(1);
|
||||||
|
updatePopupResetLabel("1.00x");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (siteDisabled) {
|
if (siteDisabled) {
|
||||||
setStatusMessage("Speeder is disabled for this site.");
|
setStatusMessage("Speeder is disabled for this site.");
|
||||||
updateSpeedDisplay(1);
|
updateSpeedDisplay(1);
|
||||||
|
updatePopupResetLabel("1.00x");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,6 +376,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
querySpeed();
|
querySpeed();
|
||||||
} else {
|
} else {
|
||||||
updateSpeedDisplay(1);
|
updateSpeedDisplay(1);
|
||||||
|
updatePopupResetLabel("1.00x");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user