Chrome拡張機能を作ってみよう③

[前回](https://qiita.com/andkirato/items/4ae015b4ddc680d3773c)はChrome拡張機能とローカルプログラムの連携までを書きました。
今回はその続きです。

## URLの監視
特定のURLにアクセスした場合にメッセージを表示するため
URLの監視を行います。

監視を行うには
manifest.jsonのcontent_scriptsの項目にあるjsで行います。
今回ですと「message.js」です。

```message.js
/*
    ■ URL監視
*/
$(function() {
  try{
    // background.jsにurlを送る
    chrome.runtime.sendMessage({method: 'checkurl', url: document.URL},
    errorHandle(function(response1) {
      // 必要ないけどとりあえず受け取る
      var message = response1.data;
    }));
  }catch(e){
    console.error(e);
  }
});

/**
 * 例外をまとめて処理する
 */
function errorHandle(process) {
    return function(){
      try {
        return process.apply(this, arguments);
      } catch (e) {
        chrome.browserAction.setIcon({path:"images/abnormal.png"});
        console.error(e);
      }
    };
  }
```

message.jsから受け取るためbackground.jsを以下の内容に修正しています。

```background.js
/*
  初期起動時の処理
*/
// インストール時かバージョンアップ時
chrome.runtime.onInstalled.addListener(function() {
  initialize();
});

// ブラウザ起動時
chrome.runtime.onStartup.addListener(function() {
  initialize();
});


function initialize() {
  // ファイルダウンロード先
  var dlFileName = "http://localhost/sample.txt";
  // ファイルを取得
  $.ajax({
    url: dlFileName,
    type: "GET",
    dataType: 'binary',
    responseType:'arraybuffer',
    timeout: 500
  })
  // 成功時
  .done(errorHandle(function (response) {
    var data = response;
    // ArrayBufferで取得するので
    var textfiledata = String.fromCharCode(...new Uint8Array(data));
    console.log(textfiledata);
    // 渡す前にbase64エンコードしておく
    textfiledata = btoa(textfiledata); 
    // ダウンロードした内容をprogramに連携する
    chrome.runtime.sendNativeMessage('put.message',
    {Action: "putmessage", Data: textfiledata},
    errorHandle(function(response, thread){
      // デコードしてJSON形式にする
      var getData = JSON.parse(decodeURIComponent(response));
      // 受け取ったコードがエラーの場合
      if(getData.Code != 0){
        throw new Error('programでエラーが発生');
      }
      // 受け取ったデータをlocalStorageに保存しておく
      localStorage.setItem('urllist', atob(getData.Data));
      return true;
    }));
    // 成功した場合は拡張機能のアイコンを切り替える
    chrome.browserAction.setIcon({path:"images/success.png"});
    // localStorageにステータスを保存
    localStorage.setItem('Status', 'ok');
  }))
  // 失敗時
  .fail(errorHandle(function () {
    // localStorageにステータスを保存
    localStorage.setItem('Status', 'ng');
  }));
  return true;
}

/**
 * Chrome拡張全体用
 */
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  switch (request.method) {
    // マニフェストファイルの内容を取得する
    case 'getManifest':
      var manifest = chrome.runtime.getManifest()
      sendResponse({data: manifest})
      break;
    // URLを受け取る
    case 'checkurl':
      var url = request.url;
      // urllistの内容と一致するか確認する
      localStorage.setItem('match', 'URLが一致しません。');
      var urllist = JSON.parse(localStorage.getItem('urllist'));
      for(var key of Object.keys(urllist)){
        if(url == urllist[key]){
          // 含んでいる場合
          localStorage.setItem('match', 'URLが一致します。');
          sendResponse({data: "URLが一致します。"});
          break;
        }
      }
      break;
    case 'getApInfo':
    default:
      console.log('no method:' + request.method);
      break;
  }
  return true;
});
/**
 * 例外をまとめて処理する
 */
function errorHandle(process) {
  return function(){
    try {
      return process.apply(this, arguments);
    } catch (e) {
      chrome.browserAction.setIcon({path:"images/abnormal.png"});
      console.error(e);
    }
  };
}
```

あとはメッセージを表示するためpopup系を修正します。

```popup.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="Pragma" content="no-cache">
    <meta http-equiv="Cache-Control" content="no-cache">

    <link href="../css/popup.css" rel="stylesheet">

    <script src="../js/jquery-3.4.1.js" ></script>
    <script src="../js/popup.js" ></script>
  </head>

  <body id="body">
  <div class="box">
    <div class="header">
      <h3 style="margin: 5px 0">動作状況</h3>
    </div>
    <div>
      <p id="status"></p>
    </div>
    <div>
      <p id="match"></p>
    </div>
  </div>
  <div class="footer">
    <div id="productver"></div>
  </div>
  </body>
</html>
```

```popup.js
$(function() {
  /*** localStorageからステータスを取得。 ***/
  var Status = localStorage.getItem('Status');
  var match = localStorage.getItem('match');
  if(Status == 'ok'){
    $('#status').html('<b>正常</b>');
    $('#match').html(match);
  }else{
    $('#status').html('<b>異常</b>');
  }
  // 特に意味はないけどマニフェストファイルのバージョン情報を取得する
  chrome.runtime.sendMessage({method: 'getManifest'},
  function(response) {
    var manifest = response.data;
    $('#productver').text(manifest.name + '　ver.' + manifest.version);
  });
});
```

* * *
拡張機能の作成については以上になります。
[次回](https://qiita.com/andkirato/items/ba68f64090026a79f577)はChrome拡張機能のインストールについて投稿します。