続・先取り! Google Chrome Extensions

第3回Extensionの新仕様とPageAction

こんにちは、株式会社ALBERTの太田です。今回はPageActionの新バージョンやTabs APIの新仕様などについて解説します。

Chromeの最新動向

と、その前にいくつかニュース的な情報がありますので、まずはそちらを紹介します。

Chrome 4系列のbeta版がリリース

2009年11月3日にChrome 4系列のbeta版がリリースされました。4系列ということでExtensionsが使えるかと思いきや、Chrome 3の時と同様にExtensionsは強制的に無効になっており、有効にすることはできません。

目玉機能はブックマークの同期機能(Googleブックマークではなく、Google Docsを使って同期されます)です。そのほかでは、stable版のChrome 4に搭載される予定の(HTML5関連の)WebDatabases、WebStorage、WebSockets、Remote fontなどはデフォルトではOFFになっています。今回のbeta版のリリースはブックマーク同期と安定性の向上がメインとなっています。来月のbeta版の更新ではExtensionsが有効になると期待していますが、まだどうなるかはわかりません。

試験的なGreasemonkey対応

2009年11月7日のdev版の更新で、FirefoxのGreasemonkey用に公開されているuser.jsファイルをExtensionとしてインストールする機能が使用できるようになりました。userscripts.orgなど、ウェブ上で公開されている.user.jsファイルをクリックするとExtensionとしてインストールするかどうか選択するダイアログが出てきますので、インストールを選べばそのスクリプトがExtensionとしてインストールされます。

内部的には.user.jsファイルをContent Scriptsとして実行するように、manifest.jsonの自動生成などを行っています。しかしながら、⁠2009年11月6日の時点では)前回の記事でも紹介しました通り、GM関数などの対応は十分ではありません。インストールはできても動かない(内部ではエラーになっている)こともありますので注意が必要です。

ExtensionのAPI仕様が修正

第1回でお伝えした通り、Toolstripsの削除が決定したほかにも、いくつかの仕様変更がありました。中でもPageActionはBrowserActionに合わせる形で大きな変更がありましたので、詳細は後ほど解説します。ほかにも、下記のような変更がありました。

  • Extensionsの設定を行えるOptions Pageの追加
  • NewTabページをカスタマイズできるAPINew Tab Pagesの追加
  • Content Scriptsの実行タイミングにdocument_idle(DOMContentLoadedより後で、onloadの前後)が追加されて、且つdocument_idleがデフォルトになりました
  • Installed Extensions(chrome://extensions/)ページのデザイン改良が行われました図1
  • chrome.tabs.sendRequestchrome.extension.onRequestというconnectionを使わないメッセージ送信APIが追加されました
  • chrome.extension.getTabContentsesというAPIがchrome.extension.getExtensionTabsに改名されました
図1 新しくなったInstalled Extensionsページ
図1 新しくなったInstalled Extensionsページ

Installed Extensionsページは、manifest.jsonで設定したIconが表示されるようになり、見栄えがするようになりました。右上のDeveloper modeをクリックすると「Load Extension…」⁠Pack Extension…」⁠Update Extensions now」などの開発者用メニューが表示されます。また、DisabledになっているExtensionsがグレーアウトされるようになり、識別し易くなりました。

PageAction API Ver2

では、新しくなったPageAction APIの仕様を解説します。新仕様はBrowserAction APIの仕様に合わせる形で作成されました。まずは定番のmanifest.jsonでの定義です。

manifest.jsonでのpage_action定義
"page_action": {
  "default_title": "action",  // optional; shown in tooltip
  "default_icon": "icons.png" // optional
}

旧バージョンはpage_actionsでしたが、新バージョンはpage_actionと、sが取れており、1つのExtensionsに1つだけしか持てないように制限されるようになりました。さらには、1つのExtensionsがPageActionとBrowserActionの両方を持つこともできません。これらの制限はアイコンでゴテゴテといったことにならないように、Chromeをできるだけシンプルに保つための制限となっています。

設定項目としては、Browser Actionsと同様で "default_title" と "default_icon" を指定します。2009年11月6日時点のdev版では、"popup" を指定することはできませんが、次のバージョンではpopupプロパティでhtmlファイルを指定することができるようになります。なお、page_actionの各プロパティはoptionalとなっていますが、page_action自体はmanifest.jsonに存在しないとBackground PageからPageAction APIを使用することができません。

BrowserActionとの違い

さて、Browser Actionと仕様を合わせたということからもわかるように、PageActionとBrowserActionは非常によく似ています。この2つはどう使い分けるべきでしょうか?

PageActionは今見ているページに合わせて表示させたり、させなかったりを変更でき、タブごとにアイコンが別々に存在するなど、名前の通りページ側のコンテキストと深く結びつきます。対して、BrowserActionはアイコンを常に表示したままで、タブを切り替えてもアイコンは1つなので、ページ側に合わせてアイコンを変えるようなケースには適しません。
BrowserActionもタブごとにアイコンを設定することができるようになりました。

よって、ページに対して表示を行うSBMカウンタのようなExtensionsはPageActionが適し、Gmail CheckerのようなExtensionsはBrowserActionが適していると言えます。これを踏まえて、前回の特集で作成したSBMカウンタをPageActionで作り直してみます。

PageAction API

PageAction APIの使い方は非常に簡単です。シンプルに任意のIconを任意のページに表示する方法は下記の通りです。

PageActionの操作
chrome.tabs.onUpdated.addListener(function(tabid, inf){
  if (inf.status === 'complete') {
    chrome.pageAction.show(tabid);
    chrome.pageAction.setIcon({tabId:tabid, path:'icon.png'});
  }
});

chrome.tabs.onUpdatedを監視し、ページが更新された際にpageActionを表示します。ここまでは非常にシンプルです。

さて、SBMカウンタでは件数を表示する必要があります。執筆時点では、PageActionのアイコンにはテキストを設置できません。そこで、canvasを使ってIcon自体にテキストを書き込む処理を行います。

canvasによるテキストの描画とImageDataの取得
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var width = canvas.width;
var height = canvas.height;
function getImageData(text) {
  ctx.clearRect(0, 0, width, height);
  ctx.font = "9px sans-serif";
  ctx.fillStyle = 'black';
  ctx.textAlign = "center";
  ctx.fillText(text, width/2, height);
  return ctx.getImageData(0, 0, width, height);
}

PageActionのIconのサイズは19px×19pxなので、canvasのサイズも19px×19pxにしています。ctx.font = "9px sans-serif" でフォントサイズと書体を指定しています。fillStyleは文字色の指定で、CSSのように色名や#ffffff、rbga(255,255,255,0.8)などの書式で色を指定できます。

textAlignを "center" とした上で、fillTextの第2二引数を canvas.width/2、つまり中心にすることで文字をセンタリングしています。

textBaselineの初期値はalphabeticで、文字の下の位置がベース位置になるので、fillTextの第3引数をcanvas.heightとして文字を下につけることができます。

これでテキストは描画できましたが、テキストだけではどのサービスなのかわからないのでアイコンを背景にしてみます。

画像を背景にしたテキストの描画

おすすめ記事

記事・ニュース一覧