Subscribed unsubscribe Subscribe Subscribe

枕を欹てて聴く

香炉峰の雪は簾を撥げて看る

SITEINFO中のnormalize-space()削除について

追記
コメントでFirefox以外からの利用もありうることに気がつきました。
そう考えると、normalize-space()は残しておいたほうがいいのかもしれません。
このentryは、AutoPagerizeとLDRFullFeedのWedataのデータからnormalize-spaceが削除されていることに気づいて書いたのですが、現在の時点で不具合が出ていないのかは少し気になります。



誤解のないように最初に。
要するにclassにnormalize-spaceはかける必要はないよって話です。
textとかにnormalize-spaceかけるのとはまた違います。

気になった理由は、ある日突然drryさんがnormalize-space(@class)を@classに変えていたのを見たからなのですが。

normalize-space()って何?

そもそもnormalize-space関数ってのはXPath内で使える関数です。

normalize-space 関数は文字列から前後の空白文字を取り除き、連続する空白文字を 1 つのスペースに置き換え、その結果として得られる文字列を返します。

normalize-space - XPath | MDN

原文も

The normalize-space function returns the argument string with whitespace normalized by stripping leading and trailing whitespace and replacing sequences of whitespace characters by a single space. Whitespace characters are the same as those allowed by the S production in XML. If the argument is omitted, it defaults to the context node converted to a string, in other words the string-value of the context node.

XML Path Language (XPath)

TAB文字を仮に\tとおくと、

"             a    ss   \t \t  b             d          "

のような文字列を渡すと、

"a ss b d"

にして返すわけです。

いつ使ってるのか

AutoPagerizeのSITEINFOとかでこんな書き方を見たことがあるのではないでしょうか。
ここでは、

<div class="page        entry"></div>

を参照したいとします。

//div[contains(concat(" ",normalize-space(@class)," ")," page ")]

これのやってることをここで簡単に説明すると、

  1. //divですべてのdiv要素を対象とする。
  2. normalize-space関数でclassに変なスペースの入れ方がされている場合に半角スペースひとつにする。
    • expample: "page entry"みたいにスペースが無駄に入っているのを"page entry"にしておいてくれる。TAB文字も変更しておいてくれる。
  3. concatで結合する。この場合、もし"page entry"なら前後に半角スペースをつけて" page entry "にする
  4. containsで一つ目の引数に二つ目の引数の文字が含まれているかを確認する。この場合" page entry "の中に" page "が入ってるかを見ている。入っていたら真を返す。
  5. [〜]を述部とかいうのですが、これの条件に当てはまったものが参照されます。containsの結果真が返されているので、うまく参照できるというわけです。

こんなにまどろっこしいことをする理由は、要するにclassが複数定義できるからです。また、前後にスペースを入れて、スペースごとmatchさせることで、たとえば

<div class="prevpage"></div>

なんてものを参照する危険を避けています。

本題 「なんでいらないのか」

で、本題なのですが、先ほどの2番、つまりnormalize-spaceのやってることっていうのは、FirefoxだとGeckoがやってくれるんですね。つまり描画された後のdiv要素は

<div class="page entry"></div>

にしといてくれるので、実質normalize-spaceは必要ないんです。ちゃんとTAB文字も変換しといてくれます。
ただし、全角スペースは変換してくれません。まあこれはもともとclassの区切りとしては認められていないものなので当然ですし、もちろんnormalize-spaceも半角スペースに変換してはくれません。

しかもありがたいことに描画したあとからJavaScriptなんかで

elm.className += "                                   next";

なんかしても

<div class="page entry next"></div>

にしておいてくれるという優れもの。

結論

normalize-spaceも一応関数なので、微細にですがXPath処理速度に影響します。よって今度からはpageクラスをもつdiv要素を厳密に参照するときのXPath

//div[contains(concat(" ",@class," ")," page ")]

でいいようです。