Editing rich text with wasavi #2

続き。

しかし、最初の状態には確かに戻らないが、markdown された文字列

line1

line2

line3

---

![...] [...](...)

を再度マークアップすれば、とりあえず

line1
line2
line3
---

という形になり、とりあえず見た目は元に戻る。たぶんその状態で送信しても gmail 側は受け入れるだろうし、それならそれでいいような気もしてきた。そもそも別にメールを編集する際にリッチテキストを用いるとして、その書式に厳密な規格なんてないのだ。とりあえずこの方針で行ってみたい。このだんらく「とりあえず」多すぎだ。

となるとまず必要なのは、DOM 要素を markdown にしたり、逆に戻したりする素敵な javascript のライブラリだ。

ただしその前にいくつか考えることがある。前の記事での新規メールの DOM の構造を見ると、たとえば dir 属性が与えられた div 要素や、width/height が与えられた img、target が与えられた a 要素などが存在している。これらの属性は、普通に markdown に落とすとすべて削がれてしまう。div はともかくとして、img や a でそれらの情報が欠落すると問題だ。

そこで、それらの要素については標準的な markdown から外れ、いわば元の要素へのリンクという形にしてみてはどうかと思う。このような img 要素があったとして


markdown にする際は



という独自の書式にするのだ(あるいはより markdown に寄せて [cci]![](id=”foo”)[/cci] みたいな形でもいいが、寄せてはあるが markdown の仕様とは違うのでかえって紛らわしいかもしれない)。これをマークアップする際は id を元に、wasavi の編集対象となっている要素から対応する img 要素を探しだし、再利用するのである。これにより width だろうが height だろうが、あるいは突き詰めればイベントハンドラでさえ wasavi 編集前後で正しく再生される。

このような特別な扱いを必要とする要素はとりあえず a、img、object、embed でいいと思う。

もう一つ言うと上の例ではパラグラフをマークアップすると div になっているが、これも普通は p になる(かもしれない)わけでそのへんも呼び出し側で固定できると嬉しい。

ということで、このへんの要件を満たしてくれる javascript の markup/markdown ライブラリを探してみることにしよう。もしも無ければ、例によって自分で書くことになる。

Editing rich text with wasavi

さてそのめんどくさい issue 120 だ。

wasavi は textarea や input 要素の他に、contenteditable 属性が与えられた任意の要素を対象にすることができる。できるのだが、問題がある。当然ながら contenteditable な要素ではその要素が内包できるあらゆる要素を内包できる。一方で、wasavi はあくまでプレーンテキストエディタであるので、編集できるのは純粋にその中のテキスト部分だけである。従って編集後にそれを対象の要素へ上書きすると、元の要素に与えられていたマークアップの情報はほぼすべて失われる。

これは仕方がない。wasavi がリッチテキストエディタになれば解決するといえばするが、そういう方向に持っていくつもりは今の所ない。従って、contenteditable な要素を wasavi で編集する際は割りきって使うしかないのである……と考えていたのだが。

件の issue は、gmail でメールを wasavi で編集すると書式付きの署名が壊れてしまうのでそれを弄らないようにしてくれ、というものだ。なるほど。これはたしかに不便な話だ。

どうしたものかな。

まずは wasavi と contenteditable な要素間でのテキストのやりとりで、テキスト以外のマークアップ情報が失われるという問題について考えるに、100%ではないにしても最も情報を保存しつつやりとりできる方法は、テキストではなく要素の innerHTML を編集対象にすることだと思う。しかしこれが万人に使いやすいのかというとかなり疑問だ。

次善の策として、DOM の構造を markdown に変換するようにしてみてはどうか。これは割と悪くない気がする。

ただし、これによって上記の署名が壊れる問題は解決しない。gmail で新規メールを編集している時:
wasavi-gmail-2

その DOM の構造は:
wasavi-gmail-1

これを markdown に変換すると div 要素の構造が失われる。つまり、再度 markdown をマークアップしたとき最初の状態に戻らない。

WebExtensions, or Standardizing a browser extension

Edge で WebExtensions ベースのエクステンションが動き始めたとか、Firefox の WebExtension が未だにバグだらけとか、そういう話題の WebExtensions 界隈なのだがひとつ気になることがある。

