続・先取り! Google Chrome Extensions

第1回 Chrome ExtensionsのAPI#1

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

Inter Extension Communication

Extensions同士での連携のために,InterExtensionCommunicationというAPIが用意されていますRevision 28565 以降⁠。こちらの使い方を簡単に見てみます。

Extension A から Bへのメッセージの送信

var B_id = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb';
var MyName = 'A';
var port = chrome.extension.connect(B_id, {name: MyName});
port.postMessage({message: 'Bさん、こんにちは'});
port.onMessage.addListener(function(msg) {
  console.log(msg);
  port.disconnect();
});

まず,メッセージを送信したいExtensionのIDを把握する必要があります。これは chrome://extensions/ などで確認できます。そのIDに対してchrome.extension.connectでコネクションを作成します。このときnameで名前を指定しておくと,受け取り側で誰からのメッセージか判断しやすくなります。

Extension Bでの,Aからのメッセージの受信とAへの返信

var A_name = 'A';
chrome.extension.onConnectExternal.addListener(
function(port) {
  port.onMessage.addListener(function(msg, info) {
    if (info.name === A_name) {
      port.postMessage({message: 'Aさん、こんにちは'});
    }
  });
});

続いて,メッセージの受け取る側の処理です。chrome.extension.onConnectExternalでほかのExtensionsからの接続を受け,メッセージを受信できる状態にします。メッセージを受け取った際の第2引数(ここではinfoという名前)には,メッセージを送信した側のExtensionの情報(idなど)が入っています。

Tabs/Windows APIの操作

最後に,Tabs/Windows APIの汎用的な操作をコードスニペットとしてまとめます。多くの関数はTabオブジェクトを引数として渡します。TabオブジェクトはTabs APIのgetgetSelectedなどのほか,Content Scriptからメッセージを受け取った際の第2引数のtabプロパティからも取得することができます。

Tabs/Windows操作のコードスニペット

//新しいタブを現在のタブの隣に開く
function open_tab(tab){
  chrome.tabs.create({
    index:tab.index+1,
    url:'chrome://newtab/',
    selected:true
  });
}
//新しいタブをバックグラウンドで現在のタブの隣に開く
function open_tab_background(tab){
  chrome.tabs.create({
    index:tab.index+1,
    url:'chrome://newtab/',
    selected:false
  });
}
//新しいタブを右端に開く
function open_tab_last(){
  chrome.tabs.create({
    url:'chrome://newtab/',
    selected:true
  });
}
//新しいタブをバックグラウンドで右端に開く
function open_tab_last_background(){
  chrome.tabs.create({
    url:'chrome://newtab/',
    selected:false
  });
}
//空白のタブを現在のタブの隣に開く
function open_blank_tab(tab){
  chrome.tabs.create({
    index:tab.index+1,
    url:'about:blank',
    selected:true
  });
}
//空白のタブを右端に開く
function open_blank_tab_last(){
  chrome.tabs.create({
    url:'about:blank',
    selected:true
  });
}
//空白のタブをバックグランドで現在のタブの隣に開く
function open_blank_tab_background(tab){
  chrome.tabs.create({
    index:tab.index+1,
    url:'about:blank',
    selected:false
  });
}
//空白のタブをバックグランドで右端に開く
function open_blank_tab_background(){
  chrome.tabs.create({
    url:'about:blank',
    selected:false
  });
}
//現在のタブを閉じる
function close_tab(tab){
  chrome.tabs.remove(tab.id);
}
//新しいウィンドウを開く
function open_window(){
  chrome.windows.create({url:'chrome://newtab/'});
}
//新しいウィンドウを空白ページで開く
function open_blank_window(){
  chrome.windows.create({url:'about:blank'});
}
//現在のウィンドウを閉じる
function close_window(tab){
  chrome.windows.remove(tab.windowId);
}
//現在のタブの右隣のタブを選択
function right_tab(tab){
  chrome.tabs.getAllInWindow(tab.windowId, function(tabs){
    tabs.forEach(function(_t,i){
      if (_t.id === tab.id){
        var newtab = tabs[i+1] || tabs[0];
        if (newtab){
          chrome.tabs.update(newtab.id, {selected:true});
        }
      }
    });
  });
}
//現在のタブの左隣のタブを選択
function left_tab(tab){
  chrome.tabs.getAllInWindow(tab.windowId, function(tabs){
    tabs.forEach(function(_t,i){
      if (_t.id === tab.id){
        var newtab = tabs[i-1] || tabs[tabs.length-1];
        if (newtab){
          chrome.tabs.update(newtab.id, {selected:true});
        }
      }
    });
  });
}
//右端のタブを選択
function last_tab(tab){
  chrome.tabs.getAllInWindow(tab.windowId, function(tabs){
    var newtab = tabs[tabs.length-1];
    if (newtab){
      chrome.tabs.update(newtab.id, {selected:true});
    }
  });
}
//左端のタブを選択
function first_tab(tab){
  chrome.tabs.getAllInWindow(tab.windowId, function(tabs){
    var newtab = tabs[0];
    if (newtab){
      chrome.tabs.update(newtab.id, {selected:true});
    }
  });
}
//現在のタブ以外を閉じる
function close_other_tabs(tab){
  chrome.tabs.getAllInWindow(tab.windowId, function(tabs){
    tabs.forEach(function(_t,i){
      if (_t.id !== tab.id) {
        chrome.tabs.remove(_t.id);
      }
    });
  });
}
//現在のタブより右のタブを閉じる
function close_right_tabs(tab){
  chrome.tabs.getAllInWindow(tab.windowId, function(tabs){
    tabs.reverse().some(function(_t,i){
      if (_t.id !== tab.id) {
        chrome.tabs.remove(_t.id);
      } else {
        return true;
      }
    });
  });
}
//現在のタブより左のタブを閉じる
function close_left_tabs(tab){
  chrome.tabs.getAllInWindow(tab.windowId, function(tabs){
    tabs.some(function(_t,i){
      if (_t.id !== tab.id) {
        chrome.tabs.remove(_t.id);
      } else {
        return true;
      }
    });
  });
}
//現在のタブを複製する(ただし、履歴は引き継げない)
function clone_tab(tab){
  chrome.tabs.create({index:tab.index+1,url:tab.url});
}

このようにどの操作もかなりシンプルに記述できます。タブの選択を切り替えたい場合はchrome.tabs.updateでselected:trueだけを送る点だけは少しわかり難いかもしれません。

そのほか,JavaScriptのTipsとして,配列の走査を途中で中断したい場合はArray.someを使用して,return trueをするとそこで走査を止めることができます(このとき,someはtrueを返します⁠⁠。

まとめ

今回は前回の特集記事以降に実装されたBrowser Actions APIを中心に,Inter Extension Communication APIと,よく使うTabs APIの操作方法をまとめました。次回はExtensionsから少し離れ,User Scriptsについて解説を行う予定です。

著者プロフィール

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

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

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