Greasy Fork is available in English.
AbemaTVでショートカットキーによる操作を可能にします。キーアサインはYouTube準拠。
当前为
// ==UserScript==
// @name AbemaTV Shortcut Key Controller
// @namespace knoa.jp
// @description AbemaTVでショートカットキーによる操作を可能にします。キーアサインはYouTube準拠。
// @include https://abema.tv/*
// @version 2.0.4
// @grant none
// ==/UserScript==
/*
共通:
[F]: フルスクリーン
[M]: ミュート
[マウスホイール]: 音量調整
リアルタイム放送:
[K], [Space], [Enter]: コメント入力欄フォーカス
[C]: コメント表示
タイムシフト放送:
[K], [Space], [Enter]: 再生・停止
[J], [←]: 10秒戻る
[L], [→]: 10秒進む
*/
// console.log('AbemaTV? => hireMe()');
(function(){
const SCRIPTNAME = 'ShortcutKeyController';
const DEBUG = false;/*
[update]
バグ修正
*/
if(window === top) console.time(SCRIPTNAME);
let site = {
elements: {
/* 共通 */
fullscreenButton: function(){return $('use[*|href*="_screen.svg"]'/*タイムシフトのbuttonにaria-labelがないので*/).parentNode.parentNode},
volumeSlider: function(){return $('button[aria-label="音声オンオフ切り替え"]').previousSibling.firstElementChild.firstElementChild},
muteButton: function(){return $('button[aria-label="音声オンオフ切り替え"]')},
/* リアルタイム */
commentButton: function(){return $('use[*|href^="/images/icons/comment.svg"]').parentNode.parentNode},
commentTextarea: function(){return $('textarea[placeholder="コメントを入力"]')},
footer: function(){return $('button[aria-label^="フルスクリーン"]').parentNode.parentNode},
closer: function(){return $('form:not([role="search"])').parentNode.parentNode.nextElementSibling;},
/* タイムシフト */
playButton: function(){return $((getComputedStyle($('use[*|href^="/images/icons/pause.svg"]')).cursor === 'pointer') ? 'use[*|href^="/images/icons/pause.svg"]' : 'use[*|href^="/images/icons/playback.svg"]').parentNode.parentNode},
rewindButton: function(){return $('use[*|href^="/images/icons/rewind_10.svg"]').parentNode.parentNode},
advancesButton: function(){return $('use[*|href^="/images/icons/advances_10.svg"]').parentNode.parentNode},
},
isCommentPaneHidden: function(){
let form = $('form:not([role="search"])');
return (form) ? (form.parentNode.parentNode.getAttribute('aria-hidden') === 'true') : false;
},
modifyVolume: function(e){
let slider = site.elements.volumeSlider(), rect = slider.getBoundingClientRect();
let volume = parseInt(slider.firstElementChild.style.height) / rect.height;
switch(e.deltaMode){
case(WheelEvent.DOM_DELTA_PIXEL):
volume += -(e.deltaY/1000);
break;
case(WheelEvent.DOM_DELTA_LINE):
default:
volume += (0 < e.deltaY) ? -(1/10) : (1/10);
break;
}
slider.dispatchEvent(new MouseEvent('mousedown', {
clientX: rect.x + (rect.width/2),
clientY: rect.y + (rect.height * (1 - volume)),
bubbles: true,
}));
},
assign: function(e){
switch(true){
case(location.href.startsWith('https://abema.tv/now-on-air/')):
return core.realtime(e);
case(location.href.startsWith('https://abema.tv/channels/')):
case(location.href.startsWith('https://abema.tv/video/watch/')):
return core.timeshift(e);
}
},
};
let core = {
initialize: function(){
window.addEventListener('wheel', site.assign, true);
window.addEventListener('keydown', site.assign, true);
},
/* リアルタイム */
realtime: function(e){
switch(true){
/* 音量 */
case(e.type === 'wheel'):
/* あらゆる場所でのイベントを拾ってwindow.addEventListenerで一括処理する代償をここで支払う */
for(let target = e.target; target; target = target.parentNode){
if([site.elements.closer(), site.elements.footer()].includes(target)){
site.modifyVolume(e);
return e.preventDefault();
}
}
/* テキスト入力中は反応しない */
case(['input', 'textarea', 'button'].includes(document.activeElement.localName)):
break;
/* Alt/Shift/Ctrl/Metaキーが押されていたら反応しない */
case(e.altKey || e.shiftKey || e.ctrlKey || e.metaKey):
break;
/* コメント入力欄フォーカス */
case(e.key == 'k'):
case(e.key == ' '):
case(e.key == 'Enter'):
/* コメント欄が表示されていなければあらかじめ表示しておく */
if(site.isCommentPaneHidden()) site.elements.commentButton().click();
site.elements.commentTextarea().focus();
return e.preventDefault();
/* コメント */
case(e.key == 'c'):
if(site.isCommentPaneHidden()) site.elements.commentButton().click();
else site.elements.closer().click();
return e.preventDefault();
/* フルスクリーン */
case(e.key == 'f'):
site.elements.fullscreenButton().click();
return e.preventDefault();
/* ミュート */
case(e.key == 'm'):
site.elements.muteButton().click();
return e.preventDefault();
}
},
/* タイムシフト */
timeshift: function(e){
switch(true){
/* 音量 */
case(e.type === 'wheel'):
site.modifyVolume(e);
return e.preventDefault();
/* テキスト入力中は反応しない */
case(['input', 'textarea', 'button'].includes(document.activeElement.localName)):
break;
/* Alt/Shift/Ctrl/Metaキーが押されていたら反応しない */
case(e.altKey || e.shiftKey || e.ctrlKey || e.metaKey):
break;
/* 再生・停止トグル */
case(e.key == 'k'):
case(e.key == ' '):
case(e.key == 'Enter'):
site.elements.playButton().click();
return e.preventDefault();
/* 10秒戻る */
case(e.key == 'j'):
case(e.key == 'ArrowLeft'):
site.elements.rewindButton().click();
return e.preventDefault();
/* 10秒進む */
case(e.key == 'l'):
case(e.key == 'ArrowRight'):
site.elements.advancesButton().click();
return e.preventDefault();
/* フルスクリーン */
case(e.key == 'f'):
site.elements.fullscreenButton().click();
return e.preventDefault();
/* ミュート */
case(e.key == 'm'):
site.elements.muteButton().click();
return e.preventDefault();
}
},
};
let $ = function(s){return document.querySelector(s)};
let log = (DEBUG) ? console.log.bind(null, SCRIPTNAME + ':') : function(){};
core.initialize();
if(window === top) console.timeEnd(SCRIPTNAME);
})();