WEB+DB PRESS Vol.49 WAI-ARIA2009年03月02日 17時35分

現在発売中の WEB+DB PRESS Vol. 49 にて Accessible Rich Internet Applications (WAI-ARIA) に関する記事を書かせていただきました。2009 年は Web アクセシビリティの年になるという噂をどこからともなく聞きつけてこのテーマにしたのですが、ちょうど WAI-ARIA 1.0 の最終草案も公開されよいタイミングになったのではと勝手に思っています。

WAI-ARIA とは何なのか、詳しいことは雑誌記事を参照していただくとして、簡単に言えば JavaScript で構築した RIA を機械的に認識するための仕様です。たとえば JavaScript でこったボタンを作ったとしましょう。利用者がどうやって「それがボタンである」ということを認識するかといえば、「周りから浮き出ていてマウスカーソルを乗せると色が変わる」といった感覚によっているわけです。

PC 上でグラフィカルなブラウザ経由でしか Web を使わないのならそれでもいいかもしれませんが、Web の閲覧環境というのは千差万別でしてそれでは困ることも多々あります。そこで、グラフィカルな表現に加えて「これはボタン、すなわち何らかの動作のトリガーとなるものである」という情報を埋め込んでおくことで、個々の閲覧環境に応じた表現をとることも可能となるのです。

さて、雑誌記事中では WAI-ARIA で拡張された tabindex 属性にも触れているのですが、それと関係して「Web2.0ナビ: 送信ボタンの上にリンクがあればtabindex=-1に」という記事がありました。フォーム内で、フォームコントロールのみをキーボードアクセス可能にするために、リンクの tabindex 属性に値 -1 を指定しようという内容です。しかし、これをやってはいけません。そのリンクがキーボードアクセス不能になり、アクセシビリティが低下してしまいます。

そもそも tabindex 属性によるアクセス順の指定には、ページ内での絶対的な順序しか指定できない (特定の要素からの相対的な順序の指定ができない) という欠点があり、乱用すれば直感的な操作を妨げてしまいます。tabindex 属性を使う際には以下 2 点に気をつけ、アクセス順を指定する属性としてではなく、フォーカス可能かどうか・キーボードアクセス可能かどうかを指定する属性として使うべきというのが私の考えです。

  1. tabindex 属性の値には基本的に 0 (フォーカス可能かつキーボードアクセス可能) か -1 (フォーカス可能だが直接的にキーボードアクセス可能ではない) かのみを用いる。
  2. HTML 4 で tabindex 属性が定義されている要素 (リンクとフォームコントロール) では基本的に tabindex 属性を用いない。

tabindex="-1" を使う場面の解説は雑誌記事に譲るとして、執筆にあたってつくづく感じたのは日本語資料の充実具合です。WCAG 2.0 が勧告からわずか 1 か月で日本語に訳され、WAI-ARIA 関連文書の日本語訳もそろっているなど、もう関係各所の皆様には足を向けて寝られません。

そんなこんなで 1 年間続けさせていただいた WEB+DB PRESS での連載も今回が最終回です。正直ライブラリ全盛のこの時期に DOM だの何だの書いていて受け入れられるのだろうかとも思いますが、何らかのヒントにでもなれば幸いです。読者の皆様、編集はじめ関係者の皆様、本当にありがとうございました。

Kanasan.JS Greasemonkey チュートリアル読書会2009年03月22日 19時28分

ちょうど 1 ヶ月前、2 月 22 日に開催された Kanasan.JS Greasemonkey チュートリアル読書会 (参加者ブログ一覧) に私も参加していました。時間がたちすぎて自分のメモからも情報を読み出せなくなりかけているのですが、何とかここに再現してまとめたいと思います。全体のまとめは「Firebugで作るGreasemonkeyスクリプト~入門と実践(From Kanasan.JS) | Blog.37to.net」に詳しいので、自分の気になった点に関してだけです。

HTML の解析

Greasemonkey スクリプトを書くには対象サイトの HTML を解析する必要があります。多くの人は Firebug を使っているようですが、私が使っているのは DOM Inspector です。これは単に昔から DOM Inspector を使っていたという慣れの問題ですが、一応 Firebug に比べて chrome 文書 (ブラウザ画面などを構成する文書) やアクセシブルノードの解析ができるといった利点もあります。

XPath での文字列置換

XPath には translate 関数がありますが、これは Perl の tr 演算子と同じで、ある 1 文字を別の 1 文字に置き換えることしかできません。ある部分文字列を別の部分文字列に置き換えたいときは、JavaScript と組み合わせたほうが早いです。Firefox 3 では EXSLT に対応しているので XSLT 中の XPath では正規表現による置換が行えますが、DOM 3 XPath を通じての拡張関数の利用はできないようです。

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="application/xml" href=""?>
<root xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:regexp="http://exslt.org/regular-expressions"
      xsl:version="1.0">
  <xsl:value-of select="regexp:replace('Hello, XPath world!', 'XPath', '', 'RegExp')"/>
</root>

document.evaluate の第 5 引数

document.evaluate メソッドの返り値である XPathResult オブジェクトを、別の evaluate メソッドの呼び出し時に第 5 引数として渡すと、その XPathResult オブジェクトが再利用されます。しかし、「再利用される」とは具体的にどうなることかという説明は DOM 3 XPath 仕様中になく、そもそも may be reused (強調は筆者による) なので確実に再利用されるという保証もありません。Firefox (Gecko) と Opera では第 5 引数に渡したオブジェクトが返り値となりますが、Safari (WebKit) では常に新しいオブジェクトを生成して返すようです。ちなみに Firefox では第 5 引数を指定すると意図しない結果になることがあります。

var result = document.evaluate("'foo'", document, null,
                               XPathResult.STRING_TYPE, null);
document.evaluate("'bar'", document, null,
                  XPathResult.STRING_TYPE, result);
result.stringValue;
// Firefox 3.6a1pre => "foobar" ("bar" を期待していたのに!)
// Opera 9.64       => "bar"
// Safari 3.1.2     => "foo"

順序付きの型と順序なしの型

XPathResult には結果の型として順序付きのもの (ORDERED_NODE_ITERATOR_TYPEORDERED_NODE_SNAPSHOT_TYPEFIRST_ORDERED_NODE_TYPE) と順序なしのもの (UNORDERED_NODE_ITERATOR_TYPEUNORDERED_NODE_SNAPSHOT_TYPEANY_UNORDERED_NODE_TYPE) があります。ソースコードを見る限り、WebKit では順序付きかどうかで処理を分けていますが、Gecko では順序なしでも順序付きと同等に扱っているようです。

雑感

初めての Kanasan さん抜きでの Kanasan.JS でしたが、主催の 37to さんをはじめスタッフの方々のおかげでスムーズな進行だったと思います。テーマのほうも初めてだったせいか初参加の方も多く、懇親会ではいろいろと興味深い話が聞けました。スタッフ、参加者の皆さんありがとうございました。「ブログを書くまでが勉強会です」ということで 1 ヶ月も Kanasan.JS を続けてしまい申し訳ありません m(_ _)m