<?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>Sat, 06 Feb 2010 07:53:35 +0900</pubDate>
<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>
<item>
<title>初めての JavaScript 第 2 版</title>
<link>http://nanto.asablo.jp/blog/2009/12/30/4784398</link>
<guid>http://nanto.asablo.jp/blog/2009/12/30/4784398</guid>
<pubDate>Wed, 30 Dec 2009 17:07:24 +0900</pubDate>
<dcterms:modified>2009-12-31T00:26:19+09:00</dcterms:modified>
<dcterms:created>2009-12-30T17:09:18+09:00</dcterms:created>
<description>&lt;p&gt;O'Reilly Japan から書籍『&lt;a href="http://www.oreilly.co.jp/books/9784873114255/"&gt;初めての JavaScript 第 2 版&lt;/a&gt;』(&lt;span lang="en"&gt;Shelley Powers&lt;/span&gt; 著、武舎広幸・武舎るみ訳) (&lt;a href="http://www.amazon.co.jp/dp/487311425X" title="Amazon.co.jp： 初めてのJavaScript 第2版: Shelley Powers, 武舎 広幸, 武舎 るみ: 本"&gt;Amazon&lt;/a&gt;) が出版されています。出版にあたって、私が技術レビューを務めさせていただきました。販促効果があるのかわかりませんが、帯に推薦文も寄せています。&lt;/p&gt;&#13;
&lt;p&gt;単なる JavaScript の書き方にとどまらず、デバッガの使い方など基礎になる事柄を幅広く取り扱っていますので、JavaScript を始めたいという方は一度手にとってみることをお勧めします。また、周囲にそのような方がいる場合もぜひ勧めてあげてください。&lt;/p&gt;&#13;
&lt;p&gt;読み終えた方は、『&lt;a href="http://www.oreilly.co.jp/books/9784873113296/"&gt;JavaScript 第 5 版&lt;/a&gt;』(&lt;a href="http://www.amazon.co.jp/dp/4873113296" title="Amazon.co.jp： JavaScript 第5版: David Flanagan, 村上 列: 本"&gt;Amazon&lt;/a&gt;) や『&lt;a href="http://www.oreilly.co.jp/books/9784873113913/"&gt;JavaScript: The Good Parts&lt;/a&gt;』(&lt;a href="http://www.amazon.co.jp/dp/4873113911" title="Amazon.co.jp： JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス: Douglas Crockford, 水野 貴明: 本"&gt;Amazon&lt;/a&gt;) に進むのもいいですし、&lt;a href="http://www.prototypejs.org/" hreflang="en"&gt;Prototype.js&lt;/a&gt; などのコードリーディングをしてみるのもいいと思います。なお、ここで Prototype.js の名前を挙げたのは、次の二つの理由によります。&lt;/p&gt;&#13;
&lt;ol&gt;&#13;
&lt;li&gt;ソースコードが比較的読みやすい。&lt;/li&gt;&#13;
&lt;li&gt;既にコードリーディングを行った人が大勢いて、Web 上に多数のコード解説がある。&lt;/li&gt;&#13;
&lt;/ol&gt;
</description>
<dc:subject>書籍・雑誌</dc:subject>
<dc:subject>JavaScript</dc:subject>
</item>
<item>
<title>第 2 回 WCAG 勉強会 @ 関西</title>
<link>http://nanto.asablo.jp/blog/2009/12/30/4784351</link>
<guid>http://nanto.asablo.jp/blog/2009/12/30/4784351</guid>
<pubDate>Wed, 30 Dec 2009 16:23:36 +0900</pubDate>
<dcterms:modified>2009-12-30T16:25:54+09:00</dcterms:modified>
<dcterms:created>2009-12-30T16:25:54+09:00</dcterms:created>
<description>&lt;p&gt;先日開かれた &lt;a href="http://sites.google.com/site/wcagstudying/"&gt;WCAG 勉強会 @ 関西&lt;/a&gt; (&lt;a href="http://twitter.com/wcagstudying" title="WCAG勉強会@関西 (wcagstudying) on Twitter"&gt;Twitter&lt;/a&gt;) の第 2 回勉強会に参加しました。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;WCAG 2.0 とは&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;Web アクセシビリティに関する指針です。W3C が発効しており、本文といくつかの関連文書からなります。これを基に JIS X 8341-3 (Web コンテンツ JIS) が改定される予定です。&lt;/p&gt;&#13;
&lt;dl&gt;&#13;
&lt;dt&gt;&lt;a href="http://www.w3.org/TR/2008/REC-WCAG20-20081211/" hreflang="en" lang="en"&gt;Web Content Accessibility Guidelines (WCAG) 2.0&lt;/a&gt; (&lt;a href="http://www.jsa.or.jp/stdz/instac/commitee-acc/W3C-WCAG/WCAG20/index.html" title="WCAG 2.0 日本語訳"&gt;日本語訳&lt;/a&gt;)&lt;/dt&gt;&#13;
  &lt;dd&gt;ここでは「本文」と呼びます。4 つの原則と 12 の指針からなりますが、要点だけ書かれているのでやや読みづらいです。&lt;/dd&gt;&#13;
&lt;dt&gt;&lt;a href="http://www.w3.org/TR/2008/NOTE-UNDERSTANDING-WCAG20-20081211/" hreflang="en" lang="en"&gt;Understanding WCAG 2.0&lt;/a&gt; (&lt;a href="http://www.comm.twcu.ac.jp/~nabe/JISX8341-3/WCAG20/UNDERSTANDING-WCAG20/" title="WCAG 2.0 解説書"&gt;日本語訳&lt;/a&gt;)&lt;/dt&gt;&#13;
  &lt;dd&gt;本文の各指針に対して、そのような指針を設けた意図や、補足の説明、個々の事例などが書かれています。「解説書」と呼ばれますが、こっちこそ本文という感じです。&lt;/dd&gt;&#13;
&lt;dt&gt;&lt;a href="http://www.w3.org/TR/2008/NOTE-WCAG20-TECHS-20081211/" hreflang="en" lang="en"&gt;Techniques for WCAG 2.0&lt;/a&gt;&lt;/dt&gt;&#13;
  &lt;dd&gt;HTML や JavaScript といった既存の技術を、どう使えば各指針に対応できるのか、また逆にどう使うと指針に対応していないとみなされてしまうのか、が記述されています。「技術書」と呼ばれます。&lt;/dd&gt;&#13;
&lt;dt&gt;&lt;a href="http://www.w3.org/WAI/WCAG20/quickref/" hreflang="en" lang="en"&gt;How to Meet WCAG 2.0&lt;/a&gt;&lt;/dt&gt;&#13;
  &lt;dd&gt;「クイックリファレンス」とも呼ばれます。使用する技術や達成水準を指定することで、各指針に対応する本文、解説書、技術書の項目を探し出せます。&lt;/dd&gt;&#13;
&lt;/dl&gt;&#13;
&lt;p&gt;本文は時代の変化にも対応できるように書かれていますが、解説書や技術書は一般的な環境の移り変わりにつれて随時更新されるかもしれないそうです。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;勉強会の流れ&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;今回の範囲は「&lt;a href="http://www.jsa.or.jp/stdz/instac/commitee-acc/W3C-WCAG/WCAG20/index.html#perceivable"&gt;原則 1: 知覚可能&lt;/a&gt;」の「&lt;a href="http://www.jsa.or.jp/stdz/instac/commitee-acc/W3C-WCAG/WCAG20/index.html#text-equiv"&gt;ガイドライン 1.1: 代替テキスト&lt;/a&gt;」までで、事前に本文と解説書の該当箇所を読んでおくこととなっていました。当日は、各自が範囲内の事項に関する疑問点を、付箋紙に書き出してホワイトボードに貼り付け、それらをひとつずつ、あるいはいくつかまとめて全員で議論するという形でした。&lt;/p&gt;&#13;
&lt;p&gt;&lt;a href="http://sites.google.com/site/kanasanjs/"&gt;Kanasan.JS&lt;/a&gt; でもそうですが、全員でひとつのことについて議論するというのは、一度にさまざまな視点が得られて面白いです。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;メディアと代替テキスト&lt;/h3&gt;&#13;
&#13;
&lt;blockquote cite="http://www.jsa.or.jp/stdz/instac/commitee-acc/W3C-WCAG/WCAG20/index.html#text-equiv"&gt;&#13;
&lt;p&gt;ガイドライン 1.1 代替テキスト：すべての非テキストコンテンツには代替テキストを提供して、拡大印刷、点字、音声、シンボル、平易な言葉などのような、ユーザが必要とする形式に変換できるようにする。&lt;/p&gt;&#13;
&lt;/blockquote&gt;&#13;
&lt;p&gt;ここでいう「代替テキスト」とは、あるメディア (媒体) から別のメディアに変換するための、中間メディアのことです。画像から点字へ、音声から字幕へ、直に変換できれば苦労はないのですが、現状ではそれが困難なため、テキストというメディアを用意することで変換にかかる負担を軽減しようというのです。&lt;/p&gt;&#13;
&lt;p&gt;この変換は、必ずしも自動で行われるわけではありません。一定の精度を確保するためには人力での変換が必要、ということもまだまだ多いようです。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;シンボルメディア&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;メディアの例として「シンボル」とありますが、これはアイコンやピクトグラムの組み合わせなどで文意を表すことを指すようです。実際に&lt;a href="http://www.news-2-you.com/index.aspx" title="news-2-you" hreflang="en"&gt;アイコンを並べてニュースを伝えるニュースサイト&lt;/a&gt; (&lt;a href="http://www.news-2-you.com/sample/nPsRegular.pdf" hreflang="en"&gt;サンプルページ、PDF&lt;/a&gt;) もあるほか、&lt;a href="http://newsmanga.com/"&gt;漫画の新聞&lt;/a&gt;も一種のシンボル化ではないかと思います。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;感覚的なコンテンツ&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;WCAG 2.0 では、特定の場合には中間メディアたる代替テキストを提供しなくてもいいとされています。そのひとつが感覚的なコンテンツで、たとえばコンサートの動画があったとき、最低限「そこに動画がある」「それはコンサートの動画である」といったことが識別できる代替テキストがあればよく、「そのコンサートを聞いてどう感じたか」などの主観的な情報は必ずしも含む必要はありません。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;類似文字の使用に関する注意&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;技術書で失敗例として挙げられているのが、&lt;a href="http://www.w3.org/TR/2008/NOTE-WCAG20-TECHS-20081211/F71" title="F71: Failure of Success Criterion 1.1.1 due to using text look-alikes to represent text without providing a text alternative | Techniques for WCAG 2.0" hreflang="en"&gt;代替テキスト無しでの類似文字の使用&lt;/a&gt;です。これは、ある文字の代わりに見た目のよく似た文字を使うことで、ひらがなの「し」の代わりにギリシャ文字の小文字イオタ (ι) を使う、漢字「神」の代わりにカタカナと漢字を並べて「ネ申」と書く、といった例があります。このことは、文字を直接ソーステキストに埋め込んだ場合だけでなく、HTML の文字参照や JavaScript のエスケープシーケンスなどで間接的に埋め込んだ場合にも当てはまります。&lt;/p&gt;&#13;
&lt;p&gt;ただし、何が何でもダメというわけではなく、適切な代替テキストが指定されていればいいようです。技術書には、&lt;a href="http://www.w3.org/TR/2008/NOTE-WCAG20-TECHS-20081211/H86" title="H86: Providing text alternatives for ASCII art, emoticons, and leetspeak | Techniques for WCAG 2.0" hreflang="en"&gt;代替テキストの指定方法として、abbr 要素とその title 属性を使った例&lt;/a&gt;が載っています。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;&amp;lt;abbr title="化物語"&gt;イヒ牛勿言吾&amp;lt;/abbr&gt;&lt;/code&gt;&lt;/pre&gt;&#13;
&#13;
&lt;h3&gt;アクセシビリティ・サポーテッド&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;WCAG 2.0 での重要な概念が「アクセシビリティ・サポーテッド」(&lt;a href="http://www.jsa.or.jp/stdz/instac/commitee-acc/W3C-WCAG/WCAG20/index.html#accessibility-supporteddef" title="アクセシビリティ・サポーテッド - WCAG 2.0"&gt;本文&lt;/a&gt;、&lt;a href="http://www.comm.twcu.ac.jp/~nabe/JISX8341-3/WCAG20/UNDERSTANDING-WCAG20/#uc-accessibility-support-head" title="「アクセシビリティ・サポート」を理解する - WCAG 2.0 解説書"&gt;解説書&lt;/a&gt;) です。これは、コンテンツが&lt;em&gt;実在の&lt;/em&gt;支援技術 (拡大鏡、スクリーンリーダ、代替ポインティングデバイスなど) で利用可能でなければいけないということで、技術書の中にも特定のブラウザや支援技術に関する注意書きが見られます。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;点字ディスプレイ&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;持ち運びできる&lt;a href="http://www.askktenten.jp/" title="ASKKてんてんホームページ"&gt;円盤式点字ディスプレイ&lt;/a&gt;がヒットしているそうです。あらかじめテキストを記憶しておいて電車の中で読むといったことが可能で、音声よりも速く読めるとか。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;音訳マニュアル&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;代替テキストを点字や音声に変換する際の指針として、&lt;a href="http://www.daikatsuji.co.jp/books/braille.html"&gt;音訳マニュアル&lt;/a&gt;が役に立つそうです。点字では、単に読みをそのまま抜き出せばいいというわけではなく、「橋」「箸」「端」はそれぞれ区別がつくよう説明を加えるなど、さまざまなノウハウが必要とされるようでした。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;ナビゲーションスキップ&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;サイトのヘッダやサイト全体にまたがるナビゲーションなど、ページの本文とは関係ない部分を読み飛ばせるような仕組みをブロックスキップといいます。ブロックスキップの実現手法の一つとして、ページの先頭に本文へのリンク (視覚メディアではしばしば非表示にされる) を付けるナビゲーションスキップ (スキップリンク) があります。&lt;/p&gt;&#13;
&lt;p&gt;しかし、少なくとも勉強会参加者の周辺では、ナビゲーションスキップを使っている人はいないようでした。ナビゲーションスキップはサイトごとに異なるので使いづらい、Yahoo! や Google などよく見るページでは本文より前のリンクを飛ばす操作に慣れている、適切な見出しと支援技術の見出しジャンプ機構があれば十分、といった背景があるそうです。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;雑感&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;実際に業務として Web アクセシビリティに携わっている方々の話を聞け、大変参考になりました。知らないこと、わかっていなかったことがほとんどで、まさしく聞くと見るとは大違いです。Web 製作に関わる方々はこの勉強会に参加して損はないと思います。&lt;/p&gt;&#13;
&lt;p&gt;Web アクセシビリティと聞くと、ぽっと出の新しくてよくわからないものと思う方もいるかもしれませんが、障害者が情報に触れる手段に関しては古くからさまざまな試みがなされてきたこと、そしてそれらの積み重ねが Web にも応用できるという点は非常に重要なことだと思います。アクセシビリティを何か特別なものとみなすのではなく、ノウハウの蓄積された、すぐそこにある日常として受け入れることが大切です。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;関連リンク&lt;/h3&gt;&#13;
&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://blog.e-riverstyle.com/2009/11/web-17.html"&gt;Webアクセシビリティに関して思うことをぐだぐだと書いてみる。 - E-riverstyle Vanguard&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://blog.e-riverstyle.com/2009/12/wcag.html"&gt;WCAG 勉強会@関西で話題になった書籍「音訳マニュアル」 - E-riverstyle Vanguard&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;
</description>
<dc:subject>Web 関連技術</dc:subject>
</item>
<item>
<title>Firefox Developers Conference 2009</title>
<link>http://nanto.asablo.jp/blog/2009/11/12/4688127</link>
<guid>http://nanto.asablo.jp/blog/2009/11/12/4688127</guid>
<pubDate>Thu, 12 Nov 2009 02:26:55 +0900</pubDate>
<dcterms:modified>2009-11-13T00:51:08+09:00</dcterms:modified>
<dcterms:created>2009-11-12T02:28:15+09:00</dcterms:created>
<description>&lt;p&gt;11 月 8 日に行われた &lt;a href="http://mozilla.jp/events/2009/fxdevcon/"&gt;Firefox Developers Conference 2009&lt;/a&gt; にて、&lt;a href="http://d.hatena.ne.jp/secondlife/"&gt;secondlife さん&lt;/a&gt;とともに&lt;a href="http://b.hatena.ne.jp/guide/firefox_addon"&gt;はてなブックマーク Firefox 拡張&lt;/a&gt;に関する発表を行いました。発表資料は次の通りです。&lt;/p&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://d.hatena.ne.jp/secondlife/20091109/1257741302"&gt;Firefox Developers Conference 2009 発表資料 - 川o・-・）＜2nd life&lt;/a&gt; (secondlife さん発表分)&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://www.ne.jp/asahi/nanto/moon/2009/11/12/hatebu-ext-impl.html"&gt;はてなブックマーク Firefox 拡張 実装の舞台裏&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;p&gt;資料中に約 3500 行の XML とありますが、この中には &lt;a href="https://developer.mozilla.org/ja/XBL"&gt;&lt;abbr title="XML Binding Language" lang="en"&gt;XBL&lt;/abbr&gt;&lt;/a&gt; 内に直接書かれた JavaScript コードの行数も含まれていると思います。XBL は、特定の機能を持つ要素が複数存在する場合に威力を発揮します。&lt;a href="http://mxr.mozilla.org/mozilla-central/source/toolkit/content/widgets/" hreflang="en"&gt;Mozilla のウィジェット (ボタンやメニューなど) のソース&lt;/a&gt;を読むためには XBL のあらましを知っておく必要があると思うのですが、意外と認知度は低いようでした。&lt;/p&gt;&#13;
&lt;p&gt;他の発表では、「ビッツにおける拡張機能開発」のユーザーの反応やサポートに関する話題が興味深かったです。ソフトウェアを広く使ってもらうには、ユーザーの反応に対し、肯定的であれ否定的であれ、すばやく対応することが重要なんだと実感しました。(たとえば &lt;a href="http://piro.sakura.ne.jp/"&gt;Piro さん&lt;/a&gt;は、&lt;a href="http://piro.sakura.ne.jp/latest/blosxom/mozilla/extension/treestyletab/2009-07-22_focus.htm"&gt;ユーザーの要望に従わないことを、理由を挙げて丁寧に説明&lt;/a&gt;しています。)&lt;/p&gt;&#13;
&lt;p&gt;また、Aza さん、&lt;a href="http://d.hatena.ne.jp/amachang/"&gt;amachang さん&lt;/a&gt;、Piro さんによるトークセッションでは、「グローバルにするためにはローカライズしなければならない」という Aza さんの言葉が心に残りました。以前、&lt;a href="http://developer.cybozu.co.jp/kazuho/"&gt;奥 (kazuho) さん&lt;/a&gt;からも同じ言葉を聞いたことがあり、世界に通用するソフトウェアを作る人間の意識を垣間見た気がします。&lt;/p&gt;&#13;
&lt;p&gt;懇親会で Aza さんに、Jetpack の HTML を使った UI が、外観やアクセシビリティ API を通したアクセスの点で、OSネイティブのウィジェットや XUL を使った UI と異なってくることについてお聞きしたかったのですが、私自身質問の要旨をまとめきれず、ちぐはぐな応答になってしまいました。ただ、WAI-ARIA の話を出されていたので、そうした仕組みを通じて (あるいはそれを背後で行ってくれるライブラリを使って) OS からのアクセスも確保していこうということだと思います。&lt;/p&gt;&#13;
&lt;p&gt;懇親会は料理のほうも素晴しく、私はもっぱらアボカドとえびのサラダと、Firefox 5 周年ケーキの切れ端をぱくついていました。&lt;a href="http://d.hatena.ne.jp/hatenapr/20091106/1257479598"&gt;はてなステッカー&lt;/a&gt; (前日人に尋ねられるまで配布されることを知らなかったのですが) が予想外の人気で、私もじゃんけん大会に参加したものの、あえなく 1 回戦敗退です。&lt;/p&gt;&#13;
&lt;p&gt;普段 Web 上でお世話になっている方々や、Mozilla を陰日向から支えてきた方々と直接お会いすることができ、非常に楽しくまた有意義なイベントでした。拡張開発の機会を与えてくださったはてなの皆さん、発表の場を用意してくださった Mozilla Japan の皆さん、発表にお越しいただいた皆さん、そして Mozilla と Firefox に対して多大な貢献をされてきた皆さんに深く感謝します。&lt;/p&gt;
</description>
<dc:subject>Mozilla Firefox</dc:subject>
</item>
<item>
<title>HTMLDocument の動的な作成</title>
<link>http://nanto.asablo.jp/blog/2009/10/29/4660197</link>
<guid>http://nanto.asablo.jp/blog/2009/10/29/4660197</guid>
<pubDate>Thu, 29 Oct 2009 06:11:27 +0900</pubDate>
<dcterms:modified>2009-10-29T17:09:35+09:00</dcterms:modified>
<dcterms:created>2009-10-29T06:16:42+09:00</dcterms:created>
<description>&lt;p&gt;ブラウザ上で、JavaScript を使って HTML のソースから HTML 文書を生成するのに、どんな方法があるのか調べました。なお、以下のスクリプトは HTML 文書上で実行することが前提です。&lt;/p&gt;&#13;
&lt;ol&gt;&#13;
&lt;li&gt;&lt;a href="#htmldoc-about-table"&gt;表の見方&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="#htmldoc-xslt"&gt;XSLT の HTML 出力&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="#htmldoc-createhtmldoc"&gt;&lt;code&gt;createHTMLDocument&lt;/code&gt; メソッド&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="#htmldoc-createdoc"&gt;&lt;code&gt;createDocument&lt;/code&gt; メソッド&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="#htmldoc-createdoc-ns"&gt;&lt;code&gt;createDocument&lt;/code&gt; メソッドと名前空間の指定&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="#htmldoc-createdoc-doctype"&gt;&lt;code&gt;createDocument&lt;/code&gt; メソッドと文書型宣言の指定&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="#htmldoc-createdoc-doctype-ns"&gt;&lt;code&gt;createDocument&lt;/code&gt; メソッドと文書型宣言及び名前空間の指定&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="#htmldoc-clonenode"&gt;&lt;code&gt;cloneNode&lt;/code&gt; メソッド&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="#htmldoc-iframe"&gt;iframe 要素&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="#htmldoc-activex"&gt;&lt;code&gt;ActiveXObject&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="#htmldoc-moz-cid"&gt;CID からの作成&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="#htmldoc-conclusion"&gt;まとめ&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ol&gt;&#13;
&#13;
&lt;h3 id="htmldoc-about-table"&gt;表の見方&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;以下の表において、各項目の意味は次の通りです。&lt;/p&gt;&#13;
&lt;dl&gt;&#13;
&lt;dt&gt;&lt;code&gt;doc&lt;/code&gt;&lt;/dt&gt;&#13;
  &lt;dd&gt;HTML 文書を作成できれば○、XML 文書を作成できれば△、それ以外なら×です。HTML 文書かどうかは、&lt;code&gt;createElement&lt;/code&gt; メソッドが HTML 要素を作成するかどうかで判断しています。&lt;/dd&gt;&#13;
