Merge upstream

# Conflicts:
#	inject.js
#	manifest.json
This commit is contained in:
codebicycle
2018-03-25 11:08:18 +03:00
3 changed files with 48 additions and 32 deletions

View File

@@ -24,7 +24,7 @@ Once the extension is installed simply navigate to any page that offers HTML5 vi
* **X** - advance video by 10 seconds. * **X** - advance video by 10 seconds.
* **V** - show/hide the controller. * **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 ### FAQ

View File

@@ -167,12 +167,12 @@ chrome.runtime.sendMessage({}, function(response) {
var shadow = wrapper var shadow = wrapper
shadow.querySelector('.draggable').addEventListener('mousedown', (e) => { 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) { forEach.call(shadow.querySelectorAll('button'), function(button) {
button.onclick = (e) => { button.onclick = (e) => {
runAction(e.target.dataset['action'], document); runAction(e.target.dataset['action'], document, false, e);
} }
}); });
@@ -223,10 +223,10 @@ chrome.runtime.sendMessage({}, function(response) {
return; return;
window.addEventListener('load', function () { window.addEventListener('load', function () {
initializeNow(document); initializeNow(window.document);
}, false); }, false);
if (document) { if (document && document.doctype && document.doctype.name == "html") {
if (document.readyState === "complete") { if (document.readyState === "complete") {
initializeNow(document); initializeNow(document);
} else { } else {
@@ -314,25 +314,28 @@ chrome.runtime.sendMessage({}, function(response) {
} }
} else if (node.children != undefined) { } else if (node.children != undefined) {
for (var i = 0; i < node.children.length; i++) { for (var i = 0; i < node.children.length; i++) {
checkForVideo(node.children[i], const child = node.children[i];
node.children[i].parentNode || parent, checkForVideo(child, child.parentNode || parent, added);
added);
} }
} }
} }
var observer = new MutationObserver(function(mutations) { var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) { // Process the DOM nodes lazily
forEach.call(mutation.addedNodes, function(node) { requestIdleCallback(_ => {
if (typeof node === "function") mutations.forEach(function(mutation) {
return; forEach.call(mutation.addedNodes, function(node) {
checkForVideo(node, node.parentNode || mutation.target, true); if (typeof node === "function")
}) return;
forEach.call(mutation.removedNodes, function(node) { checkForVideo(node, node.parentNode || mutation.target, true);
if (typeof node === "function") });
return; forEach.call(mutation.removedNodes, function(node) {
checkForVideo(node, node.parentNode || mutation.target, false); if (typeof node === "function")
}) return;
}); checkForVideo(node, node.parentNode || mutation.target, false);
});
});
}, {timeout: 1000});
}); });
observer.observe(document, { childList: true, subtree: true }); observer.observe(document, { childList: true, subtree: true });
@@ -349,7 +352,7 @@ chrome.runtime.sendMessage({}, function(response) {
}); });
} }
function runAction(action, document, keyboard) { function runAction(action, document, keyboard, e) {
var videoTags = document.getElementsByTagName('video'); var videoTags = document.getElementsByTagName('video');
videoTags.forEach = Array.prototype.forEach; videoTags.forEach = Array.prototype.forEach;
@@ -366,14 +369,12 @@ chrome.runtime.sendMessage({}, function(response) {
v.currentTime += tc.settings.advanceTime; v.currentTime += tc.settings.advanceTime;
} else if (action === 'faster') { } else if (action === 'faster') {
// Maximum playback speed in Chrome is set to 16: // 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); var s = Math.min( (v.playbackRate < 0.1 ? 0.0 : v.playbackRate) + tc.settings.speedStep, 16);
v.playbackRate = Number(s.toFixed(2)); v.playbackRate = Number(s.toFixed(2));
} else if (action === 'slower') { } 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: // 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); var s = Math.max(v.playbackRate - tc.settings.speedStep, 0.0625);
v.playbackRate = Number(s.toFixed(2)); v.playbackRate = Number(s.toFixed(2));
} else if (action === 'reset') { } else if (action === 'reset') {
@@ -382,7 +383,7 @@ chrome.runtime.sendMessage({}, function(response) {
controller.classList.add('vsc-manual'); controller.classList.add('vsc-manual');
controller.classList.toggle('vsc-hidden'); controller.classList.toggle('vsc-hidden');
} else if (action === 'drag') { } else if (action === 'drag') {
handleDrag(v, controller); handleDrag(v, controller, e);
} else if (action === 'fast') { } else if (action === 'fast') {
resetSpeed(v, tc.settings.fastSpeed); resetSpeed(v, tc.settings.fastSpeed);
} }
@@ -400,17 +401,32 @@ chrome.runtime.sendMessage({}, function(response) {
} }
} }
function handleDrag(video, controller) { function handleDrag(video, controller, e) {
const parentElement = controller.parentElement, const shadowController = controller.querySelector('#controller');
shadowController = controller.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'); video.classList.add('vcs-dragging');
shadowController.classList.add('dragging'); shadowController.classList.add('dragging');
const initialMouseXY = [e.clientX, e.clientY];
const initialControllerXY = [
parseInt(shadowController.style.left),
parseInt(shadowController.style.top)
];
const startDragging = (e) => { const startDragging = (e) => {
let style = shadowController.style; let style = shadowController.style;
style.left = parseInt(style.left) + e.movementX + 'px'; let dx = e.clientX - initialMouseXY[0];
style.top = parseInt(style.top) + e.movementY + 'px'; let dy = e.clientY -initialMouseXY[1];
style.left = (initialControllerXY[0] + dx) + 'px';
style.top = (initialControllerXY[1] + dy) + 'px';
} }
const stopDragging = () => { const stopDragging = () => {

View File

@@ -1,7 +1,7 @@
{ {
"name": "Video Speed Controller", "name": "Video Speed Controller",
"short_name": "videospeed", "short_name": "videospeed",
"version": "0.4.9.4", "version": "0.5.0",
"manifest_version": 2, "manifest_version": 2,
"description": "Speed up, slow down, advance and rewind any HTML5 video with quick shortcuts.", "description": "Speed up, slow down, advance and rewind any HTML5 video with quick shortcuts.",
"homepage_url": "https://github.com/codebicycle/videospeed", "homepage_url": "https://github.com/codebicycle/videospeed",