content-editable

wasavi はアクティブな要素が textarea、または特定の type を持った input 要素であるときに起動させられるわけだが、これを contenteditable 属性が適切な値にセットされ、内容を編集できる状態の要素にも拡大したい。

最近はそういう要素がけっこう使われているのである。たとえば Twitter で書き込む時の textarea っぽいアレは contenteditable=”true” にした div 要素だ。

編集可能要素を wasavi の対象にする場合、読み書きの際にちょっとした問題が出てくる。textarea/input の value はプレーンなテキストだが、編集可能要素はその内容の形式がプレーンテキストとは限らない。というより、ほとんどの場合 Node なのだ。

まず読み込みのことを考える。編集可能要素が Node であるというのはつまり Node のツリー構造であり、子孫要素を持つことができて、それらがブロック要素だったりインライン要素だったりする。それを踏まえた上でプレーンテキストに変換しないといけない。textContent 属性はそれらをまったく考慮しないのだ。

 * * *

というわけで、その辺りを考慮しつつプレーンテキストに変換し、wasavi へ送るようにした。このあたりを参考にした(が、コードはかなり違うものなっている)。
twitter
次は書き込みのほう。

question and answer

近頃は技術系の疑問をぐぐったりすると、たいてい stackoverflow がひっかかり、たいていそれを見れば解決してしまう。つまり大変お世話になっている。

それはそれとして、わが国にはそういうものはないのかな? と考えてみると、@IT 内にそんな感じのがあったなあと思い出した。また、ずいぶん前からやっているだけあって、システムは前世紀の掲示板みたいな感じで、たまに見るたび「うーん…使いにくい…」となっていたことも思い出した。

などといろいろと思い出しつつ再び 訪れてみたら奥さん、これがものすごく清々しいほどに stackoverflow をパクって生まれ変わっていたのですよ!

そういうスタンス嫌いじゃないです。

hotkeys

wasavi を起動するためのキーストロークを監視するために、各ページに小さなスクリプトを走らせ、そこであろうことか Node とか HTMLTextAreaElementとか HTMLInputElementとかの prototype が持つ addEventListener() と removeEventListener() をフックしている。これは、wasavi を起動するためのキーストロークを完全にページ上のスクリプトから隠すためだ。なかなかアクロバットである。

しかしこれは、特にキーボード周りのエクステンションを wasavi と同時に動かした場合にそれぞれが正しく動くのか、微妙だ。もしエクステンションシステムがもっと優れたショートカットキーの仕組みを提供してくれていれば、そっちを使ったほうが絶対にいい。

Firefox の Add-on SDK には hotkeys モジュールがある。エクステンションのバックグラウンドでストロークとそのハンドラを登録する。ハンドラ内で各タブ上のエージェントにメッセージを投げてやればいい。

Chrome には Commands API がある。これが、ちょっとまだよくわからない。コマンドは manifest に登録するのである。ふーん、え? じゃスクリプトで動的に再定義はできないの? しかしドキュメントは何も答えてくれない……。こちらも基本的な仕組みはバックグラウンドでハンドラを登録するという形になる。

Opera にはない。また、Opera 15 も Commands API はまだサポートしていない。

というわけでとりあえず Firefox の場合はエージェント上でキーストロークを監視するのではなく、hotkeys モジュールを使用するようにした。その副作用として、今まではモディファイアとして shift と ctrl だけを認識するようにしていたのが、alt/meta/accel キーも使用できるようになっている。それぞれ wasavi の設定ページでは、a/m/x と記述する。たとえば alt+meta+p なら <a-m-p> と書く。

* * *

ははあ、わかった。Commands API では、スクリプトから動的にキーストロークを再定義することはできない。その代わり、Chrome の拡張機能ページの最下部に「キーボード ショートカット」というリンクがあり、対話的にストロークを変更できる。

なるほどねー!

しかし Commands API を通したキーストロークはかなり制限されているようだ。どうも

  • モディファイアが最低 1 種必須。ここで言うモディファイアとは Ctrl または Alt。もしかしたらキーボードによっては Meta や Command も有効かもしれない。
  • モディファイアではないキーは、0 ~ 9 および A ~ Z のみ。

