一部のブラウザに実装されているCSSセレクタ(querySelectorAll)で良くわからないところ

2009-02-11 追記: 一部加筆/修正しています

document.querySelectorAll()で、W3Cの仕様通りだとエラーになりそうだけどそうならない箇所の一覧

×=エラーになる,▲=エラーにならない(または予想外の要素にマッチする), 未=未テスト, 空白=思惑通りにエラーになる,○=動作する

Chrome1
Safari3.1
Opera10 Firefox3.1 IE8 querySelectorAll("...") 仕様書的に該当する記述とか
      ***bad-selector SPEC1.単純選択肢の連鎖の制約, *は連鎖できない
      ***
**
SPEC1.単純選択肢の連鎖の制約, *は連鎖できない
      :not(div.hoge) SPEC2.否定擬似クラスの引数の制約, :not内では連鎖できない
      :not(:not(.nest-error)) SPEC2.否定擬似クラスの引数の制約, :notはネストできない
      :not() SPEC2.否定擬似クラスの引数の制約, 引数は省略できない
× × × :indeterminate 最新版で :indeterminateが仕様落ちしているためエラーになりそうだけど、Opera10では動く 
× × × × :contains("foo")) 最新版で :contains が仕様落ちしているためエラーになる
× × × × :not(:contains("foo")) 動きそうなんだけどエラーになる, 仕様の見落としがあるのかも
最新版で :contains が仕様落ちしているためエラーになる
× :not(*) IE8β2で動作しない
× :not(.expr) IE8β2で動作しない

IE8β2, IE8RC1 では、:nth-child, :only-child, :last-child 等が動作しない。

SPEC1. 4 選択子構文 | 英語

選択子は、結合子(>+~ )で区切られた、一つ以上の、単純選択子の連鎖である。

単純選択子の連鎖は、結合子で区切られていない一続きの単純選択子である。それは、常に型選択子(div)あるいは汎用選択子(*)から始まる。このほかには、型選択子(div)あるいは汎用選択子(*)は、連鎖の中で許容されない

単純選択子は、型選択子(div)、汎用選択子(*)、属性選択子([attr=val])、クラス選択肢(.class)、ID選択子(#id)、内容選択子(:contains)又は擬似クラス(:link や :first-child等)のいずれかである。一つの擬似要素(::first-line等)を、連鎖の最後の単純選択子に追加してもよい。

SPEC2. 6.6.7 否定擬似クラス | 英語

否定擬似クラスは、引数として単純選択子(否定擬似クラス自体及び擬似要素を除く)をとる、関数表記である。

# 単純選択肢の連鎖(div + .hoge)を引数にした :not(div.hoge) はエラーになりそうだし、 :not(:not(...)) は ネストした :not が制限に引っかかる

JavaScriptで実装されたCSSセレクタの動作例

文法エラーのテスト (テストが途中で止まる場合はリロードしてください)

W3Cの仕様に準拠した実装を行っているCSSセレクタでは、下から4つ下から4番目(*)と2番目(:not(.simple-selector-is-good), 一番下(:not(*))以外は全てシンタックスエラーで失敗する例です。途中のネームスペース("*|A", "A|*", "*|*")は API(querySelectorAll)実行時のみ成功し、JavaScriptでは失敗するはずです(namespaceを解釈するJavaScriptライブラリは現時点で存在しません)。

  • uupaa-selector-2.0.1 は querySelectorAll() が使える環境ではAPIで試行し、APIが失敗した場合は JavaScriptベースで検索します。
  • uupaa-selector-2.0.1(API ONLY) は querySelectorAll() だけで検索するように改造したversionです。:link と :visited も動作可能です(除IE8)。
    • 注: IE6, IE7, Firefox2, Firefox3, Opera10未満で実行するとAPIが存在しないため全てエラーになります。
  • uupaa-selector-2.0.1(JS ONLY) は JavaScriptで実装されたCSSセレクタで検索するように改造したversionです。ネームスペースは非対応です。:link は :visited を切っているため正しく動作しません。

ファイル一式

まとめ

  • 上記の例はW3Cのテストスイートに欠けている類のテストです。こういうのはまだまだあると思います。
  • 誤った記述をした場合に、全要素にマッチしてしまう実装が沢山あることに驚きました。