<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" version="2.0">
  <channel>
    <title>Days on the Moon</title>
    <link>http://nanto.asablo.jp/blog/</link>
    <description/>
    <language>ja</language>
    <generator>mc 0.0</generator>
    <pubDate>Mon, 28 Jan 2013 02:20:07 +0900</pubDate>
    <item>
      <title>jQuery のバグを見つけてから修正されるまで</title>
      <link>http://nanto.asablo.jp/blog/2013/01/28/6703606</link>
      <guid>http://nanto.asablo.jp/blog/2013/01/28/6703606</guid>
      <pubDate>Mon, 28 Jan 2013 02:17:10 +0900</pubDate>
      <dcterms:modified>2013-01-28T02:20:07+09:00</dcterms:modified>
      <dcterms:created>2013-01-28T02:20:07+09:00</dcterms:created>
      <description>&lt;p&gt;1 月 24 日に開催された &lt;a href="https://github.com/kyotojs/meetup/wiki/4"&gt;Kyoto.js meetup 4&lt;/a&gt; で「jQuery のバグを見つけてから修正されるまで」と題した発表を行いました。&lt;/p&gt;&#13;
&lt;p&gt;jQuery へのコミットに関して 2 行でまとめるとすれば次のようになるでしょうか。&lt;/p&gt;&#13;
&lt;ol&gt;&#13;
&lt;li&gt;jQuery のソースコードはショートコーディングの嵐なので心してかかる&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="https://github.com/jquery/jquery/blob/master/CONTRIBUTING.md" hreflang="en" lang="en"&gt;Contributing to jQuery&lt;/a&gt; と &lt;a href="http://docs.jquery.com/JQuery_Core_Style_Guidelines" hreflang="en" lang="en"&gt;jQuery Core Style Guidelines&lt;/a&gt; は必読&lt;/li&gt;&#13;
&lt;/ol&gt;&#13;
&lt;p&gt;発表の筋書きは以下の通りです。&lt;/p&gt;&#13;
&#13;
&lt;hr&gt;&#13;
&#13;
&lt;p&gt;jQuery のバグを見つけてから修正されるまで&lt;/p&gt;&#13;
&lt;hr style="margin: 1.5em 20%; visibility: hidden;"&gt;&#13;
&#13;
&lt;h3&gt;&lt;a href="http://www.amazon.co.jp/dp/B0088WUFLQ"&gt;フォロー・ミー&lt;/a&gt;&lt;/h3&gt;&#13;
&#13;
&lt;ul&gt;&#13;
&lt;li&gt;nanto_vi (TOYAMA Nao)&lt;/li&gt;&#13;
&lt;li&gt;株式会社はてな アプリケーションエンジニア&#13;
  &lt;ul&gt;&#13;
  &lt;li&gt;クライアントサイド (JavaScript)&lt;/li&gt;&#13;
  &lt;li&gt;サーバーサイド (Perl)&lt;/li&gt;&#13;
  &lt;/ul&gt;&#13;
&lt;/li&gt;&#13;
&lt;li&gt;jQuery をバリバリ使っている&#13;
  &lt;ul&gt;&#13;
  &lt;li&gt;Deferred&lt;/li&gt;&#13;
  &lt;li&gt;イベント&lt;/li&gt;&#13;
  &lt;li&gt;DOM 操作&lt;/li&gt;&#13;
  &lt;/ul&gt;&#13;
