こんにちは、
まず、
そして、
それでは、
Browser Actions API
Browser Actions APIはツールバーにボタンを追加するAPIです。
最初に、
 
このようにOmniBox
Browser Actionsの使い方
では、
なお、
{
  "name": "Print this page browser action extension",
  "description": "This extension adds a print button to the toolstrip",
  "version": "1.0",
  "background_page": "background.html",
  "permissions": [
    "tabs", "http://*/*", "https://*/*"
  ],
  "browser_action": {
      "default_icon": "images/icon19.png",
      "default_title": "Browser Action"
  }
}browser_
chrome.browserAction.onClicked.addListener(function(tab) {
  var action_url = "javascript:window.print();";
  chrome.tabs.update(tab.id, {url: action_url});
});このように、
Badgeの使い方
Browser ActionsにはBadgeと呼ばれるボタン上にテキストを表示する機能があります。このBadgeの使い方を見てみます。
chrome.browserAction.setBadgeText({text:"111", tabId:tab.id});
chrome.browserAction.setBadgeBackgroundColor({color:[190, 190, 190, 230], tabId:tab.id});
chrome.browserAction.setIcon({path:'icon.png', tabId:tab.id});
chrome.browserAction.setTitle({title:'MyButton', tabId:tab.id});このように、
setBadgeTextは4文字以内のテキストを指定します
ssetIconはアイコン画像のパス、
Popupの使い方
Popupは図2のモックのように、
 
こちらもmanifest.
  "browser_action": {
      "default_icon": "icon.png",
      "default_title": "Popup Sample",
      "popup": "popup.html"
  }Browser Actionsを使ったExtensionの作成
それでは、
livedoor Readerの未読件数API
livedoor Readerには未読件数を返すシンプルなAPIが存在します。具体的には http://
var API = 'http://rpc.reader.livedoor.com/notify?user=';
function check(){
  var xhr = new XMLHttpRequest();
  var url = API + UserName;
  xhr.open('GET', url, true);
  xhr.onload = function(){
    var res = xhr.responseText.substring(1);
    var count = parseInt(res, 10);
    if (count > 0) {
      update(String(count));
      setTimeout(check, 60 * 1000);
    } else {
      update('!');
    }
  };
  xhr.onerror = function(){
    update('!');
  };
  xhr.send(null);
}未読件数のテキストは |100|| という形で返ってきます。先頭の|を取り除けば、
続いて、
var LIMIT = 4;
var LIMIT_COUNT = Math.pow(10, LIMIT);
function update(count){
  if (parseInt(count,10) >= LIMIT_COUNT) {
    count = abbr_exp_notation(parseInt(count,10), LIMIT+1);
  }
  chrome.browserAction.setBadgeText(count);
}
function abbr_exp_notation(count, i){
  if (count < Math.pow(10, i)) {
    var _i = i-2;
    return Math.floor(count / Math.pow(10, _i)) + 'e' + _i;
  } else {
    return abbr_exp_notation(count, ++i);
  }
}JavaScriptにおいて、
Popupによる簡易設定フォーム
続いて、
  "browser_action": {
      "name": "LDR Unread",
      "icons": ["ldr_favicon.png"],
      "popup": { "path": "popup.html", "height": 40 }
  }中身となるHTML/
<div>
  <input type="text" placeholder="UserName" id="username">
</div>body {
  overflow: hidden;
  margin: 0px;
  padding: 0px;
  background: #dadae7;
  height:38px;
  border:1px solid #000033;
}
body > div{
  padding:6px;
}
body > div > input{
  width:100px;
}さらに、
var BG = chrome.extension.getBackgroundPage();
var username = document.getElementById('username');
username.addEventListener('change',function(){
  BG.init(this.value);
});
if (BG.UserName) {
  username.value = BG.UserName;
}Popup側では、
最後になりますが、
var UserName = localStorage.ldrUserName;
if (UserName) {
  check();
}
function init(name){
  UserName = localStorage.ldrUserName = name;
  check();
}Popupで入力されたユーザー名をlocalStorageにも保存しておき、
本当にシンプルですが、
Inter Extension Communication
Extensions同士での連携のために、
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();
});まず、
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さん、こんにちは'});
    }
  });
});続いて、
Tabs/Windows APIの操作 
最後に、
//新しいタブを現在のタブの隣に開く
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.
そのほか、
まとめ
今回は前回の特集記事以降に実装されたBrowser Actions APIを中心に、
