From 9b8f9dfbaec462bef29c12064efa8bd5202c4fc0 Mon Sep 17 00:00:00 2001 From: Chad Bailey Date: Sun, 1 Mar 2020 21:42:23 -0600 Subject: [PATCH] Added ratechange blocklist to fix #72 #521 and #584 --- inject.js | 93 ++++++++++++++++++++++++++++++++++++++++----------- manifest.json | 3 +- options.html | 24 ++++++++++--- options.js | 30 +++++++++++++++-- 4 files changed, 122 insertions(+), 28 deletions(-) diff --git a/inject.js b/inject.js index d059564..04816af 100644 --- a/inject.js +++ b/inject.js @@ -18,7 +18,12 @@ var tc = { vine.co imgur.com teams.microsoft.com - `.replace(regStrip, "") + `.replace(regStrip, ""), + blacklistrc: `\ + twitch.tv + pluralsight.com + teamtreehouse.com + `.replace(regStrip, "") } }; @@ -80,7 +85,8 @@ chrome.storage.sync.get(tc.settings, function(storage) { startHidden: tc.settings.startHidden, enabled: tc.settings.enabled, controllerOpacity: tc.settings.controllerOpacity, - blacklist: tc.settings.blacklist.replace(regStrip, "") + blacklist: tc.settings.blacklist.replace(regStrip, ""), + blacklistrc: tc.settings.blacklistrc.replace(regStrip, "") }); } tc.settings.lastSpeed = Number(storage.lastSpeed); @@ -91,6 +97,7 @@ chrome.storage.sync.get(tc.settings, function(storage) { tc.settings.startHidden = Boolean(storage.startHidden); tc.settings.controllerOpacity = Number(storage.controllerOpacity); tc.settings.blacklist = String(storage.blacklist); + tc.settings.blacklistrc = String(storage.blacklistrc); // ensure that there is a "display" binding (for upgrades from versions that had it as a separate binding) if (tc.settings.keyBindings.filter(x => x.action == "display").length == 0) { @@ -306,13 +313,13 @@ function defineVideoController() { }; } -function initializeWhenReady(document) { - escapeStringRegExp.matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; - function escapeStringRegExp(str) { - return str.replace(escapeStringRegExp.matchOperatorsRe, "\\$&"); - } +function escapeStringRegExp(str) { + matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; + return str.replace(matchOperatorsRe, "\\$&"); +} - var blacklisted = false; +function isBlacklisted() { + blacklisted = false; tc.settings.blacklist.split("\n").forEach(match => { match = match.replace(regStrip, ""); if (match.length == 0) { @@ -334,9 +341,46 @@ function initializeWhenReady(document) { return; } }); + return blacklisted; +} - if (blacklisted) return; +function isRateChangeBlocked() { + blockRateChange = false; + tc.settings.blacklistrc.split("\n").forEach(match => { + match = match.replace(regStrip, ""); + if (match.length == 0) { + return; + } + if (match.startsWith("/")) { + try { + var regexp = new RegExp(match); + } catch (err) { + return; + } + } else { + var regexp = new RegExp(escapeStringRegExp(match)); + } + if (regexp.test(location.href)) { + blockRateChange = true; + return; + } + }); + return blockRateChange; +} +function initializeWhenReady(document) { + if (isBlacklisted()) { + return; + } + if (isRateChangeBlocked()) { + document.body.addEventListener( + "ratechange", + function(event) { + event.stopImmediatePropagation(); + }, + true + ); + } window.onload = () => { initializeNow(window.document); }; @@ -502,8 +546,10 @@ function initializeNow(document) { }); break; case "attributes": - if (mutation.target.attributes["aria-hidden"] && - mutation.target.attributes["aria-hidden"].value == "false") { + if ( + mutation.target.attributes["aria-hidden"] && + mutation.target.attributes["aria-hidden"].value == "false" + ) { var flattenedNodes = getShadow(document.body); var node = flattenedNodes.filter(x => x.tagName == "VIDEO")[0]; if (node) { @@ -551,6 +597,13 @@ function initializeNow(document) { }); } +function setSpeed(controller, video, speed) { + var speedvalue = speed.toFixed(2); + video.playbackRate = Number(speedvalue); + var speedIndicator = controller.shadowRoot.querySelector("span"); + speedIndicator.textContent = speedvalue; +} + function runAction(action, document, value, e) { if (tc.settings.audioBoolean) { var mediaTags = getShadow(document.body).filter(x => { @@ -592,14 +645,14 @@ function runAction(action, document, value, e) { (v.playbackRate < 0.1 ? 0.0 : v.playbackRate) + value, 16 ); - v.playbackRate = Number(s.toFixed(2)); + setSpeed(controller, v, s); } else if (action === "slower") { // Video min rate is 0.0625: // https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/html/media/html_media_element.cc?gsn=kMinRate&l=165 var s = Math.max(v.playbackRate - value, 0.07); - v.playbackRate = Number(s.toFixed(2)); + setSpeed(controller, v, s); } else if (action === "reset") { - resetSpeed(v, 1.0); + resetSpeed(v, controller, 1.0); } else if (action === "display") { controller.classList.add("vsc-manual"); controller.classList.toggle("vsc-hidden"); @@ -622,7 +675,7 @@ function runAction(action, document, value, e) { } else if (action === "drag") { handleDrag(v, controller, e); } else if (action === "fast") { - resetSpeed(v, value); + resetSpeed(v, controller, value); } else if (action === "pause") { pause(v); } else if (action === "muted") { @@ -644,21 +697,21 @@ function pause(v) { } } -function resetSpeed(v, target) { +function resetSpeed(v, controller, target) { if (v.playbackRate === target) { if (v.playbackRate === getKeyBindings("reset")) { // resetSpeed if (target !== 1.0) { - v.playbackRate = 1.0; + setSpeed(controller, v, 1.0); } else { - v.playbackRate = getKeyBindings("fast"); // fastSpeed + setSpeed(controller, v, getKeyBindings("fast")); // fastSpeed } } else { - v.playbackRate = getKeyBindings("reset"); // resetSpeed + setSpeed(controller, v, getKeyBindings("reset")); // resetSpeed } } else { setKeyBindings("reset", v.playbackRate); // resetSpeed - v.playbackRate = target; + setSpeed(controller, v, target); } } diff --git a/manifest.json b/manifest.json index 021f792..f489342 100755 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "name": "Video Speed Controller", "short_name": "videospeed", - "version": "0.6.0", + "version": "0.6.1", "manifest_version": 2, "description": "Speed up, slow down, advance and rewind any HTML5 video with quick shortcuts.", "homepage_url": "https://github.com/igrigorik/videospeed", @@ -29,7 +29,6 @@ "https://plus.google.com/hangouts/*", "https://hangouts.google.com/*", "https://meet.google.com/*", - "https://teamtreehouse.com/*", "http://www.hitbox.tv/*" ], "css": ["inject.css"], diff --git a/options.html b/options.html index 36c9f3c..2ab49bc 100644 --- a/options.html +++ b/options.html @@ -160,14 +160,30 @@ >Blacklisted sites on which extension is disabled
(one per line)