&lt;dt&gt;&lt;code&gt;doc.title&lt;/code&gt;&lt;/dt&gt;&#13;
  &lt;dd&gt;文書ノードの &lt;code&gt;title&lt;/code&gt; プロパティから title 要素の内容を取得できれば○、できなければ×です。&lt;/dd&gt;&#13;
&lt;dt&gt;&lt;code&gt;doc.body&lt;/code&gt;&lt;/dt&gt;&#13;
  &lt;dd&gt;文書ノードの &lt;code&gt;body&lt;/code&gt; プロパティから body 要素を取得できれば○、できなければ×です。&lt;/dd&gt;&#13;
&lt;dt&gt;名前空間なし XPath&lt;/dt&gt;&#13;
  &lt;dd&gt;&lt;code&gt;//p&lt;/code&gt; のような名前空間接頭辞の付かない XPath 式で HTML 要素を取得できれば○、できなければ×です。&lt;/dd&gt;&#13;
&lt;dt&gt;名前空間付き XPath&lt;/dt&gt;&#13;
  &lt;dd&gt;&lt;code&gt;//h:p&lt;/code&gt; のような名前空間接頭辞の付いた XPath 式で HTML 要素を取得できれば○、できなければ×です。ここで、接頭辞 &lt;code&gt;h&lt;/code&gt; は名前空間 URI &lt;code&gt;http://www.w3.org/1999/xhtml&lt;/code&gt; に関連付けられているものとします。&lt;/dd&gt;&#13;
&lt;dt&gt;&lt;code&gt;innerHTML&lt;/code&gt;&lt;/dt&gt;&#13;
  &lt;dd&gt;&lt;code&gt;innerHTML&lt;/code&gt; プロパティに &lt;code&gt;&amp;lt;p&gt;hello&amp;amp;nbsp;world&lt;/code&gt; のような、整形式 XML ではなく、かつ HTML の実体参照を含んだ文字列を設定して、エラーが出なければ○、エラーになれば×です。&lt;/dd&gt;&#13;
&lt;dt&gt;スクリプト&lt;/dt&gt;&#13;
  &lt;dd&gt;script 要素で指定されたスクリプトが実行されれば○、されなければ×です。&lt;/dd&gt;&#13;
&lt;/dl&gt;&#13;
&lt;p&gt;また、使用したブラウザは次の通りです。いずれも Windows 版です。&lt;/p&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;Firefox 3.0.11&lt;/li&gt;&#13;
&lt;li&gt;Firefox 3.5.3&lt;/li&gt;&#13;
&lt;li&gt;Minefield (Firefox の開発版) 3.7a1pre、&lt;a href="http://taken.s101.xrea.com/blog/article.php?id=844" title="Taken SPC : HTML 5 Parser"&gt;HTML5 パーサ&lt;/a&gt;無効&lt;/li&gt;&#13;
&lt;li&gt;Minefield 3.7a1pre、HTML5 パーサ有効 (&lt;code&gt;html5.enable&lt;/code&gt; を &lt;code&gt;true&lt;/code&gt; に設定)&lt;/li&gt;&#13;
&lt;li&gt;Opera 9.64&lt;/li&gt;&#13;
&lt;li&gt;Opera 10.00&lt;/li&gt;&#13;
&lt;li&gt;Safari 3.2.3&lt;/li&gt;&#13;
&lt;li&gt;Safari 4.0.3&lt;/li&gt;&#13;
&lt;li&gt;Internet Explorer 6 SP3&lt;/li&gt;&#13;
&lt;li&gt;Internet Explorer 7&lt;/li&gt;&#13;
&lt;li&gt;Internet Explorer 8&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;p&gt;調査には次のファイルを使いました。&lt;/p&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://www.ne.jp/asahi/nanto/moon/2009/10/29/create-html-doc.html"&gt;&lt;code&gt;HTMLDocument&lt;/code&gt; の作成 (Firefox、Safari、Opera 用)&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;ins datetime="2009-10-29T17:10:00+09:00"&gt;&lt;a href="http://www.ne.jp/asahi/nanto/moon/2009/10/29/create-html-doc-chrome.html"&gt;&lt;code&gt;HTMLDocument&lt;/code&gt; の作成 (Firefox、Safari、Opera、Chrome 用)&lt;/a&gt;&lt;/ins&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://www.ne.jp/asahi/nanto/moon/2009/10/29/create-html-doc-ie.html"&gt;&lt;code&gt;HTMLDocument&lt;/code&gt; の作成 (IE 用)&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&#13;
&lt;h3 id="htmldoc-xslt"&gt;XSLT の HTML 出力&lt;/h3&gt;&#13;
&#13;
&lt;pre&gt;&lt;code&gt;function createHTMLDocument_XSLT(source) {&#13;
  var processor = new XSLTProcessor();&#13;
  var sheet = new DOMParser().parseFromString(&#13;
    '&amp;lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&gt;' +&#13;
      '&amp;lt;xsl:output method="html"/&gt;' +&#13;
      '&amp;lt;xsl:template match="/"&gt;' +&#13;
        '&amp;lt;html&gt;&amp;lt;head&gt;&amp;lt;title&gt;&amp;lt;/title&gt;&amp;lt;/head&gt;&amp;lt;body&gt;&amp;lt;/body&gt;&amp;lt;/html&gt;' +&#13;
      '&amp;lt;/xsl:template&gt;' +&#13;
    '&amp;lt;/xsl:stylesheet&gt;',&#13;
    'application/xml'&#13;
  );&#13;
  processor.importStylesheet(sheet);&#13;
  var doc = processor.transformToDocument(sheet);&#13;
  var range = doc.createRange();&#13;
  range.selectNodeContents(doc.documentElement);&#13;
  range.deleteContents();&#13;
  doc.documentElement.appendChild(range.createContextualFragment(source));&#13;
  return doc;&#13;
}&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;table&gt;&#13;
&lt;colgroup span="1"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="4"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="2"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="2"&gt;&lt;/colgroup&gt;&#13;
&lt;thead&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;td rowspan="2"&gt;&lt;/td&gt;&#13;
    &lt;th colspan="4" scope="colgroup"&gt;Firefox&lt;/th&gt;&#13;
    &lt;th colspan="2" scope="colgroup"&gt;Safari&lt;/th&gt;&#13;
    &lt;th colspan="2" scope="colgroup"&gt;Opera&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="col"&gt;3&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.5&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.7a&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.7a HTML5&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.2&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;4&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;9.6&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;10&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/thead&gt;&#13;
&lt;tbody&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc.title&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc.body&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;名前空間なし XPath&lt;/th&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;名前空間付き XPath&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;innerHTML&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;スクリプト&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/tbody&gt;&#13;
&lt;/table&gt;&#13;
&lt;p&gt;比較的以前から使われている方法です。XSLT を使ってある文書を HTML 文書に変換し、後は &lt;code&gt;innerHTML&lt;/code&gt; なり &lt;a href="https://developer.mozilla.org/en/DOM/range.createContextualFragment" hreflang="en"&gt;&lt;code&gt;Range#createContextualFragment&lt;/code&gt;&lt;/a&gt; なりでソースを流し込みます。Firefox 2 (Gecko 1.8.1) 以前では、&lt;a href="http://subtech.g.hatena.ne.jp/cho45/20071124/1195915920" title="XSLTProcessor - 冬通りに消え行く制服ガールは、夢物語にリアルを求めない。 - subtech"&gt;フラグメント識別子付きの URL 上でエラーが出る&lt;/a&gt;そうです。&lt;/p&gt;&#13;
&lt;p&gt;&lt;a href="https://developer.mozilla.org/en/Using_the_Mozilla_JavaScript_interface_to_XSL_Transformations" hreflang="en"&gt;&lt;code&gt;XSLTProcessor&lt;/code&gt;&lt;/a&gt;、&lt;a href="https://developer.mozilla.org/ja/DOMParser"&gt;&lt;code&gt;DOMParser&lt;/code&gt;&lt;/a&gt;、&lt;code&gt;Range#createContextualFragment&lt;/code&gt; は Mozilla による独自拡張ですが、Safari (WebKit) と Opera もサポートしています。ブラウザによっては &lt;code&gt;createContextualFragment&lt;/code&gt; を使ったパースで、head 要素や body 要素が消えてしまうことがあります。&lt;/p&gt;&#13;
&#13;
&lt;h3 id="htmldoc-createhtmldoc"&gt;&lt;code&gt;createHTMLDocument&lt;/code&gt; メソッド&lt;/h3&gt;&#13;
&#13;
&lt;pre&gt;&lt;code&gt;function createHTMLDocument_createHTMLDocument(source) {&#13;
  var doc = document.implementation.createHTMLDocument('');&#13;
  var range = doc.createRange();&#13;
  range.selectNodeContents(doc.documentElement);&#13;
  range.deleteContents();&#13;
  doc.documentElement.appendChild(range.createContextualFragment(source));&#13;
  return doc;&#13;
}&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;table&gt;&#13;
&lt;colgroup span="1"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="4"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="2"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="2"&gt;&lt;/colgroup&gt;&#13;
&lt;thead&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;td rowspan="2"&gt;&lt;/td&gt;&#13;
    &lt;th colspan="4" scope="colgroup"&gt;Firefox&lt;/th&gt;&#13;
    &lt;th colspan="2" scope="colgroup"&gt;Safari&lt;/th&gt;&#13;
    &lt;th colspan="2" scope="colgroup"&gt;Opera&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="col"&gt;3&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.5&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.7a&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.7a HTML5&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.2&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;4&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;9.6&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;10&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/thead&gt;&#13;
&lt;tbody&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc.title&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc.body&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;名前空間なし XPath&lt;/th&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;名前空間付き XPath&lt;/th&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;innerHTML&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;スクリプト&lt;/th&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/tbody&gt;&#13;
&lt;/table&gt;&#13;
&lt;p&gt;Safari と Opera は、HTML 文書を直接生成するその名も &lt;code&gt;createHTMLDocument&lt;/code&gt; メソッドを実装しています。このメソッドは、&lt;a href="http://www.w3.org/TR/2002/CR-DOM-Level-2-HTML-20020605/html.html#HTML-DOM-createHTMLDocument" hreflang="en"&gt;DOM 2 HTML 2002 年 6 月 5 日付勧告候補までは存在した&lt;/a&gt;のですが、以降は削除され勧告には含まれていません。しかし、&lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/dom.html#dom-domhtmlimplementation-createhtmldocument" hreflang="en"&gt;HTML5 草案で復活した&lt;/a&gt;ので、将来的には他のブラウザでも実装されるかもしれません。&lt;/p&gt;&#13;
&#13;
&lt;h3 id="htmldoc-createdoc"&gt;&lt;code&gt;createDocument&lt;/code&gt; メソッド&lt;/h3&gt;&#13;
&#13;
&lt;pre&gt;&lt;code&gt;function createHTMLDocument_createDocument(source) {&#13;
  var doc = document.implementation.createDocument(null, 'html', null);&#13;
  var range = document.createRange();&#13;
  range.selectNodeContents(document.documentElement);&#13;
  var content = doc.adoptNode(range.createContextualFragment(source));&#13;
  doc.documentElement.appendChild(content);&#13;
  return doc;&#13;
}&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;table&gt;&#13;
&lt;colgroup span="1"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="4"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="2"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="2"&gt;&lt;/colgroup&gt;&#13;
&lt;thead&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;td rowspan="2"&gt;&lt;/td&gt;&#13;
    &lt;th colspan="4" scope="colgroup"&gt;Firefox&lt;/th&gt;&#13;
    &lt;th colspan="2" scope="colgroup"&gt;Safari&lt;/th&gt;&#13;
    &lt;th colspan="2" scope="colgroup"&gt;Opera&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="col"&gt;3&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.5&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.7a&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.7a HTML5&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.2&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;4&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;9.6&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;10&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/thead&gt;&#13;
&lt;tbody&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;△&lt;/td&gt;&#13;
    &lt;td&gt;△&lt;/td&gt;&#13;
    &lt;td&gt;△&lt;/td&gt;&#13;
    &lt;td&gt;△&lt;/td&gt;&#13;
    &lt;td&gt;△&lt;/td&gt;&#13;
    &lt;td&gt;△&lt;/td&gt;&#13;
    &lt;td&gt;△&lt;/td&gt;&#13;
    &lt;td&gt;△&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc.title&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc.body&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;名前空間なし XPath&lt;/th&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;名前空間付き XPath&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;innerHTML&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;スクリプト&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/tbody&gt;&#13;
&lt;/table&gt;&#13;
&lt;p&gt;XML 文書を生成するための &lt;a href="http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#Level-2-Core-DOM-createDocument" hreflang="en"&gt;&lt;code&gt;createDocument&lt;/code&gt; メソッド&lt;/a&gt;を使います。これにより生成される文書はあくまでも XML 文書なので、HTML ソースのパースには呼び出し元の HTML 文書を使っています。異なる文書で生成されたノードを文書ツリーに追加するため &lt;a href="http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#Document3-adoptNode" hreflang="en"&gt;&lt;code&gt;adoptNode&lt;/code&gt;&lt;/a&gt; を使っていますが、Firefox 2 以下では対応していないので代わりに &lt;a href="http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#Core-Document-importNode" hreflang="en"&gt;&lt;code&gt;importNode&lt;/code&gt;&lt;/a&gt; を使う必要があります。&lt;/p&gt;&#13;
&#13;
&lt;h3 id="htmldoc-createdoc-ns"&gt;&lt;code&gt;createDocument&lt;/code&gt; メソッドと名前空間の指定&lt;/h3&gt;&#13;
&#13;
&lt;pre&gt;&lt;code&gt;function createHTMLDocument_createDocument_NS(source) {&#13;
  var XHTML_NS = 'http://www.w3.org/1999/xhtml';&#13;
  var doc = document.implementation.createDocument(XHTML_NS, 'html', null);&#13;
  var range = document.createRange();&#13;
  range.selectNodeContents(document.documentElement);&#13;
  var content = doc.adoptNode(range.createContextualFragment(source));&#13;
  doc.documentElement.appendChild(content);&#13;
  return doc;&#13;
}&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;table&gt;&#13;
&lt;colgroup span="1"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="4"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="2"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="2"&gt;&lt;/colgroup&gt;&#13;
&lt;thead&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;td rowspan="2"&gt;&lt;/td&gt;&#13;
    &lt;th colspan="4" scope="colgroup"&gt;Firefox&lt;/th&gt;&#13;
    &lt;th colspan="2" scope="colgroup"&gt;Safari&lt;/th&gt;&#13;
    &lt;th colspan="2" scope="colgroup"&gt;Opera&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="col"&gt;3&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.5&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.7a&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.7a HTML5&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.2&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;4&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;9.6&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;10&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/thead&gt;&#13;
&lt;tbody&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;△&lt;/td&gt;&#13;
    &lt;td&gt;△&lt;/td&gt;&#13;
    &lt;td&gt;△&lt;/td&gt;&#13;
    &lt;td&gt;△&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc.title&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc.body&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;名前空間なし XPath&lt;/th&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;名前空間付き XPath&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;innerHTML&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;スクリプト&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/tbody&gt;&#13;
&lt;/table&gt;&#13;
&lt;p&gt;Safari と Opera では、&lt;code&gt;createDocument&lt;/code&gt; で文書要素 (ルート要素) に XHTML の名前空間を指定すると、XHTML 文書が生成されます。このとき、Safari では &lt;code&gt;innerHTML&lt;/code&gt; に整形式 XML の断片しか設定できません。&lt;/p&gt;&#13;
&#13;
&lt;h3 id="htmldoc-createdoc-doctype"&gt;&lt;code&gt;createDocument&lt;/code&gt; メソッドと文書型宣言の指定&lt;/h3&gt;&#13;
&#13;
&lt;pre&gt;&lt;code&gt;function createHTMLDocument_createDocument_DTD(source) {&#13;
  var doctype = document.implementation.createDocumentType('html',&#13;
    '-//W3C//DTD HTML 4.01//EN', 'http://www.w3.org/TR/html4/strict.dtd');&#13;
  var doc = document.implementation.createDocument(null, 'html', doctype);&#13;
  var range = document.createRange();&#13;
  range.selectNodeContents(document.documentElement);&#13;
  var content = doc.adoptNode(range.createContextualFragment(source));&#13;
  doc.documentElement.appendChild(content);&#13;
  return doc;&#13;
}&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;table&gt;&#13;
&lt;colgroup span="1"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="4"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="2"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="2"&gt;&lt;/colgroup&gt;&#13;
&lt;thead&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;td rowspan="2"&gt;&lt;/td&gt;&#13;
    &lt;th colspan="4" scope="colgroup"&gt;Firefox&lt;/th&gt;&#13;
    &lt;th colspan="2" scope="colgroup"&gt;Safari&lt;/th&gt;&#13;
    &lt;th colspan="2" scope="colgroup"&gt;Opera&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="col"&gt;3&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.5&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.7a&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.7a HTML5&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.2&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;4&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;9.6&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;10&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/thead&gt;&#13;
