2010年 12月 07日


gerry++

IE で postMessage 的実装をちゃんとやる

postMessage、便利でいいですね。ドメインを跨いでうまく連携してスクリプトを書けたときの楽しさはパズル的でこのうえない感じであります。しかしながら postMessage は古い IE で動かないので、代替実装が必要です。ググるといっぱい出てきはするのですが、自分の要求にかなったものがなかったのでひとまず書きました。

$ cat /etc/hosts
127.0.0.1 anotherhost
$ git clone git://gist.github.com/701752.git gist-701752 
$ cd gist-701752
$ plackup -MPlack::App::Directory -e 'Plack::App::Directory->new({root=>"."})->to_app' -p 5000

とかやっておいて、http://localhost:5000/test.html にアクセスするとなんか出るので、ボタンをクリックしたりするとどうにかなります。フレームの中と外で別ドメインです。

要件

実装するにあたって必要だったのは、まさに postMessage だったので、以下のようなことが求められました。

  • メッセージのとりこぼしがない
  • IE で動く

逆に、古いブラウザで動けばいいので速度はそれほど求められていません。

実装

とりあえず動いてほしいので、古くから伝わり慣れている location.hash によるドメイン間通信を用いることにしました。location.hash による通信を要約すると以下の通りです。

  • データを送信したいフレームの location.hash を書きかえる
    • 書きかえるだけならドメイン関係なくできます
  • 読みだし側は location.hash を監視して変化を検知したら処理する

ただ、これには以下のような問題があります。

  • IE の URL 長制限。
    • 2038 バイト制限が存在します。
  • location.hash を監視する以上の速度でデータを送信することができない
    • 監視に使用するのは setTimeout/setInterval なので、監視間隔は厳密には不定です。

なので、2038バイト制限を超えるデータを送信するためにはデータのパケット化が必要なのと、データの紛失を防ぐために何らかの方法が必要ですが、要はパケロスする環境で信頼できるデータ通信を行いたいということなので TCP のやりかたをパクって実装してあります (シーケンス番号 + ACK)。

備考

window.name を使う方法であればデータ長制限がなくなるのでパフォーマンスは向上しそうですが、実装は複雑そうです。また、空のリソースを両方のドメインに求めるので、失敗確立があがります。

ちゃんとした postMessage 互換実装があったら教えてください……

2010年 12月 06日


餅しか食べてない

ジェーン・エア、上巻が読み終わった。ジェーンが「ロチェスター氏はわたしのことが気に入っているのでは?」から「そんなことはない! とんだ思い違いだ! 愚かなわたしめ!」となる一連のシーンは、ジェーンの、他人の感情に鋭敏なところや謙虚で意志が強いところが出ていて、非常に可愛らしくて良かった。

2010年 12月 05日


土曜日は、というか金曜日はいつのまにか寝てしまっていて、次の日7時ぐらいに起きてしまった。起きてすぐ、なんとなく書きたいコードが受かんだので適当に書いてサブテクに上げて、その後どこに行こうかと考えた末、神社TODOに入っていた廣瀬大社龍田大社に行くことにした。

読み途中の本を家に忘れて取りに帰ったりしたけれど、12時ぐらいに法隆寺駅について、そこからまず廣瀬大社へ行った。駅から割と遠かったが、晴れていて散歩にはうってつけであったし、朝早く起きれた気分がまだ継続していたので大変気分良く歩いた。

廣瀬大社の参道に入ると、定間隔で落葉が燃やされており (あれはなんだったのだろう)、煙がもやもやと漂っていた。参道の木々から漏れる光が煙を照らして、光の路ができているのが綺麗だった。本殿は春日造で、奈良っぽかった。参道を歩くといくつか摂社・末社があって面白かった。

その後、そのまま龍田大社に行ってもよかったのだけれど、せっかく法隆寺の近くまで来たので、法隆寺にも寄り道してみようと思い、法隆寺へ行った。法隆寺はたぶん修学旅行で行ったことがある気がしたが、殆ど覚えておらず、かすかに法隆寺の壁のある道の風景を覚えているぐらいだった (あるいは勘違いかもしれない)。自分はあまりお寺には興味がないので、楽しめないかと思ったが、思ったよりも楽しめた。八頭身の百済観音 (木彫りの彫刻) は大変かっこよかったし、思ったよりも人が多くなく、静かで、冬らしい感じだった。

そのまま法隆寺近くの斑鳩神社 (天満宮) に行ったり、龍田神社 (このあと行く龍田大社とは別) にも行ったりした。

それから法隆寺駅に戻り、三郷駅まで電車に乗って、龍田大社まで歩いた。龍田大社は紅葉がいくらか残っていた。境内は人が殆どおらず、厳粛だった。本殿は遠くてよくわからなかったがたぶん春日造だった。

時間があれば春日大社や、平城京跡になんとなく行ってみてもいいなと思っていたけれど、法隆寺が思ったより面白かったのでそんな時間がなくなった。

2010年 12月 04日


Test-HTML-Differences

というのを書いてみました。

一旦 normalize してから HTML を比較し、テストに失敗した場合は Test::Differences 使ったときのようになります。

#   Failed test 'test'
#   at t/lib/Text/Xatena/Test.pm line 40.
# +----+---------------------------+---------------------------+
# | Elt|Got                        |Expected                   |
# +----+---------------------------+---------------------------+
# |   0|<root>                     |<root>                     |
# |   1|  <div class="section">    |  <div class="section">    |
# |   2|    <h3>head</h3>          |    <h3>head</h3>          |
# |   3|    <p>foobar</p>          |    <p>foobar</p>          |
# |   4|    <div class="seemore">  |    <div class="seemore">  |
# |   5|      <p>barbaz</p>        |      <p>barbaz</p>        |
# |   6|    </div>                 |    </div>                 |
# *   7|  </div>                   |    <div class="section">  *
# *   8|  <div class="section">    |      <h3>head</h3>        *
# *   9|    <h3>head</h3>          |      <p>foo</p>           *
# *  10|    <p>foo</p>             |    </div>                 *
# |  11|  </div>                   |  </div>                   |
# |  12|</root>                    |</root>                    |
# +----+---------------------------+---------------------------+