利用状況把握拡張機能⑤ - オプションページとグラフ①

この記事は利用状況把握拡張機能④の続きですので、そちらにも目を通した方が
 理解しやすいと思います。
　ここでは、拡張機能に関する新しい概要や知識などはありません。

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

　最初　→ <a href="https://qiita.com/Hira_B/items/84fe189a38f43f574502">利用状況把握拡張機能①</a>

## オプションページ
　休止時間やリストの編集、また利用時間が確認できる。オプションページへはポップアップの記録閲覧か設定リンクをクリックして移動する。こちらも最初に表示させるHTMLページを作成する。今回は長いため、一つ一つ区切って解説していく。CSSは省略する。

## オプションページのHTML
**休止時間のHTML**
 ```html:Time_setting.html
<!DOCTYPE html>
    <html>
    <html lang="ja">
    <head>
        <meta charset="utf-8">
        <link rel="stylesheet" type="text/css" href="styles/setting.css">
        <script src="scripts/setting.js"></script>
        <title>もう無駄な時間なんてしない-設定画面</title>
    </head>
    <body>
    …(省略)
        <p>平日<label class="toggle_button">
        <input type="checkbox"id="checkweek"></label></p>
        <p>
            <select id="weekdayspausetimehour_start" class="hour" disabled>
            </select>時
            <select id="weekdayspausetimeminutes_start" class="minutes" disabled>
            </select>分
            ～
            <select id="weekdayspausetimehour_end" class="hour" disabled>
            </select>時
            <select id="weekdayspausetimeminutes_end" class="minutes" disabled>
            </select>分の間
        </p>
        <p>休日<label class="toggle_button"><input type="checkbox" id="checkholi"></label></p>
        <p>
            <select id="holidayspausetimehour_start" class="hour" disabled>
            </select>時
            <select id="holidayspausetimeminutes_start" class="minutes" disabled>
            </select>分
            ～
            <select id="holidayspausetimehour_end" class="hour" disabled>
            </select>時
            <select id="holidayspausetimeminutes_end" class="minutes" disabled>
            </select>分の間
        </p>
        <input type="button" id="pausetimeOK" value="OK">
 ```
　特筆すべき点は平日・休日に分かれた八つの`<select>`タブと、toggle_buttonクラス。プルダウンメニューで時間を選択し、トグルボタンは休止時間自体の有効と無効を切り替える。

 
**ブロックリストのHTML。**
 ```html:Time_setting.html
        <table>
            <tbody id="BlockList">
            <tbody>
        </table>
        <input type="button" id="addblocklistOK" value="OK">

        <table>
            <tbody id="show_AllowingList">
            </tbody>
        </table>
 ```
ブロックリストの一覧と設定の表示。JSから、BlockListのidをきっかけにテーブルを動的に生成している。許可リストも同様。
 
**閲覧時間のHTML**
 ```html:Time_setting.html
        <h2>ブロックリスト</h2>
        <h3>閲覧時間</h3>
        <div id="today_container" class="scrolltime"></div>
        <h3>開いた回数</h3>
        <div id="today_container_count" class="scrolltime"></div>
        <h2>許可リスト</h2>
        <h3>閲覧時間</h3>
        <div id="today_H_container" class="scrolltime"></div>
        <h3>開いた回数</h3>
        <div id="today_H_container_count" class="scrolltime"></div>

        <h3>閲覧時間</h3>
        <div id="week_container"></div>

        <h3>閲覧時間</h3>
        <div id="All_container"></div>
 ```
　主に使うidは六つ。today_containerとtoday_container_count。その二つにHが付いた四つはブロック・許可リストを細かく表示するもので、week_containerは週の累計、All_containerは全サイトと分かれている。

## オプションページのJavaScript
 
　次に各々のJSの処理を書いていく。単純に量が多いため、単調なコードがかなり続くため、一部のコードは省略する。全貌を確認したい際は別途あるソースコードを見てください。

 ### 休止時間のJavaScript

