宗教上の理由でLaravel 8.xのドキュメント以外読めません

# はじめに
久しぶりの記事の投稿です．
YouTubeの動画広告をスキップするChrome拡張を作ったり，QiitaのLGTMボタンをいいねボタンに戻すChrome拡張を作ったりして，コメント欄が大変なことになったのが懐かしく感じられます．

今回も，性懲りも無くChrome拡張作ってみた系のネタ記事ですが，今度作った拡張機能は普通に使えるかなと個人的には思ってます．

またしょうもないもん作ってるな，と思いながら温かい目で読んでいただけると幸いです．

では本題に入ります．

なお，本記事ではポイントを絞って解説するので（といってもコード全体で30行もないけど），全コードを載せることはしません．

# Laravelについてググった時の話
業務ではLaravelを使うことが多いので，当然　「Laravel 〇〇」 みたいにググることが多いのですが，検索ワードに「Laravel8」とか，「8.x」とか入れないとまだまだ５系６系の記事やドキュメントが上位にヒットします．

また，ブログの記事なんかを読んでいると，参考URLとしてドキュメントのページを貼ってくださっている方もいらっしゃいますが，８系じゃないことも少なくありません．

アクセスした先が８系じゃないと，
`https://readouble.com/laravel/バージョン/ja/hoge.html`
のバージョンを`8.x`にして再アクセスすることがあるんですが，この動作がめんどくさかったので，これをChrome拡張で自動化してやろうと思ったわけです．

# 作ったもの（仕様）
今回は，以下のような仕様で開発しました．

* URLを見て，バージョンが`8.x`でなければ`8.x`のページに飛ばす
* 遷移先が`404`の場合は，そもそも飛びたくない
* 遷移したとき，アクセス履歴に旧バージョンのページを残したくない（ブラウザバックを２回しなきゃいけないから）

このくらいであれば，まぁまぁ妥協できるレベルのクソアプリになりそうです．

# 【仕様１】URLを見て，バージョンが`8.x`でなければ`8.x`のページに飛ばす
これは，URLのバージョンの部分を切り出して判定して，`8.x`以外だったら`8.x`で置換するという処理で書けそうです．

### とりあえず，今アクセスしているページのURLを取得する
これは

```javascript
let currentPageUrl = location.href
```
で取れます．

https://developer.mozilla.org/ja/docs/Web/API/Location

### 取得したURLからバージョン部分を切り出す
今回切り出す部分は，
`/6.x/` とか， `/5.6/` のような部分です．
これは,`split('/')`と決め打ちインデックスでやってしまおうと思ったんですが，流石に良くないかなと思い，苦手な正規表現にチャレンジします．
バージョンの表記は`.number`だったり`.x`だったり`.dev`するので，以下のような書き方になりました．

```javascript
let oldVersionStr = currentPageUrl.match(/\/[0-9]\.([0-9]|x|dev)\//);
```
JSの正規表現は`/`で開始と終了を表すってことを知らなかったので少し躓きました．
ただこいつは，結果を配列で返してくるので，`[0]`を参照してやる必要があります．

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/match

### 新しい遷移先URLを生成する．
旧バージョン部分と`/8.x/`を入れ替えます．

```javascript
newUrl = currentPageUrl.replace(oldVersionStr[0], '/8.x/');
```
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/replace

生成した`newUrl`にアクセスすれば，とりあえず仕様１の要件は満たせそうです．

# 【仕様２】遷移先が`404`の場合は，そもそも飛びたくない
これは，飛ぶ前にページの存在を確認する必要があります．
したがって，遷移処理を書く前に，一旦HTTPリクエストを飛ばしてみて，ステータスコードを確認してから遷移するかどうかを決めることにしましょう．
JavaScriptでHTTPリクエストを飛ばす方法は，大きく分けて２つくらいあって，`axios`を使うか，`Fetch API`を使うかです．
今回は，後者の`Fetch API`を使ってみようかと思います．

```javascript
fetch(newUrl)
    .then(response => {
        if (response.ok) {
            //遷移処理
        }else{
            alert('8.x系のドキュメントページは存在しないようです.このページにとどまります．');
        }
    });
```
ページが存在していれば遷移，していなければその場に留まる，という処理を書きます．
Fetch APIは，Promiseの結果が`Response`オブジェクトとして返ってきて，そのプロパティに`ok`というやつがいます．これは，レスポンスが成功（200-299 の範囲のステータス）したか否かの真偽値が入っているプロパティです．
今回は，こいつが`true`の時に遷移するようにしましょう．

https://developer.mozilla.org/ja/docs/Web/API/Fetch_API

また，`false`が返ってきた時は，アラートでも出しておきましょう．何も出さないと
> なんで8.xに飛ばないねん．ほんまクソアプリやな

とUXがよくありませんね．

# 【仕様３】遷移したとき，アクセス履歴に旧バージョンのページを残したくない
もともと，ブラウザの履歴が保存してあるスタックをいじればいいのかな〜とか思ってたんですが，JSが直接履歴を消したりすることはできないらしい（？）ので別の方法を考えます．

```javascript
location.replace(newUrl);
```
この`replace`を使うと，現在のページのセッション履歴を保存せずにページ遷移できるので，仕様を満足することができそうです．
履歴を削除するより本質的な気がします．まさに"入れ替え"です．

https://developer.mozilla.org/en-US/docs/Web/API/Location/replace

# もう一つ，やらなきゃいけないこと
chrome拡張は，当然JSファイルだけでは動かなくて，`manifest.json`という設定ファイルが必要になります．
`manifest.json`の詳しい書き方は適当にググっていただけるといいかなと思いますが，今回の拡張機能に必要な設定が２つほどありますので紹介します．

### matches
これは，`content_scripts`のプロパティの１つですが，どのサイトで発火させるか，みたいなことを設定します．
これをワイルドカードで`https://*`とかしちゃうと常に拡張機能がスタンバッてる感じになってよくありません．適切なURLなりドメインなりを設定してやります．

```json
"matches": [
                "https://readouble.com/laravel/*"
            ]
```

### run_at
これは，拡張機能をどのタイミングで実行するかを設定します．もうちょい詳しくいうと，Content Scriptsを注入するタイミングを制御するプロパティです．以下のの３つが指定できます．

* document_start
    * cssプロパティのファイルの読込後，DOMが構築されscriptsが実行される前
* document_end
    * DOMが構築された直後，画像やフレームなどが読込まれる前
* document_idle（初期値）
    * document_endからwindow.onloadイベントまでの間の任意のタイミングで，ブラウザが決定

今回はぶっちゃけアクセスするURLがわかった時点で実行してくれていいんですけど，そんな早すぎるタイミングに実行してくれないので，無難に`document_start`を選択します．

```json
"run__at": "document_start"
```

# 終わりに
ということで，今回もしょうもないchrome拡張を作ってみました．
僕は用意がいいので，すでにchrome storeに出品してます（審査済み）ので，ぜひ使ってみてください．当然ですけど無料です．

今回も読んでいただきありがとうございました！

#### chromeストア
https://chrome.google.com/webstore/detail/jump2laravel8doc/gknlkbldebioijgmcjlohjehfmmcaojo/related?hl=ja

#### github
https://github.com/lunain84/Jump2Laravel8Doc

#### 動作の様子
https://twitter.com/fuwasegu/status/1397787927556485120?s=20