#ffffee, #800000, #f0e0d6, #eeaa88

ふたばの掲示板の特徴的な色合いはタイトルにある4つの色で構成されているのだが、これのオリジンはどこなのん? と考えてみるとそれぞれの掲示板のフッタに必ずある

GazouBBS + futaba

の、GazouBBSが多分そうなんだと思う。だから今でも敬意を表してクレジットされているということなんだろう。

ところが、このGazouBBSのアンカーはhttp://php.s3.to/へリンクしているのだが、実はもうこのドメインは失われているのであった。探してみると現在はhttp://php.loglog.jp/へ移転しているようだ。GazouBBSはhttp://php.loglog.jp/bbs/bbs3.phpで提供されている。

そういうわけなので、赤福プラスでは移転先の方へリンクするようにしている。また、その旨をふたばの管理人さんにもお伝えした。受け入れられるか、無視されるか、ころころされるかは後のお楽しみ。

* * *

管理人さんから返答があり、現状のままでということになった。

Sex and Drag and Drops

従来 Chrome では、[cci][/cci] 要素に OS のファイルマネージャからドラッグ&ドロップで画像を落とすと普通に受け付けてくれた。なので、javascript 側でそういう機能を作らなくてもまあいいかなと思っていたのだけど。

なんか最近の Chrome では [cci][/cci] のその機能がなくなってる気がする。どうして…どうして有用な機能を削除するのですか…。

というわけで結局 javascript で何とかするハメになってしまった。DragAndDrop API はすんごく使いにくいのであんまり触りたくないのだけど。HTML の規格の中でなんかこれだけやたら Microsoft の API 設計のセンスが満ち溢れて浮いてる感がある。


ドラッグ中は送信フォームが勝手に開いてこういう表示になる。画像ではないファイルをドラッグしてもこういう応答はしない。

ちなみに、ドロップはこのドロップできます領域に限られているわけではなく、赤福プラスのスクリーンのどこに落としても構わない。これはそういうデザインになっている。ただこれはいわゆる SuperDrag 系の拡張と相性が悪いかも知れないが、それは文句が出てから考えよう。

hover in, hover out

従来検索結果に出てきたレス番号にポインタを当てるとそこへスクロールさせていたのだが、割と煩わしいので引用と同様のポップアップを行うようにした。レス番号自体をクリックするとそこへスクロールはする。

そろそろリリースするかな。

sync, sync, sync

従来は設定を localStorage に持っていたが、[cci]chrome.storage.sync[/cci] に持つようにした。storage の読み出しは非同期的に行われる。バックエンドの接続と、DOMContentLoadedの待機と併せて、起動時に非同期に行われる処理がこれで3つになった。これらを [cci]Promise.all[/cci] を用いて並列的に処理するようにした。

そういえば sync って Firefox や Opera だとどういう扱いなんでしたっけ? Firefox は対応しているようだ。Opera は対応していないらしい。対応はしていないが、chrome.storage.local にフォールバックされるようで呼び出してもエラーにはならない。なにそれ。Opera Sync があるんだからそれとくっつけてよ。

カタログのリロード処理を見直した。また、デフォルトのソート順の場合はページ数を表示するようにした。選択したカタログのソート順を覚えておき、ページ全体をリロードした際も再現するようにもした。

ところで、xsl において、あるコンディションによって出力する内容を変えたいときがある。例えば出力する要素のクラス名に特定の文字列を状況によって含めたり、外したりしたい場合。

...

のようなことをしたい。波括弧に囲まれた属性値テンプレートは xpath の式だ。当然上記はエラーになる。

そんなわけで

...

のようなとてもトリッキーな書き方をせざるを得ない。= 演算子が true か false かを返し、number() がそれを 1 か 0 に変換し、式が真の場合は hide の先頭から4文字(つまり “hide” そのもの)、偽の場合は先頭から0文字(つまり空文字列)を出力する。

もうちょっとスマートな方法がないものかな。

Finding threads

従来カタログを出しているときはパネルは出せない、排他的関係だったのだがカタログ上でも出せるようにした。

この場合、検索機能は対象がスレッドになる。また、検索パネルに何がしかのクエリを書いて出しっぱなしにしておき、その状態でカタログを更新すると、検索結果も同時に更新される。つまり特定のワードを含むスレッドの判別が楽になる。

WebExtensions and clipboard operation, revised

現状では赤福プラスのファーストクラスブラウザは Chrome なのだが、一応 Firefox の WebExtensions でも動作確認はしている。でもどうなんでしょう。そもそも Firefox たまにしか立ち上げないし、また Firefox 上の他のふたば用エクステンションはここの所かなりたくさんリリースされているので、そこに加わるのもなあという感じ。

まあそれはそれとして。

WebExtensions では、パッケージ内のリソースを参照する際は moz-extension: スキームを使う。Chrome では chrome-extension: だ。これは内部で使用している xsl ファイルに埋め込まれたスタイルシートの中の background-image なんかで問題になる。background-image を使用する箇所だけを別の css ファイルにして解決(あんまりイケている解法ではない)。

以前クリップボードの取り扱いについて四苦八苦したことがあったが、基本的に変わってない。なぜか Chrome と全く違うクリップボード操作を強いられる。ただしそれとは別に、javascript からクリップボードを扱うための API ができて、割と最新のブラウザなら使えるようだ。とりあえず Chrome 69 なら使える。Firefox 63 では about:config から dom.events.asyncClipboard.dataTransfer を true にすることで使える。デフォルトの状態では使えない。

そういうわけなので


if ('clipboard' in navigator)
navigator.clipboard.writeText(text);
else if (IS_GECKO)
setClipboardGecko(text);
else
setClipboard(text);

