はじめに
久しぶりの記事の投稿です.
YouTubeの動画広告をスキップするChrome拡張を作ったり,QiitaのLGTMボタンをいいねボタンに戻すChrome拡張を作ったりして,コメント欄が大変なことになったのが懐かしく感じられます.
今回も,性懲りも無くChrome拡張作ってみた系のネタ記事ですが,今度作った拡張機能は普通に使えるかなと個人的には思ってます.
またしょうもないもん作ってるな,と思いながら温かい目で読んでいただけると幸いです.
では本題に入ります.
なお,本記事ではポイントを絞って解説するので(といってもコード全体で30行もないけど),全コードを載せることはしません.
Laravelについてググった時の話
業務ではLaravelを使うことが多いので,当然 「Laravel 〇〇」 みたいにググることが多いのですが,検索ワードに「Laravel8」とか,「8.x」とか入れないとまだまだ5系6系の記事やドキュメントが上位にヒットします.
また,ブログの記事なんかを読んでいると,参考URLとしてドキュメントのページを貼ってくださっている方もいらっしゃいますが,8系じゃないことも少なくありません.
アクセスした先が8系じゃないと,
https://readouble.com/laravel/バージョン/ja/hoge.html
のバージョンを8.x
にして再アクセスすることがあるんですが,この動作がめんどくさかったので,これをChrome拡張で自動化してやろうと思ったわけです.
作ったもの(仕様)
今回は,以下のような仕様で開発しました.
- URLを見て,バージョンが
8.x
でなければ8.x
のページに飛ばす - 遷移先が
404
の場合は,そもそも飛びたくない - 遷移したとき,アクセス履歴に旧バージョンのページを残したくない(ブラウザバックを2回しなきゃいけないから)
このくらいであれば,まぁまぁ妥協できるレベルのクソアプリになりそうです.
【仕様1】URLを見て,バージョンが8.x
でなければ8.x
のページに飛ばす
これは,URLのバージョンの部分を切り出して判定して,8.x
以外だったら8.x
で置換するという処理で書けそうです.
とりあえず,今アクセスしているページのURLを取得する
これは
let currentPageUrl = location.href
で取れます.
取得したURLからバージョン部分を切り出す
今回切り出す部分は,
/6.x/
とか, /5.6/
のような部分です.
これは,split('/')
と決め打ちインデックスでやってしまおうと思ったんですが,流石に良くないかなと思い,苦手な正規表現にチャレンジします.
バージョンの表記は.number
だったり.x
だったり.dev
するので,以下のような書き方になりました.
let oldVersionStr = currentPageUrl.match(/\/[0-9]\.([0-9]|x|dev)\//);
JSの正規表現は/
で開始と終了を表すってことを知らなかったので少し躓きました.
ただこいつは,結果を配列で返してくるので,[0]
を参照してやる必要があります.
新しい遷移先URLを生成する.
旧バージョン部分と/8.x/
を入れ替えます.
newUrl = currentPageUrl.replace(oldVersionStr[0], '/8.x/');
生成したnewUrl
にアクセスすれば,とりあえず仕様1の要件は満たせそうです.
【仕様2】遷移先が404
の場合は,そもそも飛びたくない
これは,飛ぶ前にページの存在を確認する必要があります.
したがって,遷移処理を書く前に,一旦HTTPリクエストを飛ばしてみて,ステータスコードを確認してから遷移するかどうかを決めることにしましょう.
JavaScriptでHTTPリクエストを飛ばす方法は,大きく分けて2つくらいあって,axios
を使うか,Fetch API
を使うかです.
今回は,後者のFetch API
を使ってみようかと思います.
fetch(newUrl)
.then(response => {
if (response.ok) {
//遷移処理
}else{
alert('8.x系のドキュメントページは存在しないようです.このページにとどまります.');
}
});
ページが存在していれば遷移,していなければその場に留まる,という処理を書きます.
Fetch APIは,Promiseの結果がResponse
オブジェクトとして返ってきて,そのプロパティにok
というやつがいます.これは,レスポンスが成功(200-299 の範囲のステータス)したか否かの真偽値が入っているプロパティです.
今回は,こいつがtrue
の時に遷移するようにしましょう.
また,false
が返ってきた時は,アラートでも出しておきましょう.何も出さないと
なんで8.xに飛ばないねん.ほんまクソアプリやな
とUXがよくありませんね.
【仕様3】遷移したとき,アクセス履歴に旧バージョンのページを残したくない
もともと,ブラウザの履歴が保存してあるスタックをいじればいいのかな〜とか思ってたんですが,JSが直接履歴を消したりすることはできないらしい(?)ので別の方法を考えます.
location.replace(newUrl);
このreplace
を使うと,現在のページのセッション履歴を保存せずにページ遷移できるので,仕様を満足することができそうです.
履歴を削除するより本質的な気がします.まさに"入れ替え"です.
もう一つ,やらなきゃいけないこと
chrome拡張は,当然JSファイルだけでは動かなくて,manifest.json
という設定ファイルが必要になります.
manifest.json
の詳しい書き方は適当にググっていただけるといいかなと思いますが,今回の拡張機能に必要な設定が2つほどありますので紹介します.
matches
これは,content_scripts
のプロパティの1つですが,どのサイトで発火させるか,みたいなことを設定します.
これをワイルドカードでhttps://*
とかしちゃうと常に拡張機能がスタンバッてる感じになってよくありません.適切なURLなりドメインなりを設定してやります.
"matches": [
"https://readouble.com/laravel/*"
]
run_at
これは,拡張機能をどのタイミングで実行するかを設定します.もうちょい詳しくいうと,Content Scriptsを注入するタイミングを制御するプロパティです.以下のの3つが指定できます.
- document_start
- cssプロパティのファイルの読込後,DOMが構築されscriptsが実行される前
- document_end
- DOMが構築された直後,画像やフレームなどが読込まれる前
- document_idle(初期値)
- document_endからwindow.onloadイベントまでの間の任意のタイミングで,ブラウザが決定
今回はぶっちゃけアクセスするURLがわかった時点で実行してくれていいんですけど,そんな早すぎるタイミングに実行してくれないので,無難にdocument_start
を選択します.
"run__at": "document_start"
終わりに
ということで,今回もしょうもないchrome拡張を作ってみました.
僕は用意がいいので,すでにchrome storeに出品してます(審査済み)ので,ぜひ使ってみてください.当然ですけど無料です.
今回も読んでいただきありがとうございました!
chromeストア
github
動作の様子