というような感じらしい。

つまり wasavi を起動させるための Ctrl+Enter とかは定義できない。……だめじゃん。

referencing contents inside extension

wasavi.js は以前、大きくなりすぎたので分割したことがあった。一方でバックグラウンドで動いていろいろな縁の下の力持ち役を担う background.js はそのままだった。それもやはり分割した。

* * *

wasavi が起動すると、その実体は iframe なのだが、その src はこのサーバを指している。つまり wasavi を起動したことが、期せずして Apache のログからわかってしまう。これははっきり言って不要な情報だ。別にそんな情報で統計をとったりしたくはない。

なんでそんなことをしているのかというと、Opera が悪い。もし iframe が、エクステンション内部のファイルを指すことができれば、この外部へのアクセスは不要である。ただし何でもかんでも参照できるとセキュリティ上の問題になりうるわけで、今日びのブラウザは基本的にはそういうアクセスは禁止している。

ただし、Chrome はホワイトリストに特定のファイルを登録することで、その制限を回避できる。Firefox では、Chrome のようなシステマチックな解決法は(まだ)ないけど、iframe の src を data スキームの文字列にした上で PageMod の判定部を注意深くそれに対応させることでなんとかできる。

一方、Opera は無理。いやエラーページを乗っ取ったりオレオレスキームの URL を開かせたりすればできないことはないんだけど、なんか、特定のバージョンの特定の動作に依存するようなすごく嫌な感じのハックになる。

というわけで、仕方なく、wasavi 起動時はここのサーバの html ファイルを参照するという動作を強いられていたのだった。

しかし Opera 12 はもう歴史上の、過去のブラウザである。Opera を気にすることなく、Chrome と Firefox、そしてもちろん Opera 15 に関してはそれぞれ上記のような動きをさせることにした。

ln -s #2

Windows Vista から NTFS にシンボリックリンク機能が追加されているけど、管理者権限でしか使えないから cygwin が対応してない云々というエントリを以前 書いた

実を言えば、ちょっとググれば、ローカルセキュリティポリシーエディタをたちあげて、「シンボリックリンクの作成」ポリシーに任意のアカウントを追加すれば使えるようになりますぞーというソリューションはすぐ出てくる。出てくるので、そのとおりにやったのだが…なぜか、やはり権限が足りねーよと cmd.exe に怒られるままなのである。謎だ。というのが 1 年前のことだ。

で、今何気なく再度ググってみたらこんなことが。つまり、上記ポリシーにアカウントを追加したとしても、そのアカウントが Administrators グループに入っている場合は別の機構が権限をフィルタリングしてしまい、結果、シンボリックの作成はやはりできないのだそうな。なに、それ。意味がわからない。

回避するには、次のいずれかを試す:

  1. UAC を完全に切る。もちろんおすすめできない。
  2. シンボリックリンクの作成権限を与えたいアカウント A を Administrators から外し、Users に含める。つまり管理ユーザから一般ユーザにする。もしローカルマシンにアカウントが A しかない場合は、先に別の管理ユーザを作成しておく必要がある。

というわけで 2. をやってみた。ほー一般ユーザにすると UAC のダイアログで管理ユーザのパスワードを求められるのか。なんか……原始的。sudo をパクればいいのに。

それにしても 1 年前はなんで見つからなかったのかなーあれだけググったのになー。

ちなみにだからといって、cygwin の ln -s が NTFS ネイティブなシンボリックリンクを作ってくれるようには、やはりならない。しかし ln -s として呼ばれたら /cygdrive/c/Windows/system32/cmd.exe /c “mklink <dst> <src>” 辺りを裏で呼び出すラッパを作れば対応できそうである。と思ったら、すでにそれっぽいのを作っている人がいた。あとで試してみる。

Where do Opera go? #2