WebExtensions は Chrome のエクステンションの仕様が元になっているというかまるごとパクっているわけだが、これについて当の Google が何か公式にアナウンスしたのを見た記憶がない。もしも Google が気まぐれでエクステンションの仕様をごっそり変えたらどうするの?

と思ってたらいつのまにやら W3C Browser Extension Community Group なるものができていて、Microsoft、Opera、Mozilla、そして Google といったところから開発者が参加している。ふーんじゃあどこか1社が勝手にちゃぶ台ひっくり返したりすることはないのかな。

ところで Apple からは誰も参加していないのだね。

Multiple Instances #2

そういうわけで、同時に複数の wasavi を起動できるようにした。

最も大掛かりにコードの変更を受けたのは agent.js で、一旦バラバラにして組み直したような格好だ。しかしこれでコード内の役割分担が割と明確になったので結果的にはよかった。

次に控えている issue はちょっと難しい。

Multiple Instances

issue #118

現状の実装だと、あるページに textarea が複数あった場合、wasavi の起動は排他的だ。つまり複数の wasavi を同時起動することはできない。この制限を取り払ってほしいという issue。

これを解決するとして、最も影響を受けるのはエージェントだ。まず wasavi を起動する際にフレームごとにユニークな ID を振るようにして、メッセージングの際はそれをやりとりするようにしないといけない。特にメッセージを受信した場合はフレーム ID を元に複数の wasavi のインスタンスから正しい宛先を探しだし、適切にディスパッチする必要がある。

これはこれとして、もともとエージェントの構造は若干とりとめなく関数を書き連ねてた形になっていたのが気になっていたので、大掛かりに見直す切っ掛けとしては良い。

Tegaki #2

akahukuplus-tegaki-in-summary2

ふたばのオリジナルの手描き機能では、手描き画像でスレを立てることはできない設定になっている。少なくとも虹裏 may ではできない。これはきっと理由があるのだと思うけど、まあブラウザのエクステンションでは特にそういう制限をかける必要はあるまいということで、立てられるようにした。

このとき、手描き画像のキャンバスサイズは 640×480 に拡大されるようになっている。これは Tegaki Draw and Tweet の画像サイズに準じた。

ちなみにオリジナルの手描き機能を送信する際の内部的なフォームデータは、baseform という hidden input 要素である。手描きの flash が逐一この要素に画像を base64 でエンコードした文字列を設定する。これとは別に、従来通りの普通にファイルを送信する要素は upfile である。すなわち可能性としてはファイルと手描き画像を両方同時に送信することが可能なのだが、試していないがたぶん upfile のほうが優先される。

赤福プラスでは baseform 要素を特に積極的に使う必要はない。というのは手描き画像を保持する canvas 要素から blob データを得て、送信フォームの構築時に upfile に割り当てればいいだけの話だからだ。そんな細かいことをブラウザだけでできるようになったんだねぇとしみじみしちゃうが、とりあえずレス画像としての手描きは baseform、スレ画像としては upfile を使うようにしてある。

ついでに 1 回限りの undo やペンサイズを変更するためのショートカットなどを追加。

Tegaki

虹裏の中には手書き機能が付いている板もあるのだが、赤福プラスで閲覧している状態ではその機能を利用できなかった。そうこうしているうちにはよ実装しろやバーカバーカという声まで来てしまった。

なぜ延び延びになっているかといえば、ぶっちゃけて言えば赤福プラスをいじっても 1 円も儲からないからだ。

wasavi の場合は、Pledgie へのリンクをつけてあり、まあ元をとっているのかといえば全然ではあるのだけど、一応開発に対する対価は得ている。しかし赤福プラスの場合はそういうものはつけていない。じゃあつければいいじゃんということなのだが、果たして「」やとっしーが虹裏向けのブラウザなんかにお金を払うだろうか。いや払うわけがない。そして、仮に払ったとしても、そうすると調子に乗って文句たらたらになることは火を見るよりも明らかである。

実装の面から考えてみると、元の手書き機能は flash なのであまり扱いたくない。また、代替品を作るにしてもそれなりに手間がかかる。

そういうわけでなかなか腰が重い。殊勝なとっしーがポンと30万円くらい払ってくれてしかもおかしな注文もつけてこなければ一生懸命いじるのだが。

