続・先取り! Google Chrome Extensions

第4回 ベータ版に向けたExtension総復習

この記事を読むのに必要な時間:およそ 6.5 分

続いて,SBMクラスの実装です。tabオブジェクトを受け取り,サービスごとにリクエストを投げ,レスポンスが返ってきたらそれぞれカウントをBrowserActionのアイコンに反映しています。レスポンスは順番通りに返ってくるわけではないので,サービスが増えて順番がまちまちになっても正常に動作するようにcount,titleの初期化を工夫しています。BrowserActionもtabidを指定することでBadgeText,TitleをPageActionのようにタブごとに保持させることができます。

タブの更新の監視

chrome.tabs.onUpdated.addListener(function(tabid, inf){
  if (inf && inf.status === 'loading') {
    chrome.tabs.get(tabid, function(tab){
      if (!site_check(tab.url)) {
        new SBM(tab);
      }
    });
  }
});
function site_check(url){
  if (url.indexOf('http') !== 0 || url.length > 255) return true;
  return SBMConf.disable_sites.some(function(site){
    return new RegExp(site).test(url);
  });
}

仕上げにchrome.tabs.onUpdatedでタブの更新をチェックし,タブの読み込みが開始した際にURLが有効なものであればSBMクラスをnewしてインスタンスを作ります。これで,合計ブックマーク数の表示と,Tooltipにサービスごとのブックマーク数を表示することができました。

Options Page

オプションページは chrome://extensions/ のオプションボタンをクリックした際に開かれるページです。今のところ純粋なHTMLページで,特にほかのページと異なる部分はありません(OptionsPage用の共通CSSを適用する予定はあります⁠⁠。ほかのExtensionページと同様,chrome.extension.getBackgroundPageでバックグラウンドページとやり取りをすることができ,localStorageなどを使ってExtensionの設定をカスタマイズする際に使用します。OptionsPageのlocalStorageとBackgroundPageのlocalStorageは同じオブジェクトなので,OptionsPageでlocalStorageを書き換えれば即,BackgroundPageに反映されます。なお,localStorageの値はExtensionのIDをドメインに見立てて保存されます。

BrowserActionのPopup

Popupもやはり基本はHTMLですが,こちらはページ内容に応じて表示領域が動的に変化するようになっています。また,2009年11月24日時点のdev版では,popupに対してDevToolsを開くことができません。そこで,chrome-extension://extension_id/popup.htmlのようにpopupを直接タブに開いたり,BackgroundPageのconsole.logを呼び出してコンソール出力をするといった方法でデバッグする必要があります。

さて,popupでのブックマーク数の表示ですが,BackgroundPageのSBMクラスと処理は概ね同じなので,SBMクラスを継承します。

PopupでのSBMクラスの実装

var BackGround = chrome.extension.getBackgroundPage();
var log = BackGround.console;
var SBMConf = BackGround.SBMConf;
function PSBM(tab){
    if (tab) {
        this.init(tab);
    }
}
PSBM.prototype = new BackGround.SBM();
var _request = PSBM.prototype.request;
PSBM.prototype.request = function(service, index){
    if (service.enable) {
        _request.call(this, service, index);
    } else {
        document.querySelector('#sbm_' + service.id).style.display = 'none';
    }
};
PSBM.prototype.update = function(count, service, index){
    document.querySelector('#add_' + service.id).href = fill(service.api_add, this, service);
    var link = document.querySelector('#text_' + service.id);
    link.href = fill(service.api_link, this, service);
    link.textContent = count;
};

BackgroundPageのSBMクラスは引数に何も渡さなければinitメソッドを呼ばないようにしてあるので,init,request,updateの各メソッドだけを持ったインスタンスを作ります。そのインスタンスを新しいPSBMクラスのprototypeに入れると,PSBMはSBMクラスを継承したことになります。

PSBMクラスでは継承元のrequestの前に無効なサービスであればその表示を隠す処理を入れ,またupdate時はそのサービスごとに表示を更新するようにしました。

選択中のタブの取得

chrome.tabs.getSelected(null,function(tab){
  if (BackGround.site_check(tab.url)) {
    window.close();
    return;
  }
  new PSBM(tab, BackGround.Services);
});

後はpopupがクリックされた際のタブを取得して,PSBMクラスをnewしています。なお,⁠現状では)popupが開くことをキャンセルすることができないので,無効なURLでは即座にwindow.closeでpopupを閉じるようにしています。

まとめ

現在のSBMカウンタのすべてを説明したわけではありませんが,現時点でのExtensionsの作り方は説明できたのではないかと思います。FirefoxのAdd-onなどに比べれば機能不足は否めませんが,アイデア次第では面白いものが作れる土台はできてきています。正式リリースも着々と近づいてきていますので,この機会にExtensionsを作ってみてはいかがでしょうか?

次回はまだ紹介していないAPI(ドキュメントにないものも含めて)を幾つか紹介したいと思います。

著者プロフィール

太田昌吾(おおたしょうご,ハンドルネーム:os0x)

1983年生まれ。JavaScriptをメインに,HTML/CSSにFlashなどのクライアントサイドを得意とするウェブエンジニア。2009年12月より、Google Chrome ExtensionsのAPI Expertとして活動を開始。

URLhttp://d.hatena.ne.jp/os0x/