The document is valid HTML5 + ARIA + SVG 1.1 + MathML 2.0 (subject to the utter previewness of this service).
<!doctype html>↩<html lang="ja">↩<meta charset="utf-8">↩<title>Chrome Extension meets HTML5</title>↩<link rel="stylesheet" href="screen.css" type="text/css" media="screen">↩<link rel="stylesheet" href="print.css" type="text/css" media="print">↩<link rel="stylesheet" type="text/css" href="prettify.css" />↩<link rel="canonical" href="http://ss-o.net/chrome/extension/html5.html">↩<script src="prettify.js"></script>↩<script src="outliner.js"></script>↩<script>↩window.onload=function(){↩prettyPrint();↩var root = window.getMatchedCSSRules ? document.body : document.documentElement;↩var ds = [root];↩var list = AutoIndex(createOutline(document));↩//var outline = document.getElementById('outline');↩var outline = document.createElement('div');↩outline.id = 'outline';↩outline.innerHTML = '目次';↩list.className = 'auto-index';↩outline.appendChild(list);↩document.body.insertBefore(outline, document.body.firstChild);↩var hash = '';↩function AutoIndex(outline){↩ var ol = document.createElement('ol');↩ for (var i = 0,len = outline.length;i < len;i++) {↩ var item = outline[i];↩ var li = document.createElement('li');↩ if (item.headElement) {↩ var a = document.createElement('a');↩ a.innerHTML = item.headElement.innerHTML;↩ a.href = '#' + item.headElement.id↩ a.onclick = (function(target){↩ return function(evt){↩ hash = target.id;↩ SmoothScroll(root.scrollTop, target.offsetTop);↩ return false;↩ };↩ })(item.headElement);↩ li.appendChild(a);↩ ds.push(item.headElement);↩ }↩ ol.appendChild(li);↩ if (item.childs && item.childs.length) {↩ li.appendChild(AutoIndex(item.childs));↩ }↩ }↩ return ol;↩}↩var rds = ds.slice().reverse();↩var len = ds.length;↩var end = false;↩var timer;↩document.onkeydown = key_scroll;↩function key_scroll(evt){↩ if (!evt) {↩ evt = window.event;↩ }↩ if (evt.keyCode === 75){// k↩ scroll(true);↩ return false;↩ } else if (evt.keyCode === 74) {// j↩ scroll();↩ return false;↩ } else if (evt.keyCode === 32 && !evt.shiftKey) {// Space↩ SmoothScroll(root.scrollTop, root.scrollTop + 150);↩ return false;↩ } else if (evt.keyCode === 32 && evt.shiftKey) {// Shift+Space↩ SmoothScroll(root.scrollTop, root.scrollTop - 150);↩ return false;↩ }↩}↩function scroll(up){↩ if (SmoothScroll.blocking) {↩ if (timer) {↩ clearTimeout(timer);↩ }↩ timer = setTimeout(function(){↩ scroll(up);↩ timer = null;↩ }, 100);↩ return;↩ }↩ for (var i = 0;i < len;i++) {↩ var div = up ? rds[i] : ds[i];↩ var top = div.offsetTop - root.scrollTop;↩ if (10 < (up ? -top:top)) {↩ hash = div.id;↩ SmoothScroll(root.scrollTop, div.offsetTop);↩ break;↩ }↩ }↩ var scrollMax = document.documentElement.scrollHeight- document.documentElement.clientHeight;↩ if (i === len || scrollMax === root.scrollTop) {↩ if (end) {↩ if (!up) {↩ hash = '';↩ SmoothScroll(root.scrollTop, 0);↩ } else {↩ SmoothScroll(root.scrollTop, scrollMax);↩ }↩ end = false;↩ } else {↩ end = true;↩ }↩ } else {↩ end = false;↩ }↩}↩function easeOutQuart(t, b, c, d) {↩ return -c *((t=t/d-1)*t*t*t - 1) + b;↩}↩function SmoothScroll(from, to){↩ var _y = to - from;↩ var duration = Math.log(_y < 0 ? -_y : _y) * 70;↩ var easing = easeOutQuart;↩ var begin = +new Date();↩ var timer = setInterval(scroll, 10);↩ SmoothScroll.blocking = true;↩ function scroll(){↩ var time = new Date()-begin;↩ var prog_y = easing(time, from, _y, duration);↩ window.scrollTo(0, prog_y);↩ if (time > duration) {↩ //alert(hash);↩ location.hash = hash;↩ window.scrollTo(0, to);↩ SmoothScroll.blocking = false;↩ clearInterval(timer);↩ }↩ }↩}↩var extFiles = document.getElementById('ext-files');↩var links = extFiles.getElementsByTagName('a');↩for (var i = 0; i < links.length;i++){↩ var a = links[i];↩ if(/TweetNotify/.test(a.href)) {↩ a.onclick = function(){↩ var href = this.getAttribute('href',2);↩ var pre = document.getElementById(href.replace(/\W/g,'-'));↩ if (pre) {↩ pre.style.display = (!pre.style.display || pre.style.display==='none') ? 'block' : 'none';↩ }↩ return false;↩ }↩ }↩}↩};↩</script>↩<body>↩↩<h1 id="title">Chrome Extension meets HTML5</h1>↩<p>Chrome拡張とHTML5の蜜月</p>↩<address>Shogo Ohta, 2010-3-17</address>↩↩<h2 id="profile">自己紹介</h2>↩<dl>↩ <dt>名前:<dd>太田 昌吾↩ <dt>ID:<dd>os0x(<a href="http://d.hatena.ne.jp/os0x/">blog</a>, <a href="http://twitter.com/os0x">Twitter</a>)↩ <dt>肩書?:<dd>Chrome ExtensionsのAPI Expertで、<a href="http://groups.google.co.jp/group/chromium-extensions-japan">Chromium-Extensions-Japanグループ</a>の管理人↩ <dt>お仕事:<dd><p>今年に入ってからお休み中…<br><a href="http://gihyo.jp/dev/serial/01/chrome-extensions">Chrome拡張について記事</a>を書いたり、<a href="http://gihyo.jp/dev/serial/01/crossbrowser-javascript">JavaScriptの記事</a>を書いたりしています↩ <p>2010/3/25に<a href="http://www.amazon.co.jp/dp/4844328468"><img src="chrome_os_book.jpg">Google Chrome OS 最新技術と戦略を完全ガイド: 小池良次, 中島聡, 伊藤千光, 太田昌吾, まえだひさこ, 向井領治</a>が発売されます!↩ <dt>得意分野:<dd>ほぼJavaScript専門、なかでもクロスブラウザや高速化が得意です↩ <dt>簡単な経歴:<dd>元々、OperaのUserJavaScriptやGreasemonkeyを良く書いていた(<a href="http://d.hatena.ne.jp/os0x/20071202/oautopagerize">oAutoPagerize</a>とか)<br>ChromeでもUserScriptsが動くらしい→拡張もできる(ようになる)らしい→UserJavaScriptより色々できて楽しい!→拡張作ったり、記事を書いていたらgihyo.jpで連載をすることに→そのまま勢いでAPI Expertに↩</dl>↩↩<h2 id="google-chrome">Google Chromeとは、Chrome拡張とは</h2>↩<dl>↩ <dt>Chromium↩ <dd>レンダリングエンジンにWebKitを、JavaScriptエンジンにV8を採用したオープンソースのウェブブラウザ↩ <dt>Google Chrome↩ <dd>ChromiumをGoogleがカスタムして公開しているブラウザ↩ <dt>Chrome拡張↩ <dd>Chrome/Chromium上で動く、ウェブブラウザに特定の機能を追加するアプリケーション↩</dl>↩↩<h3 id="chrome-chromium">Chrome vs Chromium</h3>↩<table class="box">↩ <tr><th></th><th>Google Chrome</th><th>Chromium</th><th>補足</th></tr>↩ <tr><th>ロゴ</th><td><a href="chrome_icon.png"><img src="chrome_icon_s.png"></a></td><td><a href="chromium_icon.png"><img src="chromium_icon_s.png"></a></td><td></td></tr>↩ <tr><th>開発者</th><td>Googler</td><td>誰でも(多くはGoogler)</td><td></td></tr>↩ <tr><th>障害報告</th><td>あり(ONにした場合)</td><td>なし</td><td></td></tr>↩ <tr><th>利用統計</th><td>あり(ONにした場合)</td><td>なし</td><td></td></tr>↩ <tr><th>HTML5のVideo、Audio</th><td>H.264、AAC、MP3、Vorbis、Theora </td><td>デフォルトではVorbisとTheoraのみ</td><td>FFmpegを使用しているので、自己責任においてこれを差し替えれば対応フォーマットを変えることができる</td></tr>↩ <tr><th>ページ翻訳機能</th><td>あり</td><td>なし</td><td>※日本語圏での評判はいまひとつ</td></tr>↩ <tr><th>サンドボックス(セキュリティ機構)</th><td>常にON</td><td>場合によってはOFFになっていることも</td><td>非公式なパッケージなどは要注意</td></tr>↩ <tr><th>品質保証</th><td>事前にテストされてからリリースされる</td><td>Nightly Buildsのみ</td><td></td></tr>↩</table>↩↩<h3 id="spec-chromium">Chromiumの特徴</h3>↩<p>オープンソースなので、すべてのソースが読める。カスタムしてビルドを作れる。↩<p>オープンソースコミュニティのパワーで、日々開発が進んでいる。また、Chromiumのカスタム版が数多く存在する。↩<p>今すぐ開発に参加できる <a href="http://code.google.com/p/chromium/">chromium - Project Hosting on Google Code</a>へ!↩↩<h3 id="spec-chrome">Chromeの特徴</h3>↩<p>stable(安定版)、beta(テスト版)、dev(開発版)の3つのリリースがある↩<p>安定版は名前の通り、一般ユーザーが使用するリリース、(セキュリティフィックスを除いて)半年に1回程度のリリース↩<p>テスト版は、主に安定版のリリース前に、安定化のためにリリースされる、時期によってはまったくリリースされないが、1ヶ月に1回程度のリリース↩<p>開発版は、安定版のリリース後、次のバージョンに向けた新機能追加を主目的(そのため不安定になることも多々)にリリースされる、1週間に1回程度のリリース<br>※開発版もリリース前は安定する。修正が多く適用されている分だけテスト版より安定することも。↩↩<h3 id="chrome-engine">Chromeの構成</h3>↩<p>JavaScriptエンジンはV8というChromeのために開発したオープンソースのエンジンを搭載↩<p>レンダリングエンジンはWebKitのWebCoreを採用↩<p>WebCoreは、WebKitのレンダリング周りの実装(JavaScript部分はJavaScriptCore)↩<p>実は、V8とWebCoreを繋ぐ部分にバグが多い…(Safariでは正常なのに、Chromeだとなんかおかしくなるなぁという現象はここに起因することがほとんど)↩<p>最近はChromiumチームが積極的にWebKitにコミットするようになっていて、かなり改善しつつある↩↩<h3 id="chrome-ext">Chrome拡張とは</h3>↩<p>HTML/CSS/JavaScriptで作る、ブラウザをもっと便利にするモノ↩<p>とにかく作るのは簡単、でも制約は多い↩↩<h3 id="ext-sample">Chrome拡張の例</h3>↩<p>実物を見てもらうのが一番↩<p><a href="https://chrome.google.com/extensions/detail/mihcahmgecmbnbcchbopgniflfhgnkff" target="_blank">Google Mail Checker - Google Chrome 拡張機能ギャラリー</a>↩<p><a href="https://chrome.google.com/extensions/detail/pabfempgigicdjjlccdgnbmeggkbjdhd" target="_blank">Chrome Stylist - Google Chrome 拡張機能ギャラリー</a>↩<p><a href="https://chrome.google.com/extensions/detail/dnlfpnhinnjdgmjfpccajboogcjocdla" target="_blank">Hatena Bookmark GoogleChrome extension - Google Chrome 拡張機能ギャラリー</a>↩↩<h3 id="ext-feature">Chrome拡張でできること</h3>↩<ul>↩ <li>バックグラウンド処理↩ <li>クロスドメイン通信(<a href="http://www.w3.org/TR/2009/WD-XMLHttpRequest2-20090820/">XMLHttpRequest Level 2</a>と<a href="http://www.w3.org/TR/2009/WD-cors-20090317/">Cross-Origin Resource Sharing</a>)↩ <li>データの永続化(<a href="http://www.w3.org/TR/2009/WD-webstorage-20091222/">Web Storage</a>、<a href="http://www.w3.org/TR/2009/WD-webdatabase-20091222/">Web SQL Database</a>、<a href="http://www.w3.org/TR/2010/WD-IndexedDB-20100105/">Indexed Database API</a>)<br>※Indexed Database APIが使えるようになるのはまだ先ですが↩ <li>デスクトップへの通知(<a href="http://dev.w3.org/2006/webapi/WebNotifications/publish/">Web Notifications</a>)↩ <li>タブ・ウィンドウの操作(新規タブを開いたり、閉じたり、選択を変えたり)↩ <li>ブックマークの操作↩ <li>UIパーツの追加(ただし、アイコンを追加するのみ)↩ <li>ポップアップの表示↩ <li>表示したページでJavaScriptを実行↩ <li>国際化↩ <li>などなど(拡張のAPIは本当にこれだけ)↩</ul>↩<p>APIはまだまだ少ないが、バックグラウンド処理、クロスドメイン通信、データの永続化をベースに、可能性は無限↩↩<h3 id="ext-security">Chrome拡張のセキュリティ</h3>↩<p><img src="context.png">↩<p>拡張コンテキスト、コンテントコンテキスト、ページコンテキストの3つのコンテキストが存在し、それぞれは完全に分かれているので、お互いが干渉してしまうことはない。さらに、拡張同士も独立したコンテキストで実行される。↩<p>拡張コンテキストはタブ操作やクロスドメイン通信などの特権を実行でき、コンテントコンテキストと通信したり、スクリプトを実行したりといったことができます。↩<p>コンテントコンテキスト(ContentScripts)は特権を持っていませんが、読み込んだページのDOMを操作することができ、拡張コンテキストと相互に通信できます。↩<p>ページコンテキストは通常のウェブページで実行されるコンテキストで、コンテントコンテキストとはDOM経由でしかやり取りできませんし、拡張コンテキストとは完全に分断されています↩<p>「悪意のあるページで拡張の特権を利用されてしまう」といったことが起こりにくい仕様になっているが、開発者から見ると面倒に感じる部分も…↩↩<h3 id="ext-manifest">manifest.json</h3>↩↩<p>拡張を定義するjsonファイル。名前、バージョンのほか、アイコンや拡張の持つ権限、ContentScriptsを実行するURLの定義など。↩<p>manifest.jsonで宣言していない機能は使用できない。↩<p>セキュリティを高めつつ、機械的にその拡張の権限を判断して、インストールするユーザーに警告を出すことができる。↩↩<h2 id="chrome-html5">Chrome拡張で使えるHTML5</h2>↩↩<h3 id="support-html5">ChromeのHTML5対応:関連API</h3>↩<dl>↩ <dt>canvas↩ <dd>対応済み↩ <dt>video, audio↩ <dd>対応済み(対応フォーマットは前述の通り)↩ <dt>Web Workers↩ <dd>対応済み↩ <dt>Web Storage↩ <dd>Chrome4ではlocalStorageのみ対応、Chrome5でsessionStorageも対応予定↩ <dt>コミュニケーションAPI↩ <dd>対応済み(ただし、Chrome4ではテキストのみの送受信)↩ <dt>Web Sockets↩ <dd>対応済み(ただし、WokerからのSocketsはChrome5で対応予定)↩ <dt>HTML Ruby↩ <dd>対応済み↩ <dt>Web Fonts↩ <dd>対応済み↩ <dt>Web SQL Database↩ <dd>対応済み(残念ながら標準化はストップしてしまいましたが…)↩ <dt>Desktop notifications↩ <dd>Chrome5で正式対応予定↩ <dt>HTML Forms↩ <dd>一部のみ対応、Chrome5ではAPIを実装、バリデーションやUIはChrome6以降↩ <dt>Application Cache↩ <dd>Chrome5で対応予定↩ <dt>Geolocation API↩ <dd>Chrome5で対応予定↩ <dt>Drag & drop↩ <dd>一部実装されているが、Chrome5で完全に対応する予定↩ <dt>File API↩ <dd>Chrome5で対応予定↩ <dt>Indexed Database API↩ <dd>Chrome6で対応予定、2010/3/11に動作したとの第一報あり↩</dl>↩<p>最新の情報は、<a href="http://dev.chromium.org/developers/web-platform-status">Web Platform Status (The Chromium Projects)</a>にまとまっています↩↩<h3 id="html5-parser">ChromeのHTML5対応:HTMLパーサー</h3>↩<pre class="prettyprint html">↩<p>第1パラグラフ↩<section>セクション</section>↩<p>第2パラグラフ↩</pre>↩<p>わざとらしい例ですが、パーサーがsectionに対応しているか否かで、下記のように解釈が変わります。↩<table class="box">↩<tr><td></td><td>Chrome</td><td>Firefox</td></tr>↩<tr><td>section要素未対応</td><td><img src="no_html5_chrome.png"><br>Chrome4</td><td><img src="no_html5_firefox.png"><br>Firefox3.6</td></tr>↩<tr><td>section要素対応</td><td><img src="yes_html5_chrome.png"><br>Chrome5</td><td><img src="yes_html5_firefox.png"><br>Firefox3.6(html5.enable)</td></tr>↩</table>↩↩<h3 id="chrome2html5">Chrome拡張からHTML5へ</h3>↩ <p>元々、Chrome拡張のAPIの仕様だった<a href="http://dev.chromium.org/developers/design-documents/desktop-notifications">Desktop Notifications</a>が、2010年1月にW3C Editor's Draftとして(<a href="http://dev.w3.org/2006/webapi/WebNotifications/publish/">Web Notifications</a>)公開されました。↩ <p>このように、Chrome拡張は各種APIがHTML5をベースとしており、同時に、Chrome拡張からHTML5にフィードバックする、という相互作用の関係があります↩ <p>HTML5を使いたい!という方は、是非Chrome拡張を!!↩↩<h2 id="ext-tutorial">Chrome拡張の作り方</h2>↩↩<p>Twitterのハッシュタグなどの検索結果をNotifications APIで表示してみます↩<p>まず、manifest.jsonと各ファイルを用意します。↩<dl id="ext-files">↩ <dt><a href="TweetNotify/manifest.json">manifest.json</a>↩ <dd>日本語はそのまま記述できるが、文字コードはUTF-8(BOMなし)にする必要がある。↩<pre class="prettyprint js hidden" id="TweetNotify-manifest-json">{↩ "name": "Hash Tweet",↩ "description": "特定のhashtagが含まれるTweetをデスクトップに表示します",↩ "version": "0.0.4",↩ "background_page": "background.html",↩ "browser_action": {↩ "default_title": "Show Notification",↩ "default_icon": "Twitter-icon.png",↩ "popup": "popup.html"↩ },↩ "icons": {↩ "48": "Twitter-icon.png"↩ },↩ "permissions": [↩ "notifications",↩ "http://*.twitter.com/",↩ "http://twitter.com/"↩ ]↩}↩</pre>↩ <dt><a href="TweetNotify/background.html">background.html</a>↩ <dd>Twitterのtokenの取得、ハッシュタグを検索して結果をNotifications APIで表示させるなど、メイン処理を行う↩ <pre class="prettyprint js hidden" id="TweetNotify-background-html">var keyword = localStorage.keyword;↩var twitter_token;↩var CheckTime = 60;↩var notifies = {};↩var tweets = {};↩var timer;↩init(keyword);↩function init(tag){↩ localStorage.keyword = keyword = tag;↩ if (twitter_token) {↩ clearTimeout(timer);↩ Object.keys(notifies).forEach(function(id){↩ var note = notifies[id];↩ note.cancel();↩ });↩ start();↩ } else {↩ xhr('http://twitter.com/', function(res){↩ var text = res.responseText;↩ var handler = function(){↩ window.parent.postMessage(document.getElementById("authenticity_token").value,"*");↩ };↩ window.onmessage = function(evt){↩ delete window.onmessage;↩ document.body.removeChild(frame);↩ twitter_token = evt.data;↩ if (keyword) {↩ start();↩ }↩ };↩ var frame = document.createElement('iframe');↩ frame.src = 'data:text/html,<html><script>window.onload = ' + handler + ';<\/script>' +↩ text.replace(/<script(?:[ \t\r\n][^>]*)?>[\S\s]*?<\/script[ \t\r\n]*>|<\/?(?:i?frame|html|script|object)(?:[ \t\r\n][^<>]*)?>/gi, ' ');↩ document.body.appendChild(frame);↩ });↩ }↩}↩function xhr(url, callback, error){↩ var xhr = new XMLHttpRequest();↩ xhr.open('GET', url, false);↩ xhr.onload = function(){callback(xhr);};↩ xhr.onerror = function(){↩ console.error(xhr);↩ if (error) error();↩ };↩ xhr.send();↩}↩function restart(){↩ chrome.browserAction.setBadgeText({text:'!'});↩ setTimeout(function(){↩ start();↩ }, 60 * 1000);↩}↩function start(){↩ var token = '&authenticity_token=' + twitter_token;↩ var api = 'http://integratedsearch.twitter.com/search.html';↩ var url = api + '?q=' + encodeURIComponent(keyword) + '&rpp=20&refresh=true' + token;↩ main(url);↩ function main(url){↩ xhr(url, function(res){↩ var text = res.responseText, data;↩ try {↩ data = JSON.parse(text);↩ } catch (e) {↩ console.error(e);↩ restart();↩ return;↩ }↩ if (data.results && data.results.length) {↩ data.results.reverse().forEach(function(item, i){↩ tweets[item.id] = item;↩ var url = 'chrome-extension://' + location.host + '/note.html#'+item.id;↩ var notify = webkitNotifications.createHTMLNotification(url);↩ notify.onclose = function(){↩ delete notifies[item.id];↩ delete tweets[item.id];↩ }↩ notify.show();↩ notifies[item.id] = notify;↩ });↩ chrome.browserAction.setTitle({title:String(data.results.length) + ' tweet(s)!'});↩ } else {↩ chrome.browserAction.setTitle({title:'no tweet..'});↩ }↩ /*↩ setTimeout(function(){↩ Object.keys(notifies).forEach(function(id, i, a){↩ var note = notifies[id];↩ setTimeout(function(){note && note.cancel();}, (i * CheckTime / a.length) * 900);↩ });↩ }, CheckTime/6 * 1000);↩ */↩ var count = 0;↩ (function loop(){↩ timer = setTimeout(function(){↩ if (++count > CheckTime) {↩ main(api + data.refresh_url + '&refresh=true' + token);↩ } else {↩ chrome.browserAction.setBadgeText({text:String(CheckTime-count)});↩ loop();↩ }↩ }, 1000);↩ })();↩ },function(){↩ restart();↩ });↩ }↩}↩chrome.extension.onRequest.addListener(function(message, sender, sendResponse){↩ sendResponse(tweets[message.id]);↩});</pre>↩ <dt><a href="TweetNotify/popup.html">popup.html</a>↩ <dd>任意のハッシュタグを入力するインターフェースとして使用↩ <pre class="prettyprint js hidden" id="TweetNotify-popup-html"><!doctype html>↩<html>↩<style>↩body{↩margin: 0px;↩padding: 0px;↩}↩body > div{↩padding:7px;↩}↩body > div > input{↩width:100px;↩}↩</style>↩<div><input type="text" value="" placeholder="keyword" id="keyword"></div>↩<script>↩var BG = chrome.extension.getBackgroundPage();↩var keyword = document.getElementById('keyword');↩keyword.addEventListener('change',function(){↩ BG.init(this.value);↩});↩if (BG.keyword) {↩ keyword.value = BG.keyword;↩}↩</script>↩</html></pre>↩ <dt><a href="TweetNotify/note.html">note.html</a>↩ <dd>Notifications APIで表示される小窓用のHTML↩ <pre class="prettyprint hidden" id="TweetNotify-note-html"><!doctype html>↩<html>↩<style>↩body{↩font-family:sans-serif;↩color:#333;↩}↩a{↩color:#003366;↩text-decoration:none;↩}↩#prof{↩float:left;↩max-width:48px;↩min-width:48px;↩}↩</style>↩<a id="user" target="_blank"><img id="prof"></a>↩<a id="tweet" target="_blank"></a>↩<script>↩chrome.extension.sendRequest({id:location.hash.slice(1)}, function(item){↩ document.querySelector('#user').href = 'http://twitter.com/' + item.from_user;↩ document.querySelector('#prof').src = item.profile_image_url;↩ var tweet = document.querySelector('#tweet');↩ tweet.href = 'http://twitter.com/' + item.from_user + '/status/' + item.id;↩ tweet.textContent = item.text;↩});↩</script>↩</html></pre>↩ <dt>Twitter-icon.png↩ <dd>Twitterのアイコン↩</dl>↩<p>以上のファイルを1つのフォルダに置き、拡張機能ページで「デベロッパーモード」選択し、パッケージ化されてない拡張の読み込みを行います↩<p>追記(2010/03/18 18:43):Chrome5以降の方は、<a href="TweetNotify.crx">TweetNotify</a>から実際にインストールできるようにしました(まだ作りこみが甘いので、長時間使用しているとメモリを消費するのでご注意ください…)↩↩<h2 id="appendix">Appendix</h2>↩<h3 id="ext-reference">Chrome Extensionsの参考URL</h3>↩<ul>↩<li><a href="http://code.google.com/chrome/extensions/">Google Chrome Extensions - Google Code</a>:公式ドキュメント↩<li><a href="http://dev.screw-axis.com/doc/chrome_extensions/">Chrome Extensions API リファレンス</a>:非公式日本語訳(<a href="http://twitter.com/nao58">@nao58</a>)↩<li><a href="http://groups.google.com/a/chromium.org/group/chromium-extensions/topics">Chromium-extensions | Google グループ</a>:公式Extension開発者フォーラム(英語)↩<li><a href="http://groups.google.co.jp/group/chromium-extensions-japan">Chromium-Extensions-Japan | Google グループ</a>:準公式Extension開発者フォーラム(日本語)↩<li><a href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/">[chrome] Index of /trunk/src/chrome/common/extensions/docs/examples</a>:Extensionのサンプル↩<li><a href="https://chrome.google.com/extensions">Google Chrome 拡張機能</a>:公式拡張ギャラリー↩</ul>↩<p>また、2010年4月9日(金)にChrome Extension TechTalkを行います。<a href="http://groups.google.co.jp/group/chromium-extensions-japan/web/chrome-extension-techtalk">Chrome Extension TechTalkのご案内</a>、ライトニングトーク発表者の募集もしていますので、是非ご応募ください!↩↩<h3 id="this-document">この資料についてのお話</h3>↩<p>この資料自体がHTML5のサンプルとなるよう作ってあります。↩<dl>↩<dt>HTML5 Validator↩<dd><a href="http://html5.validator.nu/">Validator.nu (X)HTML5 Validator</a><br>↩<a href="http://html5.validator.nu/?doc=http%3A%2F%2Fss-o.net%2Fchrome%2Fextension%2Fhtml5.html&showsource=yes">(X)HTML5 validation results for http://ss-o.net/chrome/extension/html5.html</a>↩<dt>HTML5 Outliner↩<dd><a href="http://gsnedders.html5.org/outliner/">HTML 5 Outliner</a><br>↩<a href="http://gsnedders.html5.org/outliner/process.py?url=http%3A%2F%2Fss-o.net%2Fchrome%2Fextension%2Fhtml5.html">Outline</a>↩<dt>Outlineと目次↩<dd><a href="http://d.hatena.ne.jp/amachang/20090915/1252999677">HTML5 のセクションアウトラインを生成してみよう! - IT戦記</a>のOutliner.jsを使用して、右上の目次を自動生成しています。↩</dl>↩<p><a rel="license" href="http://creativecommons.org/licenses/publicdomain/"><img alt="Creative Commons License" src="http://i.creativecommons.org/l/publicdomain/88x31.png" /></a><br>↩This work is in the <a rel="license" href="http://creativecommons.org/licenses/publicdomain/">Public Domain</a>.↩</body>↩</html>Total execution time 1382 milliseconds.