&lt;tbody&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;△&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;△&lt;/td&gt;&#13;
    &lt;td&gt;△&lt;/td&gt;&#13;
    &lt;td&gt;△&lt;/td&gt;&#13;
    &lt;td&gt;△&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc.title&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc.body&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;名前空間なし XPath&lt;/th&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;名前空間付き XPath&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;innerHTML&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;スクリプト&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/tbody&gt;&#13;
&lt;/table&gt;&#13;
&lt;p&gt;DOM 3 Core では、&lt;code&gt;createDocument&lt;/code&gt; で文書型宣言を指定すると、その文書型宣言に見合った文書を作成してもよい (&lt;span lang="en"&gt;may&lt;/span&gt;) ことになっています。Firefox 3.5 (Gecko 1.9.1) 以降ではこれに従って、HTML 4 の文書型宣言に対しては HTML 文書が、XHTML 1.0 の文書型宣言に対しては XHTML 文書が生成されます。&lt;/p&gt;&#13;
&#13;
&lt;h3 id="htmldoc-createdoc-doctype-ns"&gt;&lt;code&gt;createDocument&lt;/code&gt; メソッドと文書型宣言及び名前空間の指定&lt;/h3&gt;&#13;
&#13;
&lt;pre&gt;&lt;code&gt;function createHTMLDocument_createDocument_DTD_NS(source) {&#13;
  var XHTML_NS = 'http://www.w3.org/1999/xhtml';&#13;
  var doctype = document.implementation.createDocumentType('html',&#13;
    '-//W3C//DTD HTML 4.01//EN', 'http://www.w3.org/TR/html4/strict.dtd');&#13;
  var doc = document.implementation.createDocument(XHTML_NS, 'html', doctype);&#13;
  var range = document.createRange();&#13;
  range.selectNodeContents(document.documentElement);&#13;
  var content = doc.adoptNode(range.createContextualFragment(source));&#13;
  doc.documentElement.appendChild(content);&#13;
  return doc;&#13;
}&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;table&gt;&#13;
&lt;colgroup span="1"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="4"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="2"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="2"&gt;&lt;/colgroup&gt;&#13;
&lt;thead&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;td rowspan="2"&gt;&lt;/td&gt;&#13;
    &lt;th colspan="4" scope="colgroup"&gt;Firefox&lt;/th&gt;&#13;
    &lt;th colspan="2" scope="colgroup"&gt;Safari&lt;/th&gt;&#13;
    &lt;th colspan="2" scope="colgroup"&gt;Opera&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="col"&gt;3&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.5&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.7a&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.7a HTML5&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.2&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;4&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;9.6&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;10&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/thead&gt;&#13;
&lt;tbody&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;△&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc.title&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc.body&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;名前空間なし XPath&lt;/th&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;名前空間付き XPath&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;innerHTML&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;スクリプト&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/tbody&gt;&#13;
&lt;/table&gt;&#13;
&lt;p&gt;HTML 4 の文書型宣言と XHTML の名前空間を両方指定した場合です。&lt;/p&gt;&#13;
&#13;
&lt;h3 id="htmldoc-clonenode"&gt;&lt;code&gt;cloneNode&lt;/code&gt; メソッド&lt;/h3&gt;&#13;
&#13;
&lt;pre&gt;&lt;code&gt;function createHTMLDocument_cloneNode(source) {&#13;
  var doc = document.cloneNode(false);&#13;
  doc.appendChild(doc.importNode(document.documentElement, false));&#13;
  var range = document.createRange();&#13;
  range.selectNodeContents(document.documentElement);&#13;
  var content = doc.adoptNode(range.createContextualFragment(source));&#13;
  doc.documentElement.appendChild(content);&#13;
  return doc;&#13;
}&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;table&gt;&#13;
&lt;colgroup span="1"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="4"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="2"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="2"&gt;&lt;/colgroup&gt;&#13;
&lt;thead&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;td rowspan="2"&gt;&lt;/td&gt;&#13;
    &lt;th colspan="4" scope="colgroup"&gt;Firefox&lt;/th&gt;&#13;
    &lt;th colspan="2" scope="colgroup"&gt;Safari&lt;/th&gt;&#13;
    &lt;th colspan="2" scope="colgroup"&gt;Opera&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="col"&gt;3&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.5&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.7a&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.7a HTML5&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.2&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;4&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;9.6&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;10&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/thead&gt;&#13;
&lt;tbody&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc.title&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc.body&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;名前空間なし XPath&lt;/th&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;名前空間付き XPath&lt;/th&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;innerHTML&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;スクリプト&lt;/th&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/tbody&gt;&#13;
&lt;/table&gt;&#13;
&lt;p&gt;DOM 3 Core では、文書ノードに対する &lt;a href="http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-3A0ED0A4" hreflang="en"&gt;&lt;code&gt;cloneNode&lt;/code&gt;&lt;/a&gt; の動作は実装依存となっていますが、Firefox 3.5 以降では文書ノードを複製できます。なお、&lt;code&gt;cloneNode&lt;/code&gt; は例外を投げないことになっていますが、Opera では文書ノードを複製しようとすると例外が発生します。&lt;/p&gt;&#13;
&#13;
&lt;h3 id="htmldoc-iframe"&gt;iframe 要素&lt;/h3&gt;&#13;
&#13;
&lt;pre&gt;&lt;code&gt;function createHTMLDocument_iframe(source) {&#13;
  var iframe = document.createElement('iframe');&#13;
  document.body.appendChild(iframe);&#13;
  var doc = iframe.contentWindow.document;&#13;
  doc.open();&#13;
  doc.write(source);&#13;
  doc.close();&#13;
  document.body.removeChild(iframe);&#13;
  return doc;&#13;
}&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;table&gt;&#13;
&lt;colgroup span="1"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="3"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="4"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="2"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="2"&gt;&lt;/colgroup&gt;&#13;
&lt;thead&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;td rowspan="2"&gt;&lt;/td&gt;&#13;
    &lt;th colspan="3" scope="colgroup"&gt;Internet Explorer&lt;/th&gt;&#13;
    &lt;th colspan="4" scope="colgroup"&gt;Firefox&lt;/th&gt;&#13;
    &lt;th colspan="2" scope="colgroup"&gt;Safari&lt;/th&gt;&#13;
    &lt;th colspan="2" scope="colgroup"&gt;Opera&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="col"&gt;6&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;7&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;8&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.5&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.7a&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.7a HTML5&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;3.2&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;4&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;9.6&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;10&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/thead&gt;&#13;
&lt;tbody&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc.title&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc.body&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;名前空間なし XPath&lt;/th&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;名前空間付き XPath&lt;/th&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;×&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;innerHTML&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;スクリプト&lt;/th&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;△&lt;/td&gt;&#13;
    &lt;td&gt;―&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/tbody&gt;&#13;
&lt;/table&gt;&#13;
&lt;p&gt;iframe 要素を使って HTML 文書を生成します。IE でも動きます。iframe 要素を文書ツリーに追加しないと、&lt;code&gt;doc&lt;/code&gt; が &lt;code&gt;null&lt;/code&gt; になってしまうことがあります。Opera 9.6 では、スクリプトは実行されるものの、特定の操作 (&lt;code&gt;document.write&lt;/code&gt; など) を行うと HTML 文書をうまく取得できなくなってしまうようです。また、Opera 10 では、iframe 要素の &lt;code&gt;load&lt;/code&gt; イベントなどを見て非同期にアクセスしないと、うまく HTML 文書が取れないようです。&lt;/p&gt;&#13;
&#13;
&lt;h3 id="htmldoc-activex"&gt;&lt;code&gt;ActiveXObject&lt;/code&gt;&lt;/h3&gt;&#13;
&#13;
&lt;pre&gt;&lt;code&gt;function createHTMLDocument_ActiveXObject(source) {&#13;
  var doc = new ActiveXObject('htmlfile');&#13;
  doc.open();&#13;
  doc.write(source);&#13;
  doc.close();&#13;
  return doc;&#13;
}&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;table&gt;&#13;
&lt;colgroup span="1"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="3"&gt;&lt;/colgroup&gt;&#13;
&lt;thead&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;td rowspan="2"&gt;&lt;/td&gt;&#13;
    &lt;th colspan="3" scope="colgroup"&gt;Internet Explorer&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="col"&gt;6&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;7&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;8&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/thead&gt;&#13;
&lt;tbody&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc.title&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;doc.body&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;innerHTML&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;スクリプト&lt;/th&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
    &lt;td&gt;○&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/tbody&gt;&#13;
&lt;/table&gt;&#13;
&lt;p&gt;IE でのみ使用可能です。&lt;a href="http://furyu.tea-nifty.com/annex/2008/04/jscriptactivexo_874a.html" title="風柳亭: 【JScript】ActiveXObject('htmlfile')で発生する不具合"&gt;フラグメント識別子付きの URL を参照する iframe 要素を含むソースを指定すると、挙動がおかしくなる&lt;/a&gt;そうです。&lt;/p&gt;&#13;
&#13;
&lt;h3 id="htmldoc-moz-cid"&gt;CID からの作成&lt;/h3&gt;&#13;
&#13;
&lt;pre&gt;&lt;code&gt;const NS_HTMLDOCUMENT_CID = '{5d0fcdd0-4daa-11d2-b328-00805f8a3859}';&#13;
var doc = Components.classesByID[NS_HTMLDOCUMENT_CID].createInstance();&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;Firefox で、さらには拡張機能や userChrome.js スクリプトといった chrome 権限を持ったスクリプトでのみ可能な方法です。&lt;a href="https://developer.mozilla.org/ja/xpcshell"&gt;xpcshell&lt;/a&gt; のような &lt;code&gt;document&lt;/code&gt; オブジェクトが存在しない環境でも HTML 文書を作成できます。この CID は、少なくとも Firefox 1.0 から 3.7a1pre まで変更されていません。これにより作られた文書は空なので、自分で要素を作って挿入する必要があります。&lt;/p&gt;&#13;
&lt;ins datetime="2009-10-29T12:00:00+09:00"&gt;&#13;
&lt;p&gt;ちなみに、この方法を知ったのは、&lt;a href="http://d.hatena.ne.jp/nori090/20090814/1250207067"&gt;xpcshellでHTMLDocumentって無理なのかなぁ - The Other Road Ahead&lt;/a&gt; をきっかけに HTML 文書の作り方を調べていたときで、次のような経緯によります。&lt;/p&gt;&#13;
&lt;ol&gt;&#13;
&lt;li&gt;&lt;a href="http://twitter.com/nanto_vi/status/3314685723"&gt;Twitter: なんかコントラクトIDから直接 Documentを生成する手段があった気が → "@mozilla.org/dom"でMXR検索 → 見つからない → @mozilla\.org/.*document でGoogleソースコード検索 →&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://twitter.com/nanto_vi/status/3314717931"&gt;Twitter: "@mozilla.org/xul/xul-document;1"を発見 → その付近のソースコードを見る → NS_HTMLDOCUMENT_CID を発見 → MXR検索でCIDの実際の値を確認 → とりあえずcreateInstance() → なんかできた ← 今ここ。&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ol&gt;&#13;
&lt;/ins&gt;&#13;
&#13;
&lt;h3 id="htmldoc-conclusion"&gt;まとめ&lt;/h3&gt;&#13;
&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;code&gt;createHTMLDocument&lt;/code&gt; が使えるなら、それを使うのが楽です。&lt;/li&gt;&#13;
&lt;li&gt;Firefox では、作った HTML 文書をどう扱いたいのかによって、作成手段が異なってきます。XPath で要素を取りたいだけなら &lt;code&gt;createDocument&lt;/code&gt; でもいいですし、Firefox 3 以下でも &lt;code&gt;HTMLDocument&lt;/code&gt; 固有の機能を使いたいというのなら XSLT を使ったほうがいいかもしれません。&lt;/li&gt;&#13;
&lt;li&gt;head 要素や body 要素がなくなるのが気になるなら、自分で作る必要があります。&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 版読書会 #8</title>
<link>http://nanto.asablo.jp/blog/2009/09/30/4606915</link>
<guid>http://nanto.asablo.jp/blog/2009/09/30/4606915</guid>
<pubDate>Wed, 30 Sep 2009 03:41:56 +0900</pubDate>
<dcterms:modified>2009-09-30T03:47:37+09:00</dcterms:modified>
<dcterms:created>2009-09-30T03:47:37+09:00</dcterms:created>
<description>&lt;p&gt;&lt;a href="http://sites.google.com/site/kanasanjs/javascript-5edition-reading-8"&gt;Kanasan.JS JavaScript 第 5 版読書会 #8&lt;/a&gt; に行ってきました。今回は初めての京都での開催、それも町家でという風情あふれる読書会。真夏真冬はちょっとつらいかもしれませんが、春秋はこういった場所での勉強会というのも乙なものですね。名古屋の &lt;a href="http://groups.google.com/group/dellajs"&gt;DeLLa.JS&lt;/a&gt; では&lt;a href="http://groups.google.com/group/dellajs/web/della-js-javascript5-9"&gt;茶室での開催&lt;/a&gt;もあったそうでうらやましいことです。&lt;/p&gt;&#13;
&lt;p&gt;ちなみに会場「&lt;a href="http://www.homes-vi.com/work/omusubian.html"&gt;お結び庵&lt;/a&gt;」の運営は &lt;a href="http://homes-vi.com/"&gt;home's vi&lt;/a&gt; ("h" を抜くと「おむすび」) という法人によるものだそうで。なんとなく名前に親近感を感じてしまうのは気のせいでしょうか。&lt;/p&gt;&#13;
&lt;p&gt;読書範囲は「17.5 キーイベント」から「18章 フォームとフォーム要素」まで。ブラウザごとに変な癖があるということが少なく (完全にばらばらか結構統一されているか)、さくさくと読めました。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;キーボードショートカット&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;サイ本では、Web アプリケーションはキーボードショートカットをサポートすべきといっており、&lt;a href="http://www.w3.org/TR/2008/REC-WCAG20-20081211/" hreflang="en"&gt;WCAG (ウェブコンテンツ・アクセシビリティ・ガイドライン) 2.0&lt;/a&gt; (&lt;a href="http://www.jsa.or.jp/stdz/instac/commitee-acc/W3C-WCAG/WCAG20/index.html" title="ウェブコンテンツ・アクセシビリティ・ガイドライン (WCAG) 2.0"&gt;日本語訳&lt;/a&gt;) にも&lt;a href="http://www.jsa.or.jp/stdz/instac/commitee-acc/W3C-WCAG/WCAG20/index.html#keyboard-operation"&gt;&lt;q cite="http://www.jsa.or.jp/stdz/instac/commitee-acc/W3C-WCAG/WCAG20/index.html#keyboard-operation"&gt;すべての機能をキーボードから利用できるようにする&lt;/q&gt;&lt;/a&gt;という指針があります。&lt;/p&gt;&#13;
&lt;p&gt;しかし、製作者側でのショートカットキーの指定は、(特にアルファベットを含む場合) ブラウザやユーザー側で設定されたショートカットキーとの衝突や、サイト間での一貫性の欠如といった問題をはらんでいます。&lt;/p&gt;&#13;
&lt;p&gt;個人的に、製作者側は、キーボードアクセス可能にするにあたって、&lt;/p&gt;&#13;
&lt;dl&gt;&#13;
&lt;dt&gt;Tab&lt;/dt&gt;&#13;
  &lt;dd&gt;ウィジェット間の移動&lt;/dd&gt;&#13;
&lt;dt&gt;矢印&lt;/dt&gt;&#13;
  &lt;dd&gt;ウィジェット内の項目の移動&lt;/dd&gt;&#13;
&lt;dt&gt;Enter&lt;/dt&gt;&#13;
  &lt;dd&gt;確定、実行&lt;/dd&gt;&#13;
&lt;dt&gt;スペース&lt;/dt&gt;&#13;
  &lt;dd&gt;状態の切り替え&lt;/dd&gt;&#13;
&lt;dt&gt;Delete&lt;/dt&gt;&#13;
  &lt;dd&gt;削除&lt;/dd&gt;&#13;
&lt;/dl&gt;&#13;
&lt;p&gt;といったある程度意味の定まったキーに対しては動作を指定すべきだが、アルファベットを含むショートカットキーは使用を避けるか、少なくとも無効にできるようにすべきだと思っています。&lt;/p&gt;&#13;
&#13;
&lt;h4&gt;関連リンク&lt;/h4&gt;&#13;
&lt;dl&gt;&#13;
&lt;dt&gt;&lt;a href="http://d.hatena.ne.jp/edvakf/20090605/1244223901"&gt;自前でキーボードショートカットを実装するウェブサイトは、キーボードでブラウジングする人のことをもっと考えてあげてください - by edvakf in hatena&lt;/a&gt;&lt;/dt&gt;&#13;
  &lt;dd&gt;Web サイトが提供するキーボードショートカットを使うのは、普段からキーボードでブラウジングしている人たちであるという指摘と、キーボードショートカットを提供するスクリプトの書き方について。&lt;/dd&gt;&#13;
&lt;dt&gt;&lt;a href="http://archiva.jp/web/html-css/accesskey_and_tabindex.html"&gt;accesskeyにはアクセシビリティが無い - Archiva&lt;/a&gt;&lt;/dt&gt;&#13;
  &lt;dd&gt;HTML の accesskey 属性の問題点に関して。&lt;/dd&gt;&#13;
&lt;dt&gt;&lt;a href="http://www.plusmb.jp/2009/03/25/2981.html"&gt;accesskeyの使い方を比較(Google,Yahoo!,MySpace,mixi,モバゲー,ニコ動,etc) | 携帯サイトをつくろう。&lt;/a&gt;&lt;/dt&gt;&#13;
  &lt;dd&gt;携帯サイトではショートカットキーがある程度統一されているという話。&lt;/dd&gt;&#13;
