LoginSignup
13
13

More than 3 years have passed since last update.

GitHubのリンクが同じ画面で開かれるのがしんどかったのでChromeの拡張機能作った

Posted at

久々のQiita投稿🙌
普段はその辺でエンジニアやってる物です。

個人で使うめちゃくちゃニッチな物を作ったので、せっかくなので記事にしてみました。
そしてここから下、「cmd + クリックでええやん」禁止です🙅‍♂️
それすらめんどくさかったので作った所存です。

何を作ったの?

GitHub上でリンクをクリックした時に遷移先が同じ画面で開かれるのがしんどかったのでChromeの拡張機能を作った話です。
スクリーンショット 2020-09-21 11.19.17.png

作ったものはこちら。
Chromeウェブストアに公開しているので、よかったらダウンロードして使ってみてください。

ちなみに、2020年9月現在のGitHub上のクラスやIDを利用しているので、GitHub上のHTML構造が変更された場合突然動かなくなることも考えられます。
メンテを続けるかどうかはまだ決めてません。

GitHubのしんどさとは

コードレビューをGitHub上で行う時に、PR画面のConversation内にコミットハッシュを書くと自動でリンクになってくれる便利機能があります。
こんな感じですね。

スクリーンショット 2020-09-15 16.56.58.png

マウスオーバーでコミットログとかみられるんですけど、見たいのはそこじゃない、
そのcommitでどのファイルをどうやって修正しているかなんだ。

あとこんな時。
こんなものに他の方に協力仰ぐのも申し訳なかったので以下全部自演コメントです🙇‍♂️

スクリーンショット 2020-09-21 11.12.59.png

スクリーンショット 2020-09-21 11.13.07.png

こんなやりとり数多くあったのでGitHubユーザの方ならきっと想像できるはず。

レビュアーとしては、
「お、修正してくれたんだ〜〜修正内容どんな感じかな〜〜〜〜」って
コミットログのリンクを押して確認しようとすると、どういうわけか同じタブで画面遷移します

もちろん、戻るボタンで戻っても入力したコメントとかは消えないですよ?

でも普通に考えると、別タブで開いて修正履歴じっくり見たい時のが多く無いですか?

あと、他にもPRの概要を読みながらおもむろにFiles changedタブとか押してPR全体のファイル変更履歴とか見たくないですか?

そんな要望に応えることができるChrome拡張を作りました。
その名もgithub-target-blankです。

工夫したところ

アプローチとしてまず考えたのが、
別タブで開きたいa要素に対して target='blank'を動的に付与する
というやり方。
(rel='no-oppener no-referrer'も一緒に)

GitHubのページの特定のa要素のみtarget='blank'を付与するだけなので、そこまで大変では無いやり方ですね。

ただこのやり方だと、開かれたページがアクティブな状態になります。
そう、PRのConversationを見ているのにリンクを押すと別のタブがアクティブになってしまうわけですね。

違う、違うんだ。
僕が欲しいのはGoogle Chromeで cmd + クリックでリンクを押した時のバックグラウンドでタブが開かれるあの動きなんだ。

というわけでこのアプローチは断念。
別のアプローチをなんか無いかなーと探していたところ、こんなメソッドを発見。

MouseEvent インターフェイスは、ポインティングデバイス (マウスなど) によるユーザの対話によって発生したイベントを表します。
このインターフェイスを使用する一般的なイベントとして click, dblclick, mouseup, mousedown があります。

ふむふむ。あれこれなんか使えるくね?
っていうか、擬似的にa要素作って、MouseEventで擬似a要素をDispatchしちゃえばいいんじゃね?

って思って探したらありました。さすがはStackOverFlow。
https://stackoverflow.com/questions/10812628/open-a-new-tab-in-the-background

注意
ここで紹介されてるinitMouseEventはDeprecatedのメソッドのため、利用非推奨です。
代替機能として、MouseEventが推奨されてます。

