The Diary of Aska

Chrome Extensionsで任意のHTMLをデスクトップ通知する方法

7kai TasksにもようやくChrome Extensionsが付きました、土日ひたすら改良を重ねて気がついたら月曜日でした。

デスクトップ通知を動的なHTMLにしたい

webkitNotificationsではアイコン・タイトル・本文をそれぞれテキストで指定するcreateNotificationと、URLを指定するcreateHTMLNotificationがあり、HTMLを直接指定できません、しかしExtensionsはポップアップ(アイコンをクリックしたときに出現するHTML)やデスクトップ通知のHTMLからバックグラウンドページの変数にアクセス出来るので、これを利用してJsで描写すれば動的なHTMLをデスクトップ通知を利用できます。

イメージが持ちやすいように以下の様なファイル構成だったと仮定します。

処理の流れは。

  1. 拡張機能の初期化時にバックグラウンドページも初期化
  2. バックグラウンドページが監視
  3. バックグラウンドページが何かを検出
  4. バックグラウンドページが検出した内容を変数にセット
  5. createHTMLNotificationでデスクトップ通知
  6. デスクトップ通知がバックグラウンドページを取得 chrome.extension.getBackgroundPage()
  7. デスクトップ通知からバックグラウンドページのメソッドを起動
  8. デスクトップ通知をクリックした時のイベントセット $(body).click(function(e){ }

スクリプトをmain.js等にまとめている場合、main.jsを読むのはバックグラウンドページだけで良い、デスクトップ通知はバックグラウンドページのメソッドに必要に応じてdocumentや通知側で取得した$(selector)を渡せば良い、main.jsで$(selector)してもバックグラウンドページのHTMLを走査するからね。

クリックしたらページ遷移させたりとかも..

デスクトップ通知で $(body).click(function(e){ } すればクリックしたときに通知と関係するページを開く等の処理が可能

遷移した先で任意の要素選択した状態に..

これはページと拡張機能間の通信で可能、経路としては以下のようになる。

  1. デスクトップ通知をClick
  2. バックグラウンドのメソッド起動、コンテンツスクリプトにリクエストを投げる chrome.tabs.sendRequest
  3. コンテンツスクリプトでリクエストを受信、サービスページのDOMにJSONを仕込んでDOMイベントを起動 dispatchEvent
  4. サービスページで予めaddEventListenerしていたcallbackが起動される、JSONをパースして何かする

一応関連ソースを貼っておきます。

コンテンツスクリプトでリクエストを受信しサービス側のページに伝播

chrome.extension.onRequest.addListener(
    function(request, sender, sendResponse) {
        var customEvent = document.createEvent('Event');
        customEvent.initEvent('extentionsEvent', true, true);
        var eventDiv = document.getElementById('extentionsEventDiv');
        eventDiv.innerText = JSON.stringify(request);
        eventDiv.dispatchEvent(customEvent);
    }
);

サービス側のページ初期化時にコンテンツスクリプトからの伝播を受けられるようにしておく

// <div id="extentionsEventDiv"></div>はどっかに埋めておく
document.getElementById('extentionsEventDiv').addEventListener('extentionsEvent', function() {
    var eventText = document.getElementById('extentionsEventDiv').innerText;
    var eventData = JSON.parse(eventText);
    // ほいほい受けちまっていいのかい?
    that[eventData.method].apply(that, eventData.arguments);
}, false);

コンテンツスクリプトへのリクエスト送信

chrome.tabs.sendRequest(tab.id, {
    method: 'refresh',
    arguments: [
        {
            select_list_id: list_id,
            select_task_id: task_id
        }
    ]
});

実装例

https://github.com/s-aska/7kai-Tasks/tree/master/extensions/7kai-tasks-checker/src