&lt;/dl&gt;&#13;
&#13;
&lt;h3&gt;delete 演算子の使用&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;「17.6 onload イベント」のサンプルコードで、不要になったプロパティを delete 演算子で削除していますが、個人的には null を代入するほうが好みです。&lt;/p&gt;&#13;
&lt;p&gt;最近の JavaScript エンジンでは、同じ構造を持つオブジェクト同士は同一の「クラス」に属するものとして扱います。あるオブジェクトのプロパティを delete 演算子を使って削除すると、そのオブジェクトの構造と属する「クラス」が変化することになり、速度的に不利になる場合があります。とはいってもスクリプト全体の実行時間からすれば気にするほどではなく、どちらを選ぶかは趣味の問題でしょう。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;テキスト入力に対するイベント&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;テキスト入力欄 (input type="text"、textarea) の入力値の変化を通知するものとして change イベントがありますが、これは入力欄からフォーカスが外れるタイミングでしか発生しません。キー入力に逐次対応したいときは keydown、keypress イベントを、それ以外の手段による変更にも対応したいときはさらにタイマー (setTimeout、setInterval) を組み合わせるのが一般的なようです。&lt;/p&gt;&#13;
&lt;p&gt;手段を問わず (少なくとも一定時間内の) 入力値の変化を監視するために、HTML5 では &lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/common-input-element-attributes.html#event-input-input" hreflang="en"&gt;input イベント&lt;/a&gt;が定義されています。Firefox 1.0、Safari 3、Opera 9 以上が対応していますが、Opera では (10.00の時点でも) 切り取りやドラッグ &amp;amp; ドロップによる値の変更に反応しない (その場合フォーカスが外れた時点で input イベントが発生する)、WebKit (Safari、Chrome) では IME で未確定の入力にも反応するなど、実装にばらつきがあります。&lt;/p&gt;&#13;
&lt;p&gt;ちなみに、切り取り、貼り付けに反応するものとして、IE の &lt;a href="http://msdn.microsoft.com/en-us/library/ms536917%28VS.85%29.aspx" hreflang="en"&gt;cut&lt;/a&gt;、&lt;a href="http://msdn.microsoft.com/en-us/library/ms536955%28VS.85%29.aspx" hreflang="en"&gt;paste イベント&lt;/a&gt;があり、Firefox 3 以上、Safari もこれを実装しています (&lt;a href="https://developer.mozilla.org/ja/DOM/element.onpaste"&gt;element.onpaste - MDC&lt;/a&gt;)。このイベントはバブルしますが、IE では文書要素 (html 要素) までしかバブルしないようです。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;name 属性の名前空間&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;サイ本 18.3.1 節 (日本語版 p. 466) には&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;&amp;lt;form name="everything"&gt;&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;を&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;document.everything&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;で参照する例が出てきますが、この方法では document のプロパティ名とフォーム名が競合したときに困るので、name 属性ではなく id 属性を使い、&lt;code&gt;document.getElementById&lt;/code&gt; などでアクセスしたほうがいいです。&lt;/p&gt;&#13;
&lt;p&gt;勘違いされがちですが、form、img、a 要素の name 属性が要素を一意に識別するためのものなのに対し、input、textarea、select 要素の name 属性はサーバーに送信するコントロール名を指定するためのものと、同名の属性でも役割がまったく異なります。form 要素に限らず、前者に関しては id 属性を使ったほうが、他の要素との一貫性も取れて楽でしょう。&lt;/p&gt;&#13;
&lt;p&gt;ただし、IE 7 以下では name 属性も id 属性と同じ名前空間に入ってくる (&lt;code&gt;document.getElementById("foo")&lt;/code&gt; で name="foo" な要素が返ることがある) ので、フォームコントロールの name 属性と、ある要素の id 属性とが同じ値を取らないようにしたほうがいいかもしれません。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;フォームコントロールの値中での改行&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;フォームコントロールの値が改行を含むとき、その改行コードはブラウザによってさばらばらです。IE の場合、value プロパティに &lt;code&gt;\r&lt;/code&gt; や &lt;code&gt;\n&lt;/code&gt; を含む文字列を設定しても、取得時にはすべて &lt;code&gt;\r\n&lt;/code&gt; になっています。このような状況に対応するため、私は次のように改行コードを統一することがあります。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;var value = control.value.replace(/\r\n?/g, "\n");&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;なお、この改行コード変換用正規表現は、&lt;a href="http://www.din.or.jp/~ohzaki/perl.htm#CRLF_Unify" title="改行コードを統一する - Perlメモ"&gt;Perl では正しくない&lt;/a&gt;そうですが、JavaScript では問題ないと思います。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;IE での属性セレクタ&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;IE 7 以上は CSS の属性セレクタに対応していますが、&lt;a href="https://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=493505" hreflang="en"&gt;スクリプトから属性に変更を加えても表示が更新されない&lt;/a&gt;というバグがあります (IE 8 でも発生)。その場合でも class 属性などをいじると、それまでの変更が表示に反映されるようです。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;&amp;lt;style type="text/css"&gt;&#13;
[title="foo"] { color: #c63; }&#13;
&amp;lt;/style&gt;&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;pre&gt;&lt;code&gt;element.setAttribute('title', 'foo');&#13;
// IE では、ここで終了すると element の色が変化しない&#13;
&#13;
element.className += '';&#13;
// この時点で element の色が変化する&lt;/code&gt;&lt;/pre&gt;
</description>
<dc:subject>JavaScript</dc:subject>
<dc:subject>Web 関連技術</dc:subject>
</item>
<item>
<title>JavaScript の Iterator、関数とコンストラクタ</title>
<link>http://nanto.asablo.jp/blog/2009/08/09/4491514</link>
<guid>http://nanto.asablo.jp/blog/2009/08/09/4491514</guid>
<pubDate>Sun, 09 Aug 2009 16:21:26 +0900</pubDate>
<dcterms:modified>2009-08-09T16:27:49+09:00</dcterms:modified>
<dcterms:created>2009-08-09T16:23:11+09:00</dcterms:created>
<description>&lt;p&gt;&lt;a href="http://onsg.techtalk.jp/04" title="第04回テーマ「Jetpack入門」 (Online.sg)"&gt;オンライン勉強会の Jetpack 入門&lt;/a&gt;に参加して &lt;a href="https://jetpack.mozillalabs.com/" hreflang="en"&gt;Jetpack&lt;/a&gt; のソースコードを読んでいたら、&lt;a href="https://developer.mozilla.org/ja/New_in_JavaScript_1.7#Iterators"&gt;Iterator&lt;/a&gt; を関数として呼び出したときとコンストラクタとして呼び出したときとでは挙動が違うということを知りました。&lt;/p&gt;&#13;
&#13;
&lt;h3 id="jsiter-iterator-behavior"&gt;&lt;code&gt;Iterator&lt;/code&gt; の動作&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;オブジェクト &lt;code&gt;&lt;var&gt;o&lt;/var&gt;&lt;/code&gt; に対して for-in 文、for-each-in 文を実行したとき、及び &lt;code&gt;Iterator&lt;/code&gt; 関数、&lt;code&gt;Iterator&lt;/code&gt; コンストラクタを呼び出したときの (SpiderMonkey の) 動作は、それぞれ次のようになります。&lt;/p&gt;&#13;
&lt;table&gt;&#13;
&lt;colgroup span="1"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="2"&gt;&lt;/colgroup&gt;&#13;
&lt;thead&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="col"&gt;コード&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;&lt;code&gt;&lt;var&gt;o&lt;/var&gt;&lt;/code&gt; が &lt;code&gt;__iterator__&lt;/code&gt; メソッドを持つとき&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;&lt;code&gt;&lt;var&gt;o&lt;/var&gt;&lt;/code&gt; が &lt;code&gt;__iterator__&lt;/code&gt; メソッドを持たないとき&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/thead&gt;&#13;
&lt;tbody&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;for (&lt;var&gt;...&lt;/var&gt; in &lt;var&gt;o&lt;/var&gt;)&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;&lt;code&gt;&lt;var&gt;o&lt;/var&gt;.__iterator__(true)&lt;/code&gt; の返り値がイテレータとして使われる&lt;/td&gt;&#13;
    &lt;td&gt;&lt;code&gt;&lt;var&gt;o&lt;/var&gt;&lt;/code&gt; の列挙可能なプロパティの名前を列挙する &lt;code&gt;Iterator&lt;/code&gt; オブジェクトが作成され、イテレータとして使われる&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;for each (&lt;var&gt;...&lt;/var&gt; in &lt;var&gt;o&lt;/var&gt;)&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;&lt;code&gt;&lt;var&gt;o&lt;/var&gt;.__iterator__(false)&lt;/code&gt; の返り値がイテレータとして使われる&lt;/td&gt;&#13;
    &lt;td&gt;&lt;code&gt;&lt;var&gt;o&lt;/var&gt;&lt;/code&gt; の列挙可能なプロパティの値を列挙する &lt;code&gt;Iterator&lt;/code&gt; オブジェクトが作成され、イテレータとして使われる&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;Iterator(&lt;var&gt;o&lt;/var&gt;, &lt;var&gt;keysOnly&lt;/var&gt;)&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;&lt;code&gt;&lt;var&gt;o&lt;/var&gt;.__iterator__(Boolean(&lt;var&gt;keysOnly&lt;/var&gt;))&lt;/code&gt; の返り値が返される&lt;/td&gt;&#13;
    &lt;td&gt;&lt;code&gt;&lt;var&gt;o&lt;/var&gt;&lt;/code&gt; 自身の列挙可能なプロパティの名前 (&lt;code&gt;&lt;var&gt;keysOnly&lt;/var&gt;&lt;/code&gt; が真と評価されるとき)、または名前と値を収めた配列 (そうでないとき) を列挙する &lt;code&gt;Iterator&lt;/code&gt; オブジェクトが作成され返される&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;&lt;code&gt;new Iterator(&lt;var&gt;o&lt;/var&gt;, &lt;var&gt;keysOnly&lt;/var&gt;)&lt;/code&gt;&lt;/th&gt;&#13;
    &lt;td&gt;&lt;code&gt;&lt;var&gt;o&lt;/var&gt;&lt;/code&gt; 自身の列挙可能なプロパティの名前 (&lt;code&gt;&lt;var&gt;keysOnly&lt;/var&gt;&lt;/code&gt; が真と評価されるとき)、または名前と値を収めた配列 (そうでないとき) を列挙する &lt;code&gt;Iterator&lt;/code&gt; オブジェクトが作成され返される&lt;/td&gt;&#13;
    &lt;td&gt;&lt;code&gt;&lt;var&gt;o&lt;/var&gt;&lt;/code&gt; 自身の列挙可能なプロパティの名前 (&lt;code&gt;&lt;var&gt;keysOnly&lt;/var&gt;&lt;/code&gt; が真と評価されるとき)、または名前と値を収めた配列 (そうでないとき) を列挙する &lt;code&gt;Iterator&lt;/code&gt; オブジェクトが作成され返される&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/tbody&gt;&#13;
&lt;/table&gt;&#13;
&lt;p&gt;列挙可能なプロパティとは ECMAScript でいう DontEnum 属性を持たないプロパティ、&lt;code&gt;&lt;var&gt;o&lt;/var&gt;&lt;/code&gt; 自身のプロパティとは &lt;code&gt;&lt;var&gt;o&lt;/var&gt;&lt;/code&gt; のプロトタイプチェーンをたどらずに得られるプロパティのことです。また、&lt;code&gt;Iterator&lt;/code&gt; 関数及びコンストラクタの &lt;code&gt;&lt;var&gt;keysOnly&lt;/var&gt;&lt;/code&gt; 引数は省略可能であり、省略した場合は &lt;code&gt;false&lt;/code&gt; を指定したものとして扱われます。&lt;/p&gt;&#13;
&lt;p&gt;なお、JavaScript 1.7 では for-in 文で分割代入を使ったときにこれと異なる動作をしますが、&lt;a href="https://developer.mozilla.org/ja/New_in_JavaScript_1.8#Changes_in_destructuring_for..in"&gt;JavaScript 1.8 で修正された&lt;/a&gt;のでここでは触れません。&lt;/p&gt;&#13;
&#13;
&lt;h3 id="jsiter-example"&gt;事例&lt;/h3&gt;&#13;
&#13;
&lt;pre&gt;&lt;code&gt;var iteratorLikeObject = {&#13;
  array: ['p', 'q', 'r'],&#13;
  index: 0,&#13;
  next: function () {&#13;
    if (this.index &amp;lt; this.array.length)&#13;
      return this.array[this.index++];&#13;
    this.index = 0;&#13;
    throw StopIteration;&#13;
  }&#13;
};&#13;
&#13;
var o = {&#13;
  a: 10,&#13;
  b: 20,&#13;
  __iterator__: function (keysOnly) {&#13;
    print('keysOnly = ' + keysOnly);&#13;
    return iteratorLikeObject;&#13;
  }&#13;
};&#13;
&#13;
for (let i in o) print(i);&#13;
// =&amp;gt; keysOnly = true&#13;
// =&amp;gt; p&#13;
// =&amp;gt; q&#13;
// =&amp;gt; r&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;上のコードでは、&lt;code&gt;__iterator__&lt;/code&gt; メソッドを持つオブジェクトに対して for-in 文を実行しているので、&lt;code&gt;__iterator__&lt;/code&gt; メソッドの返り値である &lt;code&gt;iteratorLikeObject&lt;/code&gt; がイテレータとして使われます。よって、列挙される値はその &lt;code&gt;next&lt;/code&gt; メソッドの返り値である文字列 &lt;code&gt;"p"&lt;/code&gt;、&lt;code&gt;"q"&lt;/code&gt;、&lt;code&gt;"r"&lt;/code&gt; となります。&lt;/p&gt;&#13;
&lt;p&gt;ここで、&lt;code&gt;Iterator&lt;/code&gt; 関数を使ってみるとどうなるでしょうか。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;for (let i in Iterator(o)) print(i);&#13;
// =&amp;gt; keysOnly = false&#13;
// =&amp;gt; array&#13;
// =&amp;gt; index&#13;
// =&amp;gt; next&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;&lt;code&gt;Iterator&lt;/code&gt; 関数の返り値は &lt;code&gt;iteratorLikeObject&lt;/code&gt; なので、このオブジェクトに対して for-in 文が実行されます。しかし、&lt;code&gt;iteratorLikeObject&lt;/code&gt; は &lt;code&gt;__iterator__&lt;/code&gt; メソッドを持っていないため、そのプロパティの名前が列挙されます。&lt;/p&gt;&#13;
&lt;p&gt;では &lt;code&gt;__iterator__&lt;/code&gt; メソッドを追加してみましょう。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;iteratorLikeObject.__iterator__ = function (keysOnly) {&#13;
  print('keysOnly in iteratorLikeObject = ' + keysOnly);&#13;
  return this;&#13;
};&#13;
&#13;
for (let i in Iterator(o)) print(i);&#13;
// =&amp;gt; keysOnly = false&#13;
// =&amp;gt; keysOnly in iteratorLikeObject = true&#13;
// =&amp;gt; p&#13;
// =&amp;gt; q&#13;
// =&amp;gt; r&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;再び &lt;code&gt;iteratorLikeObject&lt;/code&gt; に対して for-in 文が実行されますが、今度は &lt;code&gt;__iterator__&lt;/code&gt; メソッドが存在します。しかも、&lt;code&gt;__iterator__&lt;/code&gt; メソッドでは自分自身を返しているため、&lt;code&gt;iteratorLikeObject&lt;/code&gt; がイテレータとして使われ、その &lt;code&gt;next&lt;/code&gt; メソッドの返り値が列挙されます。&lt;/p&gt;&#13;
&lt;p&gt;ここで、&lt;code&gt;Iterator&lt;/code&gt; を関数ではなくコンストラクタとして使うと、そもそも &lt;code&gt;o&lt;/code&gt; の &lt;code&gt;__iterator__&lt;/code&gt; メソッドが呼び出されなくなります。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;for (let i in new Iterator(o)) print(i);&#13;
// =&amp;gt; a,10&#13;
// =&amp;gt; b,20&#13;
// =&amp;gt; __iterator__,function (keysOnly) {&#13;
// =&amp;gt;     print("keysOnly = " + keysOnly);&#13;
// =&amp;gt;     return iteratorLikeObject;&#13;
// =&amp;gt; }&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;&lt;code&gt;Iterator&lt;/code&gt; コンストラクタは、オブジェクト自身が持つプロパティを調べるときに便利です。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;var o = {&#13;
  public1: 10,&#13;
  public2: 20,&#13;
  _private: 30,&#13;
  __proto__: {&#13;
    inherited: 40&#13;
  }&#13;
};&#13;
var keys = [i for (i in new Iterator(o, true)) if (!/^_/.test(i))];&#13;
print(keys.toSource());&#13;
// =&amp;gt; ["public1", "public2"]&lt;/code&gt;&lt;/pre&gt;&#13;
&#13;
&lt;h3 id="jsiter-iterator-object"&gt;&lt;code&gt;Iterator&lt;/code&gt; オブジェクト&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;&lt;code&gt;Iterator&lt;/code&gt; 関数またはコンストラクタにより作られる &lt;code&gt;Iterator&lt;/code&gt; オブジェクトは、next メソッドと &lt;code&gt;__iterator__&lt;/code&gt; メソッドを持ちます。他の組み込みオブジェクトのメソッドと異なり、これら 2 つのメソッドは上書きも削除もできません。&lt;/p&gt;&#13;
&lt;p&gt;&lt;code&gt;Iterator&lt;/code&gt; オブジェクトの &lt;code&gt;__iterator__&lt;/code&gt; メソッドは、引数によらず常に自分自身を返します。これにより、&lt;code&gt;for (&lt;var&gt;...&lt;/var&gt; in new Iterator(&lt;var&gt;...&lt;/var&gt;))&lt;/code&gt; と &lt;code&gt;for each (&lt;var&gt;...&lt;/var&gt; in new Iterator(&lt;var&gt;...&lt;/var&gt;))&lt;/code&gt; は同じ動作をすることになります。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;var anyObject = {};&#13;
print(Iterator.prototype.__iterator__.call(anyObject) === anyObject);&#13;
// =&amp;gt; true&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;ある &lt;code&gt;Iterator&lt;/code&gt; オブジェクトが、どのオブジェクトのプロパティを列挙するものなのかは、&lt;code&gt;__parent__&lt;/code&gt; プロパティからわかります。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;var anyObject = {};&#13;
var iterator = new Iterator(anyObject);&#13;
print(iterator.__parent__ === anyObject);&#13;
// =&amp;gt; true&lt;/code&gt;&lt;/pre&gt;
</description>
<dc:subject>JavaScript</dc:subject>
</item>
<item>
<title>LiveCoding #6 の 2</title>
<link>http://nanto.asablo.jp/blog/2009/07/19/4445872</link>
<guid>http://nanto.asablo.jp/blog/2009/07/19/4445872</guid>
<pubDate>Sun, 19 Jul 2009 23:40:45 +0900</pubDate>
<dcterms:modified>2009-07-20T19:29:26+09:00</dcterms:modified>
<dcterms:created>2009-07-19T23:44:15+09:00</dcterms:created>
<description>&lt;p&gt;&lt;a href="http://nanto.asablo.jp/blog/2009/07/15/4435439" title="第 2 回 Firefox 出張ワークショップ発表資料"&gt;OSC Kansai に出た&lt;/a&gt;帰りに &lt;a href="http://d.hatena.ne.jp/satzz/"&gt;satzz 君&lt;/a&gt;に電話したら、ちょうど &lt;a href="http://ujihisa.github.com/livecoding6/"&gt;LiveCoding #6&lt;/a&gt; をやっているとのことだったのでその足で寄ってきました。&lt;a href="http://livecoding.org/#%E7%AC%AC6%E5%9B%9E"&gt;前回も第 6 回&lt;/a&gt;だった気がするのは何かの間違いでしょうか。&lt;/p&gt;&#13;
&lt;p&gt;LiveCoding とはプログラミングの実演と実況を楽しみましょうというイベントで、出てくる言語も C から PHP まで色とりどり。まともとは思えないテクニックも多々披露されたわけですが、中でも驚愕だったのが &lt;a href="http://ujihisa.blogspot.com/"&gt;ujihisa さん&lt;/a&gt;が書いた Ruby のコード、&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;def fib n, x = (n &lt; 2) ? n : fib(n - 1) + fib(n - 2)&#13;
  x&#13;
