AbemaTV Shortcut Key Controller

AbemaTVでショートカットキーによる操作を可能にします。キーアサインはYouTube準拠。

目前为 2017-08-10 提交的版本。查看 最新版本

// ==UserScript==
// @name        AbemaTV Shortcut Key Controller
// @namespace   knoa.jp
// @description AbemaTVでショートカットキーによる操作を可能にします。キーアサインはYouTube準拠。
// @include     https://abema.tv/*
// @version     1.0.2
// @grant       none
// ==/UserScript==

// console.log('AbemaTV? => hireMe()');
(function(){
  const SCRIPTNAME = 'ShortcutKeyController';
  const DEBUG = true;
  if(window === top) console.time(SCRIPTNAME);
  const SELECTORS = {
    RIGHTPANEHIDDEN: 'div[class*="v3_wi"][aria-hidden="true"]',
    COMMENTSVG: 'use[*|href="/images/icons/comment.svg#svg-body"]',
    COMMENTTEXTAREA: 'textarea[placeholder="コメントを入力"]',
    OVERLAP: 'main > div > div > div:first-child',
    FULLSCREENONSVG: 'use[*|href="/images/icons/full_screen.svg#svg-body"]',
    FULLSCREENOFFSVG: 'use[*|href="/images/icons/mini_screen.svg#svg-body"]',
    MUTE: 'button[aria-label="音声オンオフ切り替え"]',
    REWIND10SVG: 'use[*|href="/images/icons/rewind_10.svg#svg-body"]',
    ADVANCES10SVG: 'use[*|href="/images/icons/advances_10.svg#svg-body"]',
    PAUSESVG: 'use[*|href="/images/icons/pause.svg#svg-body"]',
    PLAYBACKSVG: 'use[*|href="/images/icons/playback.svg#svg-body"]',
  };
  let core = {
    initialize: function(){
      document.addEventListener('keydown', 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);
        }
      }, true);
    },
    /* リアルタイム */
    realtime: function(e){
      switch(true){
        /* テキスト入力中は反応しない */
        case(document.activeElement.tagName == 'INPUT'):
        case(document.activeElement.tagName == 'TEXTAREA'):
          break;
        /* コメント入力欄フォーカス */
        case(e.key == 'k'):
        case(e.key == ' '):
        case(e.key == 'Enter'):
          /* コメント欄が表示されていなければあらかじめ表示しておく */
          if(q(SELECTORS.RIGHTPANEHIDDEN)) q(SELECTORS.COMMENTSVG).parentNode.parentNode.click();
          q(SELECTORS.COMMENTTEXTAREA).focus();
          return e.preventDefault();
        /* コメント */
        case(e.key == 'c'):
          if(q(SELECTORS.RIGHTPANEHIDDEN)) q(SELECTORS.COMMENTSVG).parentNode.parentNode.click();
          else q(SELECTORS.OVERLAP).click();
          return e.preventDefault();
        /* フルスクリーン */
        case(e.key == 'f'):
          q(SELECTORS[(window.fullScreen) ? 'FULLSCREENOFFSVG' : 'FULLSCREENONSVG']).parentNode.parentNode.click();
          return e.preventDefault();
        /* ミュート */
        case(e.key == 'm'):
          q(SELECTORS.MUTE).click();
          return e.preventDefault();
      }
    },
    /* タイムシフト */
    timeshift: function(e){
      switch(true){
        /* テキスト入力中は反応しない */
        case(document.activeElement.tagName == 'INPUT'):
        case(document.activeElement.tagName == 'TEXTAREA'):
          break;
        /* 再生・停止トグル */
        case(e.key == 'k'):
        case(e.key == ' '):
        case(e.key == 'Enter'):
          q(SELECTORS[(getComputedStyle(q(SELECTORS.PAUSESVG)).cursor === 'pointer') ? 'PAUSESVG' : 'PLAYBACKSVG']).parentNode.parentNode.click();
          return e.preventDefault();
        /* 10秒戻る */
        case(e.key == 'j'):
        case(e.key == 'ArrowLeft'):
          q(SELECTORS.REWIND10SVG).parentNode.parentNode.click();
          return e.preventDefault();
        /* 10秒進む */
        case(e.key == 'l'):
        case(e.key == 'ArrowRight'):
          q(SELECTORS.ADVANCES10SVG).parentNode.parentNode.click();
          return e.preventDefault();
        /* フルスクリーン */
        case(e.key == 'f'):
          q(SELECTORS[(window.fullScreen) ? 'FULLSCREENOFFSVG' : 'FULLSCREENONSVG']).parentNode.parentNode.click();
          return e.preventDefault();
        /* ミュート */
        case(e.key == 'm'):
          q(SELECTORS.MUTE).click();
          return e.preventDefault();
      }
    }
  };
  let q = function(selector){return document.querySelector(selector)};
  let log = (DEBUG) ? console.log.bind(null, SCRIPTNAME + ':') : function(){};
  core.initialize();
  if(window === top) console.timeEnd(SCRIPTNAME);
})();