おーできそう、ってことでコード書いてみました。
メインの部分はこんな感じ。
ChromeのExtensionにはjQueryも使えるっぽいけど、サイト内でバージョン競合とか起こすと嫌なので久々にVanillaJS。

hoge.addEventListener("click", function (e) {
  const evt = new MouseEvent("click", {
    metaKey: true, // Macだとcmdキーが metaKeyとして判定される学び
    ctrlKey: true, // Windowsだとバックグラウンドで開く時に使うのがctrlキーなのでこちらも設定
  });
  const a = document.createElement("a");
  a.href = e.currentTarget.url; // 遷移先のURL
  a.dispatchEvent(evt); // ここでMouseEventイベントを擬似的に作ったa要素に向けて発火
  e.preventDefault(); // 本来のa要素での移動をキャンセル
});

Macの場合cmdキーがmetaKeyになるとか知らなんだ。。。20分ぐらいハマりました。

ってなわけで、GoogleChromeでcmd(ctrl) + クリックした時にバックグラウンドでタブが開くあの動きが再現できました、わーい。

苦労したところ

ChromeExtensionの仕組みわからなすぎ問題
開発にあたり一時間ぐらいこのページとにらめっこしてました。

三つの世界の世界観がマジでわからなかったので、@sakaimoさんの記事を参考にしました。圧倒的感謝😭🙇‍♂️💦
https://qiita.com/sakaimo/items/416f36db1aa982d8d00c

特定のページだけで利用したい時はContent Scripts
アイコン(Extensionインストール後に出てくる右上のあれ)クリック時に何かしたい時はBrowser Action (Page Action)
Chrome起動中ずっと動かしときたい時はEvent Pageって区分のようです。

今回はGitHub上で動けばよかったのでContent Scriptを採用してましたが、そのうち「これはバックグラウンドでこれは普通に開きたい」とかあるだろうなぁという気持ちがあったため、extensionの設定をローカルストレージに保存するようにするために、

popup.js上で設定変更

background.jsにイベント(任意のメッセージ)を送信

background.js内で設定内容をローカルストレージに保存

contents.js発火時にローカルストレージ上の設定をbackground.js経由で取得

有効な設定要素のみ、addEventListenerを実行

っていうフローを取ってます。結局全部使ってる。

pjax対応
GitHubのHTMLElementsを眺めてるとどうやらpjaxが利用されているようで、ページ遷移した時にうまく動かないバグがありました。
この辺りはMutationObserverを使ってDOMを監視し、変更されたタイミングで再度content.jsを発火するようにしています。

const target = document.getElementById(observerSettings.selector);
// 現状だと github.com がホストに含まれるときは実行するようになっているため、
// 特定ページ意外で発火したときのエラーを防ぐために、getElementByIdで取得した要素が存在する場合のみ
// MutationObserverを利用するようにしている
if (target) { 
  const observer = new MutationObserver((mutations) => {
    // ここで任意の処理を発火することができるので、メイン処理を再度実効
  });
  observer.observe(target, observerSettings.config);
}

さいごに

久々にVanillaのJSでコーディングしたり、Chromeの拡張機能の仕組みに混乱したり、
「よっしゃできたーーー」ってなってたらinitMouseEventが利用非推奨なことに気がついて全部作り替えることになったりしましたが、
ChromeのExtensionは手軽にコーディングできる良い環境だと思いました。

なんだか、GoogleChromeで急に回転するポプ子とピピ美が見たくなった気がしたので、クソアプリアドベントカレンダーにでもエントリーしようかなと思った今日この頃。

なんやかんや言ってますが楽しくコーディングできました。
皆さんも、是非ChromeのExtensionを作ってみては如何でしょうか。
コードレビュー時のあーーーーーいまのページ移動しないで欲しいのーーーも解消されたので、本日はここまでにします。

同じような悩みがある方、是非使ってみてください。
ご意見ご感想PRお待ちしております。

おまけ

・・・きっと大変なことがあったんだろうと思いましたまる

13
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
13