end&#13;
&#13;
fib 10 # =&gt; 55&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;Ruby ではデフォルト引数内で再帰呼び出しができるだなんてちっとも知りませんでした。&lt;/p&gt;&#13;
&lt;p&gt;飛び入り LiveCoder も大歓迎といわれ、その特典である参加費 (お寿司 + カレー代 + etc.) キャッシュバックを目当てに手を挙げたのですが、ネタが思い浮かばず、&lt;a href="http://code.google.com/p/bitly-api/wiki/ApiDocumentation" hreflang="en"&gt;bit.ly API&lt;/a&gt; の存在を教えてもらって「Web ページ閲覧中にリンク先が &lt;a href="http://bit.ly/" hreflang="en"&gt;bit.ly&lt;/a&gt; 経由で何回クリックされたかを表示する Greasemonkey スクリプト」を作ることにしました。&lt;/p&gt;&#13;
&lt;p class="figure"&gt;&#13;
&lt;a href="http://www.ne.jp/asahi/nanto/moon/2009/07/19/bitly-referred.png"&gt;&lt;img class="thumbnail" src="http://www.ne.jp/asahi/nanto/moon/2009/07/19/bitly-referred-s.png" alt="[図: リンク先へのクリック回数を表示する Greasemonkey スクリプト]" width="360" height="150"&gt;&lt;/a&gt;&#13;
&lt;/p&gt;&#13;
&lt;p&gt;Greasemonkey スクリプトでは &lt;code&gt;let&lt;/code&gt; を使えないのについ &lt;code&gt;let&lt;/code&gt; と打ってしまって &lt;code&gt;var&lt;/code&gt; と打ち直したり、Greasemonkey と bit.ly と wedata の API リファレンスを読みふけったり、E4X で構築した要素を手っ取り早く使うために &lt;code&gt;innerHTML&lt;/code&gt; を使おうと思ったら、そもそも要素を作成する必要がないことがわかって単なるテキストを &lt;code&gt;innerHTML&lt;/code&gt; に代入する羽目になったり、それならとテキストノードを直接生成するように書き換えたりしているうちに制限時間 20 分はあっという間に過ぎ、45 分かけて&lt;a href="https://gist.github.com/149553/4d13a6d3f02901f36d57b848f5c815a6b9fe057c" hreflang="en"&gt;どうにか動くもの&lt;/a&gt;ができるという有様。動くのは &lt;a href="http://userscripts.org/scripts/show/11562" hreflang="en"&gt;LDRize&lt;/a&gt; 対応サイトのみ、利用するには Firefox 3.5 以上と bit.ly のアカウントが必要です。&lt;/p&gt;&#13;
&lt;p&gt;その場で &lt;a href="http://d.hatena.ne.jp/cho45/"&gt;cho45&lt;/a&gt; が「こういうときは &lt;a href="http://coderepos.org/share/wiki/JSDeferred" hreflang="en"&gt;JSDeferred&lt;/a&gt; を使えば」とプッシュしていた気がするので、後日 &lt;a href="https://gist.github.com/149553/3586e748853f54d429babbfd000694238298087d" hreflang="en"&gt;JSDeferred を使って書き直してみました&lt;/a&gt;。JSDeferred をうまいこと使えているかは不明ですが。&lt;/p&gt;&#13;
&lt;p&gt;ちなみに Greasemonkey スクリプトで &lt;code&gt;let&lt;/code&gt; が使えないというのは、&lt;a href="https://developer.mozilla.org/ja/Components.utils.evalInSandbox"&gt;&lt;code&gt;Components.utils.evalInSandbox&lt;/code&gt;&lt;/a&gt; で JavaScript のバージョンが指定できないという制限によるものです。&lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=445873" hreflang="en" title="Bug 445873 -- Components.utils.Sandbox doesn't set JS version"&gt;この仕様は Firefox 3.5 で改善&lt;/a&gt;され、適切なバージョンを指定すればサンドボックス内でも &lt;code&gt;let&lt;/code&gt;、&lt;code&gt;yield&lt;/code&gt; を使えるようになりましたが、Greasemonkey 側はまだ対応していません。&lt;/p&gt;&#13;
&lt;p&gt;コーディングが終わった後はまったり過ごしていましたが、JSDeferred のロゴを作れば女子高生の間で JSDeferred が流行るんじゃないかという話になったため、&lt;a href="http://f.hatena.ne.jp/nanto_vi/20090712013757" title="JSDeferred のロゴ"&gt;実際に作ってみました&lt;/a&gt;。&lt;a href="http://d.hatena.ne.jp/secondlife/"&gt;secondlife さん&lt;/a&gt;に「何この 5 秒で描いたような」と dis られましたが、30 秒はかかっています。JSDeferred のトップページにもこのロゴを貼り付けたので、ナウなヤングにバカウケ間違い無しですね。&lt;/p&gt;&#13;
&lt;p&gt;それと、&lt;a href="http://d.hatena.ne.jp/secondlife/20080724/1216860029"&gt;Gist で Greasemonkey スクリプトを管理しよう&lt;/a&gt;という話を聞きますが、皆さん具体的にどうやって管理しているんでしょうか? とりあえず Greasemonkey スクリプトを書いた後、&lt;a href="http://d.hatena.ne.jp/swdyh/20081207/1228655198"&gt;gisty&lt;/a&gt; で投稿してそれを &lt;code&gt;git remote&lt;/code&gt; で引っ張ってきてとやったのですが、これでいいのかよくわかりません (環境は Cygwin + Meadow)。&lt;/p&gt;&#13;
&lt;pre class="console"&gt;$ cd FIREFOX_PROFILE_DIR&#13;
$ cd gm_scripts/bitly_referred/&#13;
$ ls&#13;
bitly_referred.user.js&#13;
$ gisty post bitly_referred.user.js&#13;
Initialized empty Git repository in GISTY_DIR/149553/.git/&#13;
$ git init&#13;
$ git remote add origin git@gist.github.com:149553.git&#13;
$ git pull origin master&#13;
$ cat &amp;gt; .gitignore&#13;
*&#13;
!*.user.js&#13;
$ meadoww bitly_referred.user.js&#13;
$ git add .&#13;
$ git commit -m "Rewrite with JSDeferred"&#13;
$ git push&lt;/pre&gt;
</description>
<dc:subject>コンピュータ一般</dc:subject>
<dc:subject>Mozilla Firefox</dc:subject>
</item>
<item>
<title>第 2 回 Firefox 出張ワークショップ発表資料</title>
<link>http://nanto.asablo.jp/blog/2009/07/15/4435439</link>
<guid>http://nanto.asablo.jp/blog/2009/07/15/4435439</guid>
<pubDate>Wed, 15 Jul 2009 02:17:01 +0900</pubDate>
<dcterms:modified>2009-07-20T19:29:52+09:00</dcterms:modified>
<dcterms:created>2009-07-15T02:27:51+09:00</dcterms:created>
<description>&lt;p&gt;先日&lt;a href="http://www.kcg.ac.jp/"&gt;京都コンピュータ学院&lt;/a&gt;で開催された&lt;a href="http://www.ospn.jp/osc2009-kansai/"&gt;オープンソースカンファレンス 2009 Kansai&lt;/a&gt;、その中の一セッション「&lt;a href="http://mozilla.jp/blog/entry/4143/"&gt;第 2 回 Firefox 出張ワークショップ ～基礎から学べる拡張機能開発～&lt;/a&gt;」に講師として参加させていただきました。私の担当した後半、実際に拡張機能を作ってみる部分の資料及び完成版の拡張は以下になります。&lt;/p&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://www.ne.jp/asahi/nanto/moon/2009/07/15/firefox-workshop.html"&gt;Firefox 拡張機能開発ワークショップ in OSC Kansai 2009&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://www.ne.jp/asahi/nanto/moon/2009/07/15/contexthistory-0.1.xpi"&gt;contexthistory-0.1.xpi&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;ソースコード&#13;
  &lt;ul class="tree"&gt;&#13;
  &lt;li&gt;chrome/&#13;
    &lt;ul&gt;&#13;
    &lt;li&gt;content/&#13;
      &lt;ul&gt;&#13;
      &lt;li&gt;&lt;a href="http://www.ne.jp/asahi/nanto/moon/2009/07/15/contexthistory/chrome/content/contexthistory.js"&gt;contexthistory.js&lt;/a&gt;&lt;/li&gt;&#13;
      &lt;li&gt;&lt;a href="http://www.ne.jp/asahi/nanto/moon/2009/07/15/contexthistory/chrome/content/contexthistory.xul"&gt;contexthistory.xul&lt;/a&gt;&lt;/li&gt;&#13;
      &lt;/ul&gt;&#13;
    &lt;/li&gt;&#13;
    &lt;/ul&gt;&#13;
  &lt;/li&gt;&#13;
  &lt;li&gt;&lt;a href="http://www.ne.jp/asahi/nanto/moon/2009/07/15/contexthistory/chrome.manifest"&gt;chrome.manifest&lt;/a&gt;&lt;/li&gt;&#13;
  &lt;li&gt;&lt;a href="http://www.ne.jp/asahi/nanto/moon/2009/07/15/contexthistory/install.rdf"&gt;install.rdf&lt;/a&gt;&lt;/li&gt;&#13;
  &lt;/ul&gt;&#13;
&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;p&gt;「わからないことがあったとき、どうやって調べるか」をひとつの柱として話を進めていきたかったのですが、つたない進行で後半ややペースが押し気味になってしまい、終了時間を 5 分ほど過ぎて最低限動くものが完成するという有様でした。人によっては休憩時間もろくに取れない状態になってしまい申し訳ありません。&lt;/p&gt;&#13;
&lt;p&gt;以下に質問のあった点、補足等を記します。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;「進む」メニューの特定&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;&lt;a href="https://developer.mozilla.org/ja/DOM_Inspector"&gt;DOM Inspector&lt;/a&gt; でコンテキストメニューの「進む」メニューを探すのにいちいち文書ツリーをたどっていったのですが、後ほど&lt;a href="http://a8i.blog78.fc2.com/"&gt;あさん&lt;/a&gt;から指摘があったように、クリックで要素を選択する機能を使ったほうがはるかに簡単でした。&lt;/p&gt;&#13;
&lt;p&gt;具体的には、DOM Inspector でブラウザウィンドウを選択後、マウス選択ボタンをクリックし、ブラウザウィンドウに戻ったらアプリケーションキーまたは Shift + F10 キーでコンテキストメニューを表示させます。そうすれば後は「進む」メニューを直接クリックするだけで DOM Inspector 側で適切な要素が選択されます。&lt;/p&gt;&#13;
&lt;p class="figure"&gt;&#13;
&lt;img src="http://www.ne.jp/asahi/nanto/moon/2009/07/15/find-by-clicking-button.png" alt="[図: DOM Inspector のマウス選択ボタン]" width="300" height="200"&gt;&#13;
&lt;img src="http://www.ne.jp/asahi/nanto/moon/2009/07/15/context-menu-by-key.png" alt="[図: キー操作で表示したコンテキストメニュー]" width="300" height="200"&gt;&#13;
&lt;/p&gt;&#13;
&lt;p&gt;マウス選択状態では右クリック (Mac では Ctrl + クリック) してもその要素が選択されてしまうので、文書ツリーをたどっていく必要があると思っていたのですが、キー操作でコンテキストメニューを表示させればいいというのは個人的に盲点でした。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;名前付き関数式&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;&lt;code&gt;ContextHistory&lt;/code&gt; オブジェクトの各メソッドを記述する際、&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;var ContextHistory = {&#13;
  init: function CH_init() { ... },&#13;
};&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;と &lt;code&gt;CH_init&lt;/code&gt; のような名前をつけていることへの質問がありました。名前をつけることでスタックトレースにその名前が出るようになり、デバッグが楽になります。つけないと &lt;samp lang="en"&gt;anonymous function&lt;/samp&gt; といった表示になり、名前から関数を特定できません。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;XUL 要素の動的な生成&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;XUL、XHTML、SVG といった特定のXML応用の要素を生成するときは、&lt;code&gt;document.createElementNS&lt;/code&gt; メソッドを使い、第 1 引数にその XML 応用の名前空間 URI を指定します。一応 XUL 文書中では &lt;code&gt;createElement&lt;/code&gt; メソッドでも XUL 要素が生成されますが、そのような DOM 仕様にない Mozilla 独自の振る舞いに依存すべきではありません。さもなくば &lt;a href="http://www.media.t-kougei.ac.jp/~nagae/?p=2223"&gt;XUL と他の XML 応用とを組み合わせるときなどに混乱を招く&lt;/a&gt;ことになります。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;よく参照する Firefox のソースコード&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;&lt;a href="http://mxr.mozilla.org/" hreflang="en" lang="en"&gt;Mozilla Cross-Reference&lt;/a&gt; で Mozilla の (Firefox の) ソースコードを閲覧・検索できます。私の場合、実際によく参照するのは次のような箇所です。&lt;/p&gt;&#13;
&lt;table&gt;&#13;
&lt;caption&gt;Firefox の機能とそのソースコードの場所&lt;/caption&gt;&#13;
&lt;colgroup span="1"&gt;&lt;/colgroup&gt;&#13;
&lt;colgroup span="2"&gt;&lt;/colgroup&gt;&#13;
&lt;thead&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="col"&gt;機能&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;Firefox 3.5 系統&lt;/th&gt;&#13;
    &lt;th scope="col"&gt;最新開発版&lt;/th&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/thead&gt;&#13;
&lt;tbody&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;ブラウザの UI&lt;/th&gt;&#13;
    &lt;td&gt;&lt;a href="http://mxr.mozilla.org/mozilla1.9.1/source/browser/base/content/" hreflang="en"&gt;/browser/base/content/&lt;/a&gt;&lt;/td&gt;&#13;
    &lt;td&gt;&lt;a href="http://mxr.mozilla.org/mozilla-central/source/browser/base/content/" hreflang="en"&gt;/browser/base/content/&lt;/a&gt;&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;DOM インターフェース&lt;/th&gt;&#13;
    &lt;td&gt;&lt;a href="http://mxr.mozilla.org/mozilla1.9.1/source/dom/public/idl/" hreflang="en"&gt;/dom/public/idl/&lt;/a&gt;&lt;/td&gt;&#13;
    &lt;td&gt;&lt;a href="http://mxr.mozilla.org/mozilla-central/source/dom/interfaces/" hreflang="en"&gt;/dom/interfaces/&lt;/a&gt;&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
  &lt;tr&gt;&#13;
    &lt;th scope="row"&gt;UI 部品&lt;/th&gt;&#13;
    &lt;td&gt;&lt;a href="http://mxr.mozilla.org/mozilla1.9.1/source/toolkit/content/widgets/" hreflang="en"&gt;/toolkit/content/widgets/&lt;/a&gt;&lt;/td&gt;&#13;
    &lt;td&gt;&lt;a href="http://mxr.mozilla.org/mozilla-central/source/toolkit/content/widgets/" hreflang="en"&gt;/toolkit/content/widgets/&lt;/a&gt;&lt;/td&gt;&#13;
  &lt;/tr&gt;&#13;
&lt;/tbody&gt;&#13;
&lt;/table&gt;&#13;
&#13;
&lt;h3&gt;数値への変換&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;JavaScript で &lt;code&gt;+&lt;var&gt;expr&lt;/var&gt;&lt;/code&gt; は &lt;code&gt;Number(&lt;var&gt;expr&lt;/var&gt;)&lt;/code&gt; と同じ意味であり、&lt;code&gt;&lt;var&gt;expr&lt;/var&gt;&lt;/code&gt; を数値へ変換した結果を返します。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;ラベルの国際化&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;追加したメニューのラベルを、ロケールによらずツールバーの履歴ドロップダウンボタンのツールチップと同じにするのが目標でした。たとえば次のような手順が考えられます。&lt;/p&gt;&#13;
&lt;ol&gt;&#13;
&lt;li&gt;DOM Inspector で履歴ドロップダウンボタンを選択し、その id を確認する。&lt;/li&gt;&#13;
&lt;li&gt;view-source:chrome://browser/content/browser.xul からその id を検索し、ツールチップ文字列を表す実体参照を見つける。&lt;/li&gt;&#13;
&lt;li&gt;&lt;abbr title="Mozilla Cross-Reference" lang="en"&gt;MXR&lt;/abbr&gt; で実体名を検索し、その実体が含まれる DTD ファイルを見つける。&lt;/li&gt;&#13;
&lt;li&gt;MXR で見つかった DTD ファイル名と browser.xul のソースで参照している DTD の chrome URI とを見比べ、その DTD ファイルを指す chrome URI の見当をつける。&lt;/li&gt;&#13;
&lt;li&gt;オーバーレイファイルからその DTD を参照し、メニューのラベルとしてその実体参照を記述する。&lt;/li&gt;&#13;
&lt;/ol&gt;&#13;
&lt;p class="figure"&gt;&#13;
&lt;a href="http://www.ne.jp/asahi/nanto/moon/2009/07/15/find-history-dropdown.png"&gt;&lt;img class="thumbnail" src="http://www.ne.jp/asahi/nanto/moon/2009/07/15/find-history-dropdown-s.png" alt="[図: DOM Inspector で選択した履歴ドロップダウンボタン]" width="300" height="200"&gt;&lt;/a&gt;&#13;
&lt;a href="http://www.ne.jp/asahi/nanto/moon/2009/07/15/history-dropdown-source.png"&gt;&lt;img class="thumbnail" src="http://www.ne.jp/asahi/nanto/moon/2009/07/15/history-dropdown-source-s.png" alt="[図: 履歴ドロップダウンボタンのソースコード]" width="300" height="200"&gt;&lt;/a&gt;&#13;
&lt;a href="http://www.ne.jp/asahi/nanto/moon/2009/07/15/search-entity.png"&gt;&lt;img class="thumbnail" src="http://www.ne.jp/asahi/nanto/moon/2009/07/15/search-entity-s.png" alt="[図: MXR での実体名の検索結果]" width="300" height="200"&gt;&lt;/a&gt;&#13;
&lt;a href="http://www.ne.jp/asahi/nanto/moon/2009/07/15/dtds-for-browser.png"&gt;&lt;img class="thumbnail" src="http://www.ne.jp/asahi/nanto/moon/2009/07/15/dtds-for-browser-s.png" alt="[図: browser.xul が参照する DTD]" width="300" height="200"&gt;&lt;/a&gt;&#13;
&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;&amp;lt;!DOCTYPE overlay [&#13;
  &amp;lt;!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd"&amp;gt;&#13;
  %browserDTD;&#13;
]&amp;gt;&lt;/code&gt;&lt;/pre&gt;&#13;
&#13;
&lt;h3&gt;修正の反映&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;最初のほうで &lt;a href="https://addons.mozilla.org/firefox/addon/3559"&gt;QuickRestart&lt;/a&gt; を紹介した影響か、ソースコードを修正するたびに Firefox を再起動していた人が多かったですが、実は about:config から &lt;a href="http://kb.mozillazine.org/Nglayout.debug.disable_xul_cache" hreflang="en"&gt;nglayout.debug.disable_xul_cache&lt;/a&gt; を true にしておけば、新しいウィンドウを開くたびに最新のソースコードが読み込みなおされます。ただし、&lt;a href="https://developer.mozilla.org/ja/XPCOM"&gt;XPCOM コンポーネント&lt;/a&gt;や &lt;a href="https://developer.mozilla.org/ja/JavaScript_modules"&gt;JavaScript モジュール&lt;/a&gt;はこの限りではありません。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;拡張の JavaScript の名前空間&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;JavaScript には名前空間が存在しないので、拡張のスクリプトを書くときは、Firefox 本体や別の拡張が使っている名前と競合しないように注意する必要があります。これは拡張から Firefox 本体を自由に操作できることの裏返しでもあります。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;JAR ファイルの利点&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;拡張の構成ファイルを単独の JAR ファイルに固めることで、アクセスするファイルがひとつですむようになり、ファイルアクセスの負荷を減らすことができるそうです。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;ローカルな拡張の自動更新&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;たとえば企業内のみで使いたい拡張があるというとき、自動更新に対応させるためには、SSL を通じて更新を配布するか、電子署名を使い&lt;a href="https://developer.mozilla.org/ja/Install.rdf#updateKey"&gt;拡張に公開鍵を含める&lt;/a&gt;必要があるそうです。&lt;/p&gt;
</description>
<dc:subject>Mozilla Firefox</dc:subject>
</item>
<item>
<title>Kanasan.JS JSDeferred コードリーディング</title>
<link>http://nanto.asablo.jp/blog/2009/06/30/4403957</link>
<guid>http://nanto.asablo.jp/blog/2009/06/30/4403957</guid>
<pubDate>Tue, 30 Jun 2009 23:55:57 +0900</pubDate>
<dcterms:modified>2009-07-01T00:12:37+09:00</dcterms:modified>
<dcterms:created>2009-06-30T23:57:45+09:00</dcterms:created>
<description>&lt;p&gt;すっかり記事を書くのが遅れてしまいましたが、&lt;a href="http://sites.google.com/site/kanasanjs/jsdeferred-code-reading"&gt;Kanasan.JS JSDeferred コードリーディング&lt;/a&gt;へ行ってきました (&lt;a href="http://sites.google.com/site/kanasanjs/about/other_events" title="その他の企画 ( Kanasan.JS : JavaScript Workshop in Kansai)"&gt;参加者ブログ記事一覧&lt;/a&gt;)。&lt;a href="http://coderepos.org/share/wiki/JSDeferred" hreflang="en"&gt;JSDeferred&lt;/a&gt; は &lt;a href="http://lowreal.net/"&gt;cho45 さん&lt;/a&gt;作の、非同期処理を簡単に記述するためのライブラリです。&lt;a href="http://svn.coderepos.org/share/lang/javascript/jsdeferred/trunk/doc/index.html" title="JSDeferred Document" hreflang="en"&gt;簡単なリファレンス&lt;/a&gt;もありますが、&lt;a href="http://svn.coderepos.org/share/lang/javascript/jsdeferred/trunk/sample.html" title="JSDeferred Sample" hreflang="en"&gt;実際に動かせるサンプル&lt;/a&gt;のほうがどんなものか感覚をつかめると思います。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;Deferred オブジェクト&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;JSDeferred では、ひとつの処理をひとつの Deferred オブジェクトとして表現し、処理の流れは Deferred オブジェクトを順につなげた Deferred チェーンで表します。Deferred オブジェクトは三つのプロパティを持ちます。&lt;/p&gt;&#13;
&lt;dl&gt;&#13;
&lt;dt&gt;&lt;code&gt;callback.ok&lt;/code&gt; プロパティ&lt;/dt&gt;&#13;
  &lt;dd&gt;(正常) 処理の本体を表す関数。&lt;/dd&gt;&#13;
