YouTube トップの「興味なし」「チャンネルをおすすめに表示しない」を爆速押下する Bookmarklet

以前から YouTube の閲覧環境を調整するため、いくつかのブラウザ拡張機能を入れている。

その他、Stylus で次のようなスタイリングを行っている。主に「OutsideBar」の至らないところを無理やり調整している感じ。

@-moz-document url-prefix("https://youtube.com"), url-prefix("https://www.youtube.com") {
  /*! YouTube - Channel Block !*/
  
  /* Block アイコンを大きくする */
  .cb_block_button {
    position: absolute;
    top: 55px;
    left: 5px;
    width: 2.75em;
    background: rgba(255, 0, 0, .5);
  }
  
  /* コントロール部分を常に表示してフォーカスアウトしてもガクガクさせない */
  .ytp-progress-bar-container,
  html[it-always-show-progress-bar="true"] .html5-video-player:not(.it-mini-player).ytp-autohide .ytp-chrome-bottom .ytp-progress-bar-container {
    bottom: 47px !important;
  }
  .ytp-chrome-controls,
  html[it-always-show-progress-bar="true"] .html5-video-player:not(.it-mini-player).ytp-autohide .ytp-chrome-bottom .ytp-chrome-controls {
    opacity: 1 !important;
  }
  
  /* ヘッダの高さを縮める (フルスクリーン時は除く) */
  body:not(.no-scroll) #container.ytd-masthead {
    height: 40px !important;
  }
  /* プレーヤーをヘッダ直後に隙間なく配置する (フルスクリーン時は除く) */
  body:not(.no-scroll) #page-manager.ytd-app {
    margin-top: 40px !important;
  }
  ytd-watch-flexy:not([fullscreen]) #primary.ytd-watch-flexy,
  ytd-watch-flexy:not([fullscreen]) #secondary.ytd-watch-flexy {
    padding-top: 0 !important;
  }
  
  /* ワイド表示時の最小高さをなくす・画面下部に評価ボタンなどが見えるようにしておく */
  ytd-watch-flexy[theater]:not([fullscreen]) #player-theater-container.ytd-watch-flexy {  /* ytd-watch-flexy[fullscreen] #player-theater-container.ytd-watch-flexy */
    min-height: auto !important;
    max-height: 890px !important;
    margin-bottom: 40px !important;
  }
  /* ワイド表示時のコントロール部分を下げた時に表示されるようにする */
  ytd-watch-flexy[theater]:not([fullscreen]) .html5-video-player {
    overflow: visible !important;
    padding-bottom: 0 !important;  /* 余計な隙間を潰しておく */
  }
  /* ↑ の overflow: visible により見えない横スクロールが出てしまうのを防ぐ */
  ytd-watch-flexy[theater]:not([fullscreen]) {
    overflow-x: hidden !important;
  }
  /* ワイド表示時のコントロール部分を下げる */
  ytd-watch-flexy[theater]:not([fullscreen]) .ytp-chrome-bottom {
    bottom: -51px !important;  /* 動画にかぶらないように下部に下ろす */
    background: #000 !important;  /* 背景色を付ける */
  }
  /* ワイド表示時のプレーヤー下の動画タイトル・サイドバー部分の隙間を詰める */
  ytd-watch-flexy[theater]:not([fullscreen]) #above-the-fold,
  ytd-watch-flexy[theater]:not([fullscreen]) #secondary.ytd-watch-flexy {
    margin-top: 11px !important;
  }
}

@-moz-document url("https://youtube.com/feed/subscriptions"), url("https://www.youtube.com/feed/subscriptions"), url-prefix("https://youtube.com/watch"), url-prefix("https://www.youtube.com/watch") {
  /*! YouTube - Feeds Action Menu !*/
  
  /* フィード画面と動画画面 (関連動画) のアクションメニューの余計なやつを消す */
  tp-yt-paper-listbox > ytd-menu-service-item-renderer:nth-child(1),
  tp-yt-paper-listbox > ytd-menu-service-item-renderer:nth-child(2),
  tp-yt-paper-listbox > ytd-menu-service-item-renderer:nth-child(3) {
    display: none !important;
  }
}