```javascript:setting.js
const elementSelectHour = document.getElementsByClassName("hour");
const elementSelectMinutes = document.getElementsByClassName("minutes");
selectmenuTime(elementSelectHour,elementSelectMinutes,4);

const checkweek = document.getElementById("checkweek");
const checkholi = document.getElementById("checkholi");

const W1 = document.getElementById("weekdayspausetimehour_start");
const W2 = document.getElementById("weekdayspausetimeminutes_start");
const W3 = document.getElementById("weekdayspausetimehour_end");
const W4 = document.getElementById("weekdayspausetimeminutes_end");

const H1 = document.getElementById("holidayspausetimehour_start");
const H2 = document.getElementById("holidayspausetimeminutes_start");
const H3 = document.getElementById("holidayspausetimehour_end");
const H4 = document.getElementById("holidayspausetimeminutes_end");

setSelectPauseTime(W1,W2,W3,W4,result.PauseTime);
setSelectPauseTime(H1,H2,H3,H4,result.PauseTime_H);

checkweek.addEventListener('click',function(){
    if( checkweek.checked === false )
        setToggleButton(false,W1,W2,W3,W4);
    else
        setToggleButton(true,W1,W2,W3,W4);
});

checkholi.addEventListener('click',function(){
    if( checkholi.checked === false )
        setToggleButton(false,H1,H2,H3,H4);
    else
        setToggleButton(true,H1,H2,H3,H4);
});

document.getElementById("pausetimeOK").addEventListener("click",function(){
    if ( confirm("休止時間の設定を保存しますか？") ){
        let StorageBox = [];
        let StorageBox_H = [];
        const List = getSelectPauseTime(W1,W2,W3,W4);
        const List_H = getSelectPauseTime(H1,H2,H3,H4);
        const check = [checkweek.checked,checkholi.checked];
        
        StorageBox.push( (List[0] * 60 * 60)+(List[1] * 60) );
        StorageBox.push( (List[2] * 60 * 60)+(List[3] * 60) );
        StorageBox_H.push( (List_H[0] * 60 * 60)+(List_H[1] * 60) );
        StorageBox_H.push( (List_H[2] * 60 * 60)+(List_H[3] * 60) );
        
        chrome.storage.local.set({ Pause_Check : check });
        chrome.storage.local.set({ PauseTime : StorageBox });
        chrome.storage.local.set({ PauseTime_H : StorageBox_H });
        
    }
});

```
　設定ページが読み込まれた際にHTML側のidの取得とプルダウンメニューに値を入れる。その後はOKボタンを押した際に現在のプルダウンメニューに選択されている値を取得する。値は秒単位に全て分解してからstorageへと保存している。

 ### プルダウンメニュー

```javascript:setting.html
function selectmenuTime(elementSelectHour,elementSelectMinutes,n){
    for(let i = 0; i < n; i++){
        for(let j = 0; j < 24; j++){
            const elementHour = document.createElement("option");
            const optionText = document.createTextNode(j);
            elementSelectHour[i].appendChild(elementHour);
            elementHour.appendChild(optionText);
        }
        for(let l = 0; l < 60; l += 5){
            const elementMinutes = document.createElement("option");
            const optionText = document.createTextNode(l);
            elementSelectMinutes[i].appendChild(elementMinutes);
            elementMinutes.appendChild(optionText);
        }
    }
}
```
　編集する際、時間はプルダウンメニューから選ぶ方式にした。このプルダウンメニューは、休止時間以外にブロックリストの制限時間にも適応する。リストの方は追加と削除ができる仕様上、プルダウンメニューを動的に生成する関数を作成した。

　ここまでを描いた時点での休止時間の画面はこのようになっている。
![スライド9.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657037/09f3ce9e-c3aa-cedb-2c48-ac05194ded11.png)

　トグルボタンの有効後、プルダウンメニューの数値をいじった後OKボタンを押すと反映される仕組みになっている。無効の間はContent Scriptでの休止時間の実行はされないようになっている。

 ### ブロックリストの一覧表示
