利用状況把握拡張機能③ - メッセージ送信と制限処理

　この記事は利用状況把握拡張機能②の続きですので、そちらにも目を通した方が理解しやすいと思います。
　ここでは、拡張機能のsendMessageについて述べている。

 　前回のページ　→　<a href="https://qiita.com/Hira_B/items/3978218f8d92c7a92c6c">利用状況把握拡張機能②</a>

# 制限機能
　特定時間帯に制限を設ける機能（休止時間と命名）と、特定ページに制限時間を設ける機能（ブロックリストと命名）の二つを実装する。
 
　ブロックリストの制限時間と休止時間の二つが制限を担っている。どちらも特定の条件下で現在のページをロック画面ページ（lockscreen.html）へと移動させる。また、平日と休日で設定できる時間を分けている。

 ### 特定ページの制限時間「ブロックリスト」
　ブロックリストに設定されているページがロック画面へと移動する処理を作成する。制限時間と利用時間を比較させ、データが　利用時間＞制限時間　になった瞬間にロック画面へと移動させる処理を行う。
　処理にはmeasureViewTimeAll関数を流用したmeasureViewTimeBを作成し、ブロックリスト用に色んな所を変えたが、一番重要な部分は、下のコードを追加したところにある。

```javascript:service_worker.js
if( Week === 6 || Week === 0 ){
    if( SiteViewListB[i] >= SiteTimeLimit_H[i] ){
        clearInterval(interval);
        clearInterval(All_interval);
        locking_screen( i,SiteViewListB,LockScreen );
        chrome.tabs.sendMessage(tabs,'TimeLimitOver').then((response)=>{
        }).catch((error)=>{ console.log(error); })
    }
}else{ …（省略）  }
```

　一番上のif文は、平日か休日の判別なためそこまで重要ではない。二つ目のif文では、現在のサイトの利用時間と、そのサイトの制限時間を比較して、制限時間を超過していたらContent Scriptへとメッセージを送り、向こうでlocation.hrefを使いロック画面へと飛ばしている。
 　Content Scriptへとメッセージを飛ばすには任意のタブIDを使いメッセージを送るページを決めている。Service Worker側からDOM操作は行えないためContent Scriptへ移動してから処理を行っている。調べたところ、Manifest V2では、Service Worker(backgroundと呼ばれていたらしい)側からもDOM操作が出来たが、V3で廃止になったようだ。
　Content Scriptへとメッセージを送信する場合は`runtime.sendMessage`とは別のメソッドである`tabs.sendMessage`を使用する。

```javascript:content_script.js
chrome.runtime.onMessage.addListener((id,msg) =>{
    window.alert("制限時間を超過しました！");
    const nowURL = chrome.runtime.getURL("lockscreen.html");
    location.href = nowURL;
});
```
　Service Workerからのメッセージを受け取りロック画面へと遷移する処理。ロック画面へと遷移する前に一度アラームで警告をする（ロック画面は休止時間と合わせて後ほど）。`Chrome.runtime.getURL()`は、拡張機能から、こちらのファイル内データへとアクセスしており、この関数により読み込めるファイルは、manifest.jsonの`web_accessible_resources`から指定したファイル以外は読み込めない。

　
### 特定時間帯の制限「休止時間」
　全てのページをロック画面へと移動させる、強い抑制力をもった制限機能。そのため人によっては扱いにくいと感じるため、有効・無効の切り替え設定がある。
 
　休止時間の処理は全てContent Script側で行う。ページ情報をService Workerへと送った続き。今のページURLが、ブロックリストと許可リストのどちらかに入っているかを走査して確かめる。許可ならば変数Block_Allowをtrueにする。

```javascript:content_script.js
let Block_Allow = false;	//false = ブロック true = 許可
for(i = 0;i < result.BlockList.length; i++ ){
    if( result.BlockList[i].includes( location.host ) ){
        flag = true;
        Block_Allow = false;
        currentURL = result.BlockList[i];
        n = i;
        break;
    }
}
for(i = 0;i < result.AllowingList.length && Block_Allow != false; i++ ){
    if( result.AllowingList[i].includes( location.host ) ){
        flag = true;
        Block_Allow = true;
        currentURL = result.AllowingList[i];
        n = i;
        break;
    }
}
if( Block_Allow !== true){  //許可リストなら休止はなし
    if( (result.Pause_Check[0] === true) && (toWeek !== 0 || toWeek !== 6)  )
        setTime_and_execute( dataPauseTime,result.Pause_Check[0] );
    else if( (result.Pause_Check[1] === true)  )
        setTime_and_execute( dataPauseTime_H,result.Pause_Check[1] );
}
```
　走査した結果Block_Allowがtrueになったら、休止時間は実行しないようにしている。実行関数であるsetTime_and_executeが二つあるのは平日と休日で時間帯の設定が異なるため。