@-moz-document url("https://youtube.com/"), url("https://www.youtube.com/") {
  /*! YouTube - Home Action Menu !*/
  
  /* ホーム画面のアクションメニューの余計なやつを消す */
  tp-yt-paper-listbox > ytd-menu-service-item-renderer:nth-child(1):not(:last-child),  /* ミックスリストの場合は表示できるようにする */
  tp-yt-paper-listbox > ytd-menu-service-item-renderer:nth-child(2):not(:last-child),
  tp-yt-paper-listbox > ytd-menu-service-item-renderer:nth-child(3):not(:last-child),
  tp-yt-paper-listbox > ytd-menu-service-item-renderer:nth-child(4):not(:last-child) {
    display: none !important;
  }
}

自分は YouTube のホーム画面で動画をよく漁るのだが、まぁ「未見の面白い動画」というのは中々出てこない。嫌いな傾向の動画はキーワードを指定して「Channel Blocker」を使って非表示にしているのだが、それにしても要らない動画がよく出てくる。

なので動画右下の「…」アイコンを押下して、コンテキストメニューから「興味なし」とか「チャンネルをおすすめに表示しない」とかを選択しているのだが、イチイチココで2クリック発生するのがかったるい。

そこで、「…」アイコンを押した瞬間に「興味なし」か「チャンネルをおすすめに表示しない」を自動クリックしてくれる Bookmarklet を作ってみた。

以下にも載せておくが、圧縮前のコードは以下のとおり。

javascript:((d, q, c, p) => {
  p = d[q]('ytd-popup-container');
  d.body.insertAdjacentHTML('beforeend', '<input type=checkbox id=z accesskey=z style=position:absolute;top:0;right:0;z-index:9999>');
  new MutationObserver(_ => {
    p[q + 'All']('ytd-menu-service-item-renderer').length > 1 && setTimeout(_ =>
      p[q]('tp-yt-iron-dropdown[focused]')?.[q + 'All']('yt-formatted-string').forEach(f =>
        f.textContent != (d[q]('#z').checked ? 'チャンネルをおすすめに表示しない' : '興味なし') || c || (
          c = true,
          setTimeout(_ =>
            c && (f.parentNode.parentNode.click(), c = false)
          , 5)
        )
      )
    , 5)
  }).observe(p, {
    attributes: true,
    subtree: true
  })
})(document, 'querySelector', false);

ytd-popup-container という要素が、コンテキストメニューが格納される要素。なのでこの配下の要素の属性を MutationObserver で監視する。

コンテキストメニューが表示されている時は、配下の tp-yt-iron-dropdown 要素に focused 属性が付き、その中に項目を示す ytd-menu-service-item-renderer 要素が複数配置される。その中には yt-formatted-string 要素があり、この中身に「興味なし」とか「チャンネルをおすすめに表示しない」とかいったテキストが書かれる。

そういう関係なので、コンテキストメニューが表示された時に「興味なし」が書かれた要素をクリックする、といったことをやっている。ただ、1度の操作で MutationObserver が複数回実行されてしまって不具合があったので、期待する要素数が存在するかとか、「自動クリック処理」を行っている最中かどうかを示すフラグ変数 (c) を用意して setTimeout で若干遅延実行させたりしている次第。

んで、「興味なし」をクリックしたいか、「チャンネルをおすすめに表示しない」をクリックしたいかが場合によって変わるので、ページ右上にチェックボックスを配置し、このチェックボックスがチェックされていない時は「興味なし」をクリック、チェック状態の時は「チャンネルをおすすめに表示しない」をクリックするようにしてみた。チェックボックスには accesskey 属性を設定したので、キーボードショートカットでチェックボックスを On・Off しながら、ホーム画面に表示されている気に入らない動画の「…」アイコンを押すだけで、「興味なし」とか「チャンネルをおすすめに表示しない」とかが押下できるようになった。

拙作の @neos21/bookmarkletify もそうだったのだが、いつの間にか uglify-es パッケージは Deprecated になっていて、uglify-js の最新版 v3.16.1 を入れることで、Optional Chaining などを解釈できるようになっていた。