Chrome Extension開発を勉強してみる (8) - ominibox -

2012-07-14T00:00:00+09:00 Chrome Extension JavaScript

Chromeにはomniboxっていうアドレスバーにアクションを追加して候補を補完してくれたりする機能がありますが、これを作ってみる。

要件

Twitterアカウントでフォローしている人をアカウントを補完で出す。んでscreen_nameによりフィルターした結果を出しつつ、選択された人のアカウントのページに移動するっていうのをやる

準備

まず必要なのとして、OAuth認証をしなきゃいけないので http://oauth.googlecode.com/svn/code/javascript を使います。oauth.jsとsha1.jsをコピーしてくる。でこのファイルは拡張機能のディレクトリ内に配置しておく(ついでに今回はjQueryも使うので)

んで、http://dev.twitter.comから開発者アカウントにログインしてアプリを登録後、Consumer KeyとSecretとAccess TokenとSecretを取得してくる。今回めんどくさいのでrequest_tokenとかaccess_tokenしません。自身のAccess Tokenを予め取得しておいてそれを使ってごにょごにょします

でここまでで拡張機能ディレクトリに必要なのは

  • jquery.js
  • sha1.js
  • oauth.js
  • manifest.json
  • background.js

の5つのファイルが必要になる。後者2つはこれから書きますので(ry

manifest.json

{
  "name": "test",
  "version": "0.1",
  "omnibox": { "keyword": "twi" },
  "background": {
    "scripts": ["jquery.js", "sha1.js", "oauth.js", "background.js"]
  },
  "permissions": ["tabs", "https://api.twitter.com/"]
}

omnibox{ "keyword": "twi" }とするとアドレスバーにtwiと入力した時点でTABを押すとコマンドモードに入れるように出来る。まぁkeywordはご自身で決めれますので(ry

あと今まではbackground_pageで指定してましたが、JavaScriptだけを使う場合でHTMLElementとかに依存しないのであれば別にbackgroundで指定しても良いみたいで。実際にやるとbackground_pageなHTMLが自動で生成される模様

でここでダウンロードしてきた必要なJSファイルを指定。manifest.json以外なので今回は4つ。でhttps://api.twitter.com にアクセスする必要があるので権限を追加しておく。あとタブ操作もするのでその権限も必要

background.js

function oauth_request(url, params) {
  var message = {
    "method": "GET",
    "action": url,
    "parameters": {
      "oauth_signature_method": "HMAC-SHA1",
      "oauth_consumer_key": "[Consumer Key]",
      "oauth_token": "[Access Token]"
    }
  };

  for (var key in params) {
    message.parameters[key] = params[key];
  }

  OAuth.setTimestampAndNonce(message);
  OAuth.SignatureMethod.sign(message, {
    "consumerSecret": "[Consumer Secret]",
    "tokenSecret": "[Access Secret]"
  });

  return OAuth.addToURL(message.action, message.parameters);
}

// (自身が)フォローしている人のユーザーIDを取得する
function get_users() {
  var user_ids_url = oauth_request("https://api.twitter.com/1/friends/ids.json", { "screen_name": "kinjou_j" });

  var ids = new Array;

  $.ajax({
    "type": "GET",
    "url": user_ids_url,
    "async": false,
    "dataType": "json",
    "success": function(data) {
      ids = data.ids;
    }
  });

  return ids;
}

// フォローしている人のユーザーIDからscreen_nameとnameを取得する
function get_user_info() {
  var users = new Array;

  get_users().forEach(function(i) {
    var user_info_url = oauth_request("https://api.twitter.com/1/users/lookup.json", { "user_id": i });

    $.ajax({
      "type": "GET",
      "url": user_info_url,
      "async": false,
      "dataType": "json",
      "success": function(data) {
        var user = data[0];

        users.push({ "id": user.screen_name, "name": user.name });
      }
    });
  });

  return users;
}


var users = get_user_info();

// コマンドモードに入った際に発動?
chrome.omnibox.onInputChanged.addListener(function(text, suggest) {
  var suggests = new Array;

  if (users !== undefined && users.length > 0) {
    $.each(users, function(i, user) {

      // テキストが無い場合はフィルターは発動させない
      if (text !== undefined && text.length > 0) {
        var regexp = new RegExp("^" + text);

        // screen_nameからフィルターしてマッチしないのは除外する

        if(!regexp.test(user.id)) {
          return true;
        }
      }

      /*
      contentキーに補完されたデータに対するURL
      descriptionに補完に表示するテキストを指定?(ここまだよく分かってない)
      */

      suggests.push({
        "content": "http://twitter.com/" + user.id,
        "description": user.name
      });
    });
  }

  suggest(suggests);
});

// 候補が選択された際に発動?
chrome.omnibox.onInputEntered.addListener(function(text) {
  if (text !== undefined && /^http://twitter.com//.test(text)) {
    // ominiboxが発動しているタブを取得してそのタブで選択されたユーザーのURLでタブを更新する
    chrome.tabs.getSelected(null, function(tab) {
      chrome.tabs.update(tab.id, { "url": text });
    });
  }
});

でこれやると

みたいな感じでモードに入った状態でフォローしている人が出る。もちろんscreen_nameにマッチするようにテキストを入力したりする事でフィルターする事も出来る(下の画像の場合はtgskと入力するとscreen_nameでマッチするアカウントが補完)

追記

chrome://omnibox でちょっとしたチェックっぽいの出来る模様

Native Client(NaCl)をやってみる Chrome Extension開発を勉強してみる (7) - NPAPI -