こんにちは、
が、
Extensionsを作られた方はDeveloper DashboardからExtensionを登録できます。登録時の注意などはブログにまとめていますので、
さて、
Override PagesとNew Tabページ
まずNew Tabページとは、
早速、
{
"name": "Blank new tab page",
"version": "0.1",
"chrome_url_overrides": {
"newtab": "blank.html"
}
}
2009年12月時点で、
ちなみに、
<html>
<head>
<title>Blank New Tab</title>
<style>
div {2009/12/09 3:04
color: #cccccc;
vertical-align: 50%;
text-align: center;
font-family: sans-serif;
font-size: 300%;
}
</style>
</head>
<body>
<div style="height:40%"></div>
<div>Blank New Tab™</div>
</body>
</html>
上書きしたページはExtensionsのページとして扱われますので、
- 速く、
小さく作る - New Tabページは頻繁に使用するので、
パフォーマンスが重要です。同期的にネットワーク通信やデータベースへの接続などをすることは避けましょう。 - タイトルを設定する
- タイトルを設定ないとURLがタブに表示されてしまいます。<title>New Tab</title> のようにしましょう
- キーボードのフォーカスがあることに依存させない
- 新しいタブを開いたときは常にOmnibox
(アドレスバー) にフォーカスします。 - デフォルトのNew Tabページを再現しようとしない
- デフォルトのNew Tabページとよく似たページを作るために必要なAPI
(よく見るページ、 最近閉じたページ、 チップス、 テーマの背景画像) は (今のところ) 存在しません。今のところは、 デフォルトのページとはまったく違ったページにしたほうがよいでしょう。
Bookmarks API
続いて、
{
"permissions": [
"bookmarks"
],
}
さて、
まず、
このBookmarkTreeNodeでフォルダもブックマークも表現するという点が少々わかりにくいかと思います。次に例として全ブックマークを走査するコードを挙げてみます。
chrome.bookmarks.getTree(function(roots){
var bookmarks = [];
roots.forEach(parser);
function parser(node){
if (node.children) {
node.children.forEach(parser);
} else if(node.url) {
bookmarks.push(tree);
}
}
console.log(bookmarks);
});
chrome.
このように、
chrome.bookmarks.search("テスト", function(results) {
console.log(results);
});
名前の通り、
New Tabページを書き換える拡張
ではNew TabページをカスタマイズするExtensionを作成してみます。まず、
{
"name": "Start Tile",
"description": "replace newtab page",
"version": "0.0.1",
"chrome_url_overrides": {
"newtab": "tile.html"
},
"permissions": [
"tabs",
"bookmarks"
]
}
Tabs APIとBookmark APIを使用するので、
では、
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Start Tile</title>
<link href="tiles.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="box-table">
<div id="box-row-single">
<section>
<h2>Tab</h2>
<ul id="tab_list"></ul>
</section>
<section>
<h2>Bookmark</h2>
<ul id="bookmarks_list"></ul>
</section>
<section>
<h2>History</h2>
<ul id="history_list"></ul>
</section>
</div>
</div>
<ul id="tmpl"><li><a></a></li></ul>
<script src="tiles.js"></script>
</body>
</html>
まずは骨となるHTMLです。<ul id="tmpl">の部分はテンプレート用で、
続いて、
#tmpl{
display:none;
}
#box-table{
display:table;
border-collapse:separate;
border-spacing:0.5em;
}
#box-row-single{
display:table-row;
}
#box-row-single > section{
display:table-cell;
border-top:3px solid #0066ff;
border-right:3px solid #99ccff;
border-bottom:3px solid #99ccff;
border-left:3px solid #0066ff;
-webkit-border-top-left-radius:1.5em;
-webkit-border-bottom-right-radius:1.5em;
padding:0.5em;
width:33%;
overflow:hidden;
}
/*以下省略*/
display:table、

最後に、
var tab_list= document.getElementById('tab_list'),
bookmark_list= document.getElementById('bookmarks_list'),
history_list= document.getElementById('history_list'),
tmpl= document.getElementById('tmpl').firstChild,
FAVICON= 'http://www.google.com/s2/favicons?domain=';
まず、
function list_creater(datas, parent, callback){
datas.forEach(function(data){
if (data.url && data.title &&
data.url.indexOf('javascript:') !== 0) {
var li = tmpl.cloneNode(true);
var a = li.firstChild;
a.href = data.url;
a.textContent = data.title;
var icon = document.createElement('img');
icon.src = data.favIconUrl || FAVICON + a.host;
a.insertBefore(icon, a.firstChild);
parent.appendChild(li);
if (callback) {
callback(data, a);
}
}
});
}
この関数を使って、
chrome.bookmarks.getTree(function(roots){
var bookmarks = [];
roots.forEach(parser);
function parser(node){
if (node.children) {
node.children.forEach(parser);
} else if(node.url) {
bookmarks.push(node);
}
}
list_creater(bookmarks, bookmark_list);
});
続いて、
function TabUpdate(){
chrome.tabs.getAllInWindow(null,function(tabs){
while (tab_list.firstChild) {
tab_list.removeChild(tab_list.firstChild);
}
list_creater(tabs, tab_list, function(tab, link){
link.addEventListener('click',function(evt){
evt.preventDefault();
evt.stopPropagation();
chrome.tabs.update(tab.id,{selected:true});
}, false);
});
});
}
TabUpdate();
タブの場合、
chrome.tabs.onUpdated.addListener(function(tabid, info){
if (info.status === 'complete') {
TabUpdate();
}
});
chrome.tabs.onRemoved.addListener(function(tabid){
TabUpdate();
});
chrome.tabs.onDetached.addListener(function(tabid){
TabUpdate();
});
chrome.tabs.onAttached.addListener(function(tabid){
TabUpdate();
});
chrome.tabs.onMoved.addListener(function(tabid){
TabUpdate();
});
タブのイベントAPIをフルに使用してタブの変更を監視し、
最後に、
const LEFT_CLICK = 0;
const CENTER_CLICK = 1;
document.addEventListener('click',function(evt){
var target = evt.target;
if (target instanceof HTMLAnchorElement &&
target.href &&
target.href.indexOf('http') !== 0) {
evt.preventDefault();
chrome.tabs.getSelected(null,function(tab){
switch (evt.button) {
case LEFT_CLICK :
chrome.tabs.update(tab.id,{url:target.href});
break;
case CENTER_CLICK:
chrome.tabs.create({
url:target.href,
selected:false
});
break;
}
});
}
},false);
左クリックの場合、
今回作成したExtensionはこちらからインストールできます。
まとめ
今回はBookmark APIやOverride Pagesの使い方を解説しました。
次回は今回作成したExtensionをブラッシュアップしながら拡張の開発ノウハウなどを紹介したいと思います。