Opera 15 から、そのレンダリングエンジンは Blink に移行した、というよりアプリケーションの骨組みが Chromium ベースになった。これに従い、エクステンションの仕組みもまた Chromium のそれに準ずるようになった。Chromium エクステンションと同様の manifest.json を書き、Chromium が提供する API を使ってエクステンションを組み立てていくことになる。ただし API はサブセット(+ Opera 独自のもの)になっている。

どの程度のサブセットかは、Chromium が提供する API と、Opera 15+ の それ を参照のこと。

Opera 12 までのエクステンションは拡張子が .oex だったが、15+ では .nex になる。構造は Chrome の .crx とまったく同じ。Opera 15+ がサポートする API だけを使っているエクステンションなら、.crx のまま使えてしまうはずだ。

また、Opera のエクステンションカタログ(の開発者ページ)では登録済み oex に対する Convert 機能が追加されているようだ。これは何をするのかといえば、oex のアーカイブに oex の API をエミュレートするでっかいラッパーライブラリを付加して、全ファイルを含んだ zip を返してくれる。この oex エミュレーションライブラリがかなりの力作で、全体で 450KB くらいある。これを書いた人は本当によくがんばったと思う。

残念ながらというか幸いにというか、wasavi の場合はもともと Chrome でも動くようにしているので、そのライブラリを使うことはないのだが…。

あと、「一体 Opera は DOM3 Composition Events をいつ実装するの? 明日なの? 今年中なの? 今世紀中なの?」という諦め半分の心の叫びがタナボタ式に解決してしまったのが割というかかなり嬉しい。

Say you, say me

サッチーとそのクローンの誕生
虹裏ユーザ向けのサービスにサッチーというものがある(「」サッチー、「」ッチーとも。公式サイトでも表記は揺れている)。これはユーザが任意の虹裏(dat/img)上のスレッドを登録するとサッチーがそのユーザに代わってスレッドを、その寿命が尽きるまで追跡・保存するというものだ。スレッドに添付された画像のほか、スレッドからリンクされた特定のアップローダ上の画像なども保存する。スレッドの登録の際にタグを入力させることで、後から検索しやすくもなっている。非常に良くできたサービスだ。

このサッチー、年に数回停止してしまうことがあった。それは web 上のサービスということでしかたのないことなのだが、今年に入ってずいぶん長いこと止まったことがあったのだ。記憶が確かなら 2 月頃に数日、3 月頃に 1 ヶ月分くらい止まっただろうか。その間、特に公式のアナウンスもなかったので虹裏ユーザもさすがに不安になり、代替サービスを模索し始めた。

img では早くからサッチークローンを制作したユーザもいたようである。3 月下旬には公開され、今も稼働している。

虹裏 dat では…
さて虹裏 dat では 4 月に入ってもそういう動きは見られなかったので、じゃあやるかということで作り始めた。前述のとおり 4 月上旬くらいの事だったと思う。その頃はタテログを作っていたので、内部の仕組みはそれをそのまま利用することにした。つまりタテログはすべてのスレッドを 1 ヶ月分ログしている。1 ヶ月過ぎたら削除される。サッチー的サービスに登録されたスレッドはその削除を免れるようにするだけの話だ。もちろんタグ周りのスキーマとか UI とかは一から作る必要があるのだが。

ということで、それほど開発に手間もかからず、4 月 16 日には dat に公開し、今も稼働している。名前はなんでもよかったのだが、サッチークローンなので「○○ッチー」的な名前が機能を連想しやすいだろうということで、最初に思いついた「リッチー」とした。ライオネル。

もともとサッチーは「電脳コイル」というアニメに出てきた巡回オートマトンのことなので、「」サッチーもスレッドを巡回するの動作にひっかけたネーミングであるはずである。リッチーというネーミングには別にそういう深い意味はない。

現在
ちなみに当のサッチーはその後復旧し、今も稼働している。なのでぶっちゃけて言えばリッチーはいらない子になってしまったのであった。ただしサッチーは今でもたまにデータベースが停止してしまうことがあるようなので、まあバックアップとしては残してていいんじゃないかな? ということでそのままにしてある。

