言及が遅くなりましたが、辞書引き機能のversio 2.2.0, 2.2.1を公開しました。バージョンの上がり具合は2.2.1の方が小さいのですが、実装に掛けた労力はむしろ大きかったです。といっても前者は1行のみ、後者はGoogleで検索した結果をいくつか参考にさせていただいただけで、五十歩百歩と言えますが。
改版点のおさらい
versio 2.2.1 (39-a publikigo, en 2008/02/09)
- 【機能追加】代用表記の字上符付き文字の変換について、変換前後でカーソル(キャレット)位置が変わらないようにしました。「car」と入力した後に「cxar」のようにxを入力して「ĉar」へ変換した場合に、これまではversio 2.2.0の対応でもカーソルが末尾に移動してしまいましたが、元の通りの2文字目のままに位置するようにしました。
- 【障害対応】代用表記の字上符付き文字を変換した場合には、変換前の文字列でクエリを投げず、変換後の文字列でクエリを投げるようにしました。これまでは変換前のクエリと変換後のクエリの両方がほぼ同時にサーバに送信されており、Firefox等ではタイミングにより結果を正しく受信出来ないことが生じていました。
versio 2.2.0 (38-a publikigo, en 2008/02/09)
- 【機能追加】辞書に載っていない熟語を合成語として辞書引きするようにしました。例えば「bona tago」はこれまで辞書引き出来ませんでしたが、「bona」と「tago」の合成語であるものとして扱って解析し、辞書引き出来るようにしました。なお、「bona-tago」のようなハイフン付きの合成語と同様の処理を講じて実現しています。この処理は単語辞書引き機能でのみ動作し、文章内単語訳では動作しません。これまで通り、「bona」と「tago」はそれぞれ別の単語として辞書引き出来ます。従って、文の辞書引きは引き続き文章内単語訳機能をお使いください。
- 【障害対応】versio 2.1.0で導入したJavaScriptによる代用表記の字上符付き文字への変換について、検索語に代用表記が含まれている場合にのみ、検索語を書き換えるようにしました。これまではいかなる場合も書き換えており、常にカーソルが検索語の末尾に移動してしまっていた問題が生じていましたが、これを改めたものです。
カーソル(キャレット)位置を変えずに字上符付き文字へ変換
単純書き換えではカーソル(キャレット)が末尾へ移る
代用表記を字上符付きに自動変換する仕組みは「ワニることを避けてのマークアップ」でも言及した通りです。ただ、変換後の文字列をフォーム(検索ボックス)へそのまま差し替えたのでは、カーソル(キャレット)が末尾に移動してしまいます。
この挙動を援用したのが「検索画面に於ける再絞り込みの要否」で軽く触れただけの処理です。
画面を開いた際にフォームの検索ボックスにフォーカスを移していますが、検索結果画面「等」では既に(JavaScriptではなく、Perlが処理結果として返すHTML自体に)文字列が入っています。この場合、カーソル(キャレット)は文字列の先頭に入ってしまいます。
なお、「等」と敢えて書いている通り、検索結果画面にとどまらず「進む」「戻る」で履歴を遷移した開始画面でも当てはまるのは「検索結果画面での再絞り込み省略の断念」での教訓ですが、この処理自体は共通です。
閑話休題。基本的にユーザは検索ボックスに文字列を入れてEnterキーを打鍵したり辞書引き/絞り込みボタンを押下したりして結果画面を出そうとするわけで、その際に検索ボックスのカーソル(キャレット)は文字列の末尾にあるのが大半でしょう。敢えて先頭や途中の文字を削ったり加えたりすることは多くありません。
すると、開始画面と結果画面ではカーソル(キャレット)の位置が違ってしまい、直感的ではなくなってしまいます。
そこで、IEやFirefox等の一般的なブラウザの実装を援用して、検索ボックスの文字を検索ボックスに代入することによって、強引にカーソル(キャレット)位置を文字列の末尾に移動させていました。
ところが、代用表記を字上符付き文字を変換して動的に検索ボックスに反映すると、これと全く同じ状況が生起してしまいます。dimancxoと記入する際には普通はd,i,m,a,n,c,x,oの順に打鍵するので、確かにdimancxまで記入した時点でdimanĉに変換され、その際はカーソル(キャレット)が末尾のままであるので、問題はありません。しかし、例えばavoという状態からavĉjoを派生させるように途中の文字列を変えると、「avcx|o」(|はカーソル、以下同じ)という状態から「avĉo|」という状態に遷移してしまい、jを何のつもりもなく自然に記入すると「avĉoj|」となってしまいます。
「それをすてるなんてとんでもない!」
先の例でavcxoという文字列をavĉoに変えた後にカーソルを「avĉ|o」の位置にする為には、題名の通りJavaScriptで動的にカーソル(キャレット)位置を取得・記憶して、字上符付き文字の変換(文字列の挿入)後にカーソルを戻すという処理が必要になります。
そこで調べてみたのですが、やはりというか(2007年12月28日を以て開発終了・2008年3月1日を以てサポートが終了する予定の)Netscapeも、IEも、実装が異なります。Firefoxユーザの私としてはFirefox的な書き方だけで済めばそれでいいのですが、流石にIEを捨てるわけにはいきません。IEはまだまだドラゴンクエストでいう重要アイテム的な位置付けであり、「すてる」コマンドを実行しても「それをすてるなんてとんでもない!」と怒られてしまうのです。
さてそれでIEで位置を取得しようと調べてみたのですが、この類の情報の蓄積はまだまだ薄く、ようやく以下のようなページが検索に引っ掛かりました。
- 「Enjoy*Study」より、「テキストボックス内でカーソル位置を移動する方法」
- 「実用」より、「IE、テキストエリア内の選択範囲/キャレットの位置(文字数)を取得する」
- 「OpenSpace」の「JavaScript例文辞典」より、「テキストエリアの末尾に挿入ポイント(キャレット)を移動させる」
何が辛いって、「|」 を「カーソル」としてググっていてもSQL方面がノイズとして引っ掛かるばかりでしたが、よくよく考えれば「キャレット」という条件を追加しなければならないのですもの。Windowsになってマウスカーソルとの峻別のために「キャレット」という用語が用いられるようになったのですが、プログラミングといえばGUIでなくCUI処理ばかり書いていた私にとっては完全に盲点でした。
処理は概ね上記のようなページを参考にさせていただいた通りであり、例によって委細は(せっかくのJavaScriptでソースを自由に見られるので)勝手にご覧いただければ良いのですが、カーソル位置はそのままでは使用出来ません。なぜなら、cxをĉに変換して文字長が1つ減っているからです。従って、位置を-1してあげる必要もあります。
「ほんとうにすてますか?」
折角上記のページを参照させていただいてOperaにも対応出来るようになったのですが、どうも単純に字上符付き文字に変換するロジック自体がOperaに対応していないようで、泣く泣く処理をバイパスしていたりします。「日本語<->エスペラント語 単語変換オンライン辞書」のように字上符付き文字をべた書きしてもいいのですが、それだとサクラエディタが対応していないので億劫なのです。
Operaは市場占有率から見れば通常アイテムなので、「すてる」を選択しても「ほんとうにすてますか?」と確認を求められる程度で、「はい」で吶喊すれば捨てられないこともないのですが、W-ZERO3(Opera)での楽ちん字上符付き文字入力を擲つにはやや忍びないものがあります。
取り急ぎバイパスして後で対応すればいいかと「おおきなふくろ」に入れているのですが、いやはや、一事が万事ずぼらな私にはクロスブラウザを考慮する必要があるJavaScriptは辛いところがあります。体に鞭打ちつつOperaへの対応も善処したい所存です。