この記事の TinkerBell のバージョンは最新でありません。最新情報もごらんください。
TinkerBell(ティンカーベル)は、HTMLページに書き込んだセリフを、ふきだし表示に変換してくれる妖精さんです。
例えば、あなたのホームページのソースに、次のように書いたとします。
<script type="text/javascript" src="http://www.faireal.net/TinkerBell/0.21"></script> <script type="text/javascript"><!-- Wendy = "手で叩いて下さい!"; Peter = "蚊を殺さないで!"; TinkerMagic();//--></script>
すると、あなたのホームページをひらいた読者のデスクトップに「何か。」互換のエイジェントがいた場合、主人公役のほうが「手で叩いて下さい!」とふきだしでおしゃべりし、あいぼうが「蚊を殺さないで!」と答えます。 —— 要するに、あなたのサイトに来た来訪者のデスクトップにいる「マスコット」に、ちょっとおしゃべりさせたりできます。たわいもない話でも良いし、ホームページの更新情報や、カウンター値を読み上げさせても良いし、最近の時事ネタなどについて、あなたのサイトらしい語り口でちょっとひねったことを言わせてみても、おもしろいかもしれません。
エイジェントがいない場合でも、もちろんエラーには、なりません。いずれの場合も、上のソースを書き込んだ位置には、妖精さんの絵が表示され、「Powerd by TinkerBell」などと表示されると思います。
「何か。」系エイジェントは数えきれないほどたくさんの種類がありますが、主人公役のセリフを Wendy と呼び、あいぼうの応答を Peter と呼んでいます。例えば、ミルクチャンとハナゲのシェルなら、ミルクチャンが Wendy で、ハナゲが Peter です。また、もう一往復、会話を続けさせるには、
Wendy2="ホームページへようこそ";
Peter2 = "ごゆっくりお楽しみください‥‥";
のように書くこともできます。(TinkerBell/0.21 では、Wendy3以下は、ありません。)デスクトップ・エイジェントに指示を送る「さくらスクリプト」を使えば、表情や、まあいなどもコントロールすることができますが、少しむずかしいので、ここでは省略します。
上のセリフの書き方をみると、TinkerBell/0.1x に比べて、ずいぶん洗練されたと思われるでしょう。じつは、内部的動作も改善されていて、多バイト文字(日本語の文字)を文字化けさせずに扱うのにべんりな「ユニコード」(UTF-8)を基本にしています。ある方法を用いて、新しい Script(IE5.5以上)にだけある encodeURI() と同等の動作を、いろいろなブラウザ(ネスケ4、IE4以上……たぶん)で実現し、多バイト文字のURIエンコーディングとして推奨されている UTF-8 を用います。「何か。」のSSTPプロトコルが UTF-8 を解釈できること、最近のJavaScriptが内部的にUTF-16を使っていること、そして、utf.js - UTF-8 <=> UTF-16 convertion というライブラリや、それとふずいして公開されている my_escape 関数を用いることで、道をつないでます。
UTF-8 エンコーディングが可能かどうか?については、現時点では、「あ」を試しにコーディングしてみて「%E3%81%82」が得られれば可能と判断し、ダメなら多バイト文字をあきらめてデフォルトのASCII文字を送るようにしてます。
じつは、ネスケ4やIE5のような古いブラウザは、URLとして、日本語のSJIS文字をそのまま渡しても、SJISを通してくれます。いちばん初めの「SSMLはっか~」では、すべてそれでやってました。具体的にいうと、img要素のsrc属性の一部として、多バイト文字の引数をcgiに渡していたのです。この場合、SakuraScript のタグを使うことは、HTMLのタグの内部の要素で、さらにタグを使うことになって、いろいろとめんどうなので、SakuraScript のタグを、もう少し「URLに優しい」かたちのメタタグでラップしたのが「SSML」(Sakura Script Markup Language)という発想だったわけです。 —— この方法は野蛮ですが、アクティブスクリプトがオフになっているブラウザでも、動作させられるという非常に良い特徴を持っています。URLに多バイト文字を書くのは本来、禁止されてるわけなので、いろんな意味で「ハック」です。
新しいモジラは、多バイト文字を含む(本来ありえない)URLについては、あってはならない文字をUTF-8に変換する仕様になってました。したがって、ユニコードとSJISの判別に間違ったとき特有の、あのやけに画数の多い漢字がごちゃごちゃとならぶ文字化けが発生します。
そこで「ssFusion」では、CGI側でUTF-8も処理するようにして、SJISと場合分けをしました。ssFusionでは環境変数からブラウザを調べて、来ている文字コードを予測する、という、かなりあいまいな判別法を暫定的に採用してました(もっと実質的な方法についてもメモしたけれど実装しなかった)。……この方法も、多バイト文字をURLの一部に使うものです。
TinkerBell/0.1 は少し異なる発想の場合分けを行いました。JavaScript の escape() で、SJISのURLエンコーディングになるもの(IE3、ネスケ4、6、モジラ)は、それを採用し、UTF-16のエンコーディングになるもの(IE4以上)は、上記同様、多バイト文字をそのまま流す、というものです。
TinkerBell/0.2 からは、JavaScript にて、すべてのブラウザでUTF-8コーディングを目指すように変更しました。escape() でSJISエンコーディングが得られるネスケやモジラでも、ちょっと冒険して、あえてUTF-8にいどんでいます。うまくすると、HTML本体のほうが文字化けしてブラウザに表示されてしまう場合でさえ、その同じページの同じ文字コードで書かれているセリフを、ティンカーベルは、文字化けさせずにエイジェントに伝えられる……と考えてます。手元の環境では、(日本語版のブラウザでも)日本語のページを iso8859-1 で読んでしまうことがよくあるので、この文字化けの問題は、けっこう現実的なものです。
「何か。」にUTF-8を送るとき、Script: 行の末尾の¥eタグが正しく解釈されないことは以前から気づいていたが、これは、¥eの文字コードの問題というより、一般に、末尾に何を置いても、「何か。」は末尾の1バイトを削除したものを認識しているようだ。しばしばそのうしろに、スクリプトとして実際には送信されていない短いゴミ文字列があるかのように、ふるまう。通例スクリプトは「¥e」(Perl上では¥¥e)で終わるが受信記録をみるとeが脱落して解釈されている。eが落ちた結果「何か。」はエスケープシークエンスを暗示する単独の「¥」を認識しているので、ますます内部的に誤動作しやすくなるのかもしれない。e脱落の原因が送り手側なのか何か側なのかは未詳。
暫定的な回避方法 —— 1バイト削除されるので、1バイト余分に送る。Perl上で「¥¥e」として、それからダミーの半角スペースを入れて、それから「¥r¥n」とすれば、手元では結果オーライだった。この場合でも、ときどきsstp.logの受信スクリプトの後ろにはゴミ文字列がくっついて書き出されているが「¥e」の後ろなので無視してもらえるようだ。
観察 —— 次の Charset: 行は(したがってScript: 行の行末の改行は)正しく認識されている。しかし、「何か。」は Script: 行の行末より手前に(実際には送られてきていない)ゴミ文字があると誤認識することがある。送り手側の Script: 行の行末の改行文字に関するコーディングの問題か、もしくは、「何か。」側の内部的な問題が考えられる。
こららの問題は、SJISでスクリプトを送る場合には、発生しない。