From 949b9157e43d8e050ea1639f22db139d65c63a28 Mon Sep 17 00:00:00 2001 From: Fabio Espinosa Date: Mon, 18 Sep 2017 15:02:15 -0500 Subject: [PATCH 1/9] Add info about remembering current playback speed --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fadc177..5a8106f 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Once the extension is installed simply navigate to any page that offers HTML5 vi * **X** - advance video by 10 seconds. * **V** - show/hide the controller. -_Note: you can customize these shortcut keys in the extension settings page._ +_Note: you can customize these shortcut keys in the extension settings page and even make the extension remember your current playback speed._ ### FAQ From 371168636f70e475be9fd35bda0e79508645d1bc Mon Sep 17 00:00:00 2001 From: Roly Fentanes Date: Sun, 12 Nov 2017 17:47:53 -0500 Subject: [PATCH 2/9] better way of following mouse on controller drag --- inject.js | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/inject.js b/inject.js index f9d50d3..356d1cc 100644 --- a/inject.js +++ b/inject.js @@ -133,12 +133,12 @@ chrome.runtime.sendMessage({}, function(response) { `; shadow.innerHTML = shadowTemplate; shadow.querySelector('.draggable').addEventListener('mousedown', (e) => { - runAction(e.target.dataset['action'], document); + runAction(e.target.dataset['action'], document, false, e); }); forEach.call(shadow.querySelectorAll('button'), function(button) { button.onclick = (e) => { - runAction(e.target.dataset['action'], document); + runAction(e.target.dataset['action'], document, false, e); } }); @@ -312,7 +312,7 @@ chrome.runtime.sendMessage({}, function(response) { }); } - function runAction(action, document, keyboard) { + function runAction(action, document, keyboard, e) { var videoTags = document.getElementsByTagName('video'); videoTags.forEach = Array.prototype.forEach; @@ -345,7 +345,7 @@ chrome.runtime.sendMessage({}, function(response) { controller.classList.add('vsc-manual'); controller.classList.toggle('vsc-hidden'); } else if (action === 'drag') { - handleDrag(v, controller); + handleDrag(v, controller, e); } else if (action === 'fast') { resetSpeed(v, tc.settings.fastSpeed); } @@ -363,17 +363,32 @@ chrome.runtime.sendMessage({}, function(response) { } } - function handleDrag(video, controller) { - const parentElement = controller.parentElement, - shadowController = controller.shadowRoot.querySelector('#controller'); + function handleDrag(video, controller, e) { + const shadowController = controller.shadowRoot.querySelector('#controller'); + + // Find nearest parent of same size as video parent. + var parentElement = controller.parentElement; + while (parentElement.parentNode && + parentElement.parentNode.offsetHeight === parentElement.offsetHeight && + parentElement.parentNode.offsetWidth === parentElement.offsetWidth) { + parentElement = parentElement.parentNode; + } video.classList.add('vcs-dragging'); shadowController.classList.add('dragging'); + const initialMouseXY = [e.clientX, e.clientY]; + const initialControllerXY = [ + parseInt(shadowController.style.left), + parseInt(shadowController.style.top) + ]; + const startDragging = (e) => { let style = shadowController.style; - style.left = parseInt(style.left) + e.movementX + 'px'; - style.top = parseInt(style.top) + e.movementY + 'px'; + let dx = e.clientX - initialMouseXY[0]; + let dy = e.clientY -initialMouseXY[1]; + style.left = (initialControllerXY[0] + dx) + 'px'; + style.top = (initialControllerXY[1] + dy) + 'px'; } const stopDragging = () => { From 73fb1d34d01fa61f987b9a5f1452d12eedcf8116 Mon Sep 17 00:00:00 2001 From: Ilya Grigorik Date: Fri, 20 Oct 2017 22:21:49 -0700 Subject: [PATCH 3/9] bump to 0.5.0 --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 48f95a4..1561516 100755 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "name": "Video Speed Controller", "short_name": "videospeed", - "version": "0.4.9", + "version": "0.5.0", "manifest_version": 2, "description": "Speed up, slow down, advance and rewind any HTML5 video with quick shortcuts.", "homepage_url": "https://github.com/igrigorik/videospeed", From 7606224ec92790f65f27b348c9fb7346ecbc7d3e Mon Sep 17 00:00:00 2001 From: Ilya Grigorik Date: Wed, 27 Dec 2017 13:10:38 -0500 Subject: [PATCH 4/9] initialize on HTML docs Closes #269. --- inject.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inject.js b/inject.js index 356d1cc..bb64b16 100644 --- a/inject.js +++ b/inject.js @@ -189,7 +189,7 @@ chrome.runtime.sendMessage({}, function(response) { return; window.onload = () => initializeNow(document); - if (document) { + if (document && document.doctype.name == "html") { if (document.readyState === "complete") { initializeNow(document); } else { From e50c29c5dd521cb0b91ffcc522bfa3e54e002070 Mon Sep 17 00:00:00 2001 From: Ilya Grigorik Date: Thu, 8 Feb 2018 13:16:27 +0000 Subject: [PATCH 5/9] verify doctype is present, pass in window's document Fixes #309 --- inject.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/inject.js b/inject.js index bb64b16..8e62d92 100644 --- a/inject.js +++ b/inject.js @@ -188,8 +188,10 @@ chrome.runtime.sendMessage({}, function(response) { if (blacklisted) return; - window.onload = () => initializeNow(document); - if (document && document.doctype.name == "html") { + window.onload = () => { + initializeNow(window.document) + }; + if (document && document.doctype && document.doctype.name == "html") { if (document.readyState === "complete") { initializeNow(document); } else { From e85dad32809bbef77cdecf2c03ea9ceb2d59ae22 Mon Sep 17 00:00:00 2001 From: Ilya Grigorik Date: Thu, 8 Feb 2018 13:35:26 +0000 Subject: [PATCH 6/9] update audio+video min/max references Audio is no longer cutoff [1]. Video limits still in place. [1] https://developers.google.com/web/updates/2017/12/chrome-63-64-media-updates#remove-muting-extreme-playbackrates Closes #300. --- inject.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/inject.js b/inject.js index 8e62d92..41f9eb5 100644 --- a/inject.js +++ b/inject.js @@ -331,14 +331,12 @@ chrome.runtime.sendMessage({}, function(response) { v.currentTime += tc.settings.advanceTime; } else if (action === 'faster') { // Maximum playback speed in Chrome is set to 16: - // https://cs.chromium.org/chromium/src/media/blink/webmediaplayer_impl.cc?l=103 + // https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp?l=168 var s = Math.min( (v.playbackRate < 0.1 ? 0.0 : v.playbackRate) + tc.settings.speedStep, 16); v.playbackRate = Number(s.toFixed(2)); } else if (action === 'slower') { - // Audio playback is cut at 0.05: - // https://cs.chromium.org/chromium/src/media/filters/audio_renderer_algorithm.cc?l=49 // Video min rate is 0.0625: - // https://cs.chromium.org/chromium/src/media/blink/webmediaplayer_impl.cc?l=102 + // https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp?l=167 var s = Math.max(v.playbackRate - tc.settings.speedStep, 0.0625); v.playbackRate = Number(s.toFixed(2)); } else if (action === 'reset') { From 8e199cd975363536c9cafb00b837011dc9587922 Mon Sep 17 00:00:00 2001 From: Paul Irish Date: Mon, 19 Mar 2018 10:09:53 -0700 Subject: [PATCH 7/9] delay DOM node walking via requestIdleCallback --- inject.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/inject.js b/inject.js index 41f9eb5..816f55d 100644 --- a/inject.js +++ b/inject.js @@ -285,18 +285,29 @@ chrome.runtime.sendMessage({}, function(response) { } } } + + // Process the DOM nodes lazily + function enqueueCheckNodes(node, parent, added) { + const checkNodes = _ => checkForVideo(node, parent, added); + if ('requestIdleCallback' in window) { + requestIdleCallback(checkNodes, {timeout: 1000}); + } else { + checkNodes(); + } + } + var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { forEach.call(mutation.addedNodes, function(node) { if (typeof node === "function") return; - checkForVideo(node, node.parentNode || mutation.target, true); - }) + enqueueCheckNodes(node, node.parentNode || mutation.target, true); + }); forEach.call(mutation.removedNodes, function(node) { if (typeof node === "function") return; - checkForVideo(node, node.parentNode || mutation.target, false); - }) + enqueueCheckNodes(node, node.parentNode || mutation.target, false); + }); }); }); observer.observe(document, { childList: true, subtree: true }); From b31d53a4d0358913dbeabe6b9f73d695d877c1e6 Mon Sep 17 00:00:00 2001 From: Paul Irish Date: Mon, 19 Mar 2018 10:31:53 -0700 Subject: [PATCH 8/9] enqueue the entire MuObs handler instead. --- inject.js | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/inject.js b/inject.js index 816f55d..1a4da29 100644 --- a/inject.js +++ b/inject.js @@ -286,29 +286,22 @@ chrome.runtime.sendMessage({}, function(response) { } } - // Process the DOM nodes lazily - function enqueueCheckNodes(node, parent, added) { - const checkNodes = _ => checkForVideo(node, parent, added); - if ('requestIdleCallback' in window) { - requestIdleCallback(checkNodes, {timeout: 1000}); - } else { - checkNodes(); - } - } - var observer = new MutationObserver(function(mutations) { - mutations.forEach(function(mutation) { - forEach.call(mutation.addedNodes, function(node) { - if (typeof node === "function") - return; - enqueueCheckNodes(node, node.parentNode || mutation.target, true); + // Process the DOM nodes lazily + requestIdleCallback(_ => { + mutations.forEach(function(mutation) { + forEach.call(mutation.addedNodes, function(node) { + if (typeof node === "function") + return; + checkForVideo(node, node.parentNode || mutation.target, true); + }); + forEach.call(mutation.removedNodes, function(node) { + if (typeof node === "function") + return; + checkForVideo(node, node.parentNode || mutation.target, false); + }); }); - forEach.call(mutation.removedNodes, function(node) { - if (typeof node === "function") - return; - enqueueCheckNodes(node, node.parentNode || mutation.target, false); - }); - }); + }, {timeout: 1000}); }); observer.observe(document, { childList: true, subtree: true }); From 343a9573fffcd5e80a2a7de62b12f8c4d0fb40d0 Mon Sep 17 00:00:00 2001 From: Paul Irish Date: Mon, 19 Mar 2018 10:32:23 -0700 Subject: [PATCH 9/9] cache node.children[i] for 10% speedup. --- inject.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/inject.js b/inject.js index 1a4da29..6826ddd 100644 --- a/inject.js +++ b/inject.js @@ -279,9 +279,8 @@ chrome.runtime.sendMessage({}, function(response) { } } else if (node.children != undefined) { for (var i = 0; i < node.children.length; i++) { - checkForVideo(node.children[i], - node.children[i].parentNode || parent, - added); + const child = node.children[i]; + checkForVideo(child, child.parentNode || parent, added); } } }