Chrome拡張でデスクトップ通知の実装時に、HTMLを使うときデータを簡単に渡す方法について。

Desktop Notifications

chrome.notifications - Google Chrome を見ると、通常のタイトル、イメージ、テキストの三つを渡して表示する通知と、HTMLで自由に組める通知がある。

1
2
3
4
5
6
// Create a simple text notification:
var notification = webkitNotifications.createNotification(
'48.png', // icon url - can be relative
'Hello!', // notification title
'Lorem ipsum...' // notification body text
);

このように前者の通知は引数でデータを渡せるが、後者では HTML ファイル名を指定するだけになっている。

1
2
3
4
// Or create an HTML notification:
var notification = webkitNotifications.createHTMLNotification(
'notification.html' // html url - can be relative
);

これで内容を可変にしたいときは、例として

1
2
3
4
5
6
// Inside a notification...
chrome.extension.getBackgroundPage().doThing();
// From the background page...
chrome.extension.getViews({type:"notification"}).forEach(function(win) {
win.doOtherThing();
});

のように通知の HTML 側から取得するようなサンプルが書いてある。
これは相互参照になるのと前者よりも面倒に思う。後者でも簡単に createHTMLNotification メソッドで渡すようにできないのでないだろうか?

解決方法

サンプルのコメントの通り、createHTMLNotification の引数は「html url」であるため、URL形式で渡すことができる。よって方法として、クエリ引数かハッシュとしてデータを渡すことが可能だ。
ここでは簡単な扱えるハッシュの方法で実装した。
HTMLとその中で実行するJavaScriptファイルは以下のとおり、scriptタグ内に書くとSecurity Policyのエラーになった。

notification.html
1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<script src="notification.js"></script>
</head>
<body>
<div id="content"></div>
</body>
</html>
notification.js
1
2
3
4
5
6
7
8
document.addEventListener('DOMContentLoaded', function(){
var data = window.location.hash.substr(1);
data = JSON.parse(decodeURIComponent(data));

var html = '<img src="' + data.image + '">';
html += '<p class="text">' + data.text + '</p></div>';
document.getElementById('content').innerHTML = html;
});

さらにこれを呼び出すサンプルが次のようになる。

1
2
3
var data = { image: "image.jpg", text: "text..." };
var popup = webkitNotifications.createHTMLNotification(
'notification.html#' + encodeURIComponent(JSON.stringify(data)) );

データを JSON 化してURLエンコードをかける。 # の後ろに付けて渡す。取り出しは逆に行う。

Gistにも載せておいた。 https://gist.github.com/tilfin/4992651

補足だが、HTML Notification は W3C で策定中の Web Notifications は外れたそうだが、Chrome Extension ではサポートされている。