* * *

最後に 1 つ書いておくと、赤福プラス 3.1.207 からは手書き機能がついてある。

Pick it up

とある事情でいわゆるカラーピッカーが入り用になった。そこで、とりあえずググった所ものすごくたくさんある。なぜプログラマはカラーピッカーを書きたがるのか?

ちなみに、今回欲しいカラーピッカーの要件は:

  • シンプルでいい。HSV 方式だけでいい
  • 付加的な画像ファイルやCSSファイルを必要としないほうがいい。javascript ソースだけで動けばいい
  • jQuery 等々には依存しないほうがいい
  • 最後に選択した色を憶えててくれて、再選択できるといい
  • hex 表記との相互変換ができるといい
  • 表示開始のタイミングを呼び出し側で制御できるといい

最後の表示開始タイミング云々というのは、既存のライブラリの中には、ドキュメントの load イベント時に、カラーピッカーを起動させるべく特別なクラス名などが付加された要素に対してアタッチするようなものも少なくないのである。しかし静的なページならそれでもいいけど、動的なページだとかなり相性が悪い。そんなわけで表示開始のタイミングは呼び出し側で制御したい。こんな感じで:

targetElement.addEventListener('click', function (e) {
startColorPicker(e.target, {
onchange: function (color) {
},
ok: function (color) {
},
cancel: function () {
}
});
}, false);

ところが、この要件に合致する既存のライブラリがなかなか見つからないのである。そもそも、jQuery プラグインとして作ってあるものが大半だったりする。別に jQuery プラグインだからダメというわけではない。最初から jQuery ありの前提で書いてたアプリに組み込むのならまったく問題ない。しかしもともと jQuery なしで開発してたものにたかがカラーピッカー 1 つのために jQuery を読み込ませるのはかなりとっても相当嫌だ。jQuery プラグインと同時に、依存なし版も合わせて作って公開してくれれば更に多くの人に使われると思うのだけど。

そんなわけでググれどググれど見つからないので、しょうがないので自分で書く羽目になってしまったのである。なんでこんなものがないんだ。かなりプンプンだ。

color-picker

そんなこんなでドバババと書いたのであった。

Let’s talk about a News

ちょっと前に tsumami というアプリケーションを書いた。

これは要するに RSS リーダーの一種なのだけど、最大の特徴は取り込んだフィードを読み上げるというものだった。これに適当なニュースサイトのフィードを登録しておくと、自分の仕事をしながら世の中の動きにもついていけるという……非常に素晴らしいアプリケーション……のはずだったのだが、インストールが我ながら笑っちゃうほど死ぬほど面倒くさいわけで、もう使わなくなってしまった。

しかしフィードを読み上げるというのは面白い試みではあるので、リベンジとして作りなおしてみた。今回は Chrome のエクステンションなので、単にインストールするだけである。ただし任意のフィードは登録できなくて、とりあえず今の所 NHK News WEB のものだけ。

PhoneticNews
https://chrome.google.com/webstore/detail/phoneticnews/jdpmokplldjoalkopfkeedeehmfaejjh

vi flavored browser UX #3

実は今現在最新の Firefox Developer Edition 46.0a では Keysnail が動作しないので、とても不便である。

せっかく Chrome 上での vi flavored なエクステンション群の評価をしたので、cVim をベースに uBlock、ScriptBlock 等を入れて色々整えてみた所割合快適な感じになってしまって、あれ? これ Firefox もう窓から投げ捨ててしまってもいいんじゃないの? という気になりつつある。

従来、どういうわけか Linux 上で Chromium(Opera も)を動かすとオムニバー上のキー入力が耐えられないほど重かった。また Chrome ではオムニバー周辺をエクステンションからいじることはほとんどできない。アドレスを編集するときに [cci]^F[/cci] [cci]^B[/cci] [cci]^H[/cci] 位は使いたいのだ。そのあたりが Firefox を常用ブラウザに選んだ理由だったのだが、オムニバーの代わりに cVim のコマンドラインを代用すれば今まで感じていた不満が何とかなってしまうわけで、そんなわけで 3 日に 1 回くらい落ちる Firefox Developer Edition を常用する理由がなくなってしまった。