gihyo.
検索ボックスとコンテキストメニューの拡張
これまでは、
![図1 検索ボックス 図1 検索ボックス](/assets/images/dev/serial/01/chrome-web-store/0007/thumb/TH800_001.jpg)
![図2 コンテキストメニュー 図2 コンテキストメニュー](/assets/images/dev/serial/01/chrome-web-store/0007/thumb/TH800_002.jpg)
Webアプリの構成
今回は、
![ディレクトリ図](/assets/images/dev/serial/01/chrome-web-store/0007/thumb/TH400_dir.png)
{
"name": "Odometer",
"description": "距離計",
"version": "0.4",
"app": {
"launch": {
"local_path": "main.html"
}
},
"icons": {
"16": "icon_16.png",
"48": "icon_48.png",
"128": "icon_128.png"
},
"omnibox": {
"keyword": "Odometer"
},
"options_page": "options.html",
"background_page": "background.html",
"permissions": [
"geolocation",
"notifications",
"background",
"contextMenus",
"tabs"
]
}
検索ボックスを拡張するための指定として、
コンテキストメニューを拡張するためには、
Omnibox
Omniboxは、
Omniboxの使い方
先に実際のOmniboxの使い方を説明しましょう。検索ボックスには、
検索ボックスにマニフェストファイルで指定したキーワードを入力する
図3 検索ボックスにキーワードを入力 Webアプリのアイコンが表示されたサジェストを選択する
図4 Webアプリのサジェストを選択 図5 Webアプリに渡すキーワード エンターキーで入力完了とWebアプリの呼び出し
続けてWebアプリに渡すキーワードを入力
図6 Webアプリの呼び出し
OmniboxからのWebアプリの呼び出し
今回は、
// 検索ボックス設定
chrome.omnibox.onInputEntered.addListener(
function(text){
searchOnApp(text);
}
);
onInputEnteredイベントは、
// アプリのメイン画面URL
var APP_URL = chrome.extension.getURL('main.html');
/*
* アプリ上で住所検索を行います
*/
function searchOnApp(text){
selectOrCreateTab(APP_URL, function(tab){
var view = getView(APP_URL);
if ( !view ) {
return;
}
if ( tab.status === 'loading') {
view.searchText = text;
} else {
view.searchByText(text);
}
});
}
/*
* 指定されたURLのタブがあれば選択し、なければ作成します
*/
function selectOrCreateTab(url, callback){
chrome.tabs.getAllInWindow(null, function(tabs){
for ( var i = 0, len = tabs.length; i < len; i++ ) {
if ( tabs[i].url == url ) {
chrome.tabs.update(tabs[i].id, { selected: true }, callback);
return;
}
}
chrome.tabs.create({ url: url }, callback);
});
}
/*
* アプリ内の指定されたURLのWindowオブジェクトを取得します
*/
function getView(url){
var views = chrome.extension.getViews();
for ( var i = 0, len = views.length; i < len; i++ ) {
if ( views[i].location.href === url ) {
return views[i];
}
}
}
selectOrCreateTab メソッドでOdometerのタブを選択、
Odometerで検索するには、
//初期表示
//住所検索の呼び出しがあれば検索実行
if ( searchText ) {
searchByText(searchText);
searchText = '';
}
~省略~
/*
* 住所検索(テキスト指定)
*/
function searchByText(text){
document.getElementById('address').value = text;
search();
}
Omniboxのサジェスト
今回は利用していませんが、
// デフォルトのサジェスト
chrome.omnibox.setDefaultSuggestion({
content: "default",
description: "デフォルト"
});
// 入力中のサジェスト
chrome.omnibox.onInputChanged.addListener(
function(text, suggest){
suggest([
{ content: 'search ' + text, description: '住所検索=> ' + text }
]);
}
);
![図7 検索ボックスのサジェスト 図7 検索ボックスのサジェスト](/assets/images/dev/serial/01/chrome-web-store/0007/thumb/TH800_007.jpg)
メソッド/ | 説明 |
---|---|
setDefaultSuggestion(suggest) | デフォルトのサジェストを設定する |
イベント | 説明 |
---|---|
onInputCancelled | キーワードの入力がキャンセルイベント |
onInputChanged | キーワードの入力変更イベント コールバックにキーワードとサジェストを引数に持つ。function(text, suggest){…} |
onInputEntered | キーワードの入力完了イベント コールバックにキーワードを引数に持つ。function(text){…} |
onInputStarted | キーワードの入力開始イベント |
Context Menus
Context Menusは、
メニューの作成
今回は、
// コンテキストメニュー作成
chrome.contextMenus.create({
title: '住所検索',
contexts: ['selection'],
onclick: function(info, tab){
var text = info.selectionText;
searchOnApp(text);
}
});
titleでメニューの表示名を設定し、
さまざまなメニューと階層化
単なるラベルのメニュー以外にも、
var parentId = chrome.contextMenus.create({
title: 'サンプルメニュー'
});
// チェックボックス
chrome.contextMenus.create({
type: 'checkbox',
title: 'チェックボックス',
parentId: parentId
});
// セパレーター
chrome.contextMenus.create({
type: 'separator',
parentId: parentId
});
// ラジオボタン
chrome.contextMenus.create({
type: 'radio',
title: 'ラジオボタン',
parentId: parentId
});
![図8 さまざまなメニュー 図8 さまざまなメニュー](/assets/images/dev/serial/01/chrome-web-store/0007/thumb/TH800_008.jpg)
メソッド/ | 説明 |
---|---|
create(createProperties, callback) | メニューを作成する |
remove(menuItemId, callback) | メニューを削除する |
removeAll(callback) | メニューをすべて削除する |
update(id, updateProperties, callback) | メニューを更新する |
メソッド/ | 説明 |
---|---|
type | メニューのタイプ normal: ラベル checkbox: チェックボックス radio: ラジオボタン separator: セパレーター |
title | メニューの表示名 |
checked | typeがcheckboxまたはradioの場合のチェック状態 |
contexts | メニューを表示するフォーカスの対象を配列で指定する all: すべて page: ページ frame: iframe内 selection: テキスト選択 link: リンク editable: 入力可能フォーム image: 画像 video: 動画 audio: 音声 |
onclick | クリック時のコールバック function(info, tab){…} infoは、 |
documentUrlPatterns | メニューを表示するURLパターン |
targetUrlPatterns | contextsがimage、 |
メソッド/ | 説明 |
---|---|
menuItemId | メニューID |
parentMenuItemId | 親メニューID |
mediaType | メディアタイプ contexts: image/ |
linkUrl | リンクURL contexts: link |
srcUrl | ソースURL contexts: image/ |
pageUrl | ページURL contexts: page |
frameUrl | フレームURL contexts: frame |
selectionText | 選択テキスト contexts: selection |
editable | 編集可能かどうか contexts: editable |
※:contextsは同時に複数マッチする場合があります。
まとめ
これで、
今回は、
- ※
crxファイルはzipファイルですので、
右クリックからのダウンロード後に拡張子をzipに変えていただければ中身を参照できます。