先日、四国GTUG主催のHTML5ハッカソンに参加してきました。
私はHTML5のことをよくわかってないので、全然HTML5の事を活かしたアプリとか考えれなかったので、前回の中国GTUGのHTML5ハッカソンの時と同様に、Chrome Extensionを作ることにしたのでした。アイデア出し自体も全然やってなかったけど、なんかアイデア降ってくるだろうと思っていたのですが、全然降ってこなくて、悩んだ挙げ句に考えたのが、楽天WebAPIを使ったアプリです。そう、困ったときの楽天WebAPI。
選択した文字列を右クリックでAndroidに送れるChromeToPhoneがあるので、右クリックにメニューを加えることができるだろうと。それだったら、選択した文字列から楽天Books検索できたらいちいち楽天のページ開かなくてもいいんじゃねーの?と思って、それを調べていました。HTML5ハッカソンでは時間が全然足りなくて半分もできなかったのですが、今日完成させることができたので、公開しました。よかったらどうぞ!
以降、作ったときのポイントなどを記述していきます。
一番困るかなと思っていたのは、クロスドメインでのAjaxなのですが、XMLHttpRequestクラスとパーミッションに指定ドメインを追加をすれば、簡単に通信できました。しかし、その前に実はjQueryを使ってgetJsonメソッドで取得できていました。jsonpで取れたので、これだとパーミッション要らない…。でもお行儀が悪く見えるかなーと思ったので、XMLHttpRequestを使うように修正しました。
前に作成したChrome ExtensionのTitleListでは、BrowserActionのpopup.htmlでのコーディングしかしてなかったのですが、今回はContextMenusを使うをつかったので、background_pageのbackground.htmlでのコーディングをしてます。ちょこっと。
// background.htmlで読み込んでいるbackground.js ** 検索文字列を設定*/ var searchWord; function rakutenBooksSearch(info, tab) { searchWord = info.selectionText; // 検索キーワードを変数に持たせて、タブを表示する。 // タブ側のjavscriptで表示処理を行なう chrome.tabs.create({ "url" : "popup.html", "selected" : true }); } var context = "selection"; var title = "楽天Books検索"; var id = chrome.contextMenus.create({ "title" : title, "contexts" : [context], "onclick" : rakutenBooksSearch });
まず、後半のほうで、右クリックにメニューを追加するためにchrome.contextMenus.createメソッドを呼んでいます。contextsにselectionを渡して、文字列を選択したときだけ表示されるようにしています。選択したら、rakutenBooksSearch関数が呼ばれるわけです。
そして最初で、background.html側で定義しているjsの変数にアクセスするので、searchWordという変数を作成してます。rakutenBooksSearch関数内で、選択文字列を取得し(info.selectionText)、それをsearchWordに保存しています。保存後、検索結果をタブで表示するために、タブの生成をしています。
popup.htmlという名前を付けていますが、別にpopup.htmlじゃなくてもいいです。
タブで表示した側のhtml(popup.html)で、JavaScriptを読み込みます。
そのJavaScriptで、background.htmlで使っているJavaScriptの変数を読み取ります。
chrome.extension.getBacgroujndPage();がそれです。
// popup.htmlで読み込んでいるJavaScript // background.htmlの要素を取得する var bg = chrome.extension.getBackgroundPage(); // 現在の楽天検索の対象ページ var currentPage = 1; // 楽天検索結果の最大ページ(1で初期化) var pageCount = 1 // 右クリックから送られてきた文字列で楽天Books検索を実行 rakutenBooksSearch(bg.searchWord, currentPage); function rakutenBooksSearch(word, page) { // 省略。urlやクエリの組み立てなどを行なう // manifest.jsonのpermissionsに定義したドメインのurlに対するXMLHttpRequest var xhr = new XMLHttpRequest(); xhr.open("GET", url + queryString, true); // 通信状態が変わったら呼ばれるコールバックを定義 xhr.onreadystatechange = function() { if(xhr.readyState == 4 && xhr.status == 200) { // 通信は成功 } else if (xhr.readyState == 4) { // 通信は終了したがエラー } else { // 通信が終了していない } } // 通信開始 xhr.send(); } // 以降、省略
xhr.onreadystatechangeにコールバックを定義するのですが、そこで処理を適当に定義するわけです。
最後に、manifest.jsonを公開しておきますので参考にどうぞ。
パーミッションに、Chrome固有の機能だけでなく、ドメインを指定しておくのがミソです。
{ "name": "楽天Books検索", "version": "1.0", "description": "楽天Booksより総合検索を行ないます", "background_page": "background.html", "permissions": ["tabs", "contextMenus", "http://api.rakuten.co.jp/"], "offline_enabled": false, "icons": { "16": "icon_16.png", "48": "icon_48.png", "128": "icon_128.png" } }
以上です。
ブラウザを使った業務アプリなどだったら、決まった操作とかばかりならChrome Extensionを作る事でものすごい効率がアップするんじゃないかと思います。
Chromeというブラウザ上のみではあるけれど、可能性が拡がってすごいですね、本当に。html5にも詳しくなって、便利なExtensionが作れたらなぁ〜と思います。