diff --git a/inject.js b/inject.js
index 89f27f6..5aab37e 100644
--- a/inject.js
+++ b/inject.js
@@ -2,20 +2,31 @@ chrome.runtime.sendMessage({}, function(response) {
var tc = {
settings: {
speed: 1.0, // default 1x
- resetSpeed: 1.0, // default 1x
- speedStep: 0.1, // default 0.1x
- fastSpeed: 1.8, // default 1.8x
- rewindTime: 10, // default 10s
- advanceTime: 10, // default 10s
- resetKeyCode: 82, // default: R
- slowerKeyCode: 83, // default: S
- fasterKeyCode: 68, // default: D
- rewindKeyCode: 90, // default: Z
- advanceKeyCode: 88, // default: X
+
+ /**
+ * these are not used and deprecated, will be removed in next update
+ * but should be stay there because chrome.storage.sync.get needs them
+ */
+ resetSpeed: 1.0, // default 1.0
+ speedStep: null, // default 0.1x just for buttons
+ fastSpeed: null, // default 1.8x
+ rewindTime: null, // default 10s just for buttons
+ advanceTime: null, // default 10s just for buttons
+ resetKeyCode: null, // default: R
+ slowerKeyCode: null, // default: S
+ fasterKeyCode: null, // default: D
+ rewindKeyCode: null, // default: Z
+ advanceKeyCode: null, // default: X
+ fastKeyCode: null, // default: G
+ /**
+ * these(above) are not used and deprecated, will be removed in next update
+ * but should be stay there because chrome.storage.sync.get needs them.
+ */
+
displayKeyCode: 86, // default: V
- fastKeyCode: 71, // default: G
rememberSpeed: false, // default: false
startHidden: false, // default: false
+ keyBindings: [],
blacklist: `
www.instagram.com
twitter.com
@@ -25,20 +36,66 @@ chrome.runtime.sendMessage({}, function(response) {
}
};
- chrome.storage.sync.get(tc.settings, function(storage) {
+ chrome.storage.sync.get(tc.settings, function (storage) {
+ tc.settings.keyBindings = storage.keyBindings; // Array
+ if (storage.keyBindings.length == 0) // if first initialization of 0.5.3
+ {
+ // UPDATE
+ tc.settings.keyBindings.push({
+ action: "slower",
+ key: Number(storage.slowerKeyCode) || 83,
+ value: Number(storage.speedStep) || 0.1,
+ force: false,
+ predefined: true
+ }); // default S
+ tc.settings.keyBindings.push({
+ action: "faster",
+ key: Number(storage.fasterKeyCode) || 68,
+ value: Number(storage.speedStep) || 0.1,
+ force: false,
+ predefined: true
+ }); // default: D
+ tc.settings.keyBindings.push({
+ action: "rewind",
+ key: Number(storage.rewindKeyCode) || 90,
+ value: Number(storage.rewindTime) || 10,
+ force: false,
+ predefined: true
+ }); // default: Z
+ tc.settings.keyBindings.push({
+ action: "advance",
+ key: Number(storage.advanceKeyCode) || 88,
+ value: Number(storage.advanceTime) || 10,
+ force: false,
+ predefined: true
+ }); // default: X
+ tc.settings.keyBindings.push({
+ action: "reset",
+ key: Number(storage.resetKeyCode) || 82,
+ value: 1.0,
+ force: false,
+ predefined: true
+ }); // default: R
+ tc.settings.keyBindings.push({
+ action: "fast",
+ key: Number(storage.fastKeyCode) || 71,
+ value: Number(storage.fastSpeed) || 1.8,
+ force: false,
+ predefined: true
+ }); // default: G
+ tc.settings.version = "0.5.3";
+
+ chrome.storage.sync.set({
+ keyBindings: tc.settings.keyBindings,
+ version: tc.settings.version,
+ displayKeyCode: tc.settings.displayKeyCode,
+ rememberSpeed: tc.settings.rememberSpeed,
+ startHidden: tc.settings.startHidden,
+ blacklist: tc.settings.blacklist.replace(/^\s+|\s+$/gm, '')
+ });
+ }
tc.settings.speed = Number(storage.speed);
- tc.settings.resetSpeed = Number(storage.resetSpeed);
- tc.settings.speedStep = Number(storage.speedStep);
- tc.settings.fastSpeed = Number(storage.fastSpeed);
- tc.settings.rewindTime = Number(storage.rewindTime);
- tc.settings.advanceTime = Number(storage.advanceTime);
- tc.settings.resetKeyCode = Number(storage.resetKeyCode);
- tc.settings.rewindKeyCode = Number(storage.rewindKeyCode);
- tc.settings.slowerKeyCode = Number(storage.slowerKeyCode);
- tc.settings.fasterKeyCode = Number(storage.fasterKeyCode);
- tc.settings.fastKeyCode = Number(storage.fastKeyCode);
tc.settings.displayKeyCode = Number(storage.displayKeyCode);
- tc.settings.advanceKeyCode = Number(storage.advanceKeyCode);
tc.settings.rememberSpeed = Boolean(storage.rememberSpeed);
tc.settings.startHidden = Boolean(storage.startHidden);
tc.settings.blacklist = String(storage.blacklist);
@@ -48,6 +105,18 @@ chrome.runtime.sendMessage({}, function(response) {
var forEach = Array.prototype.forEach;
+ function getKeyBindings(action, what = "value") {
+ try {
+ return tc.settings.keyBindings.find(item => item.action === action)[what];
+ } catch (e) {
+ return false;
+ }
+ }
+
+ function setKeyBindings(action, value) {
+ tc.settings.keyBindings.find(item => item.action === action)["value"] = value;
+ }
+
function defineVideoController() {
tc.videoController = function(target, parent) {
if (target.dataset['vscid']) {
@@ -60,7 +129,7 @@ chrome.runtime.sendMessage({}, function(response) {
this.id = Math.random().toString(36).substr(2, 9);
if (!tc.settings.rememberSpeed) {
tc.settings.speed = 1.0;
- tc.settings.resetSpeed = tc.settings.fastSpeed;
+ setKeyBindings("reset", getKeyBindings("fast")); // resetSpeed = fastSpeed
}
this.initializeControls();
@@ -130,7 +199,7 @@ chrome.runtime.sendMessage({}, function(response) {
forEach.call(shadow.querySelectorAll('button'), function(button) {
button.onclick = (e) => {
- runAction(e.target.dataset['action'], document, false, e);
+ runAction(e.target.dataset['action'], document, getKeyBindings(e.target.dataset['action']), e);
}
});
@@ -225,7 +294,7 @@ chrome.runtime.sendMessage({}, function(response) {
docs.push(window.top.document);
} catch (e) {
}
-
+
docs.forEach(function(doc) {
doc.addEventListener('keydown', function(event) {
var keyCode = event.keyCode;
@@ -242,28 +311,23 @@ chrome.runtime.sendMessage({}, function(response) {
}
// Ignore keydown event if typing in an input box
- if ((document.activeElement.nodeName === 'INPUT'
- && document.activeElement.getAttribute('type') === 'text')
+ if (document.activeElement.nodeName === 'INPUT'
|| document.activeElement.nodeName === 'TEXTAREA'
|| document.activeElement.isContentEditable) {
return false;
}
- if (keyCode == tc.settings.rewindKeyCode) {
- runAction('rewind', document, true)
- } else if (keyCode == tc.settings.advanceKeyCode) {
- runAction('advance', document, true)
- } else if (keyCode == tc.settings.fasterKeyCode) {
- runAction('faster', document, true)
- } else if (keyCode == tc.settings.slowerKeyCode) {
- runAction('slower', document, true)
- } else if (keyCode == tc.settings.resetKeyCode) {
- runAction('reset', document, true)
- } else if (keyCode == tc.settings.displayKeyCode) {
+ if (keyCode == tc.settings.displayKeyCode) {
runAction('display', document, true)
- } else if (keyCode == tc.settings.fastKeyCode) {
- runAction('fast', document, true);
}
+ var item = tc.settings.keyBindings.find(item => item.key === keyCode);
+ if (item) {
+ runAction(item.action, document, item.value);
+ if (item.force === "true") {// disable websites key bindings
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
return false;
}, true);
@@ -324,7 +388,7 @@ chrome.runtime.sendMessage({}, function(response) {
});
}
- function runAction(action, document, keyboard, e) {
+ function runAction(action, document, value, e) {
var videoTags = document.getElementsByTagName('video');
videoTags.forEach = Array.prototype.forEach;
@@ -336,18 +400,18 @@ chrome.runtime.sendMessage({}, function(response) {
if (!v.classList.contains('vsc-cancelled')) {
if (action === 'rewind') {
- v.currentTime -= tc.settings.rewindTime;
+ v.currentTime -= value;
} else if (action === 'advance') {
- v.currentTime += tc.settings.advanceTime;
+ v.currentTime += value;
} else if (action === 'faster') {
// Maximum playback speed in Chrome is set to 16:
// 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) + value, 16);
v.playbackRate = Number(s.toFixed(2));
} else if (action === 'slower') {
// Video min rate is 0.0625:
// 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.07);
+ var s = Math.max(v.playbackRate - value, 0.07);
v.playbackRate = Number(s.toFixed(2));
} else if (action === 'reset') {
resetSpeed(v, 1.0);
@@ -357,33 +421,61 @@ chrome.runtime.sendMessage({}, function(response) {
} else if (action === 'drag') {
handleDrag(v, controller, e);
} else if (action === 'fast') {
- resetSpeed(v, tc.settings.fastSpeed);
+ resetSpeed(v, value);
+ } else if (action === 'pause') {
+ pauseSpeed(v, value);
+ } else if (action === 'muted') {
+ muted(v, value);
}
}
});
}
+ function pauseSpeed(v, target) {
+ // not working as expected in youtube for now
+ if (v.playbackRate === target) {
+ v.play()
+ }
+ resetSpeed(v, target)
+ }
+
function resetSpeed(v, target) {
if (v.playbackRate === target) {
- if(v.playbackRate === tc.settings.resetSpeed)
- {
+ if (v.playbackRate === getKeyBindings("reset")) { // resetSpeed
if (target !== 1.0) {
v.playbackRate = 1.0;
} else {
- v.playbackRate = tc.settings.fastSpeed;
+ v.playbackRate = getKeyBindings("fast"); // fastSpeed
}
}
else
{
- v.playbackRate = tc.settings.resetSpeed;
+ v.playbackRate = getKeyBindings("reset"); // resetSpeed
}
} else {
- tc.settings.resetSpeed = v.playbackRate;
- chrome.storage.sync.set({'resetSpeed': v.playbackRate});
+ setKeyBindings("reset", v.playbackRate);// resetSpeed
+ // chrome.storage.sync.set({'resetSpeed': v.playbackRate});
v.playbackRate = target;
}
}
+ function muted(v, value) {
+ v.muted = v.muted !== true; //reverse muted status
+ /* this can be used if someone wants just mute button
+ switch (value) {
+ case 2:
+ v.muted = false;
+ break;
+ case 1:
+ v.muted = true;
+ break;
+ default:
+ v.muted = v.muted !== true;
+ break;
+ }
+ */
+ }
+
function handleDrag(video, controller, e) {
const shadowController = controller.shadowRoot.querySelector('#controller');
diff --git a/manifest.json b/manifest.json
index 22948d8..ad5de12 100755
--- a/manifest.json
+++ b/manifest.json
@@ -1,7 +1,7 @@
{
"name": "Video Speed Controller",
"short_name": "videospeed",
- "version": "0.5.2",
+ "version": "0.5.3",
"manifest_version": 2,
"description": "Speed up, slow down, advance and rewind any HTML5 video with quick shortcuts.",
"homepage_url": "https://github.com/igrigorik/videospeed",
diff --git a/options.css b/options.css
index dd72980..22ad04e 100644
--- a/options.css
+++ b/options.css
@@ -84,10 +84,6 @@ label {
vertical-align: top;
}
-label[for=rememberSpeed] {
- width: 200px;
-}
-
#status {
color: #9D9D9D;
display: inline-block;
@@ -97,3 +93,11 @@ label[for=rememberSpeed] {
#faq {
margin-top: 2em;
}
+
+select {
+ width: 170px;
+}
+
+.customForce {
+ display: none;
+}
\ No newline at end of file
diff --git a/options.html b/options.html
index 5c73e73..1b3c0eb 100644
--- a/options.html
+++ b/options.html
@@ -10,59 +10,81 @@
Video Speed Controller
-
+
Other
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
@@ -75,7 +97,8 @@
-
+
+
diff --git a/options.js b/options.js
index c1136e0..165b945 100644
--- a/options.js
+++ b/options.js
@@ -1,32 +1,35 @@
var tcDefaults = {
- speed: 1.0, // default 1x
- speedStep: 0.1, // default 0.1x
- rewindTime: 10, // default 10s
- advanceTime: 10, // default 10s
- fastSpeed: 1.8, // default 1.8x
- resetKeyCode: 82, // default: R
- slowerKeyCode: 83, // default: S
- fasterKeyCode: 68, // default: D
- fastKeyCode: 71, // default: G
- rewindKeyCode: 90, // default: Z
- advanceKeyCode: 88, // default: X
+ speed: 1.0, // default:
displayKeyCode: 86, // default: V
rememberSpeed: false, // default: false
startHidden: false, // default: false
+ keyBindings: [
+ {action: "slower", key: 83, value: 0.1, force: false, predefined: true}, // S
+ {action: "faster", key: 68, value: 0.1, force: false, predefined: true}, // D
+ {action: "rewind", key: 90, value: 10, force: false, predefined: true}, // Z
+ {action: "advance", key: 88, value: 10, force: false, predefined: true}, // X
+ {action: "reset", key: 82, value: 1, force: false, predefined: true}, // R
+ {action: "fast", key: 71, value: 1.8, force: false, predefined: true} // G
+ ],
blacklist: `
www.instagram.com
twitter.com
vine.co
imgur.com
- `.replace(/^\s+|\s+$/gm,'')
+ `.replace(/^\s+|\s+$/gm, '')
};
+var keyBindings = [];
+
var keyCodeAliases = {
- 32: 'Space',
- 96: 'Num 0',
- 97: 'Num 1',
- 98: 'Num 2',
- 99: 'Num 3',
+ 0: 'null',
+ null: 'null',
+ undefined: 'null',
+ 32: 'Space',
+ 96: 'Num 0',
+ 97: 'Num 1',
+ 98: 'Num 2',
+ 99: 'Num 3',
100: 'Num 4',
101: 'Num 5',
102: 'Num 6',
@@ -64,6 +67,9 @@ function recordKeyPress(e) {
e.stopPropagation();
} else if (e.keyCode === 8) { // Clear input when backspace pressed
e.target.value = '';
+ } else if (e.keyCode === 27) { // When esc clicked, clear input
+ e.target.value = 'null';
+ e.target.keyCode = null;
}
};
@@ -88,50 +94,64 @@ function updateShortcutInputText(inputId, keyCode) {
document.getElementById(inputId).keyCode = keyCode;
}
+function updateCustomShortcutInputText(inputItem, keyCode) {
+ inputItem.value = keyCodeAliases[keyCode] || String.fromCharCode(keyCode);
+ inputItem.keyCode = keyCode;
+}
+
+function add_shortcut() {
+ var html = `
+
+
+
+
`;
+ var div = document.createElement('div');
+ div.setAttribute('class', 'row customs');
+ div.innerHTML = html;
+ var customs_element = document.getElementById("customs");
+ customs_element.insertBefore(div, customs_element.children[customs_element.childElementCount - 1]);
+}
+
+function createKeyBindings(item) {
+ const action = item.querySelector(".customDo").value;
+ const key = item.querySelector(".customKey").keyCode;
+ const value = Number(item.querySelector(".customValue").value);
+ const force = item.querySelector(".customForce").value;
+ const predefined = !!item.id;//item.id ? true : false;
+
+ keyBindings.push({action: action, key: key, value: value, force: force, predefined: predefined});
+}
+
// Saves options to chrome.storage
function save_options() {
+ keyBindings = [];
+ Array.from(document.querySelectorAll(".customs")).forEach(item => createKeyBindings(item)); // Remove added shortcuts
- var speedStep = document.getElementById('speedStep').value;
- var rewindTime = document.getElementById('rewindTime').value;
- var advanceTime = document.getElementById('advanceTime').value;
- var fastSpeed = document.getElementById('fastSpeed').value;
- var resetKeyCode = document.getElementById('resetKeyInput').keyCode;
- var rewindKeyCode = document.getElementById('rewindKeyInput').keyCode;
- var advanceKeyCode = document.getElementById('advanceKeyInput').keyCode;
- var slowerKeyCode = document.getElementById('slowerKeyInput').keyCode;
- var fasterKeyCode = document.getElementById('fasterKeyInput').keyCode;
- var fastKeyCode = document.getElementById('fastKeyInput').keyCode;
var displayKeyCode = document.getElementById('displayKeyInput').keyCode;
var rememberSpeed = document.getElementById('rememberSpeed').checked;
var startHidden = document.getElementById('startHidden').checked;
var blacklist = document.getElementById('blacklist').value;
- speedStep = isNaN(speedStep) ? tcDefaults.speedStep : Number(speedStep);
- rewindTime = isNaN(rewindTime) ? tcDefaults.rewindTime : Number(rewindTime);
- advanceTime = isNaN(advanceTime) ? tcDefaults.advanceTime : Number(advanceTime);
- fastSpeed = isNaN(fastSpeed) ? tcDefaults.fastSpeed : Number(fastSpeed);
- resetKeyCode = isNaN(resetKeyCode) ? tcDefaults.resetKeyCode : resetKeyCode;
- rewindKeyCode = isNaN(rewindKeyCode) ? tcDefaults.rewindKeyCode : rewindKeyCode;
- advanceKeyCode = isNaN(advanceKeyCode) ? tcDefaults.advanceKeyCode : advanceKeyCode;
- slowerKeyCode = isNaN(slowerKeyCode) ? tcDefaults.slowerKeyCode : slowerKeyCode;
- fasterKeyCode = isNaN(fasterKeyCode) ? tcDefaults.fasterKeyCode : fasterKeyCode;
- fastKeyCode = isNaN(fastKeyCode) ? tcDefaults.fastKeyCode : fastKeyCode;
displayKeyCode = isNaN(displayKeyCode) ? tcDefaults.displayKeyCode : displayKeyCode;
+ chrome.storage.sync.remove(["resetSpeed", "speedStep", "fastSpeed", "rewindTime", "advanceTime", "resetKeyCode", "slowerKeyCode", "fasterKeyCode", "rewindKeyCode", "advanceKeyCode", "fastKeyCode"]);
chrome.storage.sync.set({
- speedStep: speedStep,
- rewindTime: rewindTime,
- advanceTime: advanceTime,
- fastSpeed: fastSpeed,
- resetKeyCode: resetKeyCode,
- rewindKeyCode: rewindKeyCode,
- advanceKeyCode: advanceKeyCode,
- slowerKeyCode: slowerKeyCode,
- fasterKeyCode: fasterKeyCode,
- fastKeyCode: fastKeyCode,
displayKeyCode: displayKeyCode,
rememberSpeed: rememberSpeed,
startHidden: startHidden,
+ keyBindings: keyBindings,
blacklist: blacklist.replace(/^\s+|\s+$/gm,'')
}, function() {
// Update status to let user know options were saved.
@@ -146,26 +166,41 @@ function save_options() {
// Restores options from chrome.storage
function restore_options() {
chrome.storage.sync.get(tcDefaults, function(storage) {
- document.getElementById('speedStep').value = storage.speedStep.toFixed(2);
- document.getElementById('rewindTime').value = storage.rewindTime;
- document.getElementById('advanceTime').value = storage.advanceTime;
- document.getElementById('fastSpeed').value = storage.fastSpeed;
- updateShortcutInputText('resetKeyInput', storage.resetKeyCode);
- updateShortcutInputText('rewindKeyInput', storage.rewindKeyCode);
- updateShortcutInputText('advanceKeyInput', storage.advanceKeyCode);
- updateShortcutInputText('slowerKeyInput', storage.slowerKeyCode);
- updateShortcutInputText('fasterKeyInput', storage.fasterKeyCode);
- updateShortcutInputText('fastKeyInput', storage.fastKeyCode);
updateShortcutInputText('displayKeyInput', storage.displayKeyCode);
document.getElementById('rememberSpeed').checked = storage.rememberSpeed;
document.getElementById('startHidden').checked = storage.startHidden;
document.getElementById('blacklist').value = storage.blacklist;
+
+ for (let i in storage.keyBindings) {
+ var item = storage.keyBindings[i];
+ if (item.predefined) {
+ //do predefined ones because their value needed for overlay
+ // document.querySelector("#" + item["action"] + " .customDo").value = item["action"];
+ updateCustomShortcutInputText(document.querySelector("#" + item["action"] + " .customKey"), item["key"]);
+ document.querySelector("#" + item["action"] + " .customValue").value = item["value"];
+ document.querySelector("#" + item["action"] + " .customForce").value = item["force"];
+ }
+ else {
+ // new ones
+ add_shortcut();
+ const dom = document.querySelector(".customs:last-of-type")
+ dom.querySelector(".customDo").value = item["action"];
+
+ if (item["action"] === "pause" || item["action"] === "muted")
+ dom.querySelector(".customValue").disabled = true;
+
+ updateCustomShortcutInputText(dom.querySelector(".customKey"), item["key"]);
+ dom.querySelector(".customValue").value = item["value"];
+ dom.querySelector(".customForce").value = item["force"];
+ }
+ }
});
}
function restore_defaults() {
chrome.storage.sync.set(tcDefaults, function() {
restore_options();
+ document.querySelectorAll(".removeParent").forEach(button => button.click()); // Remove added shortcuts
// Update status to let user know options were saved.
var status = document.getElementById('status');
status.textContent = 'Default options restored';
@@ -175,6 +210,10 @@ function restore_defaults() {
});
}
+function show_experimental() {
+ document.querySelectorAll(".customForce").forEach(item => item.style.display = 'inline-block');
+}
+
function initShortcutInput(inputId) {
document.getElementById(inputId).addEventListener('focus', inputFocus);
document.getElementById(inputId).addEventListener('blur', inputBlur);
@@ -185,18 +224,47 @@ document.addEventListener('DOMContentLoaded', function () {
restore_options();
document.getElementById('save').addEventListener('click', save_options);
+ document.getElementById('add').addEventListener('click', add_shortcut);
document.getElementById('restore').addEventListener('click', restore_defaults);
+ document.getElementById('experimental').addEventListener('click', show_experimental);
- initShortcutInput('resetKeyInput');
- initShortcutInput('rewindKeyInput');
- initShortcutInput('advanceKeyInput');
- initShortcutInput('slowerKeyInput');
- initShortcutInput('fasterKeyInput');
- initShortcutInput('fastKeyInput');
initShortcutInput('displayKeyInput');
- document.getElementById('rewindTime').addEventListener('keypress', inputFilterNumbersOnly);
- document.getElementById('advanceTime').addEventListener('keypress', inputFilterNumbersOnly);
- document.getElementById('speedStep').addEventListener('keypress', inputFilterNumbersOnly);
- document.getElementById('fastSpeed').addEventListener('keypress', inputFilterNumbersOnly);
+ function eventCaller(event, className, funcName) {
+ if (!event.target.classList.contains(className)) {
+ return
+ }
+ funcName(event);
+ }
+
+ document.addEventListener('keypress', (event) => {
+ eventCaller(event, "customValue", inputFilterNumbersOnly)
+ });
+ document.addEventListener('focus', (event) => {
+ eventCaller(event, "customKey", inputFocus)
+ });
+ document.addEventListener('blur', (event) => {
+ eventCaller(event, "customKey", inputBlur)
+ });
+ document.addEventListener('keydown', (event) => {
+ eventCaller(event, "customKey", recordKeyPress)
+ });
+ document.addEventListener('click', (event) => {
+ eventCaller(event, "removeParent", function () {
+ event.target.parentNode.remove()
+ })
+ });
+ document.addEventListener('change', (event) => {
+ eventCaller(event, "customDo", function () {
+ switch (event.target.value) {
+ case "muted":
+ case "pause":
+ event.target.nextElementSibling.nextElementSibling.disabled = true;
+ event.target.nextElementSibling.nextElementSibling.value = 0;
+ break;
+ default:
+ event.target.nextElementSibling.nextElementSibling.disabled = false;
+ }
+ })
+ });
})