…みたいな感じにした。

Load the replies, quickly

「続きを読む」リンクを押した際、すでに読み込み済みのレス群に対しても、そうだねや、レス削除、赤字、なー等の変化を察知し、文書自体をリロードした場合と完全に同期するようになっている。

これはけっこう割と重い…というか時間がかかる。というのは現状では50レスのブロックごとに200ミリ秒の休憩を挟んでいるからだ。これはまあしょぼPCを考えてのことなのだが、さすがに今時この程度の処理で息切れするPCもあるまいということで、続きを読んだ際はフルスピードで走らせることにしよう(最初にスレッドを開いた際は100ミリ秒ずつ休憩しながら走査するようにした)。ということで1000レス超のスレッドでも1秒位で全走査がいけるようになったと思う。実はもっと高速化できるアイデアもあるのだが、それはおいおい実装することにする。

それから、新しいレス群を出力した後、それらの上辺がスクリーンのちょうど半分の位置に来るよう自動スクロールさせているのだが、その辺のスクロール速度をちょっといじったりもした。というのは、走査が高速化した分だけこちらは逆にスクロール速度を落としたのであった。トランジションなので速すぎても意味がないということだ。

また、塩辛瓶に上げられた webm/mp4 ファイルはインラインにプレーヤーを展開するようにしているが、ogg/mp3 ファイルについても同様に振る舞うようにした。ところで困ったことに Chrome 組み込みの動画や音声の操作コントロールはどういうわけかボリュームの調整ができない。これどうしたものだろうか。

Kara-age

赤福プラスが生成するHTMLのフッタ部分のうち、クレジットの上部は長らく中身が空っぽの矩形になっている。かつてはふたばにamazonの広告が表示されていて、矩形はそのためのものだった。しかしamazonの広告が復活する見込みはなさそうなので、別の利用法を考えてみよう。

  • 自前の広告を貼る: ふたばはあくまで人様のサイトである。そんなことが許されるのか?
  • 何か機能を持った領域にする: 例えば閉じたスレの一覧みたいなのがあったら便利…かな?
  • 特に何の機能もない領域にする: なんか適当に画像貼っておく

どうもいいアイデアが思い浮かばない。最後のやつでいいかな。

特に何の機能もない領域

tagging an image


画像を保存する際のファイル名のテンプレートに[cci]$TEXT[/cci]というものを新設した。これはキタ━━━━━━(゚∀゚)━━━━━━ !!!!!を除く最初のコメントに展開される。

レス画像を貼れる板の場合、レス画像を貼ってありかつコメントはキタ━━━━━━(゚∀゚)━━━━━━ !!!!!であるレスの引用は、そのレス番号を用いるのだそうだ。というわけでレス番号をクリックした際はそういうふうに振る舞うようにした。

webm/mp4を選択した際、それらもプレビュー表示の対象になるようにした。

ところでファイル名にコメントが含まれることのメリットというのは検索性の多少の向上というものがあるのだと思うけど、完全ではない。上の画像で言うとラーメンならラーメン、つけ麺ならつけ麺、豚野郎と犬子ならそういった文言がファイル名に含まれていれば完璧だが、そうなっているのもあれば、なっていないのもある。

画像を渡すとそれをAIが解析して、適切なタグ群を返すwebサービスみたいなのがあればいいのに。

Attach an image from clipboard

ついで、クリップボードに画像が格納されている時、コメント欄で Ctrl+V を押すとそれを直接添付ファイルにする機能を実装してみよう。

基本的にはコメント欄の paste イベントで clipboardData.files を見てその中から画像っぽいものを取り出し、それを覚えておき、投稿時に upfile 要素の内容の代わりに使用する、だけ。

のだが、いくつかめんどくさい点がある。

  • 貼り付けた画像のプレビューを生成しなければならない。これ自体は普通に upfile 要素で選択された画像をプレビューする処理と同じで何か新しくコードを書くわけではない。ただし、基本的な流れは画像を示す file インスタンスの内容を img 要素に割り当て、読み込み完了後に canvas 要素に縮小描画するというもので、特に file→img を従来は data スキーム経由で行っていた。しかしこれはけっこう重い。そんなわけでそこを createObjectURL/revokeObjectURL で行うようにした。今までそうしなかったというのはつまり Presto Opera でも動かすためだ。でももう Presto Opera のことは忘れる
  • 貼り付けられた画像のサイズが、板に貼れる上限を超えている場合。クリップボードに格納されている画像は、おそらく確実にブラウザへは image/png 形式で渡ってくる。png なのでサイズ的には常に大きめだ。それが板の上限を超えていた場合は jpeg でエンコードし直す必要がある。

    その場合は file を canvas に描画した後 toDataURL(‘image/jpeg’) で jpeg エンコードされた data スキームの URL を得て、それを XHR で読み込んで arraybuffer として取得し、そこから blob を生成…となる。途中で生成した canvas はそのままプレビュー生成にも使う。この辺、なんか回りくどい。canvas に blob を返すエンコードメソッドを設けてくれれば、それを FileReader から好きに読み込めばいいので汎用的だと思うのだけど…。

    あと、真面目に作るなら、jpeg エンコードしてもなお上限を超えている場合を考慮して、段階的に jpeg のクオリティを下げていくようなループにするべきなのだが、そこまではしなかった。

    ちなみに板に貼れる上限というのは注意書きの中で例えば「2000KBまで」とか書いてあるのをパースして覚えておくのですが。2000KB というのは 2000*1024=2048000byte のことでいいんだろうか。それとも 2000*1000=2000000byte か? 試してみた所 2000000byte 超のファイルは受け入れられるようなので前者とみなすようにした

だいたいこんな感じ。