&lt;dt&gt;&lt;code&gt;callback.ng&lt;/code&gt; プロパティ&lt;/dt&gt;&#13;
  &lt;dd&gt;例外処理の本体を表す関数。&lt;/dd&gt;&#13;
&lt;dt&gt;&lt;code&gt;_next&lt;/code&gt; プロパティ&lt;/dt&gt;&#13;
&lt;dd&gt;Deferred チェーン上の次の処理 (継続) を表す Deferred オブジェクト。&lt;/dd&gt;&#13;
&lt;/dl&gt;&#13;
&lt;p&gt;さらに、Deferred オブジェクトの実行状態を意識すると、JSDeferred を使って書かれたコードが読みやすくなるのではないかと思います。&lt;/p&gt;&#13;
&lt;dl&gt;&#13;
&lt;dt&gt;待機 (&lt;span lang="en"&gt;idle&lt;/span&gt;) 状態&lt;/dt&gt;&#13;
  &lt;dd&gt;処理が実行されない状態。&lt;code&gt;call&lt;/code&gt;/&lt;code&gt;fail&lt;/code&gt; メソッドが呼び出されると実行中状態へ移る。&lt;/dd&gt;&#13;
&lt;dt&gt;実行待ち (&lt;span lang="en"&gt;waiting&lt;/span&gt;) 状態&lt;/dt&gt;&#13;
  &lt;dd&gt;処理がそのうち実行される状態。&lt;code&gt;cancel&lt;/code&gt; メソッドが呼び出されると待機状態へ移る。&lt;/dd&gt;&#13;
&lt;dt&gt;実行中 (&lt;span lang="en"&gt;running&lt;/span&gt;) 状態&lt;/dt&gt;&#13;
  &lt;dd&gt;正常処理または例外処理が実行されている状態。処理本体の実行が終了したら待機状態へ移る。このとき、処理本体の返り値が Deferred オブジェクトなら、その Deferred オブジェクトの継続 (&lt;code&gt;_next&lt;/code&gt; プロパティ) を自身の継続と同じにする。そうでなければ、自身の継続たる Deferred オブジェクトを実行する (実行中状態へ移す)。&lt;/dd&gt;&#13;
&lt;/dl&gt;&#13;
&#13;
&lt;h3&gt;わかったこと、注意すべきこと&lt;/h3&gt;&#13;
&#13;
&lt;ul&gt;&#13;
&lt;li&gt;単に &lt;code&gt;new Deferred()&lt;/code&gt; または &lt;code&gt;Deferred()&lt;/code&gt; とすると、待機状態の Deferred オブジェクトが作られる。&lt;/li&gt;&#13;
&lt;li&gt;処理本体で Deferred オブジェクトが返されたなら、自身の継続を (直接は) 実行しない。&lt;/li&gt;&#13;
&lt;li&gt;&lt;code&gt;parallel&lt;/code&gt; 関数は飛ばして、先に &lt;code&gt;next&lt;/code&gt; 関数、&lt;code&gt;wait&lt;/code&gt; 関数を読んだほうがよさそう。&lt;/li&gt;&#13;
&lt;li&gt;&lt;code&gt;next&lt;/code&gt; 関数 (&lt;code&gt;Deferred.next&lt;/code&gt;) と &lt;code&gt;next&lt;/code&gt; メソッド (&lt;code&gt;Deferred.prototype.next&lt;/code&gt;) は別物。&#13;
  &lt;ul&gt;&#13;
  &lt;li&gt;&lt;code&gt;next&lt;/code&gt; 関数は、実行待ち状態の Deferred オブジェクトを新規作成する。引数に渡された関数がその Deferred オブジェクトの処理本体となる。&lt;/li&gt;&#13;
  &lt;li&gt;&lt;code&gt;next&lt;/code&gt; メソッドは、待機状態の Deferred オブジェクトを新規作成し、それを自身の継続とする。引数に渡された関数がその Deferred オブジェクトの処理本体となる。自身の実行状態は変化しない。&lt;/li&gt;&#13;
  &lt;/ul&gt;&#13;
&lt;/li&gt;&#13;
&lt;li&gt;&lt;code&gt;next&lt;/code&gt; 関数については、とりあえず &lt;code&gt;next_default&lt;/code&gt; だけを見れば十分。&#13;
  &lt;ul&gt;&#13;
  &lt;li&gt;&lt;code&gt;next_faster_way_readystatechange&lt;/code&gt;、&lt;code&gt;next_faster_way_Image&lt;/code&gt; は、特定の環境用に高速化を施した版。詳細は「&lt;a href="http://subtech.g.hatena.ne.jp/cho45/20090125/1232831437"&gt;JSDeferred を高速化する (試し中) - 冬通りに消え行く制服ガールは、夢物語にリアルを求めない。 - subtech&lt;/a&gt;」を参考に。&lt;/li&gt;&#13;
  &lt;/ul&gt;&#13;
&lt;/li&gt;&#13;
&lt;li&gt;他の記事では、「&lt;a href="http://d.hatena.ne.jp/edvakf/20090414/1239726515"&gt;JSDeferredがやっとわかった - by edvakf in hatena&lt;/a&gt;」が詳細でわかりやすい。&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&#13;
&lt;h3&gt;Deferred チェーンの図示&lt;/h3&gt;&#13;
&#13;
&lt;pre&gt;&lt;code&gt;next(function f() {&#13;
  ...&#13;
  return next(function g() {&#13;
    ...&#13;
  });&#13;
}).&#13;
next(function h() {&#13;
  ...&#13;
});&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;は、最初に次のような Deferred チェーンを作ります。&lt;/p&gt;&#13;
&lt;p&gt;&lt;img src="http://www.ne.jp/asahi/nanto/moon/2009/06/30/deferred-chain-1.png" alt="[図 1: 上記コードが最初に作る Deferred チェーン]"&gt;&lt;/p&gt;&#13;
&lt;p&gt;ここで、Deferred チェーン先頭の Deferred オブジェクトの処理が終了し、&lt;code&gt;f&lt;/code&gt; が Deferred オブジェクトを返すと、Deferred チェーンは次のようになります。&lt;/p&gt;&#13;
&lt;p&gt;&lt;img src="http://www.ne.jp/asahi/nanto/moon/2009/06/30/deferred-chain-2.png" alt="[図 2: 上記コードが f 実行後に作る Deferred チェーン]"&gt;&lt;/p&gt;&#13;
&lt;p&gt;&lt;code&gt;h&lt;/code&gt; (を処理本体とする Deferred オブジェクト) は &lt;code&gt;f&lt;/code&gt; (を処理本体とする Deferred オブジェクト) の継続として実行されるわけではありませんが、&lt;code&gt;g&lt;/code&gt; (を処理本体とする Deferred オブジェクト) の継続として実行されるので、結局 &lt;code&gt;f&lt;/code&gt;、&lt;code&gt;g&lt;/code&gt;、&lt;code&gt;h&lt;/code&gt; の順番で処理が進むことになります。&lt;/p&gt;&#13;
&lt;p&gt;また、&lt;code&gt;f&lt;/code&gt; で待機状態の Deferred オブジェクトを返せば、処理の流れをいったん &lt;code&gt;f&lt;/code&gt; で止めておき、明示的にその Deferred オブジェクトの &lt;code&gt;call&lt;/code&gt; メソッドを呼び出したときに &lt;code&gt;h&lt;/code&gt; から処理の流れを再開するといったことができます。&lt;/p&gt;
</description>
<dc:subject>JavaScript</dc:subject>
<dc:subject>Web 関連技術</dc:subject>
</item>
<item>
<title>Web 開発者の責任 (翻訳)</title>
<link>http://nanto.asablo.jp/blog/2009/05/06/4289222</link>
<guid>http://nanto.asablo.jp/blog/2009/05/06/4289222</guid>
<pubDate>Wed, 06 May 2009 19:31:46 +0900</pubDate>
<dcterms:modified>2009-05-06T20:11:29+09:00</dcterms:modified>
<dcterms:created>2009-05-06T19:35:26+09:00</dcterms:created>
<description>&lt;p&gt;&lt;a href="http://ejohn.org/" hreflang="en"&gt;&lt;span lang="en"&gt;John Resig&lt;/span&gt; 氏&lt;/a&gt;による &lt;a href="http://ejohn.org/blog/a-web-developers-responsibility/" hreflang="en" lang="en"&gt;A Web Developer's Responsibility&lt;/a&gt; という記事が素晴しかったので、著者の許可を得てここに日本語訳を掲載します。&lt;/p&gt;&#13;
&#13;
&lt;hr&gt;&#13;
&#13;
&lt;p&gt;Web 開発者の最大の負担は、ブラウザのバグと非互換性への対応に膨大な時間を費やすことであるといって間違いないでしょう。それゆえに、それらへの対応に不満をいうのは、Web 開発者全員の常となっていました。ブラウザのバグは迷惑でいらだたしく、仕事を大幅に難しくします。&lt;/p&gt;&#13;
&lt;p&gt;ブラウザのバグはとてもいらだたしく、通常の開発における最大の負担です。ですから、開発対象のブラウザが、自身のバグを見つけ修正できるようにしてやるのは、すべての Web 開発者にとっての責任です。自分が見つけたバグに対して責任を持ち、「ほかの誰かがこれを見つけるだろう」とは思わないことで、ブラウザの進歩の速度は加速していくでしょう。&lt;/p&gt;&#13;
&lt;blockquote&gt;&#13;
&lt;p&gt;ブラウザを支援する解決策は 2 段階からなります。第 1 に、ブラウザのバグを見つけるたびに、個別のブラウザへ&lt;b&gt;バグ報告を登録しましょう&lt;/b&gt;。第 2 に、自分のサイトを主なブラウザの&lt;b&gt;最新のビルド&lt;/b&gt;で積極的にテストしましょう。&lt;/p&gt;&#13;
&lt;/blockquote&gt;&#13;
&lt;p&gt;Web 開発者の圧倒的多数は、一度もブラウザベンダにバグ報告を登録したことがないばかりか、ブラウザのナイトリー版を使ったことさえありません。これは恥じるべきことです。考えてみれば、ブラウザの何が異常かを評価するのに、ブラウザでの開発に日々を費やす人ほどその資格がある人というのはほとんどいないのです。&lt;/p&gt;&#13;
&lt;p&gt;ブラウザのバグを登録せず、ナイトリーでのテストもしないプロの開発者を見たとき、私は特に驚きました。ほとんどの開発者の主な仕事のひとつに、クロスブラウザの問題を取り繕うことがあります。よって、バグの数を減らす (そして仕事を劇的に単純化する) ことは最優先事項になります。&lt;/p&gt;&#13;
&lt;p&gt;私は個人的に全主要ブラウザベンダにバグ報告を登録してきて、良い報告を生み出すいくつかの特徴に気づきました。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;良いバグ報告の登録方法&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;良いバグ報告を生み出す 3 つのポイントは、分類、テストケース、そして単純化です。正しく分類され、単純化されたテストケースが提供されたバグは、どんなものでもブラウザの開発者によるレビューが保証されます。&lt;/p&gt;&#13;
&lt;p&gt;バグを登録する場所から始めましょう。&lt;/p&gt;&#13;
&lt;p&gt;&lt;b&gt;バグ報告を登録する&lt;/b&gt;&lt;/p&gt;&#13;
&lt;p&gt;大抵、バグ報告を登録するときは、実際の提出フォームへたどり着く前に、いくつかの深い層を通り抜けなければいけません。最も利用すべきフォームの直接の URL を以下に示します。&lt;/p&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="https://bugzilla.mozilla.org/enter_bug.cgi?product=Core"&gt;Mozilla/Firefox&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="https://bugs.webkit.org/enter_bug.cgi?product=WebKit"&gt;WebKit/Safari&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="https://connect.microsoft.com/IE/Feedback"&gt;Internet Explorer 8&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://code.google.com/p/chromium/issues/entry"&gt;Google Chrome&lt;/a&gt; / &lt;a href="http://code.google.com/p/v8/issues/entry"&gt;V8 JavaScript Engine&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="https://bugs.opera.com/wizard/"&gt;Opera&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;p&gt;バグを登録するときは、登録対象のブラウザの最新のナイトリー (後で説明します) でもテストしておきましょう。これは、ブラウザの開発者が最初に尋ねることのひとつです。もしそのブラウザの現在の開発版でも依然としてバグが存在し、いまだ修正されていないことを示せたのなら、ブラウザの開発者たちはずっと簡単に取り組み始められるでしょう。&lt;/p&gt;&#13;
&lt;p&gt;&lt;b&gt;注:&lt;/b&gt; 多くのバグ報告ページは、報告を提出する前にアカウントの作成を求めてきます。これは迷惑ですが負担は 1 回きりです。&lt;/p&gt;&#13;
&#13;
&lt;h4&gt;バグを分類する&lt;/h4&gt;&#13;
&lt;p&gt;バグを適切に分類することは重要な第一歩です。しばしば、(レイアウトや DOM といった) 特定のモジュールのオーナーは、新しく来た提出をすべて監視しています。バグを適切な分類に割り当てることは、そのバグを修正するのにもっとも適した人物の眼前へ、直ちにバグを持ち込むことになります。&lt;/p&gt;&#13;
&lt;p&gt;バグの分類はブラウザ次第です。(Opera や Internet Explorer のような) いくつかのブラウザがバグの登録に簡易的な分類を用意している一方で、他のブラウザ (WebKit/Safari や Mozilla/Firefox) は機能が存在する特定のモジュールを示すために複雑な分類を使います。&lt;/p&gt;&#13;
&lt;p&gt;&lt;b&gt;Mozilla/Firefox:&lt;/b&gt; コンポーネントを選択してください。最も一般的なのは DOM、Layout、JavaScript Engine などです。&lt;/p&gt;&#13;
&lt;p&gt;&lt;b&gt;WebKit/Safari:&lt;/b&gt; コンポーネントを選択してください。最も一般的なのは HTML DOM、Layout and Rendering、JavaScriptCore などです。&lt;/p&gt;&#13;
&lt;p&gt;&lt;b&gt;Google Chrome:&lt;/b&gt; Chrome に対して登録すべきか判断するのには注意が必要です。最初に Safari の最新リリースと最新の WebKit ナイトリーとの両方でバグをテストしてください。もしバグが Chrome のみに存在するのならそこに登録し、そうでなければ WebKit/Safari にバグを登録しましょう。しかし、もうひとつ問題があります。Chrome の JavaScript エンジン (V8) にのみ存在するバグは、(どさくさにまぎれて行方不明にならないよう) Chrome ではなく V8 のバグトラッカーに登録されるべきです。&lt;/p&gt;&#13;
&lt;p&gt;また、Chrome は明示的な分類手段を提供していません。すべてのバグは開発者によりレビューされ、それから分類されます (このプロセスを制御することはできません)。&lt;/p&gt;&#13;
&lt;p&gt;複数のプラットフォーム (OS X と Windows、Windows と Linux など) でのテストも手早く行うべきです。バグが複数のプラットフォームに存在することを特定すれば、ブラウザの開発者がバグの原因の発見に必要とする時間を削減するのに劇的に役立ちます。&lt;/p&gt;&#13;
&#13;
&lt;h4&gt;テストケースを提供する&lt;/h4&gt;&#13;
&lt;p&gt;再現可能なテストケースは、どんな形式であれ何もないよりは優れています。問題が封入された Web ページは一般的に良い取っ掛かりとなります。もし Web ページをバグ報告に直接添付できるのなら、さらに良いでしょう (ブラウザの開発者がそのチケットに取り組むのには、しばらく時間がかかるかもしれません。指定された URL にテストケースがもはや存在しなければ、開発者は単にチケットを閉じてほかの作業へ移るでしょう)。&lt;/p&gt;&#13;
&lt;p&gt;そうはいっても、悪いテストケースというべきものもあります。最悪なのは「http://example.com の Web サイトを見たら、ブラウザ X では動かなかったので、修正してください」といった類のものです。これは、失敗の正確な理由を見つけだすため、誰かに膨大な時間をとらせることになり、バグをキューのより後ろへと押し出すでしょう。&lt;/p&gt;&#13;
&lt;p&gt;最良のテストケースは単純さを提供する類のものです。&lt;/p&gt;&#13;
&lt;h4&gt;単純さを提供する&lt;/h4&gt;&#13;
&lt;p&gt;単純なテストケースを提供することは、間違いなくバグ報告を作成する上で一番難しく、かついらだつ部分です。しかしこれは、大概報告に気づき修正してもらう上での重点でもあります。最も資質のある開発者でさえ、十分良いテストケースを作成するのに 30 分もかからないでしょう。&lt;/p&gt;&#13;
&lt;p&gt;このようなテストケースを作成する手順は単純です。バグがあるページを持ってきて、バグの再現に影響しないものをすべて切り取ってしまうのです。これは、スタイルシート、画像、JavaScript ファイル、JavaScript ライブラリ、そして HTML を含みます。&lt;/p&gt;&#13;
&lt;p&gt;たとえば、しばらく前に私が &lt;a href="http://dromaeo.com/"&gt;Dromaeo&lt;/a&gt; テストスイートを走らせていたとき、WebKit がある地点に到達すると常にクラッシュすることに気づきました。私はまず、不必要な HTML、CSS、画像などテストを切り取ることから始めました。最終的に私は単独のテストにたどり着きました。文字列の分割です。それから私は、外部依存が必要なくなるように、可能な限りテストスイートを剥ぎ取っていきました。&lt;/p&gt;&#13;
&lt;p&gt;&lt;a href="https://bugs.webkit.org/show_bug.cgi?id=17047"&gt;最終結果&lt;/a&gt;に注目してください:&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;var str = "", ret, fn = [];&#13;
&#13;
for ( var i = 0; i &amp;lt; 16384; i++ )&#13;
  str += "a";&#13;