　休止時間が実行されたら、現在の時刻とstorageに保存されている休止時間の開始と終了の時間を取得して比較する。判別式は開始時刻<現在時刻<終了時刻となっていたらロック画面へと移動させる処理をしている。特定時間帯にサイトをロック画面へと移動させる休止時間の処理。Content Script側で実行され、PauseTime[0]~[3]までの配列の中には休止時間帯のデータが入っている。
　　　　[0]　休止時間開始（時間）
　　　　[1]　休止時間開始（分）
　　　　[2]　休止時間終了（時間）
　　　　[3]　休止時間終了（分）

```javascript:content_script.js
function setTime_and_execute( PauseTime,checked ){
    let nowTime = new Date();
    let Pause_Start = new Date();
    let Pause_End = new Date();
    if( PauseTime[0] > PauseTime[2] ){//日付跨いでいたら
    Pause_End.setDate(Pause_End.getDate() + 1 );
    }
    Pause_Start.setHours(PauseTime[0],PauseTime[1],0,0)
    Pause_End.setHours(PauseTime[2],PauseTime[3],0,0);
    if( Pause_Start.getTime() <= nowTime && nowTime <= Pause_End.getTime() ){
        const nowURL = chrome.runtime.getURL("lockscreen.html");
        location.href = nowURL;
    }
}
```
　一度、storageの中にテストデータを入れて制限時間と休止時間が作動するかを確認した。制限時間を超過した場合は、そのページにアラームを表示させてからロック画面へと移動する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657037/6f2e84eb-f337-f608-9441-c8bc1ad9667e.png)
休止時間の場合は前触れなく移動する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657037/d5dfd4a2-2f34-abba-d506-e7ae953d49d6.png)

移動させた後はこのような画面へと移動する。制限時間の超過により制限状態になったページは３０分間使用不可になる。仮にもう一度ページへ移動しても再度このロック画面が表示される。なお、拡張機能の中に、この制限状態をこちら側から解除する機能は存在しない。（あったら恐らく使うので）

### 制限機能の影響を受けない「許可リスト」
　ブロックリストへと含めたくない、または制限を掛けたくないというページに対しては、ブロックリストと対極にある許可リストへとページを保存する。こちらは訪問回数はあるが、制限機能の影響はないため時間を気にせずに利用したいページへと設けることができる。

　ここまでで利用時間の記録と、制限機能の開発は一通り終わったため、ここからはユーザー側が拡張機能に対して操作を行う部分を作成していく。現状では、記録は取れても見ることはできず、リストの追加・削除が出来ず、休止時間と制限時間の編集はなに一つできない。
　次回からその問題を解決する機能を実装していく。
 
 　制限機能は、これにて完成。
  
 ## 関連した記事
 - <a href="https://qiita.com/Hira_B/items/84fe189a38f43f574502">利用状況把握拡張機能① - 拡張機能の概要とmanifestの読み込み</a>　
 - <a href="https://qiita.com/Hira_B/items/3978218f8d92c7a92c6c">利用状況把握拡張機能② - storageとContent Script、Service Workerの役割</a>
 - <a href="https://qiita.com/Hira_B/items/7f1160cb274bce2b4292">利用状況把握拡張機能③ - メッセージ送信と制限処理 ←現在の記事</a>
 - <a href="https://qiita.com/Hira_B/items/8a30109f47d1cef6a61e">利用状況把握拡張機能④ - 拡張機能のdefault_popup</a>
 - <a href="https://qiita.com/Hira_B/items/6acd07e5f76150cda476">利用状況把握拡張機能⑤ - オプションページとグラフ①</a>
 - <a href="https://qiita.com/Hira_B/items/7fc516607a499298678c">利用状況把握拡張機能⑥ - オプションページとグラフ②</a>
 - <a href="https://qiita.com/Hira_B/items/141a0d506c14bbe7a6e5
">利用状況把握拡張機能⑦ - ソースコード</a>