- Regex is supported. Be sure + + Regex is supported. Be sure it is in "//g" format.
- ie: /(.+)youtube\.com(\/*)$/gi
+ ie: /(.+)youtube\.com(\/*)$/gi +
+
+ + +
diff --git a/options.js b/options.js index 865195f..657b8ad 100644 --- a/options.js +++ b/options.js @@ -23,6 +23,11 @@ var tcDefaults = { vine.co imgur.com teams.microsoft.com + `.replace(regStrip, ""), + blacklistrc: `\ + twitch.tv + pluralsight.com + teamtreehouse.com `.replace(regStrip, "") }; @@ -191,7 +196,25 @@ function validate() { var regexp = new RegExp(match); } catch (err) { status.textContent = - "Error: Invalid Regex: " + match + ". Unable to save"; + "Error: Invalid blacklist regex: " + match + ". Unable to save"; + valid = false; + return; + } + } + }); + document + .getElementById("blacklistrc") + .value.split("\n") + .forEach(match => { + match = match.replace(regStrip, ""); + if (match.startsWith("/")) { + try { + var regexp = new RegExp(match); + } catch (err) { + status.textContent = + "Error: Invalid ratechange blacklist regex: " + + match + + ". Unable to save"; valid = false; return; } @@ -216,6 +239,7 @@ function save_options() { var startHidden = document.getElementById("startHidden").checked; var controllerOpacity = document.getElementById("controllerOpacity").value; var blacklist = document.getElementById("blacklist").value; + var blacklistrc = document.getElementById("blacklistrc").value; chrome.storage.sync.remove([ "resetSpeed", @@ -238,7 +262,8 @@ function save_options() { startHidden: startHidden, controllerOpacity: controllerOpacity, keyBindings: keyBindings, - blacklist: blacklist.replace(regStrip, "") + blacklist: blacklist.replace(regStrip, ""), + blacklistrc: blacklistrc.replace(regStrip, "") }, function() { // Update status to let user know options were saved. @@ -261,6 +286,7 @@ function restore_options() { document.getElementById("controllerOpacity").value = storage.controllerOpacity; document.getElementById("blacklist").value = storage.blacklist; + document.getElementById("blacklistrc").value = storage.blacklistrc; // ensure that there is a "display" binding for upgrades from versions that had it as a separate binding if (storage.keyBindings.filter(x => x.action == "display").length == 0) {