突貫で作った割に、リッチーにはサッチーが持っている機能をあらかた実装したのだが、まだ決定的に欠けているものがある。残念ながらユーザの中には特定の他のユーザへの私怨なのか、あまりふさわしくないスレッドを登録したり、ふさわしくないタグを登録したりする人がいるのである。そういうのを自動的かつ効率的に察知したり、抑制したり、削除したりする仕組みをまだ作っていない(仕組みがないだけで、データは直接データベースをいじればいいのだが)。

そして…
しかしとりあえずサービスとしてはすでに回っているので、とりあえずタテログとリッチーをいじるのはこのへんで一段落とし、wasavi を開発のメインストリームに戻そうと思う。Blink Opera も公開されたし。

Where do Opera go?

Opera の話。

今年の 2 月、Opera のレンダリングエンジンが Webkit に移行することが発表され、その後正確には Blink への移行であることが非公式に判明した。それ以来デスクトップ版については音沙汰がなかったのだが、いよいよその最初のバージョンが公開された。

その出来や評判がどうなのかは、件のエントリへの 1000 件を超えるコメントのほとんどが、Blink Opera が Presto Opera から様々な機能が削ぎ落とされ、つまり一言で表せば単なる Opera スキンをかぶった Chromium になっていることに対する失望で埋められているといえばここで改めて書くまでもないだろう。

で、日が明けてこういうエントリが公開された。つまり Blink Opera がそういう状態なのは最初のバージョンだからであって、バージョンが進むにつれ Presto Opera が持っている機能が再実装されるので心配しないでくれという表明だ。

Presto Opera に機能的に追いつくのはクリスマスプレゼントの時期になるんじゃないかなーと個人的には予想。

Orphan

ところでメインマシンは Windows7 PC なのだけど、実際には VirtualBox に入れた Ubuntu Server へ、cygwin 上の ssh で接続して作業しているので Windows は開発環境としてはあんまり活用していない。Photoshop とか Illustrator とかを使ったり地デジを見る OS と化している。

それはそれでいいのだが、VirtualBox で困った点がひとつある。PC が 30 分放置の後に自動的にスリープする。スリープを解除すると、どうも動きが怪しくなるのだ。

VirtualBox 上の Ubuntu Server は、タスクスケジューラに登録したタスクで、ログオン時に headless 状態で起動させている。つまり画面を描画するウィンドウを持っていない。したがって、ウィンドウに付属している、仮想環境に対してちょっかいを出す機能を利用できない。ちょっかいを出すには VBoxManage.exe をコマンドプロンプトから呼び出すほかにないのだ。しかしスリープを解除するとどうも VBoxManage が実行中の仮想環境を見失ってしまうようなのである。

正確には、仮想環境が起動すると同時にそれを監視する COM サーバ(SBoxSVC.exe)も起動するようなのだが、それを VBoxManage.exe が見つけられなくなってしまう感じかもしれない。不思議なことに、GUI の VirtualBox マネージャを起動させると、そちらはちゃんと実行中の仮想環境を認識する。しかしマネージャは実行中の環境に対して設定を変えることはできないのだった。

仮想環境自体はふつうに動き続けているので、一度状態保存するなりシャットダウンして起動しなおせばいいのだが。ちょっと不便ではある。

funnIEst browser #2

件の Windows7 PC には SignalNow Express という有名なアプリを入れている。

今更書くまでもなく、これは地震情報をリアルタイムでレポートしてくれる。そのウィンドウは IE コンポーネントを利用したブラウザを内包していて、それで Google Maps を動かして地図を出している。

で、例によって件の PC は IE の調子がどうもおかしいわけで、SignalNow Express もその影響をもろに受ける。地震速報のチャイムが鳴るとウィンドウが出るのだが、即応答なしになる。揺れが落ち着いた頃にえっちらおっちらと地図を出し始めるのだ。これでは死ぬような地震が来たら確実に死ぬ。

そういうわけで「あー! Windows 再インストールしたい!」とか「新しいマシンがほしい!」的な欲求が沸き上がっているところなのだ。