diff --git a/inject.js b/inject.js index 255d811..352cadf 100644 --- a/inject.js +++ b/inject.js @@ -8,8 +8,11 @@ chrome.extension.sendMessage({}, function(response) { this.video = target; this.initializeControls(); - chrome.storage.sync.get('speed', function(storage) { - var speed = storage.speed ? storage.speed : '1.00'; + chrome.storage.sync.get({ + speed: '1.00', + rememberSpeed: false + }, function(storage) { + var speed = storage.rememberSpeed ? storage.speed : '1.00'; target.playbackRate = speed; this.speedIndicator.textContent = speed; }.bind(this)); @@ -92,18 +95,24 @@ chrome.extension.sendMessage({}, function(response) { videoTags.forEach(function(v) { if (!v.paused && !v.classList.contains("vc-cancelled")) { if (action === 'rewind') { - v.playbackRate -= 0.10; - v.currentTime -= 10; - } else if (action === 'faster') { v.playbackRate += 0.10 } - else if (action === 'slower') { v.playbackRate = Math.max(v.playbackRate - 0.10, 0.00) } + v.playbackRate = Math.max(v.playbackRate - speedStep, 0.00); + v.currentTime -= rewindTime; + } else if (action === 'faster') { + v.playbackRate += speedStep } + else if (action === 'slower') { + v.playbackRate = Math.max(v.playbackRate - speedStep, 0.00); } } }); } - document.addEventListener('keydown', function(event) { - if (event.keyCode == 65) { runAction('rewind') } // A - else if (event.keyCode == 68) { runAction('faster') } // D - else if (event.keyCode == 83) { runAction('slower') } // S + document.addEventListener('keypress', function(event) { + + // if lowercase letter pressed, check for uppercase key code + var keyCode = String.fromCharCode(event.keyCode).toUpperCase().charCodeAt(); + + if (keyCode == rewindKeyCode) { runAction('rewind') } + else if (keyCode == fasterKeyCode) { runAction('faster') } + else if (keyCode == slowerKeyCode) { runAction('slower') } return false; }, true); @@ -120,6 +129,23 @@ chrome.extension.sendMessage({}, function(response) { videoTags.forEach(function(video) { var control = new tc.videoController(video); }); + + var speedStep, rewindTime, rewindKeyCode, slowerKeyCode, fasterKeyCode; + + chrome.storage.sync.get({ + speedStep: 0.1, // default 0.10x + rewindTime: 10, // default 10s + rewindKeyCode: 65, // default: A + slowerKeyCode: 83, // default: S + fasterKeyCode: 68 // default: D + }, + function(storage) { + speedStep = Number(storage.speedStep); + rewindTime = Number(storage.rewindTime); + rewindKeyCode = Number(storage.rewindKeyCode); + slowerKeyCode = Number(storage.slowerKeyCode); + fasterKeyCode = Number(storage.fasterKeyCode); + }); } }, 10); }); diff --git a/manifest.json b/manifest.json index 825f091..f58bb91 100755 --- a/manifest.json +++ b/manifest.json @@ -1,6 +1,6 @@ { "name": "HTML5 Video Playback Speed Controller", - "version": "0.1.2", + "version": "0.1.3", "manifest_version": 2, "description": "Lean in and speed up your video learning with handy shortcuts to accelerate, slow-down, and rewind your video via your keyboard.", "homepage_url": "https://github.com/igrigorik/videospeed", @@ -10,6 +10,7 @@ "128": "icons/icon128.png" }, "permissions": [ "activeTab", "storage" ], + "options_page": "options.html", "content_scripts": [{ "all_frames": true, "matches": [ "http://*/*", "https://*/*"], diff --git a/options.css b/options.css new file mode 100644 index 0000000..425bfed --- /dev/null +++ b/options.css @@ -0,0 +1,94 @@ +body { + margin: 0; + padding-left: 15px; + padding-top: 53px; + font-family: sans-serif; + font-size: 12px; + color: rgb(48, 57, 66); +} + +h1, h2, h3 { + font-weight: normal; + line-height: 1; + user-select: none; + cursor: default; +} +h1 { + font-size: 1.5em; + margin: 21px 0 13px; +} +h3 { + font-size: 1.2em; + margin-bottom: 0.8em; + color: black; +} +p { + margin: 0.65em 0; +} + +header { + position: fixed; + top: 0; + left: 15px; + right: 0; + border-bottom: 1px solid #EEE; + background: linear-gradient(white, white 40%, rgba(255, 255, 255, 0.92)); +} +header, section { + min-width: 600px; + max-width: 738px; +} +section { + padding-left: 18px; + margin-top: 8px; + margin-bottom: 24px; +} +section h3 { + margin-left: -18px; +} + +button { + -webkit-appearance: none; + position: relative; + + margin: 0 1px 0 0; + padding: 0 10px; + min-width: 4em; + min-height: 2em; + + background-image: linear-gradient(#EDEDED, #EDEDED 38%, #DEDEDE); + border: 1px solid rgba(0,0,0,0.25); + border-radius: 2px; + outline: none; + box-shadow: 0 1px 0 rgba(0,0,0,0.08), inset 0 1px 2px rgba(255,255,255,0.75); + color: #444; + text-shadow: 0 1px 0 rgb(240,240,240); + font: inherit; + + user-select: none; +} + + +input[type="text"] { + width: 75px; + text-align: center; +} + +.row { + margin: 5px 0px; +} + +label { + display: inline-block; + width: 170px; +} + +label[for=rememberSpeed] { + width: 200px; +} + +#status { + color: #9D9D9D; + display: inline-block; + margin-left: 50px; +} \ No newline at end of file diff --git a/options.html b/options.html new file mode 100644 index 0000000..b42e4a3 --- /dev/null +++ b/options.html @@ -0,0 +1,49 @@ + + + + HTML5 Video Playback Speed Controller Options + + + +
+

HTML5 Video Playback Speed Controller

+
+ +
+

Shortcuts

+
+ + +
+
+ + +
+
+ + +
+
+ +
+

Others

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + + + \ No newline at end of file diff --git a/options.js b/options.js new file mode 100644 index 0000000..51ecf40 --- /dev/null +++ b/options.js @@ -0,0 +1,120 @@ +function recordKeyPress(e) { + var normalizedChar = String.fromCharCode(e.keyCode).toUpperCase(); + e.target.value = normalizedChar; + e.target.keyCode = normalizedChar.charCodeAt(); + + e.preventDefault(); + e.stopPropagation(); +}; + +function inputFilterNumbersOnly(e) { + var char = String.fromCharCode(e.keyCode); + if (!/[\d\.]$/.test(char) || !/^\d+(\.\d*)?$/.test(e.target.value + char)) { + e.preventDefault(); + e.stopPropagation(); + } +}; + +function inputFocus(e) { + e.target.value = ""; +}; + +function inputBlur(e) { + e.target.value = String.fromCharCode(e.target.keyCode).toUpperCase(); +}; + +function updateShortcutInputText(inputId, keyCode) { + document.getElementById(inputId).value = String.fromCharCode(keyCode).toUpperCase(); + document.getElementById(inputId).keyCode = keyCode; +} + +// Saves options to chrome.storage +function save_options() { + + var speedStep = document.getElementById('speedStep').value; + var rewindTime = document.getElementById('rewindTime').value; + var rewindKeyCode = document.getElementById('rewindKeyInput').keyCode; + var slowerKeyCode = document.getElementById('slowerKeyInput').keyCode; + var fasterKeyCode = document.getElementById('fasterKeyInput').keyCode; + var rememberSpeed = document.getElementById('rememberSpeed').checked; + + speedStep = isNaN(speedStep) ? 0.1 : Number(speedStep); + rewindTime = isNaN(rewindTime) ? 10 : Number(rewindTime); + rewindKeyCode = isNaN(rewindKeyCode) ? 65 : rewindKeyCode; + slowerKeyCode = isNaN(slowerKeyCode) ? 83 : slowerKeyCode; + fasterKeyCode = isNaN(fasterKeyCode) ? 68 : fasterKeyCode; + + chrome.storage.sync.set({ + speedStep: speedStep, + rewindTime: rewindTime, + rewindKeyCode: rewindKeyCode, + slowerKeyCode: slowerKeyCode, + fasterKeyCode: fasterKeyCode, + rememberSpeed: rememberSpeed + }, function() { + // Update status to let user know options were saved. + var status = document.getElementById('status'); + status.textContent = 'Options saved'; + setTimeout(function() { + status.textContent = ''; + }, 1000); + }); +} + +// Restores options from chrome.storage +function restore_options() { + chrome.storage.sync.get({ + speedStep: 0.1, + rewindTime: 10, + rewindKeyCode: 65, + slowerKeyCode: 83, + fasterKeyCode: 68, + rememberSpeed: false + }, function(storage) { + document.getElementById('speedStep').value = storage.speedStep.toFixed(2); + document.getElementById('rewindTime').value = storage.rewindTime; + updateShortcutInputText('rewindKeyInput', storage.rewindKeyCode); + updateShortcutInputText('slowerKeyInput', storage.slowerKeyCode); + updateShortcutInputText('fasterKeyInput', storage.fasterKeyCode); + document.getElementById('rememberSpeed').checked = storage.rememberSpeed; + }); +} + +function restore_defaults() { + + chrome.storage.sync.set({ + speedStep: 0.1, + rewindTime: 10, + rewindKeyCode: 65, + slowerKeyCode: 83, + fasterKeyCode: 68, + rememberSpeed: false + }, function() { + restore_options(); + // Update status to let user know options were saved. + var status = document.getElementById('status'); + status.textContent = 'Default options restored'; + setTimeout(function() { + status.textContent = ''; + }, 1000); + }); + +} + +// Event Listeners +document.addEventListener('DOMContentLoaded', restore_options); +document.getElementById('save').addEventListener('click', save_options); +document.getElementById('restore').addEventListener('click', restore_defaults); + +initShortcutInput('rewindKeyInput'); +initShortcutInput('slowerKeyInput'); +initShortcutInput('fasterKeyInput'); + +document.getElementById('rewindTime').addEventListener('keypress', inputFilterNumbersOnly); +document.getElementById('speedStep').addEventListener('keypress', inputFilterNumbersOnly); + +function initShortcutInput(inputId) { + document.getElementById(inputId).addEventListener('focus', inputFocus); + document.getElementById(inputId).addEventListener('blur', inputBlur); + document.getElementById(inputId).addEventListener('keypress', recordKeyPress); +}