&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&#13;
&lt;h3&gt;&lt;a href="http://www.amazon.co.jp/dp/B006QJSI3A"&gt;ある日どこかで&lt;/a&gt;&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;街中にクリスマスの装飾が灯り始めるころ&lt;/p&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://less.carbonfairy.org/post/38137563537"&gt;jQuery 1.8でDeferred.thenの挙動が変わった&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;p&gt;うんうん、変わったよね&lt;/p&gt;&#13;
&lt;p&gt;…&lt;/p&gt;&#13;
&lt;p&gt;……&lt;/p&gt;&#13;
&lt;hr style="margin: 1.5em 20%; visibility: hidden;"&gt;&#13;
&lt;p&gt;そういえば &lt;code&gt;Deferred&lt;/code&gt; を使ったとき &lt;code&gt;this&lt;/code&gt; の値はどうなるんだったっけ?&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;$.Deferred().done(function () {&#13;
    this // ← ココとか&#13;
}).then().done(function () {&#13;
    this // ← ココの値は?&#13;
});&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;jQuery 1.8.3 と jQuery 1.9 Beta 1 で結果が違う!&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;&lt;a href="http://www.amazon.co.jp/dp/B004GQ6814"&gt;汚れなき悪戯&lt;/a&gt;&lt;/h3&gt;&#13;
&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://bugs.jquery.com/ticket/11405" hreflang="en" lang="en"&gt;#11405 (deferred.notify() invokes progressCallbacks with deferred as context) -- jQuery Core - Bug Tracker&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="https://github.com/jquery/jquery/commit/23d7cf0488bfeaab51d8f55435cab01f5cf990ca" hreflang="en" lang="en"&gt;Deferred: .resolve(), .reject() and .notify() now set the callback conte... &amp;#183; 23d7cf0 &amp;#183; jquery/jquery&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;p&gt;ふむふむ…… (コードを読む)&lt;/p&gt;&#13;
&lt;p&gt;ふむふむ…… (コードを読む)&lt;/p&gt;&#13;
&lt;p&gt;ふむふむ…… あれ?&lt;/p&gt;&#13;
&lt;hr style="margin: 1.5em 20%; visibility: hidden;"&gt;&#13;
&lt;p&gt;これ、自分の書いたコードが動かなくなる?&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;$.Deferred().then(function () {&#13;
    // ここでの this が&#13;
    return $.Deferred().resolveWith(this, arguments);&#13;
}).done(function () {&#13;
    // ここにも引き継がれてほしい&#13;
    this&#13;
});&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;……&lt;/p&gt;&#13;
&lt;hr style="margin: 1.5em 20%; visibility: hidden;"&gt;&#13;
&lt;p&gt;まずい!&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;&lt;a href="http://www.amazon.co.jp/dp/B006QJS6SM"&gt;バック・トゥ・ザ・フューチャー&lt;/a&gt;&lt;/h3&gt;&#13;
&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="https://github.com/jquery/jquery/blob/1.8.3/src/callbacks.js" hreflang="en"&gt;https://github.com/jquery/jquery/blob/1.8.3/src/callbacks.js&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="https://github.com/jquery/jquery/blob/1.8.3/src/deferred.js" hreflang="en"&gt;https://github.com/jquery/jquery/blob/1.8.3/src/deferred.js&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="https://github.com/jquery/jquery/blob/1.9.0b1/src/callbacks.js" hreflang="en"&gt;https://github.com/jquery/jquery/blob/1.9.0b1/src/callbacks.js&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="https://github.com/jquery/jquery/blob/1.9.0b1/src/deferred.js" hreflang="en"&gt;https://github.com/jquery/jquery/blob/1.9.0b1/src/deferred.js&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;p&gt;どこを直せば自分のコードが動くのか&lt;/p&gt;&#13;
&lt;p&gt;コードとにらめっこ&lt;/p&gt;&#13;
&lt;p&gt;にらめっこ&lt;/p&gt;&#13;
&lt;p&gt;にらめっこ&lt;/p&gt;&#13;
&lt;p&gt;……&lt;/p&gt;&#13;
&lt;hr style="margin: 1.5em 20%; visibility: hidden;"&gt;&#13;
&lt;p&gt;問題なのはここ、でもここを変えると先の変更の意味が失われるから……&lt;/p&gt;&#13;
&lt;hr style="margin: 1.5em 20%; visibility: hidden;"&gt;&#13;
&lt;p&gt;こことここか!&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;&lt;a href="http://www.amazon.co.jp/dp/B008CD78AM"&gt;羊たちの沈黙&lt;/a&gt;&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;直すならテストを書かないと&lt;/p&gt;&#13;
&lt;p&gt;テストを書くならテストを走らせないと&lt;/p&gt;&#13;
&lt;p&gt;テストを走らせるなら jQuery のビルド環境を作らないと&lt;/p&gt;&#13;
&lt;p&gt;&lt;code&gt;grunt&lt;/code&gt;? Node.js なら入ってるし楽勝でしょ&lt;/p&gt;&#13;
&lt;p&gt;……&lt;/p&gt;&#13;
&lt;hr style="margin: 1.5em 20%; visibility: hidden;"&gt;&#13;
&lt;p&gt;うわあ、この Node.js バージョンが古い!&lt;/p&gt;&#13;
&lt;p&gt;うわあ、この OS バージョンが古い!&lt;/p&gt;&#13;
&lt;p&gt;うわあ、この Python (ry&lt;/p&gt;&#13;
&lt;p&gt;……&lt;/p&gt;&#13;
&lt;hr style="margin: 1.5em 20%; visibility: hidden;"&gt;&#13;
&lt;p&gt;沈黙&lt;/p&gt;&#13;
&lt;hr style="margin: 1.5em 20%; visibility: hidden;"&gt;&#13;
&lt;p&gt;そしてクリスマスが過ぎ、正月が過ぎた&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;&lt;a href="http://www.amazon.co.jp/dp/B003KK0MHI"&gt;風と共に去りぬ&lt;/a&gt;&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;やっぱり正月松の内は休まないとね&lt;/p&gt;&#13;
&lt;p&gt;ってなになに……&lt;/p&gt;&#13;
&lt;hr style="margin: 1.5em 20%; visibility: hidden;"&gt;&#13;
&lt;p&gt;げげー、&lt;code&gt;1.9-stable&lt;/code&gt; ブランチ!&lt;/p&gt;&#13;
&lt;hr style="margin: 1.5em 20%; visibility: hidden;"&gt;&#13;
&lt;p&gt;もはや一刻の猶予も許されない&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;&lt;a href="http://www.amazon.co.jp/dp/B000068RHI"&gt;禁じられた遊び&lt;/a&gt;&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;&lt;a href="https://gist.github.com/4608475"&gt;ビルド環境がないならテスト環境を作ればいいじゃない&lt;/a&gt;&lt;/p&gt;&#13;
&lt;p&gt;俺にはこの SpiderMonkey JavaScript Shell がある!&lt;/p&gt;&#13;
&lt;hr style="margin: 1.5em 20%; visibility: hidden;"&gt;&#13;
&lt;p&gt;秘技、テストのコピペ改変!&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;&lt;a href="http://www.amazon.co.jp/dp/B000J3OOAK"&gt;荒野の用心棒&lt;/a&gt;&lt;/h3&gt;&#13;
&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://bugs.jquery.com/ticket/13160" hreflang="en" lang="en"&gt;#13160 (Deferred.then doesn't propagete custom context) -- jQuery Core - Bug Tracker&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;p&gt;&lt;img src="http://www.hatena.ne.jp/users/na/nanto_vi/profile_s.gif" alt="nanto_vi"&gt; 「これ直さへんとあかんちゃう?」&lt;/p&gt;&#13;
&lt;p&gt;J 「プルリクエストにしてーな」&lt;/p&gt;&#13;
&lt;p&gt;&lt;img src="http://www.hatena.ne.jp/users/na/nanto_vi/profile_s.gif" alt="nanto_vi"&gt; 「&lt;a href="https://github.com/jquery/jquery/pull/1114" hreflang="en"&gt;プルレクったでー&lt;/a&gt;」&lt;/p&gt;&#13;
&lt;p&gt;D 「&lt;a href="https://github.com/nanto/jquery/commit/e7fdda981928befda72b78e9e2b17e33e232a603" hreflang="en"&gt;ここ冗長やろ。もっと削れるやろ&lt;/a&gt;」&lt;/p&gt;&#13;
&lt;p&gt;&lt;img src="http://www.hatena.ne.jp/users/na/nanto_vi/profile_s.gif" alt="nanto_vi"&gt; (そない言われても…… これ以上どう切り詰めろいうんや……)&lt;/p&gt;&#13;
&lt;p&gt;&lt;img src="http://www.hatena.ne.jp/users/na/nanto_vi/profile_s.gif" alt="nanto_vi"&gt; (しゃあないな、この条件分岐をもっと前に持ってきて……)&lt;/p&gt;&#13;
&lt;p&gt;&lt;img src="http://www.hatena.ne.jp/users/na/nanto_vi/profile_s.gif" alt="nanto_vi"&gt; (あれ、この変数、フラグに流用できるちゃうか……)&lt;/p&gt;&#13;
&lt;p&gt;&lt;img src="http://www.hatena.ne.jp/users/na/nanto_vi/profile_s.gif" alt="nanto_vi"&gt; 「&lt;a href="https://github.com/nanto/jquery/commit/412d910697f7c33a29066009930e1373fd80b27a" hreflang="en"&gt;どや!&lt;/a&gt;」&lt;/p&gt;&#13;
&lt;p&gt;D 「まあええんちゃうか」&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;&lt;a href="http://www.amazon.co.jp/dp/B004NR1A96"&gt;素晴らしき哉、人生!&lt;/a&gt;&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;D 「修正取り込んだで。おーきに」&lt;/p&gt;&#13;
&lt;p&gt;J 「&lt;a href="http://jquery.github.com/cla.html" hreflang="en"&gt;僕と契約して貢献者になってよ!&lt;/a&gt;」&lt;/p&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://blog.jquery.com/2013/01/15/jquery-1-9-final-jquery-2-0-beta-migrate-final-released/" hreflang="en" lang="en"&gt;jQuery 1.9 final, jQuery 2.0 beta, Migrate final released | Official jQuery Blog&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;hr style="margin: 1.5em 20%; visibility: hidden;"&gt;&#13;
&lt;p&gt;めでたしめでたし&lt;/p&gt;&#13;
&lt;hr style="margin: 1.5em 20%; visibility: hidden;"&gt;&#13;
&lt;p&gt;※ この物語は実話を基にしたフィクションです。&lt;/p&gt;
</description>
      <dc:subject>JavaScript</dc:subject>
    </item>
    <item>
      <title>jQuery で HTTP 接続するときの書き方</title>
      <link>http://nanto.asablo.jp/blog/2012/12/16/6661787</link>
      <guid>http://nanto.asablo.jp/blog/2012/12/16/6661787</guid>
      <pubDate>Sun, 16 Dec 2012 19:41:58 +0900</pubDate>
      <dcterms:modified>2012-12-18T10:49:27+09:00</dcterms:modified>
      <dcterms:created>2012-12-16T19:44:15+09:00</dcterms:created>
      <description>&lt;p&gt;12 月 13 日に &lt;a href="https://github.com/kyotojs/meetup/wiki"&gt;Kyoto.js&lt;/a&gt; の第 3 回 meetup で、「jQuery で HTTP 接続するときの書き方」と題した 5 分間のライトニングトークを行いました。以下にその内容を一部再構成して収録します。&lt;/p&gt;&#13;
&#13;
&lt;hr&gt;&#13;
&#13;
&lt;p&gt;こんにちは、nanto_vi です。今日は jQuery で HTTP 接続をするときの書き方について話します。&lt;/p&gt;&#13;
&lt;p&gt;皆さん jQuery を使うことも多いかと思います。jQuery で HTTP 接続をするとき、古いサンプルだと次のような書き方が載っています。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;$.ajax({&#13;
    url: '/foo/bar',&#13;
    data: { baz: 'qux' },&#13;
    success: function (data) {&#13;
        console.log(data);&#13;
    },&#13;
});&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;接続完了時の処理をコールバック関数として &lt;code&gt;$.ajax()&lt;/code&gt; に渡してやる形ですね。&lt;del datetime="2012-12-18T10:50:00+09:00"&gt;しかし、現在この書き方は非推奨となっており、替わりに&lt;/del&gt;次のように&lt;ins datetime="2012-12-18T10:50:00+09:00" class="nodate"&gt;も&lt;/ins&gt;書きます。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;$.ajax({&#13;
    url: '/foo/bar',&#13;
    data: { baz: 'qux' },&#13;
}).done(function (data) {&#13;
    console.log(data);&#13;
});&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;&lt;code&gt;$.ajax()&lt;/code&gt; の返り値に対して、&lt;code&gt;done&lt;/code&gt; メソッドで接続完了後の処理を登録する形です。この書き方の何がいいかといえば、返り値を使いまわしたり &lt;code&gt;done&lt;/code&gt; メソッドを複数回呼び出したりして、完了後の処理を後から追加できるところです。昔の書き方では完了後の処理がコールバック関数として &lt;code&gt;$.ajax()&lt;/code&gt; の内部に格納されていましたが、現在は「完了後の処理」だけを &lt;code&gt;$.ajax()&lt;/code&gt; の外部に (「プロミス」として) 取り出すことが可能になったわけですね。&lt;/p&gt;&#13;
&#13;
&lt;p&gt;今「内部の処理を外部に取り出す」と言いましたが、この言葉はどこかで聞き覚えがありませんか。そう、内部イテレータと外部イテレータです。&lt;/p&gt;&#13;
&lt;p&gt;内部イテレータは、オブジェクトが個々の要素に対する処理を受け取り、オブジェクト内部で自身の各要素に適用させる形、&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;// 内部イテレータの使用例&#13;
$('p').each(function () {&#13;
    doSomethingWith(this);&#13;
});&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;外部イテレータは、オブジェクトから「各要素を列挙する」という機能だけをオブジェクト外部に取り出す形です。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;// 外部イテレータの実装例と使用例&#13;
$.fn.iterator = function () {&#13;
    var i = 0, n = this.length, self = this;&#13;
    return {&#13;
        hasNext: function () { return i &amp;lt; n; },&#13;
        next: function () { return self[i++]; }&#13;
    };&#13;
};&#13;
&#13;
var iterator = $('p').iterator();&#13;
while (iterator.hasNext()) {&#13;
    var element = iterator.next();&#13;
    doSomethingWith(element);&#13;
}&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://ufcpp.net/study/csharp/sp2_itpattern.html"&gt;[雑記] 内部イテレータと外部イテレータ (C# によるプログラミング入門)&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%86%E3%83%AC%E3%83%BC%E3%82%BF"&gt;イテレータ - Wikipedia&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://www.kmonos.net/wlog/41.php#_1240040809"&gt;イテレータ - w.l.o.g.&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;p&gt;&lt;a href="https://developer.mozilla.org/ja/docs/JavaScript/New_in_JavaScript/1.7" hreflang="en"&gt;JavaScript 1.7&lt;/a&gt; 以降ではジェネレータという機能により、内部イテレータのような書き方で外部イテレータを生成することができます。&lt;/p&gt;&#13;
&#13;
&lt;p&gt;さて、「処理を内部に持ってしまっている」というのは、イベントハンドラの登録も同じですね。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;$(document).on('click', function (event) {&#13;
    ...&#13;
});&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;イベント発生時の処理をコールバック関数として jQuery オブジェクト内部に渡していますが、これを外部に持ち出すことはできないのでしょうか。&lt;/p&gt;&#13;
&lt;p&gt;実はそれを可能にするものとして &lt;a href="http://msdn.microsoft.com/en-us/data/gg577609.aspx" hreflang="en"&gt;Reactive Extensions&lt;/a&gt; (Rx) があります。&lt;a href="http://www.atmarkit.co.jp/fdotnet/introrx/introrx_01/introrx_01_01.html"&gt;Rx 入門記事&lt;/a&gt;の図にもあるように、Rx を使うと空間にまたがる要素 (配列など) の列挙と時間にまたがる要素 (イベントなど) の列挙を統一的に扱うことができます。&lt;/p&gt;&#13;
&lt;p&gt;Reactive Extensions は主に .NET Framework 上で利用されていますが、JavaScript での実装として &lt;a href="http://reactive-extensions.github.com/RxJS/" hreflang="en"&gt;RxJS&lt;/a&gt; が公開されています。&lt;/p&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://neue.cc/2010/12/20_290.html"&gt;neue cc - linq.js &amp;amp; Reactive Extensions for JavaScript(RxJS)入門&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://neue.cc/2010/07/28_269.html"&gt;neue cc - Reactive Extensions入門 + メソッド早見解説表&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://rx.codeplex.com/" lang="en" hreflang="en"&gt;Rx (Reactive Extensions) - Home&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;div class="quote"&gt;&#13;
&lt;blockquote&gt;&lt;p&gt;ObserverパターンとIteratorパターンは同じだったんだよ！なんだってー！&lt;/p&gt;&lt;/blockquote&gt;&#13;
&lt;p class="cite"&gt;&lt;a href="http://neue.cc/2009/09/04_197.html"&gt;neue cc - .NET Reactive Framework メソッド探訪第一回:FromEvent&lt;/a&gt;&lt;cite&gt;&#13;
&lt;/div&gt;&#13;
&lt;div class="quote"&gt;&#13;
&lt;blockquote&gt;&lt;p&gt;そう、ObserverパターンとIteratorパターンは同じなのだよ、ナンダッテー！&lt;/p&gt;&lt;/blockquote&gt;&#13;
&lt;p class="cite"&gt;&lt;a href="http://neue.cc/2010/03/18_247.html"&gt;neue cc - Reactive Extensions for JavaScript&lt;/a&gt;&lt;cite&gt;&#13;
&lt;/div&gt;&#13;
&#13;
&lt;p&gt;(このあたりで時間切れ)&lt;/p&gt;
</description>
      <dc:subject>JavaScript</dc:subject>
    </item>
    <item>
      <title>はてなでコードを書くときに気をつけていること</title>
      <link>http://nanto.asablo.jp/blog/2011/12/18/6249094</link>
      <guid>http://nanto.asablo.jp/blog/2011/12/18/6249094</guid>
      <pubDate>Sun, 18 Dec 2011 14:37:15 +0900</pubDate>
      <dcterms:modified>2011-12-18T16:03:24+09:00</dcterms:modified>
      <dcterms:created>2011-12-18T14:48:36+09:00</dcterms:created>
      <description>&lt;p&gt;こんにちは、&lt;a href="http://www.hatena.ne.jp/"&gt;はてな&lt;/a&gt;でアプリケーションエンジニアをしている nanto_vi です。この記事は &lt;a href="http://atnd.org/events/22740" lang="en"&gt;Hatena::Staff Advent Calendar 2011&lt;/a&gt; の一環として書いています。&lt;span lang="en"&gt;Advent Calendar&lt;/span&gt; の会場ははてなブログとなっていますが、主催の antipop さんに尋ねたところ何でもよいというような返答があったのでここで書きます。&lt;/p&gt;&#13;
&lt;p&gt;はじめに謝っておきますが、この記事ははてなとほとんど関係がありません。タイトルに「はてな」と入っているのは &lt;span lang="en"&gt;Advent Calendar&lt;/span&gt; の要件を満たすための目くらましあり、内容はといえばはてなのノウハウでもなんでもない、私が最近個人的に心がけていることです。ごめんなさい。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;できれば明示的に&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;業務で書くコードは複数人により読み書きされメンテナンスされるので、わかりやすさが重要になってきます。わかりやすさを保つためには暗黙的に行われる操作を減らし、明示的にコードに表した方がよいと感じます。たとえば、Perl では、&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;use Encode;&#13;
&#13;
# encode_utf8 関数は Encode モジュールで定義されている&#13;
my $octets = encode_utf8 $string;&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;のようにモジュール読み込み時に自動的に関数をインポートすることができますが、それよりも、&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;use Encode qw/encode_utf8/;&#13;
&#13;
my $octets = encode_utf8 $string;&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;のようにインポートする関数を明示的に指定したほうが、その関数がどこで定義されているのかわかりやすいでしょう。&lt;/p&gt;&#13;
&lt;p&gt;個人的には、関数や変数の名前で &lt;code&gt;grep&lt;/code&gt; をかけてその定義(外部で定義されている場合は宣言)を探し出せることが、「明示的」であるための最低線ではないかと思います。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;入力には正規化を、出力には符号化を&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;アプリケーションを作るうえで入出力の扱いは避けて通れません。入力元はユーザーだったりバッチ処理スクリプトの引数だったり、出力先はユーザーだったりデータベースサーバーだったりしますが、いずれにおいても入力には正規化処理を、出力には符号化処理を、それぞれ施すことになります。&lt;/p&gt;&#13;
&lt;p&gt;正規化は一般に不可逆です。空白文字類をすべてスペースに置換した後はもともとスペース以外の空白文字が含まれていたのかわかりませんし、数値「42」を生み出した入力は &lt;code&gt;"42"&lt;/code&gt; でも &lt;code&gt;"42.0"&lt;/code&gt; でも、はたまた &lt;code&gt;"0x2A"&lt;/code&gt; でもありえます。&lt;/p&gt;&#13;
&lt;p&gt;符号化は一般に可逆です。あるデータをユーザーのもとへ送り届けるのに、そのデータを HTML のテキストとして扱えるよう一部文字を文字参照の形に符号化し、その HTML ソース全体を文字符号化方式 UTF-8 をもって符号化し、さらには HTTP メッセージに、TCP のセッションに、IP のパケットにと符号化を重ねていきますが、それらすべては符号化規則を逆に適用することで元の形式へ復元できます。&lt;/p&gt;&#13;
&lt;p&gt;たとえば HTML として解析され、その結果が JavaScript の文字列として、HTML として、URI としてと順に解析されるデータを Template-Toolkit で出力する場合、解析の逆順でそれぞの形式に応じた符号化を施す必要があります。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;&amp;lt;script type="text/javascript"&amp;gt;&#13;
document.write('&amp;lt;a href="/search?q=[% word | uri | html | js %]"&amp;gt;検索&amp;lt;\/a&amp;gt;');&#13;
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;script 要素の内容は CDATA 型であり文字参照は解決されないので、最後に &lt;code&gt;html&lt;/code&gt; フィルタをかけることはしません。また、そもそもこのような多重にフィルタをかける事態は避けたほうが賢明でしょう。&lt;/p&gt;&#13;
&lt;p&gt;入出力いずれにおいても、データがどういう形式で扱われるのかを意識し、それに応じた正規化処理または符号化処理を施すことで、意図しない入力が致命的な挙動を引き起こすこともある程度は防げるのではないかと考えます。&lt;/p&gt;&#13;
&lt;p&gt;&lt;a href="http://d.hatena.ne.jp/hitode909/20111218/1324190795"&gt;次は hitode909 さん&lt;/a&gt;です。&lt;/p&gt;
</description>
      <dc:subject>コンピュータ一般</dc:subject>
    </item>
    <item>
      <title>IE 6/7 で文書間通信を実現するための一案</title>
      <link>http://nanto.asablo.jp/blog/2011/12/08/6237308</link>
      <guid>http://nanto.asablo.jp/blog/2011/12/08/6237308</guid>
      <pubDate>Thu, 08 Dec 2011 23:32:29 +0900</pubDate>
      <dcterms:modified>2011-12-09T00:00:48+09:00</dcterms:modified>
      <dcterms:created>2011-12-09T00:00:48+09:00</dcterms:created>
      <description>&lt;p&gt;HTML5-WEST.jp 飲み会 UST というのがあるそうで、「参戦希望者募集」とお誘いを受けたのですが、「参戦」というからには何かしら戦の準備を整えねばなるまいと、以前から考えていたことを夜なべして実装しました。&lt;/p&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://www.ne.jp/asahi/nanto/moon/2011/12/08/ie-post-message.html"&gt;文書間通信をより広範囲な環境で動作させるための考察&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://www.ne.jp/asahi/nanto/moon/2011/12/08/outer.html"&gt;IE 6/7 を含む各種ブラウザで動作する、異なるドメイン間での通信のデモ&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;p&gt;いわゆる HTML5 の文書間通信、&lt;code&gt;window.postMessage()&lt;/code&gt; を IE 6/7 でどう再現するかという話で、&lt;code&gt;about:blank&lt;/code&gt; を指す隠しフレームを二つ用い、&lt;code&gt;window.name&lt;/code&gt; を介することで双方向の通信を実現しています。&lt;/p&gt;&#13;
&lt;p&gt;どうも IE での &lt;code&gt;about:blank&lt;/code&gt; は、その空白ページを読み込ませた文書の生成元を継承するらしく、たとえば &lt;code&gt;http://example.org/&lt;/code&gt; から &lt;code&gt;location.href = 'about:blank';&lt;/code&gt; を実行すれば &lt;code&gt;http://example.org&lt;/code&gt; を生成元とする &lt;code&gt;about:blank&lt;/code&gt; になります (少なくともそのように見えます)。これを利用し、一つのフレームに二つの文書から交互に &lt;code&gt;about:blank&lt;/code&gt; を読み込ませあうことで、そのフレームの &lt;code&gt;window.name&lt;/code&gt; を両文書で共有できるという仕組みです。&lt;/p&gt;&#13;
&lt;p&gt;&lt;code&gt;about:blank&lt;/code&gt; を読み込ませるのに &lt;code&gt;location.reload()&lt;/code&gt; を使えば履歴に余分な項目を残すこともありませんし、フラグメント識別子を使った場合と違ってデータ量にもだいぶ余裕が出ます。&lt;/p&gt;
</description>
      <dc:subject>JavaScript</dc:subject>
      <dc:subject>Web 関連技術</dc:subject>
    </item>
    <item>
      <title>Template::Plugin::JSON::Escape 公開</title>
      <link>http://nanto.asablo.jp/blog/2011/06/15/5914816</link>
      <guid>http://nanto.asablo.jp/blog/2011/06/15/5914816</guid>
      <pubDate>Wed, 15 Jun 2011 20:57:49 +0900</pubDate>
      <dcterms:modified>2011-06-15T20:58:42+09:00</dcterms:modified>
      <dcterms:created>2011-06-15T20:58:42+09:00</dcterms:created>
      <description>&lt;p&gt;&lt;a href="http://search.cpan.org/perldoc?Template::Plugin::JSON::Escape" hreflang="en"&gt;&lt;code&gt;Template::Plugin::JSON::Escape&lt;/code&gt;&lt;/a&gt; という Perl モジュールを公開しました。&lt;/p&gt;&#13;
&lt;p&gt;&lt;a href="http://template-toolkit.org/" hreflang="en" lang="en"&gt;Template Toolkit&lt;/a&gt; を使って HTML を出力するとき、HTML 中に JSON を埋め込みたいことがあります。そのためのモジュールとして &lt;a href="http://search.cpan.org/perldoc?Template::Plugin::JSON" hreflang="en"&gt;&lt;code&gt;Template::Plugin::JSON&lt;/code&gt;&lt;/a&gt; が存在するのですが、これは小なり記号 (&lt;code&gt;&amp;lt;&lt;/code&gt;) などの文字を素通しするため、JSON の内容によっては不正な HTML が出力されてしまいます。&lt;/p&gt;&#13;
&lt;p&gt;&lt;code&gt;Template::Plugin::JSON::Escape&lt;/code&gt; は一部記号を &lt;code&gt;\uxxxx&lt;/code&gt; の形式にエスケープするので、JSON の内容にかかわらず出力する HTML を妥当に保てます (もちろん、JSON 出力部以外が妥当な HTML を出力するのであれば、です。なお、SGML のコメント内に JSON を埋め込む場合はこの限りではありません)。副次作用として、XSS の防止にも一定の効果を期待できます。&lt;/p&gt;&#13;
&lt;p&gt;また、&lt;code&gt;Template::Plugin::JSON&lt;/code&gt; 0.06 は &lt;a href="http://search.cpan.org/perldoc?Moose" hreflang="en"&gt;&lt;code&gt;Moose&lt;/code&gt;&lt;/a&gt; を使っていますが、私が普段 Perl を使っている環境には &lt;code&gt;Moose&lt;/code&gt; が入っていません。そのためだけに &lt;code&gt;Moose&lt;/code&gt; を導入するのは難しいので、&lt;code&gt;Moose&lt;/code&gt; を使用しないモジュールが求められていたというのもあります。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;関連する話題&lt;/h3&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://subtech.g.hatena.ne.jp/mala/20100222/1266843093"&gt;HTMLのscriptタグ内に出力されるJavaScriptのエスケープ処理に起因するXSSがとても多い件について - 金利0無利息キャッシング – キャッシングできます - subtech&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://subtech.g.hatena.ne.jp/mala/20101122/1290436563"&gt;twitterのXSSとJSON in ECMAScriptと外部JSONを安全に取り扱うためのアプローチ - 金利0無利息キャッシング – キャッシングできます - subtech&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;
</description>
      <dc:subject>Perl</dc:subject>
    </item>
    <item>
      <title>Perl の URI モジュールにおける文字列とオクテット列の扱いに関して</title>
      <link>http://nanto.asablo.jp/blog/2011/05/27/5883636</link>
      <guid>http://nanto.asablo.jp/blog/2011/05/27/5883636</guid>
      <pubDate>Fri, 27 May 2011 17:28:04 +0900</pubDate>
      <dcterms:modified>2012-01-08T16:18:13+09:00</dcterms:modified>
      <dcterms:created>2011-05-27T17:31:20+09:00</dcterms:created>
      <description>&lt;p&gt;Perl の URI モジュールには ASCII 外の文字の扱いに関して欠陥がある。ここでは Perl における URI の扱いについて述べ、URI モジュールの修正方針を提案する。&lt;/p&gt;&#13;
&lt;ins datetime="2012-01-08T16:20:00+09:00"&gt;&#13;
&lt;p&gt;この記事で取り上げた問題に関して主たる部分は URI.pm 1.59 で (この提案とは違った形で) 修正済みであり、この提案は &lt;span lang="en"&gt;obsolete&lt;/code&gt; です。&lt;/p&gt;&#13;
&lt;/ins&gt;&#13;
&#13;
&lt;h3&gt;用語の定義&lt;/h3&gt;&#13;
&#13;
&lt;dl&gt;&#13;
&lt;dt&gt;URI&lt;/dt&gt;&#13;
&lt;dd&gt;&lt;a href="http://tools.ietf.org/html/rfc3986" hreflang="en"&gt;RFC 3986&lt;/a&gt; (&lt;a href="http://www.studyinghttp.net/rfc_ja/rfc3986"&gt;日本語訳&lt;/a&gt;) で定義される識別子。&lt;/dd&gt;&#13;
&lt;dt&gt;URI.pm&lt;/dt&gt;&#13;
&lt;dd&gt;Perl の URI モジュール。ここでは、ファイルとしての URI.pm だけでなく、&lt;a href="http://search.cpan.org/dist/URI/" hreflang="en"&gt;URI パッケージ&lt;/a&gt;下に含まれるコード全般を指す。断りがない限りバージョン 1.58 に基づく。&lt;/dd&gt;&#13;
&lt;dt&gt;文字列&lt;/dt&gt;&#13;
&lt;dd&gt;UTF-8 文字列と Latin-1 文字列のいずれか。&lt;/dd&gt;&#13;
&lt;dt&gt;UTF-8 文字列&lt;/dt&gt;&#13;
&lt;dd&gt;Perl の文字列値で、UTF8 フラグが立っているもの。&lt;/dd&gt;&#13;
&lt;dt&gt;Latin-1 文字列&lt;/dt&gt;&#13;
&lt;dd&gt;Perl の文字列値で、UTF8 フラグが立っておらず、文字の並びとして扱われることを期待されているもの。&lt;/dd&gt;&#13;
&lt;dt&gt;オクテット列&lt;/dt&gt;&#13;
&lt;dd&gt;Perl の文字列値で、UTF8 フラグが立っておらず、バイトの並びとして扱われることを期待されているもの。Latin-1 文字列とオクテット列の機械的な判別は不可能。&lt;/dd&gt;&#13;
&lt;/dl&gt;&#13;
&#13;
&lt;h3&gt;発端となった問題&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;URI.pm のメソッドに UTF-8 文字列とオクテット列を同時に渡した場合、期待した出力が得られないことがある。特に Perl 5.10 以下では、&lt;code&gt;use utf8&lt;/code&gt; 環境下で bareword に UTF8 フラグが立つため、この問題が発生しやすい。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/perl5.8.8&#13;
use strict;&#13;
use warnings;&#13;
use utf8;&#13;
use URI;&#13;
use Encode qw/encode_utf8/;&#13;
&#13;
my $uri = URI-&gt;new('http://example.org/');&#13;
$uri-&gt;query_form( foo =&gt; encode_utf8('字') );&#13;
print $uri-&gt;query, "\n";&#13;
# actual:   "foo=%C3%A5%C2%AD%C2%97"&#13;
# expected: "foo=%E5%AD%97"&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="https://rt.cpan.org/Public/Bug/Display.html?id=53681" hreflang="en" lang="en"&gt;Bug #53681 for URI: A bad utf8-related trap on query_form()&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://d.hatena.ne.jp/dayflower/20090129/1233202917"&gt;use utf8 環境下で =&amp;gt; オペレータの左辺が UTF8 flag on になってしまう - daily dayflower&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&#13;
&lt;h3&gt;Perl において URI はどう扱われるべきか&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;URI は US-ASCII の範囲内の文字で構成されるが、特定の文字符号化方式を仮定しない。URI には任意の文字符号化方式で符号化されたオクテットの並びが (パーセントエンコードされて) 含まれうる。たとえば、二つの URI &lt;a href="http://ja.wikipedia.org/wiki/%E3%81%AF%E3%81%A6%E3%81%AA"&gt;http://ja.wikipedia.org/wiki/%E3%81%AF%E3%81%A6%E3%81%AA&lt;/a&gt; と &lt;a href="http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA"&gt;http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA&lt;/a&gt; において、パーセントエンコードされた部分はいずれも「はてな」という文字の並びを表すが、前者は UTF-8、後者は EUC-JP で符号化され、パーセントエンコードされたものである。&lt;/p&gt;&#13;
&lt;p&gt;それゆえ、Perl において URI はオクテット列として扱われるべきである。そのオクテット列がどの文字符号化方式を用いて解釈されるかは、URI とは別の層の問題である。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;URI.pm をどう修正すべきか&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;現在、URI.pm では入力を文字列として扱うものとオクテット列として扱うものが混在している。たとえば、&lt;code&gt;host&lt;/code&gt; メソッドの引数に渡した値は UTF-8 文字列または Latin-1 文字列として解釈され、&lt;code&gt;query&lt;/code&gt; メソッドの引数に渡した値はオクテット列であるかのように扱われる。&lt;/p&gt;&#13;
&lt;p&gt;ここでは、前節の主張に従い、URI.pm に関する入出力はすべてオクテット列として扱うことを提案する。IRI に関するものを除き、URI.pm の各メソッドに渡された引数はすべてオクテット列とみなされ、返り値はオクテット列となるべきである。&lt;/p&gt;&#13;
&lt;p&gt;引数に UTF-8 文字列が渡された場合は、それを UTF-8 で符号化されたオクテット列として扱うのがよいと考える。&lt;a href="http://search.cpan.org/dist/HTTP-Message/" hreflang="en"&gt;&lt;code&gt;HTTP::Message&lt;/code&gt;&lt;/a&gt; の &lt;code&gt;content&lt;/code&gt; メソッドのように UTF-8 文字列を渡されたらエラーとするのもひとつの手ではあるが、現在の URI.pm との互換性を大きく損ねないためにはエラーにしないほうがよいと判断する。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;国際化ドメイン名の扱い&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;URI.pm の入出力をオクテット列とみなすとき、問題となるのは国際化ドメイン名の扱いである。本来なら ASCII 外の文字を含めるのに &lt;code&gt;URI::IRI&lt;/code&gt; のような専用のモジュールを使うべきだろうが、現在の URI.pm との互換性を損ねないためには、&lt;code&gt;URI-&amp;gt;new(...)&lt;/code&gt; や &lt;code&gt;$uri-&amp;gt;host(...)&lt;/code&gt; で ASCII 外の文字を指定できるのが好ましい。&lt;/p&gt;&#13;
&lt;p&gt;あくまで入力はオクテット列とみなすという方針を貫きつつ国際化ドメイン名を受け付けるため、URI のホスト部に関してはオクテット列を UTF-8 で符号化されたものとみなし、UTF-8 でデコードした文字列を Punycode 符号化して出力のホスト部とする。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;URI.pm の互換性の確保&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;ここで提案する修正により、URI.pm は後方互換性を失う。特にホスト部に関しては、これまで Latin-1 文字列として扱われてきたものが、UTF-8 で符号化されたオクテット列として扱われ、まったく違った出力を得ることになる。&lt;/p&gt;&#13;
&lt;p&gt;そこで、過去の挙動に戻せるよう、&lt;code&gt;$URI::COERCE_OCTETS&lt;/code&gt; 変数を設ける。この変数のデフォルト値は真であるが、値が偽なら以前と同様に入力をオクテット列とみなさず処理を行う。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;修正の段取り&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;以上の提案を実装すべく、現在 &lt;a href="https://github.com/nanto/uri/tree/coerce_octets"&gt;github の nanto/uri レポジトリの coerce_octets ブランチ&lt;/a&gt;で作業中である。さしあたってどのような出力を期待しているのか明らかにするため、&lt;a href="https://github.com/nanto/uri/blob/coerce_octets/t/utf8.t"&gt;ASCII 外の文字を含む入出力に関するテスト&lt;/a&gt;を書いた。実装が一段落したら URI.pm に対するパッチとして提出するつもりである。&lt;/p&gt;&#13;
&lt;ins class="block" datetime="2011-05-30T17:50:00+09:00"&gt;&#13;
&lt;p&gt;&lt;a href="https://rt.cpan.org/Ticket/Display.html?id=43859" hreflang="en" lang="en"&gt;#43859: should be _utf8_off -ed raw data before URI encoding&lt;/a&gt; に&lt;a href="https://github.com/nanto/uri/compare/master...coerce_octets"&gt;修正の URL&lt;/a&gt; を添えて返信した。&lt;/p&gt;&#13;
&lt;/ins&gt;
</description>
      <dc:subject>Perl</dc:subject>
    </item>
    <item>
      <title>chrome URL からファイル一覧を取得する</title>
      <link>http://nanto.asablo.jp/blog/2011/01/12/5634277</link>
      <guid>http://nanto.asablo.jp/blog/2011/01/12/5634277</guid>
      <pubDate>Wed, 12 Jan 2011 01:41:12 +0900</pubDate>
      <dcterms:modified>2011-01-12T01:46:08+09:00</dcterms:modified>
      <dcterms:created>2011-01-12T01:42:17+09:00</dcterms:created>
      <description>&lt;p&gt;Firefox にて、&lt;a href="https://gist.github.com/774684" hreflang="en"&gt;ディレクトリを指す chrome URL から、そのディレクトリ以下の全ファイルの URL を返すサンプルコード&lt;/a&gt;を書きました。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;ChromeFiles.get("chrome://browser/content/");&#13;
/* =&amp;gt; [ "chrome://browser/content/NetworkPanel.xhtml",&#13;
 *      "chrome://browser/content/aboutDialog.css",&#13;
 *      ...,&#13;
 *      "chrome://browser/content/browser.css",&#13;
 *      "chrome://browser/content/browser.js",&#13;
 *      "chrome://browser/content/browser.xul",&#13;
 *      ... ]&#13;
 */&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;特徴として、実際のファイルが (&lt;code&gt;.jar&lt;/code&gt; または &lt;code&gt;.xpi&lt;/code&gt; に) &lt;a href="https://dev.mozilla.jp/2010/11/making-add-on-compatible-firefox-4/" title="アドオンの Firefox 4 対応に関する最新情報 - Mozilla Developer Street (modest)"&gt;パッケージ化&lt;/a&gt;されているかどうかに関わらず、ファイル一覧を取得できることが挙げられます。ソースコード全体は上記 Gist へのリンクを参照してもらうとして、以下は各関数の解説です。&lt;/p&gt;&#13;
&#13;
&lt;pre&gt;&lt;code&gt;var ChromeFiles = {&#13;
    get: function CF_get(spec) {&#13;
        const ios = Cc['@mozilla.org/network/io-service;1'].&#13;
                    getService(Ci.nsIIOService);&#13;
        let uri = ios.newURI(spec, null, null);&#13;
        return this.getByURI(uri);&#13;
    },&#13;
&#13;
    ...&#13;
};&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;単に、文字列として受け取った URL を &lt;code&gt;&lt;a href="https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIURI" hreflang="en"&gt;nsIURI&lt;/a&gt;&lt;/code&gt; のインスタンスにして、&lt;code&gt;getByURI()&lt;/code&gt; へ処理を委譲しているだけです。&lt;/p&gt;&#13;
&#13;
&lt;pre&gt;&lt;code&gt;getByURI: function CF_getByURI(uri) {&#13;
    // 1. ディレクトリを指す URL にする&#13;
    let baseURI = uri.clone().QueryInterface(Ci.nsIURL);&#13;
    baseURI.path = baseURI.directory;&#13;
&#13;
    // 2. chrome URL からローカルファイルシステムでの URL へ変換&#13;
    const registry = Cc['@mozilla.org/chrome/chrome-registry;1'].&#13;
                     getService(Ci.nsIChromeRegistry);&#13;
    let localURI = registry.convertChromeURL(baseURI);&#13;
&#13;
    // 3. ディレクトリ中のファイル名を取得&#13;
    let leafNames = null;&#13;
    if (localURI instanceof Ci.nsIFileURL) {&#13;
        leafNames = this.getLeafNamesByDirectory(localURI.file);&#13;
    } else if (localURI instanceof Ci.nsIJARURI) {&#13;
        leafNames = this.getLeafNamesByJARURI(localURI);&#13;
    } else {&#13;
        throw new Error('Unknown URI: ' + localURI.spec);&#13;
    }&#13;
&#13;
    // 4. ディレクトリのパスとファイル名を結合&#13;
    let baseSpec = baseURI.spec;&#13;
    return leafNames.sort().map(function (leafName) baseSpec + leafName);&#13;
},&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;ol&gt;&#13;
&lt;li&gt;&#13;
  &lt;p&gt;chrome URL において、&lt;code&gt;chrome://&lt;var&gt;{package}&lt;/var&gt;/content/&lt;/code&gt; と &lt;code&gt;chrome://&lt;var&gt;{package}&lt;/var&gt;/content/&lt;var&gt;{package}&lt;/var&gt;.xul&lt;/code&gt; は&lt;a href="https://developer.mozilla.org/ja/XUL_Tutorial/The_Chrome_URL" title="Chrome URL - MDC Doc Center"&gt;同じリソースを表し&lt;/a&gt;、&lt;code&gt;&lt;a href="https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIIOService" hreflang="en"&gt;nsIIOService&lt;/a&gt;#newURI()&lt;/code&gt; の引数に前者を渡しても返ってくる URI オブジェクトの &lt;code&gt;spec&lt;/code&gt; は後者になります。確実にディレクトリを指す URI オブジェクトを得るためには、自分で URI オブジェクトのプロパティを変更しなければなりません。&lt;/p&gt;&#13;
  &lt;p&gt;ところが、&lt;code&gt;newURI()&lt;/code&gt; で作られたオブジェクトは可変でない (&lt;span lang="en"&gt;immutable&lt;/span&gt; な) ことがあり、このときプロパティに値を設定しようとすると例外が発生します。chrome URL の場合 &lt;code&gt;clone()&lt;/code&gt; で生成した URI オブジェクトは可変になるので、まずは URI オブジェクトを複製します。&lt;/p&gt;&#13;
  &lt;p&gt;パスからディレクトリ部分だけを抜き出すのは、&lt;code&gt;&lt;a href="https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIURL" hreflang="en"&gt;nsIURL&lt;/a&gt;&lt;/code&gt; インターフェースの &lt;code&gt;directory&lt;/code&gt; プロパティを使うのが簡単です。&lt;code&gt;nsIURL&lt;/code&gt; インターフェースを経由すれば、ディレクトリ以外にもファイル名や拡張子などをすぐに取得できます。&lt;/p&gt;&#13;
&lt;/li&gt;&#13;
&lt;li&gt;&#13;
  &lt;p&gt;chrome URL からローカルファイルシステム上でのファイル位置をあらわす URL への変換は、&lt;code&gt;&lt;a href="http://www.oxymoronical.com/experiments/apidocs/interface/nsIChromeRegistry" hreflang="en"&gt;nsIChromeRegistry&lt;/a&gt;#convertChromeURL()&lt;/code&gt; で一発です。これにより得られる URL は大抵の場合 file URL か jar URL かのいずれかです。&lt;/p&gt;&#13;
&lt;/li&gt;&#13;
&lt;li&gt;&#13;
  &lt;p&gt;ディレクトリ中のファイル名一覧を配列として取得します。処理本体は file URL の場合と jar URL の場合で別になります。&lt;/p&gt;&#13;
  &lt;p&gt;なお、&lt;code&gt;&lt;a href="https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsISupports#QueryInterface%28%29" hreflang="en"&gt;QueryInterface()&lt;/a&gt;&lt;/code&gt; を使わなくとも、&lt;code&gt;instanceof&lt;/code&gt; 演算子で &lt;code&gt;&lt;a href="http://www.oxymoronical.com/experiments/apidocs/interface/nsIFileURL" hreflang="en"&gt;nsIFileURL&lt;/a&gt;&lt;/code&gt; インターフェースを実装していることを確認できたなら、それ以降は &lt;code&gt;nsIFileURL&lt;/code&gt; の &lt;code&gt;file&lt;/code&gt; プロパティから &lt;code&gt;&lt;a href="https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIFile" hreflang="en"&gt;nsIFile&lt;/a&gt;&lt;/code&gt; オブジェクトを取得できます。&lt;/p&gt;&#13;
&lt;/li&gt;&#13;
&lt;li&gt;&#13;
  &lt;p&gt;得られたファイル名一覧の順序はわからないので、辞書順で並べ替えます。その後にディレクトリ部分を表す chrome URL と結合すれば、ディレクトリ直下のファイルを指す chrome URL の一覧が得られます。&lt;/p&gt;&#13;
&lt;/li&gt;&#13;
&lt;/ol&gt;&#13;
&#13;
&lt;pre&gt;&lt;code&gt;getLeafNamesByDirectory: function CF_getLeafNamesByDirectory(dir) {&#13;
    let files = dir.directoryEntries;&#13;
    let leafNames = [];&#13;
    while (files.hasMoreElements()) {&#13;
        let file = files.getNext().QueryInterface(Ci.nsIFile);&#13;
        if (file.isFile())&#13;
            leafNames.push(file.leafName);&#13;
    }&#13;
    return leafNames;&#13;
},&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;ディレクトリを表す &lt;code&gt;nsIFile&lt;/code&gt; オブジェクトから、その子ファイルの名前一覧を取得します。単に子ファイルを列挙していき、それがディレクトリなどでないときにファイル名を取得するだけです。&lt;/p&gt;&#13;
&#13;
&lt;pre&gt;&lt;code&gt;getLeafNamesByJARURI: function CF_getLeafNamesByJARURI(jarURI) {&#13;
    // 1. ZipReader を作成&#13;
    let zip = this.openZipReader(jarURI.JARFile);&#13;
&#13;
    try {&#13;
        // 2. ディレクトリ直下のファイルのパスを取得&#13;
        let baseEntry = jarURI.JAREntry;&#13;
        let pattern = baseEntry + '?*~' + baseEntry + '?*/*';&#13;
        let entries = zip.findEntries(pattern);&#13;
&#13;
        // 3. ファイル名部分だけを抜き出し、返す&#13;
        let leafNames = [];&#13;
        while (entries.hasMore())&#13;
            leafNames.push(entries.getNext().substring(baseEntry.length));&#13;
        return leafNames;&#13;
    } finally {&#13;
        zip.close();&#13;
    }&#13;
},&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;jar URI は &lt;code&gt;jar:file://path/to/file.jar!/path/to/entry/&lt;/code&gt; のような形で表されます。&lt;code&gt;&lt;a href="http://www.oxymoronical.com/experiments/apidocs/interface/nsIJARURI" hreflang="en"&gt;nsIJARURI&lt;/a&gt;&lt;/code&gt; インターフェースは、&lt;code&gt;file://path/to/file.jar&lt;/code&gt; の部分を示す &lt;code&gt;JARFile&lt;/code&gt; プロパティ (返ってくるのは &lt;code&gt;nsIURI&lt;/code&gt; オブジェクト) と、&lt;code&gt;/path/to/entry/&lt;/code&gt; の部分を指す &lt;code&gt;JAREntry&lt;/code&gt; プロパティ (返ってくるのは文字列) を持っています。&lt;/p&gt;&#13;
&lt;ol&gt;&#13;
&lt;li&gt;&#13;
  &lt;p&gt;JAR ファイル (または XPI ファイル) は ZIP 書庫なので、内部のファイル情報を読み取るためには &lt;code&gt;&lt;a href="https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIZipReader" hreflang="en"&gt;nsIZipReader&lt;/a&gt;&lt;/code&gt; のインスタンスを作成し書庫を開く必要があります。&lt;/p&gt;&#13;
&lt;/li&gt;&#13;
&lt;li&gt;&#13;
  &lt;p&gt;書庫内部のファイル名一覧を取得するには &lt;code&gt;findEntries()&lt;/code&gt; を使います。ここで指定するファイル名のパターンにおいて、&lt;code&gt;"?"&lt;/code&gt; は任意の1文字を、&lt;code&gt;"*"&lt;/code&gt; は任意の文字列を、&lt;code&gt;"&lt;var&gt;pattern1&lt;/var&gt;~&lt;var&gt;pattern2&lt;/var&gt;"&lt;/code&gt; は &lt;code&gt;&lt;var&gt;pattern1&lt;/var&gt;&lt;/code&gt; にマッチするが &lt;code&gt;&lt;var&gt;pattern2&lt;/var&gt;&lt;/code&gt; にはマッチしないものを表します。&lt;/p&gt;&#13;
  &lt;p&gt;&lt;code&gt;"/path/to/entry/*"&lt;/code&gt; というパターンでは &lt;code&gt;/path/to/entry/&lt;/code&gt; 自信も含まれてしまうので、ディレクトリではないファイルだけを抽出するために &lt;code&gt;"/path/to/entry/?*"&lt;/code&gt; と指定します。また、それだけだと子孫ディレクトリ中のファイルも含まれるので、&lt;code&gt;"/path/to/entry/?*/*"&lt;/code&gt; を除外してやります。&lt;/p&gt;&#13;
&lt;/li&gt;&#13;
&lt;li&gt;&#13;
  &lt;p&gt;&lt;code&gt;findEntries()&lt;/code&gt; で得られた値にはディレクトリ部分も含まれるので、その部分は切り取ってファイル名だけにします。&lt;/p&gt;&#13;
&lt;/li&gt;&#13;
&lt;/ol&gt;&#13;
&#13;
&lt;pre&gt;&lt;code&gt;openZipReader: function CF_openZipReader(uri) {&#13;
    let zip = Cc['@mozilla.org/libjar/zip-reader;1'].&#13;
              createInstance(Ci.nsIZipReader);&#13;
    if (uri instanceof Ci.nsIFileURL) {&#13;
        // 1. file URL なら単にそのファイルを開く&#13;
        zip.open(uri.file);&#13;
    } else if (uri instanceof Ci.nsIJARURI) {&#13;
        // 2. jar URL なら JAR ファイル内部のファイルを開く&#13;
        let innerZip = this.openZipReader(uri.JARFile);&#13;
        zip.openInner(innerZip, uri.JAREntry);&#13;
    } else {&#13;
        throw new Error('Unknown URI: ' + uri.spec);&#13;
    }&#13;
    return zip;&#13;
},&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;ol&gt;&#13;
&lt;li&gt;&#13;
  &lt;p&gt;JAR ファイルがローカルファイルシステム上に直接存在するなら、単に &lt;code&gt;open()&lt;/code&gt; メソッドにファイルオブジェクトを渡して開くだけです。&lt;/p&gt;&#13;
&lt;/li&gt;&#13;
&lt;li&gt;&#13;
  &lt;p&gt;開こうとする JAR ファイルが別の書庫内に存在することもあります。その場合は &lt;code&gt;openInner()&lt;/code&gt; に、JAR ファイルが含まれる書庫と、その書庫内での JAR ファイルのパスを指定してやります。&lt;/p&gt;&#13;
  &lt;p&gt;&lt;code&gt;nsIZipReader#openInner()&lt;/code&gt; は Firfox 4 で追加されたものですが、Firefox 4 より前では jar URL がネストすることはないといっていいので、ここで使っても問題ないでしょう。&lt;/p&gt;&#13;
&lt;/li&gt;&#13;
&lt;/ol&gt;&#13;
&#13;
&lt;p&gt;たとえば Firefox 4 Beta で&lt;a href="https://addons.mozilla.org/firefox/addon/5890/"&gt;ツリー型タブ&lt;/a&gt;を使うと、&lt;code&gt;chrome://treestyletab/content/&lt;/code&gt; の実体は &lt;code&gt;jar:jar:file://&lt;var&gt;{profile}&lt;/var&gt;/extensions/treestyletab@piro.sakura.ne.jp.xpi!/chrome/treestyletab.jar!/content/treestyletab/&lt;/code&gt; といった URL になりますが、上記のようにすればその内部のファイル構成を知ることができます。&lt;/p&gt;&#13;
&lt;p&gt;また、&lt;code&gt;resource://gre/modules/XPCOMUtils.jsm&lt;/code&gt; といった resource URL に関しても、&lt;code&gt;&lt;a href="http://www.oxymoronical.com/experiments/apidocs/interface/nsIResProtocolHandler" hreflang="en"&gt;nsIResProtocolHandler&lt;/a&gt;#resolveURI()&lt;/code&gt; を使えばローカルファイルシステム上の URL へ変換でき、上と同様にファイル一覧の取得などが可能になります。&lt;/p&gt;
</description>
      <dc:subject>Mozilla Firefox</dc:subject>
      <dc:subject>JavaScript</dc:subject>
    </item>
    <item>
      <title>Firefox Developers Conference 2010</title>
      <link>http://nanto.asablo.jp/blog/2010/12/28/5611693</link>
      <guid>http://nanto.asablo.jp/blog/2010/12/28/5611693</guid>
      <pubDate>Tue, 28 Dec 2010 00:18:38 +0900</pubDate>
      <dcterms:modified>2010-12-28T00:22:03+09:00</dcterms:modified>
      <dcterms:created>2010-12-28T00:20:48+09:00</dcterms:created>
      <description>&lt;p&gt;&lt;a href="http://mozilla.jp/events/2010/fxdevcon/"&gt;Firefox Developers Conference 2010&lt;/a&gt; に行ってきた。全体のまとめとしては以下が詳しい。&lt;/p&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://efcl.info/2010/1121/res2092/"&gt;Firefox Developers Conference 2010 アウトラインメモ | Web scratch&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://www32.atwiki.jp/nakamura001/pages/103.html"&gt;nakamura001 @ ウィキ - Firefox Developers Conference 2010&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;p&gt;&lt;a href="http://b.hatena.ne.jp/t/fxdevcon?sort=eid"&gt;はてなブックマークで fxdevcon タグがつけられたエントリー&lt;/a&gt;を見てまわるのもいい。&lt;a href="http://mozilla.jp/firefox/beta/features/"&gt;Firefox 4 ベータ版機能概要&lt;/a&gt;では新しいタブインターフェース "Panorama" の紹介動画を見られる。&lt;/p&gt;&#13;
&lt;p&gt;内容に関しては上述のページを参考にしてもらうとして、個人的に感じたことををいくつか挙げる。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;Beyond Firefox 4 (Jay Sullivan)&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;Mozilla はユーザーの選択肢を広めることを重視する、逆に言えば単一のプラットフォームを目指すわけではないということのようだ。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;John Resig feat. Shibuya.js&lt;/h3&gt;&#13;
&#13;
&lt;h4&gt;&lt;a href="http://www.slideshare.net/t_wada/jstest-shibuyajs-fxdevcon"&gt;10+1 Things you should know about JavaScript testing (t_wada)&lt;/a&gt;&lt;/h4&gt;&#13;
&lt;p&gt;私の場合、Web ブラウザ向け JavaScript のテストを書いていないのはさくっとテストできる環境を知らないからというのが大きい。Firefox 拡張に関しては &lt;a href="http://www.clear-code.com/software/uxu/"&gt;UxU&lt;/a&gt; という素晴しい環境があったから部分的とはいえテストを書けた。&lt;/p&gt;&#13;
&lt;p&gt;カスタムイベントで処理をつなぐというのは結構やる。&lt;a href="http://nanto.asablo.jp/blog/2007/03/23/1339498"&gt;イベントモデルの実装&lt;/a&gt;も何回かやったけど、jQuery が使えるなら jQuery の実装 (&lt;a href="http://api.jquery.com/bind/" hreflang="en"&gt;bind&lt;/a&gt;、&lt;a href="http://api.jquery.com/trigger/" hreflang="en"&gt;trigger&lt;/a&gt;) を使うのが楽だ。カスタムイベント名には &lt;a href="http://dev.w3.org/2006/webapi/progress/#suggested-progressevent-types" hreflang="en"&gt;Progress Events 仕様&lt;/a&gt;で提案されているものを流用したほうがいいかと思ったが、trigger 時に独自引数を渡すならかえって紛らわしいかもしれない。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;// 独自のオブジェクトに jQuery のイベントモデル実装を組み込む例&#13;
&#13;
function Loader() {&#13;
    this.$ = $({});&#13;
}&#13;
$.extend(Loader.prototype, {&#13;
    method: function () {&#13;
        this.$.trigger('load', args);&#13;
    }&#13;
});&#13;
&#13;
var loader = new Loader();&#13;
loader.$.bind('load', function (args) {});&lt;/code&gt;&lt;/pre&gt;&#13;
&#13;
&lt;h4&gt;&lt;a href="http://sakura.mesolabs.com/fxdevcon2010"&gt;Node.js にまつわる 7 つの誤解 (meso)&lt;/a&gt;&lt;/h4&gt;&#13;
&lt;p&gt;現在、Node.js の開発は個人の手を離れ Joyent 社主導で行われているそうだ。会社によってはライブラリ/フレームワークの採用基準に、それが一定規模の団体によって保守されているかどうかが含まれるだろうから、Node.js の普及を促進する上ではよいことだと思う。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;トークセッション: HTML5 時代の技術で Web プラットフォームはどう変わるのか (矢倉眞隆、村岡正和、浅井智也)&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;&lt;span lang="en"&gt;W3C CSS working group&lt;/span&gt; ではレイアウト関係が要注目とのこと。&lt;a href="http://dev.w3.org/csswg/css3-flexbox/Overview.new.src.html" hreflang="en" lang="en"&gt;Flexible Box Layout Module&lt;/a&gt; は Mozilla の XUL ボックスモデルに由来するもので、(Mozilla から Apple へ移籍した &lt;span lang="en"&gt;Dave Hyatt&lt;/span&gt; の手により) 類似のモデルが WebKit でも実装されている。ただし、現在の草案は display プロパティの値に "box" ではなく "flex" を採用するなど、両実装と異なる点が多い。&lt;a href="http://dev.w3.org/csswg/css3-grid-align/" hreflang="en" lang="en"&gt;Grid Alignment Module&lt;/a&gt; は Microsoft が中心となって策定を進めている (編者の一人 &lt;span lang="en"&gt;Alex Mogilevsky&lt;/span&gt; は &lt;span lang="en"&gt;Flexible Box Layout Module&lt;/span&gt; の編者も兼任)。両モジュールともアプリケーション UI の整形を念頭に置いているが、手軽さでは &lt;span lang="en"&gt;Flexible Box&lt;/span&gt;、柔軟性では &lt;span lang="en"&gt;Grid Alignment&lt;/span&gt; が勝っているように感じる。&lt;/p&gt;&#13;
&lt;p&gt;まとめとして、矢倉氏は描画には canvas だけでなく SVG、通信には WebSocket だけでなく &lt;span lang="en"&gt;Server-Sent Events&lt;/span&gt; など、あることを実現するのにさまざまな手段があるのを知ってほしいと、村岡氏は積極的に HTML5 を書き、関連 API を使って開発し、そして仕様策定者側にフィードバック (提案) しようと述べていた。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;大ライトニングトーク&lt;/h3&gt;&#13;
&#13;
&lt;h4&gt;&lt;a href="http://x86.cx/"&gt;HTML 2.0 (TAKESAKO)&lt;/a&gt;&lt;/h4&gt;&#13;
&lt;p&gt;"2.0" というのはバズワード。HTML パーサのエラー処理方法の違いを利用してブラウザを判別する試みである。HTML5 では HTML 構文の解析方法がエラー処理も含めて規定されるので、今後ブラウザが HTML5 HTML 構文に対応していく中でこのような試みは困難になっていくと思われる。&lt;/p&gt;&#13;
&#13;
&lt;h4&gt;&lt;a href="http://www.ne.jp/asahi/nanto/moon/2010/12/28/placeholder.html"&gt;placeholder 実装マニアックス&lt;/a&gt;&lt;/h4&gt;&#13;
&lt;p&gt;テキスト入力欄に何らかのメッセージを表示し、入力欄にフォーカスするとそれが消えるという UI は以前から見られた。HTML5 では placeholder 属性でこのメッセージを指定できるが、未対応ブラウザでこの挙動を再現しようとすればスクリプトを使う必要がある。&lt;/p&gt;&#13;
&lt;p&gt;まず考えられるのは入力欄の value プロパティにメッセージの文面を設定し、フォーカス移動に際してこれを消去することである。しかしこの場合、フォーム送信時のメッセージ消去や、ブラウザがフォームコントロールの入力値を記憶することへの対処が必要となる。&lt;/p&gt;&#13;
&lt;p&gt;別の方法として、CSS を使いメッセージと入力欄を重ね合わせることも可能だ。メッセージ部分を絶対配置の要素とし、文書木上では入力欄の直前に挿入する。left 及び top プロパティを指定しなければ絶対配置の要素は「その要素が絶対配置でなかったときの位置」に置かれる。この絶対配置要素の初期位置は意外と便利で、top、left、right、bottom プロパティのいずれかひとつのみ指定すれば、水平方向または垂直方向にだけずらすこともできる。&lt;/p&gt;&#13;
&lt;p&gt;なお、placeholder に指定するのは入力欄に関する補助的な情報 (なくても問題ないもの) であり、入力欄に対するラベルではない。ラベルは label 要素で指定する。中には入力中に参照したい情報もあるだろうし、&lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=545817" title="Bug 545817 -- Tracker for placeholder accessibility" hreflang="en"&gt;状況によっては placeholder の内容が提示されないこともある&lt;/a&gt;ようなので、そもそも placeholder を使うべき場面なのか検討したほうがいい。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;懇親会&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;食事があっという間になくなってしまったのが残念だった。&lt;/p&gt;&#13;
&lt;p&gt;ブラウザの進化速度は速い。できることはどんどん多くなるが、それらをどう組み立てていくかというパターンはまだ不安定に思える。その部分を探っていきたい。&lt;/p&gt;
</description>
      <dc:subject>Mozilla Firefox</dc:subject>
      <dc:subject>Web 関連技術</dc:subject>
    </item>
    <item>
      <title>リンクのようなボタンを作る</title>
      <link>http://nanto.asablo.jp/blog/2010/12/15/5584008</link>
      <guid>http://nanto.asablo.jp/blog/2010/12/15/5584008</guid>
      <pubDate>Wed, 15 Dec 2010 23:52:28 +0900</pubDate>
      <dcterms:modified>2010-12-16T10:38:02+09:00</dcterms:modified>
      <dcterms:created>2010-12-15T23:53:49+09:00</dcterms:created>
      <description>&lt;p&gt;こんばんは、&lt;a href="http://atnd.org/events/10497"&gt;JavaScript Advent Calendar 2010&lt;/a&gt;、15 日目担当の nanto_vi (なんと) です。&lt;a href="http://nnh.to/12/15.html"&gt;12 月 15 日が何の日か&lt;/a&gt;調べてみると東北本線が宮城県に到達した日とのこと。当時は上野から仙台まで 12 時間 20 分かかったそうです。それから 123 年を経た現在では同じ時間で鹿児島中央から新青森まで行けるようになり、鉄道の速度にも JavaScript の実行速度にも日進月歩を感じる今日この頃です。&lt;/p&gt;&#13;
&lt;p&gt;さて、アプリケーションを作っていると、見た目はリンクのようだがリンクでない UI 部品を使いたくなるときがあります。ここで「リンクでない」とは、クリックしてもページ遷移が発生しないということです。このような UI 部品は、ページ遷移の代わりにメニューの表示といった何らかのアクションを引き起こす、すなわちボタンとして振舞います。&lt;/p&gt;&#13;
&lt;p&gt;ユーザーインターフェース記述言語として HTML を使っているとき、この「リンクのようなボタン」をどのように実現すればいいのでしょうか。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;input、button 要素&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;ボタンとして振舞うものはボタンとして記述すべきです。HTML では汎用的なボタンとして &lt;code&gt;&amp;lt;input type="button"&amp;gt;&lt;/code&gt; 及び &lt;code&gt;&amp;lt;button type="button"&amp;gt;&lt;/code&gt; が用意されています。スタイルシートを使えば見た目をリンクのようにもできるでしょうし、画像を使いたければ &lt;code&gt;&amp;lt;input type="image"&amp;gt;&lt;/code&gt; もあります。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;&amp;lt;input type="button" value="リンクのようなボタン" onclick="..."&amp;gt;&#13;
&amp;lt;button type="button" onclick="..."&amp;gt;リンクのようなボタン&amp;lt;/button&amp;gt;&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;しかし、フォームコントロールに対してはスタイルシートが期待通り適用されないこともあり、ボタンをどうしてもインライン要素にしたいときにこの方法は取れません。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;a 要素&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;リンクのように見えるならリンクにすればいいということで a 要素が使われることもあります。click イベントを処理するときにデフォルトアクションをキャンセルすれば、もともと指定してあったリンク先に飛ぶことはありません。あるいはリンク先に &lt;code&gt;javascript:void(0);&lt;/code&gt; と指定することでページ遷移が発生しないようにします。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;&amp;lt;a href="#" onclick="...; return false;"&amp;gt;リンクのようなボタン&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;しかし、a 要素はあくまでハイパーリンク、すなわち他のリソースへ移動するためのものです。外見がどうあろうとリンクでないものの記述に使うの好ましくありません。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;span 要素&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;click イベントに対する処理はどんな要素にも付加できるので、a 要素にこだわる必要はありません。「リンクのような」の部分はスタイルシートで実現できます。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;&amp;lt;style&amp;gt;&#13;
.trigger {&#13;
  color: #00f;&#13;
  text-decoration: underline;&#13;
  cursor: pointer;&#13;
}&#13;
&amp;lt;/style&amp;gt;&#13;
&#13;
&amp;lt;span class="trigger" onclick="..."&amp;gt;リンクのようなボタン&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;しかし、これではキーボードを用いてボタンにアクセスすることができません。多くのブラウザでは Tab キーでリンクやフォームコントロールへ移動できますが、span 要素はその対象から外れています。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;span 要素 + tabindex 属性&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;tabindex 属性はフォーカス順を変更するものだと思っていたあなた、それはこの属性が持つパワーのほんの一部でしかありません。HTML5 において tabindex 属性は要素をフォーカス可能にする属性として生まれ変わったのです。この属性はどんな要素にもつけられ、値に 0 を指定すればその要素がキーボードアクセス可能になります。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;&amp;lt;span class="trigger" tabindex="0" onclick="..."&amp;gt;&#13;
  リンクのようなボタン&#13;
&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;しかし、Tab キーでこのボタンにフォーカスし、Enter キーを押しても何もおきません。a要素によるリンクなら Enter キーを押すと click イベントが発生するのにも関わらずです。なお、Opera なら span 要素でも Enter キーにより click イベントが発生し、指定したアクションが実行されます。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;span 要素 + tabindex 属性 + onkeypress 属性&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;click イベントが発生しないなら自分で click イベントに対する処理を呼び出せばいいのです。onclick 属性に指定したコードは onclick プロパティから関数として取得できます。Enter キーを表すキーコードは 13 なので、そのときのみ処理を実行します。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;&amp;lt;span class="trigger" tabindex="0" onclick="..."&#13;
      onkeypress="if (event.keyCode === 13) this.onclick(event);"&amp;gt;&#13;
  リンクのようなボタン&#13;
&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;しかし、click イベントに対する処理が onclick 属性に書かれているとは限りません。addEventListener や attachEvent メソッドでイベントリスナが追加されていることもあれば、祖先要素、文書ノードで click イベントが処理されていることもあります。また、Opera ではこの場合 Enter キーを押すと onclick 属性の内容が2回実行されてしまいます。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;span 要素 + tabindex 属性 + キーイベント処理&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;click イベントに対する処理を直接実行できなくとも、click イベントを発生させれば自然とそれらが実行されます。イベントを発生させるのに、DOM イベントモデルでは dispatchEvent、IE のイベントモデルでは fireEvent メソッドを用います。Opera 対策に keypress イベントのデフォルトアクションをキャンセルしておきましょう。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;&amp;lt;script&amp;gt;&#13;
function activate(event) {&#13;
    event = event || window.event;&#13;
    if (event.keyCode !== 13) return;&#13;
    if (document.createEvent) {&#13;
        var e = document.createEvent('MouseEvent');&#13;
        e.initMouseEvent(&#13;
            'click', true, true, event.view, 1,&#13;
            event.screenX, event.screenY, event.clientX, event.clientY,&#13;
            event.ctrlKey, event.altKey, event.shiftKey, event.metaKey, 0, null&#13;
        );&#13;
        event.target.dispatchEvent(e);&#13;
        event.preventDefault();&#13;
    } else if (document.createEventObject) {&#13;
        var e = document.createEventObject(event);&#13;
        event.srcElement.fireEvent('onclick', e);&#13;
        event.returnValue = false;&#13;
    }&#13;
}&#13;
&amp;lt;/script&amp;gt;&#13;
&#13;
&amp;lt;span class="trigger" tabindex="0"&#13;
      onclick="..." onkeypress="activate(event);"&amp;gt;&#13;
  リンクのようなボタン&#13;
&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;しかし、視覚的なブラウザであれば見た目からこの要素が何らかのアクションを引き起こすことがわかりますが、環境によってもそもそもこれが「押せる」ということすら伝わらないかもしれません。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;span 要素 + tabindex 属性 + キーイベント処理 + role 属性&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;視覚によらず、機械的に UI 部品を認識するための仕様として &lt;abbr title="Accessible Rich Internet Applications" lang="en"&gt;WAI-ARIA&lt;/abbr&gt; があります。要素がボタンの「役割」を果たすことを表すには、role 属性の値に "button" を指定します。これで人の目からだけでなく、機械から見たときもボタンとして認識・操作できるようになりました。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;&amp;lt;span class="trigger" role="button" tabindex="0"&#13;
      onclick="..." onkeypress="activate(event);"&amp;gt;&#13;
  リンクのようなボタン&#13;
&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/pre&gt;&#13;
&#13;
&lt;h3&gt;サンプル&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;&lt;a href="http://www.ne.jp/asahi/nanto/moon/2010/12/15/link-button-sample.html"&gt;リンクのようなボタンのサンプル&lt;/a&gt;で実際の挙動を確認できます。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;終わりに&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;以上はあくまで JavaScript の使える環境が前提です。スクリプトが動かなくとも最低限の機能は利用できるよう気をつけましょう。スクリプトが動く場合でも、本当にリンクのようなボタンでなければいけないのか、通常のボタン、またはハイパーリンクでは実現できないのかよく検討した上で使うようにしてください。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;参考資料&lt;/h3&gt;&#13;
&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/" lang="en" hreflang="en"&gt;HTML5 (including next generation additions still in development)&lt;/a&gt;&#13;
  &lt;ul&gt;&#13;
  &lt;li&gt;&lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#sequential-focus-navigation-and-the-tabindex-attribute" lang="en" hreflang="en"&gt;8.3.1 Sequential focus navigation and the tabindex attribute&lt;/a&gt;&lt;/li&gt;&#13;
  &lt;li&gt;&lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/content-models.html#annotations-for-assistive-technology-products-%28aria%29" lang="en" hreflang="en"&gt;3.2.6 Annotations for assistive technology products (ARIA)&lt;/a&gt;&lt;/li&gt;&#13;
  &lt;/ul&gt;&#13;
&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://www.w3.org/TR/2010/WD-wai-aria-20100916/" lang="en" hreflang="en"&gt;Accessible Rich Internet Applications (WAI-ARIA) 1.0&lt;/a&gt; (&lt;a href="http://www.hitachi.co.jp/universaldesign/wai-aria/wd_20090224/index.html" title="アクセシブル・リッチ・インターネット・アプリケーション（WAI-ARIA）1.0"&gt;2009 年 2 月 24 日付草案日本語訳&lt;/a&gt;)&#13;
  &lt;ul&gt;&#13;
  &lt;li&gt;&lt;a href="http://www.w3.org/TR/2010/WD-wai-aria-20100916/roles#button" lang="en" hreflang="en"&gt;button (role)&lt;/a&gt;&lt;/li&gt;&#13;
  &lt;/ul&gt;&#13;
&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/ja-jp/library/aa511258.aspx"&gt;Windows ユーザー エクスペリエンス ガイドライン&lt;/a&gt;&#13;
  &lt;ul&gt;&#13;
  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/ja-jp/library/aa511483.aspx"&gt;リンク&lt;/a&gt;&lt;/li&gt;&#13;
  &lt;/ul&gt;&#13;
&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/ja-jp/library/aa511454.aspx"&gt;コマンド ボタンとリンクの比較&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://dev.ariel-networks.com/column/tech/ux/view"&gt;プログラマのためのUXチートシート ― ありえるえりあ&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;
</description>
      <dc:subject>JavaScript</dc:subject>
      <dc:subject>Web 関連技術</dc:subject>
    </item>
    <item>
      <title>Kanasan.JS JavaScript 第 5 版読書会 #10 XPath 発表資料</title>
      <link>http://nanto.asablo.jp/blog/2010/09/27/5370782</link>
      <guid>http://nanto.asablo.jp/blog/2010/09/27/5370782</guid>
      <pubDate>Mon, 27 Sep 2010 08:58:53 +0900</pubDate>
      <dcterms:modified>2010-09-27T09:00:19+09:00</dcterms:modified>
      <dcterms:created>2010-09-27T09:00:19+09:00</dcterms:created>
      <description>&lt;p&gt;6 月のことになりますが、&lt;a href="http://sites.google.com/site/kanasanjs/about/javascript-di5ban-du-shu-hui"&gt;Kanasan.JS JavaScript 第 5 版読書会&lt;/a&gt; #10 にて XPath に関する発表を行いました。内容は基本的な XPath の解説です。&lt;/p&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://www.ne.jp/asahi/nanto/moon/2010/09/27/xpath.html"&gt;発表資料: Excellent XPath Expressions (図、注釈付き)&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://www.ne.jp/asahi/nanto/moon/2010/09/27/xpath-figures.odg"&gt;図の元データ (OpenDocument Graphics 形式)&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;p&gt;本番では図の準備が間に合わずホワイトボードに描きながら発表したのですが、逐次挙がる質問に対してもすぐ描き直して対応できたので、かえって理解を深めるのに役立ったのではないかと思います。資料中の注釈は口頭で説明したことなどを書き起こしたものです。&lt;/p&gt;&#13;
&lt;p&gt;タイトルに &lt;span lang="en"&gt;excellent&lt;/span&gt; と入っていますが何か特に素晴しいということはなく、単に頭韻を踏みたかっただけです。(しかし &lt;span lang="en"&gt;excellent&lt;/span&gt; と &lt;span lang="en"&gt;expression&lt;/span&gt; では &lt;span lang="en"&gt;ex&lt;/span&gt; の発音が違うので踏めてないという……)&lt;/p&gt;
</description>
      <dc:subject>JavaScript</dc:subject>
      <dc:subject>Web 関連技術</dc:subject>
    </item>
    <item>
      <title>日記始めました</title>
      <link>http://nanto.asablo.jp/blog/2010/04/01/4987912</link>
      <guid>http://nanto.asablo.jp/blog/2010/04/01/4987912</guid>
      <pubDate>Thu, 01 Apr 2010 09:39:46 +0900</pubDate>
      <dcterms:modified>2010-04-01T09:42:29+09:00</dcterms:modified>
      <dcterms:created>2010-04-01T09:42:29+09:00</dcterms:created>
      <description>&lt;p&gt;このブログを始めた当初は趣味やら愚痴やら何でも書くつもりだったのですが、技術系のネタが多勢を占めるにつれ、それ以外のことが書きづらくなってきました。そうした、Web なりプログラミングなりと関係ないことについて、これからは別に日記を設け、そこに書きとめておくことにします。&lt;/p&gt;&#13;
&lt;p&gt;そのための場所として&lt;a href="http://www.hatena.ne.jp/"&gt;はてな&lt;/a&gt;を考えていたのですが、悲しむべきことに、いつの間にか&lt;a href="http://d.hatena.ne.jp/hatenadiary/20090819/1250681214"&gt;日記ではなくブログサービスになっていました&lt;/a&gt;。しかし、はてなダイアリーを使わなければいけない理由もできてしまったので、そのあたりには目をつむることにします。&lt;/p&gt;&#13;
&lt;p&gt;というわけで、今後非技術系の話は日記 &lt;a href="http://d.hatena.ne.jp/nanto_vi/"&gt;Ways on the Moon&lt;/a&gt; でやっていきます。JavaScript や Mozilla に関しては引き続きここ、Days on the Moon に書くつもりなので、よろしくお願いいたします。&lt;/p&gt;
</description>
      <dc:subject>その他雑文</dc:subject>
    </item>
    <item>
      <title>Mozilla 勉強会 @ 大阪</title>
      <link>http://nanto.asablo.jp/blog/2010/03/03/4917550</link>
      <guid>http://nanto.asablo.jp/blog/2010/03/03/4917550</guid>
      <pubDate>Wed, 03 Mar 2010 04:53:22 +0900</pubDate>
      <dcterms:modified>2010-03-03T04:58:01+09:00</dcterms:modified>
      <dcterms:created>2010-03-03T04:55:34+09:00</dcterms:created>
      <description>&lt;p&gt;2 月 20 日に行われた &lt;a href="https://dev.mozilla.jp/events/workshop02/"&gt;Mozilla 勉強会 @ 大阪&lt;/a&gt;に行ってきました。「js-ctypes で音声読み上げ」という題でライトニングトークをしたので、そのスライドとサンプルコードを公開します。&lt;/p&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://www.ne.jp/asahi/nanto/moon/2010/03/03/js-ctypes-reading.html"&gt;js-ctypes で音声読み上げ&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://gist.github.com/308409"&gt;read-selection.uc.js&lt;/a&gt; (userChrome.js 用スクリプト)&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;p&gt;&lt;a href="https://developer.mozilla.org/ja/JavaScript_code_modules/ctypes.jsm"&gt;js-ctypes&lt;/a&gt; は C/C++ 用のライブラリ関数を JavaScript から呼び出すための機能で、Firefox の次期バージョンに搭載される予定です。ここでは「&lt;a href="http://d.hatena.ne.jp/ara_k/20091204/1259935014"&gt;AquesTalkとkakasiを組み合わせて再生。 - 世界はアルゴリズムでできている。&lt;/a&gt;」を参考に音声読み上げライブラリを呼び出してみました。&lt;/p&gt;&#13;
&lt;p&gt;上記コードでは標準 C ライブラリ関数を使って無理やりポインタを扱っていますが、&lt;a href="http://people.mozilla.com/~dwitte/ctypes-talk-20100222/ctypes.html" hreflang="en" lang="en"&gt;Overview of js-ctypes&lt;/a&gt; や &lt;a href="https://wiki.mozilla.org/Jsctypes/api" hreflang="en"&gt;MozillaWiki の js-ctypes のページ&lt;/a&gt;を見るに、将来的には標準でポインタや構造体、コールバック関数を使えるようにするみたいです。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;IME の実装の概要について (&lt;a href="http://www.d-toybox.com/studio/weblog/show.php"&gt;中野雅之さん&lt;/a&gt;)&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;現在 Mozilla で IME 周りのコードを書いているのは中野さんだけだそうです (レビュワは Windows と Linux に一人ずつ)。「&lt;a href="http://d.hatena.ne.jp/NyaRuRu/20070309/p1"&gt;TSF を使う (1) - Windows Input Method の歴史 - NyaRuRuの日記&lt;/a&gt;」によると Mozilla は IME 関係の描画を自前で行っているそうで、それを一人でやり続けているというのには頭が下がります。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;研究プラットフォームとしての Firefox の可能性 (&lt;a href="http://www.dl.kuis.kyoto-u.ac.jp/~tyamamot/"&gt;山本岳洋さん&lt;/a&gt;)&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;研究の一環として &lt;a href="http://rerank.jp/"&gt;Rerank.jp&lt;/a&gt; を作っている方です。当初は C# でアプリケーションを作成していたが、いちいち起動するのが面倒で自分でさえも使わなくなってしまったとのこと。そういう点では、常に起動しているアプリケーション実行環境で、おまけにクロスプラットフォームというのはとっつきやすいのかもしれませんね。&lt;/p&gt;&#13;
&lt;p&gt;ちなみに私が知る限りでは、ほかにも次のような研究が Firefox (Mozilla) を使っています。&lt;/p&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://d.hatena.ne.jp/Gemma/20091209/1260375914"&gt;Web ブラウザと融合するインスタントメッセンジャー「むすび」&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://db-event.jpn.org/deim2009/proceedings/files/E4-6.pdf"&gt;大画面ディスプレイ上でのウェブブラウジングにおける効率的タスク切り替え支援手法 (PDF)&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://piro.sakura.ne.jp/xul/webmap/"&gt;ブラウザの履歴を二次元的に記録・表示する「Web Map」&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&#13;
&lt;h3&gt;&lt;a href="https://dev.mozilla.jp/2010/02/mozilla-workshop-osaka-dadaa/"&gt;Jetpack Reboot&lt;/a&gt; (&lt;a href="http://minism.jp/"&gt;あかつかだいすけさん&lt;/a&gt;)&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;今 Jetpack は基礎から作り直している最中だそうです。Jetpack のランタイムを各フィーチャーが含んで、個別の「拡張機能」として扱えるようになり、またそれに伴い &lt;a href="https://addons.mozilla.org/"&gt;addons.mozilla.org (AMO)&lt;/a&gt; での公開手順も整備中とのこと。ある程度広まって問題点も明らかになり、それでいて 1.0 も出ていないこの時期は、まさに「再起動」にぴったりだと思います。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;modest と研究と勉強会&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;Mozilla/Firefox の開発情報を集約する場として、&lt;a href="https://dev.mozilla.jp/"&gt;Mozilla Developer Street (modest)&lt;/a&gt; を積極的に使ってほしいという話がありました。Firefox を研究に使うのと同時に、modest を大学で使っていくのもありだそうです。&lt;/p&gt;&#13;
&lt;p&gt;また、このような勉強会を今後も定期的に開いていくそうですが、大学での開催も可能とのことです。Firefox を研究に使いたいけれど開発方法がわからないという方は、modest で声を上げてみてはいかがでしょうか。&lt;/p&gt;
</description>
      <dc:subject>Mozilla Firefox</dc:subject>
      <dc:subject>JavaScript</dc:subject>
    </item>
    <item>
      <title>勝手に添削: Selection内のHTML Textをいい感じに取得する</title>
      <link>http://nanto.asablo.jp/blog/2010/02/05/4858761</link>
      <guid>http://nanto.asablo.jp/blog/2010/02/05/4858761</guid>
      <pubDate>Fri, 05 Feb 2010 09:15:00 +0900</pubDate>
      <dcterms:modified>2010-02-06T07:53:35+09:00</dcterms:modified>
      <dcterms:created>2010-02-05T09:15:45+09:00</dcterms:created>
      <description>&lt;p&gt;というわけでやってまいりましたこのコーナー! 本日のお題は「&lt;a href="http://d.hatena.ne.jp/Constellation/20100203/1265207970"&gt;Selection内のHTML Textをいい感じに取得する - 枕を欹てて聴く&lt;/a&gt;」でございます。選択範囲のHTMLソースを抜き出すというやつですね。では早速いってみましょう!&lt;/p&gt;&#13;
&lt;blockquote class="code" cite="http://d.hatena.ne.jp/Constellation/20100203/1265207970"&gt;&#13;
&lt;pre&gt;&lt;code&gt;  if(src.focusNode){&#13;
    // selection&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;/blockquote&gt;&#13;
&lt;p&gt;まずは &lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#selection" hreflang="en"&gt;HTML5 テキスト選択 API&lt;/a&gt; の &lt;code&gt;Selection&lt;/code&gt; オブジェクトが登場! 以後これに対する操作が続きます。しかしこの &lt;code&gt;Slection&lt;/code&gt; オブジェクト、&lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#dom-selection-getrangeat" hreflang="en"&gt;&lt;code&gt;getRangeAt&lt;/code&gt; メソッド&lt;/a&gt;を使うとなんと選択範囲に対応する &lt;a href="http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113" lang="en" hreflang="en"&gt;DOM 2 Traversal and Range&lt;/a&gt; の &lt;code&gt;Range&lt;/code&gt; オブジェクトが取れちゃうんです!&lt;/p&gt;&#13;
&lt;blockquote class="code" cite="http://d.hatena.ne.jp/Constellation/20100203/1265207970"&gt;&#13;
&lt;pre&gt;&lt;code&gt;    // common parent node search&#13;
    (以下 21 行省略)&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;/blockquote&gt;&#13;
&lt;p&gt;それ &lt;a href="http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113/ranges.html#Level-2-Range-attr-commonParent" hreflang="en"&gt;&lt;code&gt;Range#commonAncestorContainer&lt;/code&gt;&lt;/a&gt; で取れるよ!&lt;/p&gt;&#13;
&lt;blockquote class="code" cite="http://d.hatena.ne.jp/Constellation/20100203/1265207970"&gt;&#13;
&lt;pre&gt;&lt;code&gt;      // common配下のindexを見て, focus と anchorがどちらが前方かを調べる&#13;
      (以下 9 行省略)&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;/blockquote&gt;&#13;
&lt;p&gt;それ &lt;a href="http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113/ranges.html#Level-2-Range-attr-startParent" hreflang="en"&gt;&lt;code&gt;Range#startContainer&lt;/code&gt;&lt;/a&gt; と &lt;a href="http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113/ranges.html#Level-2-Range-attr-endParent" hreflang="en"&gt;&lt;code&gt;Range#endContainer&lt;/code&gt;&lt;/a&gt; でわかるよ!&lt;/p&gt;&#13;
&lt;blockquote class="code" cite="http://d.hatena.ne.jp/Constellation/20100203/1265207970"&gt;&#13;
&lt;pre&gt;&lt;code&gt;      // focusに沿って後方をremove&#13;
      (以下15行省略)&#13;
      // anchorに沿って前方をremove&#13;
      (以下11行省略)&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;/blockquote&gt;&#13;
&lt;p&gt;それ &lt;a href="http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113/ranges.html#Level2-Range-method-extractContents" hreflang="en"&gt;&lt;code&gt;Range#extractContents()&lt;/code&gt;&lt;/a&gt; か &lt;a href="http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113/ranges.html#Level2-Range-method-cloneContents" hreflang="en"&gt;&lt;code&gt;Range#cloneContents()&lt;/code&gt;&lt;/a&gt; でできるよ!&lt;/p&gt;&#13;
&lt;p&gt;というわけで不要な要素を除去する部分は置いといて今までの経過をまとめてみると、&lt;/p&gt;&#13;
&#13;
&lt;pre&gt;&lt;code&gt;function convertToHTMLString(source, safe) {&#13;
  if (!source || (source.getRangeAt &amp;amp;&amp;amp; source.isCollapsed)) return '';&#13;
  var range = source.getRangeAt ? source.getRangeAt(0) : null;&#13;
  var node = range ? range.cloneContents() : source.cloneNode(true);&#13;
  if (safe) { ... }&#13;
  return new XMLSerializer().serializeToString(node);&#13;
}&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;なんということでしょう! コメント空行抜きでも 86 行あった部分が実質たったの 2 行に!&lt;/p&gt;&#13;
&lt;p&gt;これに残った部分を付け足していくわけですが、&lt;a href="http://gist.github.com/295297" hreflang="en" title="converToHTMLString 関数"&gt;出来上がった品はこちら&lt;/a&gt;になります。(&lt;a href="http://www.ne.jp/asahi/nanto/moon/2010/02/05/convertToHTMLString.html" hreflang="en" title="converToHTMLString 関数を使ったサンプル"&gt;お試しはこちら!&lt;/a&gt;)&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;まとめ&lt;/h3&gt;&#13;
&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;code&gt;Range&lt;/code&gt; かわいいよ &lt;code&gt;Range&lt;/code&gt;。&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://nanto.asablo.jp/blog/2008/10/18/3829312"&gt;選択範囲からリンクを抜き出す&lt;/a&gt;こともできちゃうし。&lt;/li&gt;&#13;
&lt;li&gt;でも Opera 10 で文書木に属してないノードの &lt;code&gt;Range&lt;/code&gt; を作ろうとするとエラーになっちゃう……、ぐすん。(10.50 は試してない。)&lt;/li&gt;&#13;
&lt;li&gt;&lt;del&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms533874%28VS.85%29.aspx" hreflang="en"&gt;それ IE なら 1 行ででき&lt;/a&gt;&lt;/del&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;p&gt;以上、&lt;!--今日に備えてぐっすり眠るつもりがなぜか徹夜してしまったのとその他--&gt;もろもろの要因で&lt;del datetime="2010-02-05T09:30:00+09:00"&gt;無駄に&lt;/del&gt;ハイテンションの nanto_vi (なんと) がお届けしました!&lt;/p&gt;
</description>
      <dc:subject>JavaScript</dc:subject>
      <dc:subject>Web 関連技術</dc:subject>
    </item>
    <item>
      <title>Firefox 3.6 での XPath による要素取得</title>
      <link>http://nanto.asablo.jp/blog/2010/01/24/4836539</link>
      <guid>http://nanto.asablo.jp/blog/2010/01/24/4836539</guid>
      <pubDate>Sun, 24 Jan 2010 22:44:59 +0900</pubDate>
      <dcterms:modified>2010-01-24T22:47:20+09:00</dcterms:modified>
      <dcterms:created>2010-01-24T22:47:20+09:00</dcterms:created>
      <description>&lt;p&gt;Firefox 3.6 にしたら、動的に生成した文書からの XPath による要素取得ができなくなったという報告が挙がっています。&lt;/p&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://vimperator.g.hatena.ne.jp/voidy21/20100118/1263820341"&gt;Firefox3.6でdirect_bookmark.jsとdirect_hb.jsのはてブのタグを取得できていない問題(未解決→解決) - ヴィンペラートル・オクタウィアヌス - vimperatorグループ&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://d.hatena.ne.jp/mountain_dew/20100124/1264304665"&gt;subscldr.jsが動かなくなったのを直してみた - mountain_dewの日記&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;p&gt;この原因は、&lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=468708" title="Bug 468708 -- namespaceURI for HTML elements should be http://www.w3.org/1999/xhtml" hreflang="en"&gt;Firefox 3.6 で HTML 要素の名前空間の扱いが変わった&lt;/a&gt;ことにあります。Firefox 3.6 (Gecko 1.9.2) では、HTML5 に従い、HTML 要素が (XML 文書中でなくても) XHTML の名前空間 (HTML5 でいうところの「&lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#html-namespace-0" hreflang="en"&gt;HTML の名前空間&lt;/a&gt;」) &lt;code&gt;http://www.w3.org/1999/xhtml&lt;/code&gt; に属するようになりました。&lt;/p&gt;&#13;
&lt;p&gt;これに伴って、これまでは XML 文書中でも有効だった、XPath 式の評価における HTML 要素の特別扱い (要素名の大文字小文字を区別しない、非修飾名を HTML の名前空間に属するものとみなす) が、HTML 文書中でのみ有効となったようです。なお、この特別扱いは、&lt;a href="http://www.w3.org/TR/1999/REC-xpath-19991116/" hreflang="en"&gt;XPath 1.0&lt;/a&gt; に違反しますが、&lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/apis-in-html-documents.html#interactions-with-xpath-and-xslt" title="3.4 Interactions with XPath and XSLT - HTML5" hreflang="en"&gt;HTML5 で認められています&lt;/a&gt;。&lt;/p&gt;&#13;
&lt;p&gt;&lt;code&gt;document.implementation.createDocument(null, 'html', null)&lt;/code&gt; で作成されるのは XML 文書なので、接頭辞なしの XPath 式では HTML 要素を取得できなくなってしまいました。このことは、「&lt;a href="http://nanto.asablo.jp/blog/2009/10/29/4660197"&gt;HTMLDocument の動的な生成&lt;/a&gt;」でも、(こちらは Firefox 3.7a ですが) &lt;a href="http://nanto.asablo.jp/blog/2009/10/29/4660197#htmldoc-createdoc"&gt;&lt;code&gt;createDocument&lt;/code&gt; メソッド&lt;/a&gt;での名前空間なし XPath の結果が×になっていることで確認可能です。&lt;/p&gt;&#13;
&lt;p&gt;解決策としては、HTML 文書を作成するようにすればいい話です。これには &lt;a href="http://nanto.asablo.jp/blog/2009/10/29/4660197#htmldoc-xslt"&gt;XSLT の HTML 出力&lt;/a&gt;を使ってもいいのですが、なぜか今現在の Firefox nightly (3.7a1pre 20100123) ではこの方法がうまくいかないので、&lt;a href="http://nanto.asablo.jp/blog/2009/10/29/4660197#htmldoc-createdoc-doctype-ns"&gt;&lt;code&gt;createDocument&lt;/code&gt; メソッドに文書型宣言と名前空間を指定する&lt;/a&gt;ほうをおすすめします。&lt;/p&gt;&#13;
&lt;p&gt;ちなみに &lt;a href="http://github.com/swdyh/autopagerize/commit/79c7e0b2a6f813d24c72321f5d699246b25b5545" hreflang="en"&gt;AutoPagerize では &lt;code&gt;document.cloneNode&lt;/code&gt; メソッドを使っています&lt;/a&gt;が、これは読み込む文書が基本的に同じ Web サイト内のものであり、現在の文書が HTML 文書なら次も HTML 文書、XML 文書なら次も XML 文書と推定できるからです。XML 文書から HTML 文書を読み込む場合など、汎用性を考えるならやはり &lt;code&gt;createDocument&lt;/code&gt; メソッドを使ったほうがいいでしょう。&lt;/p&gt;
</description>
      <dc:subject>Mozilla Firefox</dc:subject>
      <dc:subject>Web 関連技術</dc:subject>
    </item>
    <item>
      <title>Kanasan.JS Jetpack ワークショップ</title>
      <link>http://nanto.asablo.jp/blog/2009/12/30/4784624</link>
      <guid>http://nanto.asablo.jp/blog/2009/12/30/4784624</guid>
      <pubDate>Wed, 30 Dec 2009 18:08:47 +0900</pubDate>
      <dcterms:modified>2009-12-30T18:10:51+09:00</dcterms:modified>
      <dcterms:created>2009-12-30T18:10:51+09:00</dcterms:created>
      <description>&lt;p&gt;&lt;a href="http://sites.google.com/site/kanasanjs/jetpack_work_shop"&gt;Kanasan.JS Jetpack ワークショップ&lt;/a&gt;に行ってきました。&lt;a href="https://jetpack.mozillalabs.com/" hreflang="en"&gt;Jetpack&lt;/a&gt; は Firefox 用の簡易拡張プラットフォーム。私としては通常の拡張機能のほうが高い自由度を持てて好きなのですが、Firefox を広く一般に使ってもらうには、簡単なものを簡単に作れるようにするという点が重要なのでしょう。&lt;/p&gt;&#13;
&lt;p&gt;最初に &lt;a href="http://d.hatena.ne.jp/mollifier/20091201/p1"&gt;mollifier さんによる Jetpack 入門&lt;/a&gt;があった後、二人組になり各グループで Jetpack フィーチャーを作っていくという流れ。私は &lt;a href="http://d.hatena.ne.jp/murky-satyr/"&gt;satyr さん&lt;/a&gt;とペアになったのですが、さすが satyr さん、&lt;a href="http://d.hatena.ne.jp/keyword/%A5%B3%A1%BC%A5%C9%A5%B4%A5%EB%A5%D5" title="コードゴルフとは - はてなキーワード"&gt;ゴルファー&lt;/a&gt;だけあって見慣れぬ記法を次々と使ってきます。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;var { href } = location;&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;上のコードは分割代入の省略形式で、&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;var { href: href } = location;&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;の略、さらには、&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;var href = location.href;&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;の略なのですが、JavaScript 1.8 以降 (Firefox 3 以降) での機能とあって、私自身も久しく頭から抜けていました。&lt;/p&gt;&#13;
&lt;p&gt;そんなこんなで完成した (といっても実際のコーディングはほとんど satyr さんでしたが) のが、現在閲覧中のページの &lt;a href="http://validator.w3.org/" hreflang="en" lang="en"&gt;W3C Markup Validation Service&lt;/a&gt; での検証結果をステータスバーに表示する Jetpack フィーチャー、&lt;a href="http://gist.github.com/250170" hreflang="en"&gt;HTMLValidator for Jetpack&lt;/a&gt; です。&lt;/p&gt;&#13;
&lt;p&gt;ちなみに開発中に引っかかったのが、特定の名前空間に属する要素の jQuery での扱い。&lt;a href="http://validator.w3.org/check?uri=http%3A%2F%2Fnanto.asablo.jp%2Fblog%2F&amp;amp;output=soap12"&gt;http://validator.w3.org/check?uri=http%3A%2F%2Fnanto.asablo.jp%2Fblog%2F&amp;amp;output=soap12&lt;/a&gt; のように &lt;code&gt;output&lt;/code&gt; パラメータに値 &lt;code&gt;soap12&lt;/code&gt; を指定すると、検証結果が、&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&gt;&#13;
&amp;lt;env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"&gt;&#13;
&amp;lt;env:Body&gt;&#13;
&amp;lt;m:markupvalidationresponse env:encodingStyle="http://www.w3.org/2003/05/soap-encoding" xmlns:m="http://www.w3.org/2005/10/markup-validator"&gt;&#13;
    &amp;lt;m:uri&gt;http://nanto.asablo.jp/blog/&amp;lt;/m:uri&gt;&#13;
    &amp;lt;m:checkedby&gt;http://validator.w3.org/&amp;lt;/m:checkedby&gt;&#13;
    &amp;lt;m:doctype&gt;-//W3C//DTD HTML 4.01 Transitional//EN&amp;lt;/m:doctype&gt;&#13;
    &amp;lt;m:charset&gt;utf-8&amp;lt;/m:charset&gt;&#13;
    &amp;lt;m:validity&gt;true&amp;lt;/m:validity&gt;&#13;
    ...&#13;
&amp;lt;/m:markupvalidationresponse&gt;&#13;
&amp;lt;/env:Body&gt;&#13;
&amp;lt;/env:Envelope&gt;&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;と XML 形式で返ってくるのですが、ここから jQuery で validity 要素を選択するには、&lt;code&gt;res&lt;/code&gt; を返ってきた XML 文書ノードオブジェクトとして、&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;$(res).find("m\\:validity")&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;のように指定する必要があるのでした。&lt;/p&gt;&#13;
&lt;p&gt;そもそも DOM の &lt;code&gt;getElementsByTagName&lt;/code&gt; メソッドからして、引数に指定できるのは要素名 (非修飾名) のみと勘違いしていたのですが、実際は、名前空間に属する要素を選択するためには接頭辞も含めた修飾名を指定する必要があるとのこと。名前空間の指定に、語彙に対して常に一意な名前空間 URI ではなく、文書片ごとに変わる可能性のある名前空間接頭辞を用いるのは、大変気持ち悪いです。&lt;/p&gt;
</description>
      <dc:subject>Mozilla Firefox</dc:subject>
      <dc:subject>JavaScript</dc:subject>
    </item>
  </channel>
</rss>