　次はこの拡張機能の中でも屈指の長コードであるブロックリスト。単に一覧表示するだけでなく削除と制限時間の編集を、全てHTMLを動的に生成することで実装する。だが、200行以上あるためかなりコードを省略。

```javascript:setting.html
const elementTableAl = document.getElementById("show_AllowingList");//tbody Block
const elementTableBlock = document.getElementById("BlockList");     //tbody Allow

//ブロックリスト
for(let i = 0; i < result.BlockList.length; i++)//ブロックリスト
{
    //ブロックリストのテーブル作成
    const elementRow = document.createElement("tr");
    const elementCell = document.createElement("td");	//URL
    const elementdelete = document.createElement("td");	//delete
    const elementSpan = document.createElement("span");
    let spanText = document.createTextNode(result.BlockList[i]);
    
    elementTableBlock.appendChild(elementRow);
    elementRow.appendChild(elementCell);
    …（省略）
    
    let elementImage = new Image(20,20);
    let pointClass = "pointerB";
    let deleteId = "010" + i;
    
    elementdelete.setAttribute("width","20px");
    elementImage.setAttribute("id",deleteId);
    elementImage.src= "../images/delete.png";
    …（省略）
    
    //休日・平日制限時間
    const HolidayText = document.createTextNode("平日");
    const WeekdayText = document.createTextNode("休日");		
    const TimeHour = document.createTextNode("時間");
    const TimeMinutes = document.createTextNode("分");
    …（省略）
    let HourMenu_W_id		="080" + i;		//休日(時間)
    let MinutesMenu_W_id	="081" + i;		//休日(分
    let HourMenu_H_id		="090" + i;		//平日(時間
    let MinutesMenu_H_id	="091" + i;		//平日(分

    …（省略）
    
    num = result.BlockList.length;
}

const elementSelectHour2 = document.getElementsByClassName("hour2");
const elementSelectMinutes2 = document.getElementsByClassName("minutes2");

selectmenuTime(elementSelectHour2,elementSelectMinutes2,num * 2);

//プルダウンメニューに今のストレージの時間データを設定
for(let i = 0; i < num; i++)
    setSelectMenuTime(i,result.SiteTimeLimit_W,result.SiteTimeLimit_H);

//ブロックリストの時間設定
document.getElementById("addblocklistOK").addEventListener("click",function(){
    if( confirm("設定を保存しますか？") ){
        //Storageへの上書き用
        let StorageBox = [];	//平日
        let StorageBox_H = [];	//休日
        for(let i = 0; i < num; i++){
            const List = getSelectTimeLimit(i);
            StorageBox.push( (List[0] * 60 * 60)+(List[1] * 60) );
            StorageBox_H.push( (List[2] * 60 * 60)+(List[3] * 60) );
        }
        
        chrome.storage.local.set({ SiteTimeLimit : StorageBox });
        chrome.storage.local.set({ SiteTimeLimit_H : StorageBox_H });
    }
});
for(let i = 0; i < result.AllowingList.length; i++){//許可リスト
    …（削除のみなので省略）
}

//削除ボタン(BlockList)
document.querySelectorAll('.pointerB').forEach(function(tr){
    tr.addEventListener('click',(e) =>{
        deleteList( e.target.id,"BlockList" );
    });
});
 ```
　変数の宣言や似たようなコードは多数省略する。色々書かれているが、ここで重要な部分は`document.createElement`はHTML要素を生成する。生成した要素を`appendChild`で追加している。`setAttribute`メソッドは、指定された要素に属性を付与することができる。Storageから持ってきたリストの個数（BlockList.length）でループを行い、動的にHTMLにテーブルを作成している。
　テーブルを作成し、その中に行ごとの削除、制限時間のプルダウンメニューを作成して完成。

 長丁場になるので、一旦ここでオプションページの記事を区切ります。


 次の記事　→　利用状況把握拡張機能⑤　設定ページとグラフ②

 ## 関連した記事

 - <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>