&#13;
for ( var i = 16384; i &amp;lt;= 131072; i *= 2 ) (function(i){&#13;
  fn.push(function(){&#13;
    ret = str.split("");&#13;
  });&#13;
&#13;
  str += str;&#13;
})();&#13;
&#13;
window.onload = function(){&#13;
  setInterval(function(){&#13;
    if ( fn.length )&#13;
      fn.shift()();&#13;
  }, 13);&#13;
};&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;残ったものは、依然としてクラッシュを起こすにもかかわらず、これ以上ないほど単純です。この単純化に基づいてこの問題の理由は&lt;a href="https://bugs.webkit.org/show_bug.cgi?id=17047"&gt;すばやく特定され&lt;/a&gt;、たった 2 週間後には解決されていました。&lt;/p&gt;&#13;
&#13;
&lt;h4&gt;私のバグに取り組んでいますか?&lt;/h4&gt;&#13;
&lt;p&gt;これは興味深い点です。しかし、Mozilla/Firefox、WebKit/Safari、Chrome では (これらはすべて比較的開かれたプロジェクトなので) 判断しやすい点です。これら各ブラウザでバグの状態を判断する最良の方法を以下に示します。&lt;/p&gt;&#13;
&lt;p&gt;&lt;b&gt;Mozilla/Firefox:&lt;/b&gt; バグは、最初に選択したコンポーネント分類のデフォルトの窓口係に割り当てられるところから始まります。これはまだ何も意味せず、単純に人々の目をチケットにひきつけるだけです。人々はそのチケットに自分自身を CC し始めます (これはその人がそのバグの進行に興味を持つという意味です)。しかしながら、決定的な瞬間は、誰かがそのバグを自分自身に割り当てたときで、事実上その人がそのバグの状態に責任を持ち始めます。ほとんどの貢献者はそのバグにつけられるコメントが自動的にメールされるよう設定しているので、そのバグの状態に関して何かしら疑問があれば、遠慮せずコメントを投稿できます。しかし、そういったことは適度なペースで行ってください (日ごとに、あるいは週ごとにでさえ、更新状況を尋ねることは貢献者をいらだたせるでしょう)。&lt;/p&gt;&#13;
&lt;p&gt;&lt;b&gt;WebKit/Safari:&lt;/b&gt; WebKit は Mozilla/Firefox ととてもよく似た設定を使います。そのバグを管理し完了まで後押ししてくれる誰かをただ受け入れましょう。しかしながら、黄金のチケットはそのバグが「&lt;a href="http://www.cocoabuilder.com/archive/message/cocoa/2005/5/13/135738"&gt;rdar&lt;/a&gt; へ行く」時です。Radar は Apple の内部的な (非公開の) バグトラッカーです。バグがそこへ移動したということは、事実上 (そのバグを「所有する」人によってでなくても、別の Apple の従業員によって) そのバグのある時点での完了が保証されるということです。Apple は依然として WebKit の更新の裏での大きな立役者なので、バグが rdar に移されるのは期待すべきことです。とはいっても、rdar は非公開で Apple の従業員向けなので、バグが完全に修正されるか、またそれはいつかを知るという恩恵はもはや得られません。そうなれば後は待つのみです。&lt;/p&gt;&#13;
&lt;p&gt;&lt;b&gt;Chrome:&lt;/b&gt; Chrome は Mozilla/Firefox ととてもよく似たシステムを使います。そのバグが現在割り当てられている人とのコミュニケーションを持続し、彼らが持つだろう質問には何でも答えるようにしましょう。&lt;/p&gt;&#13;
&lt;p&gt;最終的にバグが解決されたのなら、おめでとうございます! あなたは Web を万人にとってよりよい場所にするのに役立てたのです。&lt;/p&gt;&#13;
&lt;p&gt;しかし、いつもそうなるとは限りません。&lt;/p&gt;&#13;
&#13;
&lt;h4&gt;私のバグが却下されたらどうなりますか?&lt;/h4&gt;&#13;
&lt;p&gt;却下されたバグは次の 2 通りに分類されます:&lt;/p&gt;&#13;
&lt;ol&gt;&#13;
&lt;li&gt;バグではなかったので却下された。&lt;/li&gt;&#13;
&lt;li&gt;ブラウザベンダがそのバグに取り組みたくないので却下された。&lt;/li&gt;&#13;
&lt;/ol&gt;&#13;
&lt;p&gt;1 番目はさらに 2 つの小分類に分けられます。&lt;/p&gt;&#13;
&lt;p&gt;本当にバグでなかったのなら、おめでとうございます! 標準、あるいはそれ以外のブラウザのあいまいさに関する、今まで詳しくは知らなかったことを学べました。今やあなたはよりよい Web 開発者です! ブログへ向かい、発見したあいまいな新しいバグや API に関して書き、それを世界に向けて説明すべきです。&lt;/p&gt;&#13;
&lt;p&gt;または、バグなのに所有者が不必要にバグを閉じてしまいました。こうなると、バグを再開するために、この状況について議論する必要があります。&lt;/p&gt;&#13;
&lt;p&gt;2 番目 (ベンダーがバグに取り組みたくない場合) もまた 2 通りに処理されます。&lt;/p&gt;&#13;
&lt;p&gt;第 1 に、バグの状況について議論しましょう。これはブラウザの開発者に、この問題を修正するために貴重なリソースをささげるべきという情報を与えるのに役立ちます。&lt;/p&gt;&#13;
&lt;p&gt;または第 2 に、もし彼らが本当にそのバグの修正を嫌がっているのなら、ブログや Twitter アカウント、それに他の Web 開発者があなたの言うことを聞いている場所で厳しく叱責しましょう。もしあなたの立場に同意してくれる人を誰も見つけられなかったのなら、おそらくあなたがおかしいです。しかし、もしそれが、ブラウザベンダが修正を拒んではいるが正当な問題だったのなら、結束しおおっぴらに苦情を申し立てられるほかの人が簡単に見つかるはずです。まさにこれでいいのです。あなたはこの結果を正しく獲得しました。このバグを明るみに出すのに必要なすべての正当な努力をすることにより、すべての宣言でこれに関して不満を言うのに十分な特権を得るのです。&lt;/p&gt;&#13;
&#13;
&lt;h4&gt;バグを議論する&lt;/h4&gt;&#13;
&lt;p&gt;ここで、あなたはバグが閉じられた時点にいるものとします。このとき、閉じた人にそれは間違いだ、すなわち、このバグは実際に正真正銘のバグである、と納得させる必要があります。&lt;/p&gt;&#13;
&lt;p&gt;こうしたときに使える最良の論拠のいくつかを、使うべき順番に沿って以下に示します:&lt;/p&gt;&#13;
&lt;ol&gt;&#13;
&lt;li&gt;そのバグが退行であることを示しましょう。それが以前のリリースでは動いており、変更のせいで動かなくなったことを証明しましょう。#2 と併用するととても効果的です。&lt;/li&gt;&#13;
&lt;li&gt;実在の Web サイトが壊れていることを示しましょう。もし実際の利用者が、ポーランドの X 銀行やカナダの Y ショッピングサイトをもはや訪れようとしないことを示せれば、ブラウザはその問題を修正するためにあっさり全力を尽くすでしょう (Opera でない限り。その場合 Opera 側はサイトを強制的に動かすために &lt;a href="http://www.opera.com/docs/browserjs/"&gt;browser.js&lt;/a&gt; を使うかもしれません。しかし、それはまた別の話です)。&lt;/li&gt;&#13;
&lt;li&gt;そのバグが修正されないことで破られている Web 標準を示しましょう。もしある特定のバグが修正されないことが原因で、W3C DOM 仕様が正しく実装されていないことを示せたなら、ブラウザベンダはそれを修正しなければいけないと感じるでしょう。もしそう感じないなら、これは格好のブログの題材となるでしょう。&lt;/li&gt;&#13;
&lt;li&gt;そのバグを修正しないことで他のブラウザとの互換性が失われることを示しましょう。もし IE と Safari、Opera のすべてがある特定の機能を実装するか、ある特定のバグを修正したなら、Firefox は (それが仕様と矛盾しない限り) 他の実装に従わなければならないでしょう。これは最も議論しづらいことです。しかし、より多くのブラウザが同行していればいるほど、話はより簡単になります。&lt;/li&gt;&#13;
&lt;/ol&gt;&#13;
&lt;p&gt;もしこれらの段階のいずれも証明できなかったなら、何にせよあなたはただ自分の痒いところを掻いているだけであり、そのバグはほうっておくべきです。&lt;/p&gt;&#13;
&#13;
&lt;h4&gt;例&lt;/h4&gt;&#13;
&lt;p&gt;私が異なるブラウザベンダに登録したバグの代表例をいくつか見せたいと思います。&lt;/p&gt;&#13;
&lt;p&gt;&lt;b&gt;WebKit/Safari&lt;/b&gt;&lt;/p&gt;&#13;
&lt;p&gt;&lt;a href="https://bugs.webkit.org/show_bug.cgi?id=17954"&gt;半径 0 の canvas の arc() が例外を投げる&lt;/a&gt;: canvas の arc() メソッドの呼び出しが例外を投げていました。私はとても単純なテストケースを提供し、仕様のうち WebKit が一致していない部分を指し示しました。これは投稿されたのと同じ日に解決されました。&lt;/p&gt;&#13;
&lt;p&gt;&lt;a href="https://bugs.webkit.org/show_bug.cgi?id=17047"&gt;多数の生きたオブジェクトに起因する .split("") でのメモリ不足エラー&lt;/a&gt;: ホストされた Web ページを単純簡潔にしたものを提供し、約 3 週間後に修正されました。&lt;/p&gt;&#13;
&lt;p&gt;&lt;b&gt;Mozilla/Firefox&lt;/b&gt;&lt;/p&gt;&#13;
&lt;p&gt;&lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=403977"&gt;Array.prototype.sort の大幅な速度低下&lt;/a&gt;: 単純簡潔な退行を示しました。正確な問題を突き止めるのにとても役立つ大量の Shark プロファイルデータをバグに含めました。これは 1 ヶ月以内に修正されました。&lt;/p&gt;&#13;
&lt;p&gt;&lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=418183"&gt;.children を実装すべき&lt;/a&gt;: Mozilla が (他の主要なブラウザすべてに存在する) .children メソッドを実装する必要があるか議論しました。十分な議論から、最終的 (約 6 ヵ月後) にそれを含めることになりました。&lt;/p&gt;&#13;
&lt;p&gt;&lt;b&gt;Internet Explorer 8&lt;/b&gt;&lt;/p&gt;&#13;
&lt;p&gt;&lt;a href="http://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=388477"&gt;querySelectorAll の NodeList の例外&lt;/a&gt;: 単純なテストケースを提供し、「時間不足」のため却下されました。&lt;/p&gt;&#13;
&lt;blockquote&gt;&#13;
&lt;p&gt;現時点で私たちはこの問題を修正するつもりはありません。報告を理解してはいますが、残念ながら私たちは、顧客と Web 開発者に対する価値を最大化するために、何の作業をするか選択する必要がある段階にいるのです。&lt;/p&gt;&#13;
&lt;/blockquote&gt;&#13;
&lt;p&gt;つまり、彼らはそれが問題であるということに同意しながら、修正するつもりはないのです。ですので、私は今それについて不満を訴えています。&lt;/p&gt;&#13;
&lt;p&gt;&lt;a href="https://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=336232"&gt;HTMLElement.prototype.querySelectorAll が存在しない&lt;/a&gt;: 後でわかりましたが、これは querySelectorAll が標準準拠のページにのみ存在する (互換モードには存在しない) ことが原因でした。これはまったく奇妙なことですが、私はその決定の背後にある論拠を理解したと思います。いずれはっきりしますが、一度 IE 8 が動き始めれば、これが多くの人々を困惑させるのではないかと私は思っています。私は今や IE 8 についてより多くのことを知っており、IE 8 に対するより良い開発者です。&lt;/p&gt;&#13;
&lt;p&gt;&lt;b&gt;Google Chrome&lt;/b&gt;&lt;/p&gt;&#13;
&lt;p&gt;&lt;a href="http://code.google.com/p/chromium/issues/detail?id=883"&gt;for in ループが定義された順序で発生しない&lt;/a&gt;: これは互換性の問題でした (他のすべてのブラウザは特定のやり方で振舞います)。私は単純なテストケースを提供しました。このバグは誤って WontFix として閉じられましたが (これは混乱を招きました)、実際には修正されました。私はここで間違いを犯し、V8 に対して登録すべきこのバグを、実際は Chrome に対して登録してしまいました。V8 側でこの問題を扱う&lt;a href="http://code.google.com/p/v8/issues/detail?id=6"&gt;バグ&lt;/a&gt;をここに示します。&lt;/p&gt;&#13;
&lt;p&gt;&lt;a href="http://code.google.com/p/chromium/issues/detail?id=888"&gt;setTimeout(..., 0) の発火が早すぎる&lt;/a&gt;: これは実際には Chrome チームによる構造の変更に起因するものでした。Mike Belshe (その変更の作者) が何が起きたのかを説明するために私へ個人的にメールを送ってきました。結果として私はより情報を得て、&lt;a href="http://ejohn.org/blog/javascript-in-chrome/"&gt;そのことに関するブログを書きました&lt;/a&gt;。&lt;/p&gt;&#13;
&lt;p&gt;&lt;b&gt;Opera&lt;/b&gt;&lt;/p&gt;&#13;
&lt;p&gt;(私の知る限り、Opera はバグ報告に対する公式の公開された場を提供していません。)&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;ナイトリービルドのテスト方法&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;ブラウザのナイトリービルドでのテストの詳細に入る前に、私はおそらく最も一般的な質問に答えるべきでしょう。&lt;b&gt;なぜブラウザのナイトリービルドをテストすることに気を遣うべきなのですか?&lt;/b&gt; それには 2 つの理由があります。&lt;/p&gt;&#13;
&lt;p&gt;第 1 に、バグ報告を登録するときは、提出しようとするバグが既に修正されているかどうかを判別する必要があるでしょう。もしそれがナイトリーで既に修正されていたなら、それを提出するか悩む必要はありません。そのバグは次のリリースで修正されるでしょう。しかしながら、もしそのバグが解決されていなかったら、バグの登録を続けるべきです。&lt;/p&gt;&#13;
&lt;p&gt;第 2 に、ブラウザがリリースされたときにあなたのコードが壊れていないか確かめるために、そのブラウザの最新のナイトリーであなたのサイトまたはライブラリを定期的にテストすべきです。どれくらいの頻度でテストするかはあなたしだいです。しかし、より頻繁にテストすればするほど、あなたのサイトまたはライブラリが、ある時点で大規模な退行に遭遇する可能性は低くなります。自分たちのサイトを壊す新バージョンのブラウザがマーケットに存在することを見つけて喜ぶ開発者はいないといって間違いないと思います。&lt;/p&gt;&#13;
&lt;p&gt;ナイトリーに対するバグの登録は、他のバグの登録と同じです。単純化されたテストケースを提供し、退行が起きたことを強調するようにしましょう。もしあなたが十分な頻度でテストしていれば、開発者は行動に取り掛かるに違いないでしょう。&lt;/p&gt;&#13;
&#13;
&lt;h4&gt;最新のナイトリーを入手する&lt;/h4&gt;&#13;
&lt;p&gt;ブラウザベンダはブラウザの最新版を入手するためのさまざまな方法を提供しています。その上、いくつかのブラウザは他のものよりも頻繁にリリースしています (たとえば、Chrome は 1 日に何回も、Firefox は 1 日に 1 回、Opera は 2 週間かそこらに 1 回更新します)。&lt;/p&gt;&#13;
&lt;p&gt;&lt;b&gt;Mozilla/Firefox&lt;/b&gt;&lt;/p&gt;&#13;
&lt;p&gt;Mozilla は Firefox のナイトリーリリースを提供しています。これは、&lt;a href="http://ejohn.org/blog/sexy-firefox-3/"&gt;Firefox のプロファイル&lt;/a&gt;を使って Firefox の既存のコピーと同時にインストールし使えます。一度ナイトリーリリースをダウンロードすれば、毎日自動的に更新されるでしょう。&lt;/p&gt;&#13;
&lt;p&gt;ダウンロード: &lt;a href="http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/latest-trunk/"&gt;Firefox ナイトリーリリース&lt;/a&gt;&lt;/p&gt;&#13;
&lt;p&gt;&lt;b&gt;WebKit/Safari&lt;/b&gt;&lt;/p&gt;&#13;
&lt;p&gt;WebKit ナイトリーを OS X でインストールするのは簡単です。これはプロファイルの詳細なしに完全に並行して存在できます。しかしながら、これらは自動的には更新されません。私は WebKit ナイトリーが (OS X で) 確実に最新であり続けるよう、&lt;a href="http://web.mac.com/reinholdpenner/Software/NightShift.html"&gt;NightShift&lt;/a&gt; を使っています。&lt;/p&gt;&#13;
&lt;p&gt;Windows でナイトリーをインストールすることはより面倒ですが (いくつかのスクリプトの実行とファイルのコピーを伴います)、動きはします。&lt;/p&gt;&#13;
&lt;p&gt;ダウンロード: &lt;a href="http://nightly.webkit.org/"&gt;WebKit/Safari ナイトリーリリース&lt;/a&gt;&lt;/p&gt;&#13;
&lt;p&gt;&lt;b&gt;Internet Explorer&lt;/b&gt;&lt;/p&gt;&#13;
&lt;p&gt;Internet Explorer のインストールは「一大事」です。それは以前にインストールされたブラウザのコピーを完全に吹き飛ばしてしまいます。このため、あなたのシステムにインストールされた Internet Explorer の複数のコピーを保持するために、いくつかのトリックを使うべきでしょう。IE 6 (とそれより古いもの) を扱える&lt;a href="http://tredosoft.com/Multiple_IE"&gt;インストーラ&lt;/a&gt;や、IE 7 を考慮に入れた&lt;a href="http://tredosoft.com/IE7_standalone"&gt;別のもの&lt;/a&gt;があります。一度これらのスタンドアローン版をすべてインストールすれば、安心して IE 8 をダウンロードしインストールできます。&lt;/p&gt;&#13;
&lt;p&gt;IE 8 は各ベータリリースから自動的に更新されていましたが、もうそうしてはいないようです。もし &lt;a href="https://connect.microsoft.com/IE"&gt;Micirosoft IE Beta Connect&lt;/a&gt; プログラムにサインアップすれば、テスト用の最近のビルドを入手できます。重ねて言いますが、これらすべてのビルドは現在の古い版を上書きします。&lt;/p&gt;&#13;
&lt;p&gt;ダウンロード: &lt;a href="http://www.microsoft.com/windows/Internet-explorer/beta/default.aspx"&gt;IE 8 ベータ&lt;/a&gt;、&lt;a href="https://connect.microsoft.com/IE/Downloads"&gt;IE 8 ウィークリービルド&lt;/a&gt;&lt;/p&gt;&#13;
&lt;p&gt;&lt;b&gt;Google Chrome&lt;/b&gt;&lt;/p&gt;&#13;
&lt;p&gt;Google は 1 日に複数のビルド (各リビジョンにつきひとつ) を提供しています。これらのビルドはお互いに並行して存在できますが、自動的には更新されません。一人のユーザーがそのために使える&lt;a href="http://dirhael.dcmembers.com/cnu/"&gt;自動更新&lt;/a&gt;アプリケーションをビルドしました。&lt;/p&gt;&#13;
&lt;p&gt;ダウンロード: &lt;a href="http://build.chromium.org/buildbot/snapshots/chromium-rel-xp/"&gt;Google Chrome ナイトリービルド&lt;/a&gt;&lt;/p&gt;&#13;
&lt;p&gt;&lt;b&gt;Opera&lt;/b&gt;&lt;/p&gt;&#13;
&lt;p&gt;Opera の複数のバージョンは並行してインストールでき、自動的に更新されます。Opera はナイトリービルドを提供していませんが (2 週間かそこらに 1 回出ます)、比較的最近のブラウザの実例を供給するでしょう。&lt;/p&gt;&#13;
&lt;p&gt;ダウンロード: &lt;a href="http://my.opera.com/desktopteam/blog/"&gt;Opera デスクトップチームブログ&lt;/a&gt; (ビルドはここに投稿されます)&lt;/p&gt;&#13;
&#13;
&lt;hr&gt;&#13;
&#13;
&lt;p&gt;Web 開発の今後に積極的な役割を担うことの重要性は、決して誇張ではありません。他の開発者が先にバグを登録してくれることを期待する、あるいはブラウザベンダがすべての退行の可能性に気づくことを期待するという受身の立場から、積極的に熱心でいることへの移行は、信じられないほど多くの力をあなたにもたらします。Web コミュニティとブラウザの間のコミュニケーションを改善するためにあなたがする最小限の作業は、Web 全体の質を改善するのに大きく役立ちます。&lt;/p&gt;&#13;
&lt;p&gt;あなたのおかげで修正されたすべてのバグを、名誉の印として身に着けるべきです。あなたは、Web をよりよい場所にするための役割を果たしたのです。&lt;/p&gt;&#13;
&#13;
&lt;hr&gt;&#13;
&#13;
&lt;p&gt;訳文は以上です。&lt;/p&gt;&#13;
&lt;p&gt;バグ報告は基本的に英語で行いますが、個人的な経験からいうと、テストケースがしっかりしていれば英語が適当でもわかってくれます。英語を書くのは慣れていなくてもコードを書くのは慣れているでしょうから、それを通せばいいのです。&lt;/p&gt;&#13;
&lt;p&gt;なお、Firefox に関しては、日本語でバグ登録ができる場として &lt;a href="http://bugzilla.mozilla.gr.jp/"&gt;Bugzilla-jp&lt;/a&gt; が存在し、その案内として&lt;a href="https://developer.mozilla.org/ja/Bugzilla-jp/Guide"&gt;はじめてのバグジラ&lt;/a&gt;があります。&lt;a href="http://jp.opera.com/support/bugs/"&gt;Opera へのバグ報告&lt;/a&gt;や IE へのフィードバックも日本語のものを受け付けてくれるようです。&lt;/p&gt;
</description>
<dc:subject>Web 関連技術</dc:subject>
</item>
<item>
<title>Kanasan.JS JavaScript 第 5 版読書会 #7</title>
<link>http://nanto.asablo.jp/blog/2009/04/28/4272284</link>
<guid>http://nanto.asablo.jp/blog/2009/04/28/4272284</guid>
<pubDate>Tue, 28 Apr 2009 00:36:25 +0900</pubDate>
<dcterms:modified>2009-04-28T00:39:34+09:00</dcterms:modified>
<dcterms:created>2009-04-28T00:39:34+09:00</dcterms:created>
<description>&lt;p&gt;&lt;a href="http://sites.google.com/site/kanasanjs/about/javascript-di5ban-du-shu-hui/part7"&gt;Kanasan.JS JavaScript 第 5 版読書会 #7&lt;/a&gt; に行ってきました (&lt;a href="http://www.lingr.com/room/Kanasan.JS/archives/2009/04/12" title="Kanasan.JS : JavaScript Workshop in Kansai (at Lingr) &gt; Archives &gt; April 12, 2009"&gt;当日のチャットログ&lt;/a&gt;)。範囲は前回に引き続き CSS の操作、そしてイベント周りと、一般に「JavaScript」といったとき話題になりやすい部分です。参加者のブログ記事は「&lt;a href="http://blog.37to.net/2009/04/javascriptcss_from_k/"&gt;JavaScriptでCSSとイベントを扱う from Kanasan.JS | Blog.37to.net&lt;/a&gt;」のほか&lt;a href="http://sites.google.com/site/kanasanjs/about/javascript-di5ban-du-shu-hui" title="JavaScript第５版読書会 ( Kanasan.JS : JavaScript Workshop in Kansai)"&gt;読書会のページ&lt;/a&gt;からたどれます。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;&lt;code&gt;display: inline-block;&lt;/code&gt;&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;サイ本では解説されていませんが、CSS の display プロパティの値 inline-block に関して話が盛り上がりました。inline-block 及びそれがどのようなレイアウトに使えるかについては以下で解説されています。&lt;/p&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://www.yomotsu.net/works/081016cssnite/"&gt;書籍などに紹介されていない display : inline-block について (ヨモツネット)&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://gyauza.egoism.jp/clip/archives/2008/10/081016-inline-block/"&gt;inline-blockはもう使える（だいたい） | Takazudo Clipping*&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;p&gt;ところで、上記ページのサンプルはいずれも Firefox 2 以下で -moz-inline-box を使っています。しかし、-moz-inline-box が指定された要素の子要素は &lt;a href="https://developer.mozilla.org/ja/XUL_Tutorial#The_Box_Model"&gt;XUL のボックスモデル&lt;/a&gt;に従って整形されるため、そのままでは期待した表示になりません。ヨモツネットのサンプルではこの問題への対策として子要素に幅を指定していますが、別のアプローチとして子要素に &lt;a href="https://developer.mozilla.org/en/CSS/-moz-box-flex" hreflang="en"&gt;-moz-box-flex プロパティ&lt;/a&gt;を指定するという方法もあります。実際に&lt;a href="http://www.ne.jp/asahi/nanto/moon/2009/04/28/inline-block.html" title="display: inline-block; を用いたページ送りのレイアウトのサンプル"&gt;この方法を用いたページ送りのサンプル&lt;/a&gt;を作ってみました。HTML と CSS は次のようになります。&lt;/p&gt;&#13;
&lt;pre&gt;&lt;code&gt;&amp;lt;ul&amp;gt;&#13;
  &amp;lt;li&amp;gt;&amp;lt;a href="http://example.org/"&amp;gt;1&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&#13;
  &amp;lt;li&amp;gt;&amp;lt;a href="http://example.org/"&amp;gt;10&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&#13;
  &amp;lt;li&amp;gt;&amp;lt;a href="http://example.org/"&amp;gt;100&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&#13;
  &amp;lt;li&amp;gt;&amp;lt;a href="http://example.org/"&amp;gt;1000000000000&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&#13;
