JavaScriptでCSSパーサーを書くための情報を収集中(1日目)

<style type="text/css">
 ...
</style>
  1. CSS ファイルを一本化できればステキ。ブラウザ毎に書き分けるのって本来の姿じゃない。
  2. CSS3 の機能を古いブラウザで使えればもっとステキ。
  3. 古いブラウザに時間を掛けたくない。CSSバッドノウハウなんてノーサンキュー。やりたいことが表現できればそれでいい。
  4. ブラウザに CSS の解釈を任せなきゃいいんじゃないか?

まずは、JavaScriptCSSパーサーを書くための情報収集からです。

わかってること

ロード済みのスタイルシートは、document.styleSheets に擬似配列として格納されています。長さは document.styleSheets.length から取得できます。

スタイルシートの各ルールは、cssRules (IE なら rules)に格納されています。

document.styleSheets[0].cssRules[0].selectorText からセレクタ("a:hover")が取り出せます。
document.styleSheets[0].cssRules[0].style.cssText から宣言("color: black")が取り出せます。
これらから、ブラウザが解釈済みの ルールセットを取り出すことができます。

ブラウザが解釈しないルールがある場合はどうなるの?

IE6 は以下の CSS をパースすると

<style type="text/css">
div > ul > li {
  color: pink;
}
</style>

document.styleSheets[0].rules[0].selectorText が、"UNKNOWN" になります。
IE6 は "E > F" といったセレクタを理解しようとしません。
この場合、document.styleSheets[0].rules[0].style.cssText は "COLOR: pink" になります。
div > ul > li { color: pink; } というルールを復元するための情報は、 document.styleSheets から失われてしまっています。

情報がロストしてんのにどうすんの?

document.getElementsByTagName("style")[0].innerHTML を見ると、本来のCSSがテキストとして残っているようです。

div > ul > li {
  color: pink;
}

ただし、document.styleSheets[0].rules にアクセスした後では innerHTML が改変されてしまいます(document.styleSheets や length へのアクセスなら大丈夫)。

UNKNOWN {
        COLOR: pink
}

このことから、IE で生の CSS を取得するには、rules にアクセスせず、直接 innerHTML から取得しなければなりません。

他のブラウザは大丈夫?

未知の擬似クラス(:digit)をブラウザに食べさせ、どうなるか試してみました。

:digit {
  color: pink;
}

CASE1: cssRules または rules にアクセス後に innerHTML, innerText, textContent からルールを取り出す

Browser innerHTML innerText textContent
Firefox2
Firefox3
Firefox3.5
Opera9.27
Opera9.61
Opera10β
Safari4
Google Chrome3β
IE6 :unknown { COLOR: pink } ""
IE7 :unknown { COLOR: pink } ""
IE8(mode7) :unknown { COLOR: pink } ""
IE8(mode8) "" ""

○ = そのまま維持されている
‐ = プロパティが存在しない

CASE2: cssRules または rules にアクセスせず innerHTML, innerText, textContent からルールを取り出す

Browser innerHTML innerText textContent
Firefox2
Firefox3
Firefox3.5
Opera9.27
Opera9.61
Opera10β
Safari4
Google Chrome3β
IE6 ""
IE7 ""
IE8(mode7) ""
IE8(mode8) ""
開発ツール起動中 IE8(mode7) :unknown { COLOR: pink } ""
開発ツール起動中 IE8(mode8) "" ""


IE8 はデグレードしてる。⇒ IE8 の開発ツールが起動していると、何らかのタイミングで評価してしまうらしく結果が変ってしまいます。

今日のまとめ

  • IE6, IE7 は、document.styleSheets[].rules にさわらなければ 生の CSS にアクセスできる。おさわり厳禁なキャバクラ仕様。(д)
    • IE8 は鉄壁のガードでチラっとも見せてくれない。これは宿題。XHR 使うことになるのかな?
  • IE 以外のブラウザは、element.textContent から 生の CSS にアクセスできる。

<link rel="stylesheet" type="text/css" href="..." /> や @import については次回