Context Menus と Omnibox を使って API の無い Web アプリの検索を実行する。
Chrome Extensions を作ろう
ちょっと社内の機能発表の用にネタアプリでも作ろうと思ったのが発端。うちは社長から営業、管理に至るまで Google Chrome が大好きで(弊社サービスは Chrome は公式にはサポートしていないが、社内ユーザーが多すぎて渋々対応している。。まあ特に何もしなくてもいい良い子なのでいいのですが)、せっかくだから弊社サービスの検索機能を Chrome から呼び出せるようにしてやろうと考えた訳です。
検索文字列を取得する
このあたりは Context Menus も Omnibox も楽勝で取得できる。
以下では manifest.json への記述は省略してるので注意してください。
Context Menus の場合
今回は選択中のテキストで検索するっていう機能に絞ります。
以下の background.html に書いておけばOK。
var id = chrome.contextMenus.create({"title" : "コンテキストメニューに出したいタイトル", "contexts": ["selection"], "onclick": genericOnClick}); function genericOnClick(info, tab) { console.log(info.selectionText); // 選択中にコンテキストメニューを呼び出した際の文字列が取得できる }
実はコンテキストメニューのタイトルに選択中のテキストを表示したかったんですが、方法が分かりませんでした。現状はできなさそうに見えます。
Omnibox の場合
もっと簡単になります。
chrome.omnibox.onInputEntered.addListener(function(text) { console.log(text); // manifest.json で設定したキーワードで検索した場合の文字列が取得できる });
新しいタブで開く
結局 API が無いので Chrome Extensions でやれる事はひとまずここまでです。
とりあえず自社サービスのURL を開いた状態で Tab を開くわけですが、本来であれば「ログイン」という行為が必要です。ただ、そこを API 抜きでやろうとすると割と面倒くさい(というか Get してトークン抜いて、POSTし直してぐらいですが、設定画面作る時間がなかった。。)ので、ログイン状態のセッションを維持してる状態での使用を想定しているという仕様にしていきなり開くと検索窓のある画面に入るという事にします。
tabs
var urls = 'サービスの URL'; chrome.tabs.create({ url:urls, selected:true // 選択状態で開く });
検索を実行する
つまり何がしたいかと言うと、API が無い上に、クエリ引数で検索ワードを渡す仕様にもなっていないので、検索するには POST のリクエストを飛ばすしか無いわけです。新しいタブを開いたところで、そのリクエストを強引に飛ばすという方法もあるでしょうが、不精な私はてっとり早く、検索窓に取得した検索用文字列を入れて、検索ボタンを押してやればいいんではないかと考えたわけですね。(この時点で発表会まで残り3時間、、本来の発表のためのスライドも作れていない。)
executeScript
スマートにやる方法が思いつかなかったので、タブを開いた時点でのイベントでスクリプトを流しこむという手段を取りました。
chrome.tabs.create({ url:urls, selected:true }, function(tabid) { var srcs = "document.getElementById('検索窓テキストボックスのID').value = '" + searchWord + "';" + "document.getElementById('検索のトリガーとなるボタンのID').click();" chrome.tabs.executeScript(tabid, { code : srcs }); });
このタブを開いた時点のイベントってのが、タブの中の DOM が構築し終わった後なのかがよく分からなかったのですが、とりあえず動いたのでよしとしました。見てる限りは全ての DOM が構築される前に呼ばれてるように見えますが、まあ大丈夫だったようです。必要な要素は上の方に集まっていましたし。