&amp;lt;/ul&amp;gt;&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;pre&gt;&lt;code&gt;/* デフォルトのマージン、パディングが影響しないように。 */&#13;
ul, li {&#13;
  margin: 0;&#13;
  padding: 0;&#13;
}&#13;
&#13;
ul {&#13;
  text-align: center;&#13;
}&#13;
&#13;
li {&#13;
  display: -moz-inline-box; /* Firefox 2 以下用。 */&#13;
  display: inline-block;&#13;
  /* 内容の幅が大きいとき自動的に自分の幅も広がるよう、width ではなく&#13;
   * min-width を用いる。Firefox 2 以下では -moz-inline-box な要素の&#13;
   * min-width がボーダーボックスの最小幅として解釈されてしまうが、&#13;
   * ここではボーダー、パディングの幅が 0 なので影響しない。&#13;
   */&#13;
  min-width: 3em;&#13;
}&#13;
/* IE 6/7 では、デフォルトで inline でない要素は inline-block を&#13;
 * 指定した後、さらに inline を指定しないと inline-block 表示にならない。&#13;
 * margin をつけるのは inline-block 間の空白文字が表示されないため。&#13;
 */&#13;
* + html li {&#13;
  display: inline;&#13;
  margin: 0 0.2em;&#13;
}&#13;
* html li {&#13;
  display: inline;&#13;
  width: 3em; /* IE 6 は min-width 非対応だが width で代用可。 */&#13;
  margin: 0 0.2em;&#13;
}&#13;
&#13;
li a {&#13;
  display: block;&#13;
  border: 0.1em solid;&#13;
  /* Firefox 2 以下でマージンボックスの幅が包含ブロック (この場合は&#13;
   * -moz-inline-box な要素の内容ボックス) の幅いっぱいに広がるように。&#13;
   */&#13;
  -moz-box-flex: 1;&#13;
}&#13;
/* IE 6 でボーダーボックス全体がリンクとして機能するように。 */&#13;
* html li a {&#13;
  height: 0;&#13;
}&lt;/code&gt;&lt;/pre&gt;&#13;
&lt;p&gt;この方法の利点として、-moz-inline-box な要素の幅が % 単位で指定されていても内容の幅がそれに追従してくれるといったことが挙げられます。&lt;/p&gt;&#13;
&lt;p&gt;ちなみに、IE 7 以下での inline-block 表示に &lt;code&gt;display: inline; zoom: 1;&lt;/code&gt; を用いず、いったん inline-block を指定して別の規則で inline を指定していたり、ひとつの規則内に &lt;code&gt;_width: 3em; /margin: 0 0.2em;&lt;/code&gt; とまとめて書くのではなく、&lt;code&gt;* + html ... { margin: ...; } * html ... { width: ...; margin: ...; }&lt;/code&gt; と IE 用の規則に分けて書いていたりするのは、できるだけ CSS の書式に則りたいという個人的な趣味によるものです。&lt;/p&gt;&#13;
&lt;p&gt;MacIE 5 にも対応しようとすれば IE 6/7 向けの指定を &lt;code&gt;/*\*/ ～ /**/&lt;/code&gt; で囲む必要があるのかもしれませんが、確認できる環境がないのでそこまではしていません。Firefox 2 もすでにサポート期限が切れているので、最低限リンクが機能すればレイアウトが期待通りでなくてもかまわないという姿勢もありでしょう。&lt;/p&gt;&#13;
&lt;p&gt;この例では -moz-inline-box な要素の子要素がブロック要素だったので子要素に -moz-box-flex を指定しましたが、Takazudo Clipping* のサンプルのように -moz-inline-box な要素の内容がテキストノードだったりインライン要素だったりした場合には、-moz-inline-box な要素に &lt;code&gt;&lt;a href="https://developer.mozilla.org/en/CSS/-moz-box-pack" hreflang="en"&gt;-moz-box-pack&lt;/a&gt;: center;&lt;/code&gt; を指定することで内容を中央ぞろえにできます。&lt;/p&gt;&#13;
&lt;p&gt;このように、inline-block 表示はちょっと無理をすれば大抵のブラウザで可能ですが、別に無理をしなくてもいいときもあります。ページ送りに関していえば、各項目の幅をそろえなくてもいい (「1」の項目と「10」の項目の幅が異なってもいい)、かつ項目内で行の折り返しが発生してもいい (または内容が数字だけなので折り返しが発生しない) というのなら、そもそも inline-block を使う必要がありません。(IE 6 での不具合を避けるために inline-block を指定することはあるかもしれませんが。)&lt;/p&gt;&#13;
&lt;p&gt;なお、&lt;code&gt;zoom: 1;&lt;/code&gt; という指定はいわゆる CSS ハックの一環として用いられることが多いですが、このときそのまま &lt;code&gt;zoom: 1;&lt;/code&gt; と書いてはいけません。&lt;code&gt;/zoom: 1&lt;/code&gt;、&lt;code&gt;_zoom: 1&lt;/code&gt;、&lt;code&gt;* html ... { zoom: 1; }&lt;/code&gt; など、必ず IE のみに適用されるような書き方をしましょう。これは、&lt;a href="http://trac.webkit.org/changeset/31155" hreflang="en"&gt;WebKit も zoom プロパティをサポート&lt;/a&gt;しており、そうしたハックを必要としないブラウザに想定外の影響を与えるのを防ぐためです。もちろん、実際にズーム効果を求めて zoom プロパティを使用する場合はこの限りではありません。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;rect 関数の書式&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;CSS の clip プロパティに rect 関数を指定することで、絶対配置の要素の一部だけ切り抜いて表示できます。rect 関数の引数には切り抜く矩形の各辺の位置を示す値を指定しますが、各引数の区切り文字には注意が必要です。&lt;a href="http://www.w3.org/TR/2008/REC-CSS2-20080411/visufx.html#value-def-shape" hreflang="en"&gt;CSS 2 だと、本文中ではスペース区切りなのにサンプルではコンマ区切り&lt;/a&gt;になっています。&lt;a href="http://www.w3.org/TR/2009/CR-CSS2-20090423/visufx.html#value-def-shape" hreflang="en"&gt;CSS 2.1 だと本文もコンマ区切り&lt;/a&gt;に統一され、製作者はコンマ区切りを使うべきであり、ユーザーエージェントはコンマ区切りをサポートしなければならないが、同時にスペース区切りをサポートしても良いということになっています。実際は IE 7 以下がスペース区切りしか受け付けてくれないので、スペース区切りを使うことになるでしょう。&lt;/p&gt;&#13;
&lt;p&gt;このほかにも clip プロパティと rect 関数の挙動は CSS 2 と CSS 2.1 とで大きく変化しており、「&lt;a href="http://w3g.jp/css/display_position/clip"&gt;clip CSS 表示と配置 (World Wide Web Guide)&lt;/a&gt;」に詳しくまとめられています。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;getComputedStyle と currentStyle の違い&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;ある要素の実際の CSS プロパティの値を調べるのに、IE 以外のブラウザでは getComputedStyle メソッドが、IEでは currentStyle プロパティが使えます。しかし、この両者から得られる値は、前者が使用値 (&lt;span lang="en"&gt;used value&lt;/span&gt;) であるのに対し後者が指定値 (&lt;span lang="en"&gt;specified value&lt;/span&gt;) であるという違いがあります。二つの値に関しては以下の文書が参考になります。&lt;/p&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://hp.vector.co.jp/authors/VA022006/css/cascade.html#css21-assigning-values"&gt;値わりあて，カスケード処理，継承 - CSS2リファレンス&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://d.hatena.ne.jp/amachang/20080409/1207756586"&gt;CSS の「値」とは何か - IT戦記&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;p&gt;JavaScript から CSS の値を操作するときは、指定値よりも使用値を得られたほうが嬉しい場面が多い気がします。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;イベントハンドラ内容属性とスコープ&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;HTML 要素の属性としてイベントハンドラを記述した場合、そのイベントハンドラを実行する際のスコープにはその要素を表す DOM 要素ノードオブジェクト (これは &lt;code&gt;this&lt;/code&gt; から参照できる値でもあります) が含まれます。&lt;code&gt;this.value&lt;/code&gt; と書く代わりに単に &lt;code&gt;value&lt;/code&gt; と書いても同様に動くということです。サイ本にはこうした動作に関して何も標準が存在しないと書かれていますが、&lt;a href="http://www.w3.org/TR/2009/WD-html5-20090423/browsers.html#event-handler-content-attributes" hreflang="en"&gt;HTML 5 草案ではイベントハンドラを実行する手順が明文化&lt;/a&gt;されています。&lt;/p&gt;&#13;
&#13;
&lt;H3&gt;IE のメモリリーク&lt;/H3&gt;&#13;
&#13;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/ja-jp/library/bb250448.aspx"&gt;IE のメモリリーク問題&lt;/a&gt;は、IE 6/7 で部分的には解決されました (IE 6 は更新プログラムを適用した場合)。「部分的」という理由は以下の記事で解説されています。&lt;/p&gt;&#13;
&lt;ul&gt;&#13;
&lt;li&gt;&lt;a href="http://d.hatena.ne.jp/zorio/20070626/1182875782"&gt;IEのメモリリークが直ってるっぽい。 - zorioの日記&lt;/a&gt;&lt;/li&gt;&#13;
&lt;li&gt;&lt;a href="http://d.hatena.ne.jp/zorio/20070918/1190135017"&gt;やっぱりIEのメモリリークは直ってなかった - zorioの日記&lt;/a&gt;&lt;/li&gt;&#13;
&lt;/ul&gt;&#13;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/jscript/archive/2008/03/05/jscript-in-internet-explorer-8-beta-1-for-developers.aspx" hreflang="en" title="JScript Blog : JScript in Internet Explorer 8 Beta 1 for Developers"&gt;IE 8 では &lt;abbr title="Component Object Model" lang="en"&gt;COM&lt;/abbr&gt; という基盤技術に手を入れる&lt;/a&gt;ことで循環参照によるメモリリーク問題を根本的に解決したようです。&lt;/p&gt;&#13;
&#13;
&lt;h3&gt;雑感&lt;/h3&gt;&#13;
&#13;
&lt;p&gt;ブラウザ上で何かしようとするとネックになってくるのが IE の存在です。CSS に関しては IE 8 で大きく前進しましたが、イベントモデルをはじめとする DOM 周りはいまだ独自路線のままです。IE 9 でこれらの点が改善され、Range や XPath といった高度な機能を手軽に扱えるよう、Web 開発者の一人一人が積極的に発言し Microsoft に声を伝えていく必要があると思います。&lt;/p&gt;&#13;
&lt;p&gt;ちなみに、今回の範囲である DOM Events や DOM Style については、&lt;a href="http://gihyo.jp/magazine/wdpress/archive/2008/vol46"&gt;WEB+DB PRESS Vol. 46&lt;/a&gt;/&lt;a href="http://gihyo.jp/magazine/wdpress/archive/2008/vol47" title="WEB+DB PRESS Vol. 47"&gt;47&lt;/a&gt; の連載『JavaScript + ブラウザ探検』でも解説しています。よろしければそちらもご覧ください。&lt;/p&gt;
</description>
<dc:subject>JavaScript</dc:subject>
<dc:subject>Web 関連技術</dc:subject>
</item>
<item>
<title>改名します</title>
<link>http://nanto.asablo.jp/blog/2009/04/01/4218680</link>
<guid>http://nanto.asablo.jp/blog/2009/04/01/4218680</guid>
<pubDate>Wed, 01 Apr 2009 00:18:28 +0900</pubDate>
<dcterms:modified>2009-04-02T00:22:00+09:00</dcterms:modified>
<dcterms:created>2009-04-01T00:18:59+09:00</dcterms:created>
<description>&lt;p&gt;私は普段テキストエディタに Emacs (正確には Meadow) を使っているのですが、nanto_vi という名前のせいか vi 使いに間違えられることが多く、先日も人に挨拶しようと思ったら「僕は Emacs 派なんで」と握手を拒否されてしまいました。ただ静かにエディタを使っていたいだけなのに、このようないわれなき差別を受けるのはもうこりごりです。争いのない平和な世界のためにいいエディタはないかと探していたところ、&lt;a href="http://www5f.biglobe.ne.jp/~t-susumu/library/tpad.html"&gt;TeraPad&lt;/a&gt; というエディタの存在を思い出しました。&lt;/p&gt;&#13;
&lt;p&gt;TeraPad は何よりもアイコンが優れており、今でこそやや古さを感じさせるものの、Windows 2000 のころには一番 Windows にマッチするアイコンのエディタといっても過言ではありませんでした。GUI アプリケーションにとってアートワークは命であり、アイコンが漢字一文字だったりした日にはどれだけ機能に秀でていようと使いたくなくなります。以後 vi 派と Emacs 派の宗教論争という古き時代から決別し、グラフィカルな未来へと邁進するという意志をこめ、名前を nanto_terapad と改めます。名前は変わってもブログの更新頻度は変わらないと思うので、今後とも気長にお付き合いしていただければ幸いです。&lt;/p&gt;&#13;
&lt;div class="ins"&gt;&#13;
&lt;p&gt;&lt;ins datetime="2009-04-02T00:20:00+09:00"&gt;なんか仲直りできたっぽいんでやっぱ改名はなしで。&lt;/ins&gt;&lt;/p&gt;&#13;
&lt;/div&gt;
</description>
<dc:subject>その他雑文</dc:subject>
</item>
</channel>
</rss>
