Chrome Extension の createHTMLNotification メソッドでデータを渡してフレキシブルに内容を構成するには
Chrome拡張でデスクトップ通知の実装時に、HTMLを使うときデータを簡単に渡す方法について。
Desktop Notifications
chrome.notifications - Google Chrome を見ると、通常のタイトル、イメージ、テキストの三つを渡して表示する通知と、HTMLで自由に組める通知がある。
// 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 ファイル名を指定するだけになっている。
// Or create an HTML notification: var notification = webkitNotifications.createHTMLNotification( 'notification.html' // html url - can be relative );
これで内容を可変にしたいときは、例として
// 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
<!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
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; });
さらにこれを呼び出すサンプルが次のようになる。
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 ではサポートされている。