Policy Violation

先週 Google Chrome web store team から、「wasavi が掲載ポリシーに違反している、1 週間の猶予をやるから直して再アップロードしろカスが」というメールが来た。

ポリシーというのはたとえば内容の表現とか、広告とか、ユーザーデータの取り扱いとか、そういうものだ。しかし wasavi が内包している内容と言ったらシンプルなエラーメッセージくらいだし、広告はないし、ユーザーデータもオプションページでいじれるもの以外にないわけで、違反ってなんのこっちゃという感じだった。そして困ったことに、どの点が問題なのかという肝心の点がメールに書いていない。

そんなわけでハドラーこれどうなってるの? というお返事をしたところ、「なんか間違いだったみたい。気にすんなカスが☆」ということであった。

なるほど。

serif or sans-serif #2

このブログにたまにスクリーションショットを上げるが、それを見てもわかる通り Chrome のフォントをTakao P 明朝に設定している。これ自体はとても良く出来ているフォントなのだが、繁体字や簡体字の文字までカバーしているわけではないので、そこだけ別のグリフになってしまうことがごくたまにあり、それが気になる。

フリーで、Unicode の多くのコードポイントに対応していて、明朝体あるいは serif のフォントというと Google Noto Fonts の Noto Serif CJK JP である。というわけで、入れてみた。

Takao 明朝に比べると若干硬い感じを受けるが、それはまあ慣れなので。もうひとつ気になるのは含まれるアルファベットが若干アセンダ・ディセンダが広く、うわ〜気取りすぎ!な感じはなくもない。まあそれも慣れなので。

とは言え、慣れではどうにもならないものもあるのです。Chrome のフォントの設定は標準フォント・sans-serif フォント・serif フォント(と、その他)に分けられている。素直に考えれば、標準フォントはページになんにも font-family が指定されていないときに使用されるフォント、sans-serif と serif は font-family 中のそれぞれの総称フォントということだろう。

しかしこの通りに標準フォントと serif フォントに Noto Serif CJK を与えても、そのとおりに表示されない web ページはたくさんある。表示されないのは意図されたもので、つまり font-style に sans-serif を含んでいるページが多い。これは悪習なんじゃないだろうか。font-family には「ぜひともこのフォントで表示してほしい」ものだけを書いてほしい。そしてそのフォントは Web フォントの技術を用いて web ページ側が提供してほしい。font-family は「どういう風に表示されるかは保証しないけどこのフォントで表示してくれたら嬉しいな〜」なフォント名を書くものではない。

Save to #4

いくつか気なる点が出始めてきた。

Kokoni のコンテキストメニューは、image/video/audio に対するものと link に対する物の両方に対して表示するようになっている。ここで、例えば img 要素を含んだ a 要素に対してコンテキストメニューを出したとき、保存対象は a.href か img.src か? という難しい判断を迫られる。

Save file to ではこういう場合、リンク先を保存というメニュー項目と画像を保存というメニュー項目を両方出現させる。しかし Chrome の拡張の場合、それは不可能なのだった。コンテキストメニューのルートに複数のメニュー項目を追加しようとした場合、ルートには拡張の名前の項目だけが追加され、拡張側から追加しようとした項目はその下に迂回されてしまう。

つまり通常はコンテキストメニューから “ここに保存” -> “Pictures” というルートを辿るのが、上記のマークアップの場合は “Kokoni” -> “ここにリンクを保存” または “ここに画像を保存” -> (いずれかの)”Pictures” というように展開されるメニューが1段増える。

リンクに対するコンテキストメニューを出した時はそういうものだと受け入れるとして、問題はどうも拡張から生成できるメニュー項目数に妙な制限があるらしいことなのだった。つまりツリーに対応するメニュー項目群を2倍定義しないといけないのだが、そうすると簡単に制限に引っかかる可能性が高くなる。メニュー項目をより動的に生成できるようなイベントが用意されていればその都度必要とされる項目だけを生成することで解決するのだが、chrome のコンテキストメニュー API はいまいちその辺の融通が効かない。

もうひとつ、参照したディレクトリの履歴をコンテキストメニューに含めるようにしているが、現状では単純に最後に参照したディレクトリを先頭に持ってくるようにしているので、例えば 9 割方 [cci]Pictures/けものフレンズ[/cci] に保存しているが、たまに [cci]Pictures[/cci] に保存しただけで履歴の順番が変わってしまう。履歴のソート順として参照回数順、辞書順などのオプションを実装する必要がある。

Save to #3

インストール手順を英語でも書いた。

Enjoy Kokoni!
https://appsweets.net/kokoni/index-en.html

同時に、basename を省略してアクセスしても、accept-language ヘッダの先頭が ja かどうかで適宜振り分けるようにしたのだが。Chrome の場合 [cci]$ LANGUAGE=en google-chrome[/cci] などとしても accept-language ヘッダの内容は変化しない、Firefox の場合は逆に言語設定で ja を先頭にしているにかかわらず accept-language には ja が追加されない…など、それぞれがなんか妙な動きをして困る。

困るといえば、テストのためにいろんな画像を虹裏から落としているのだが、割と同じ画像を保存してしまうことがある。こういう場合に Kokoni 側で面倒を見るべきだろうか。でもそれはそれで面倒くさいなあ…。

やっぱりやめた。

$ fdupes -fdN ~/ピクチャ/けものフレンズ

すればいいだけのことだ。

それにしてもこの手の拡張が Chrome にも欲しいという意見は2012年頃からあったのに、なんで誰も作らなかったんだろう…。

Save to #2

Chrome Web Storeに公開した。

それから、詳しいインストールの仕方を書いたページを作った。しかし絶対パスや相対パスというむつかしいこんぴゅーたー用語が万人に通じるのか若干不安がある。Chrome の filesystem まわりの API がフルパスの扱いに関してぶっ壊れっぱなしで、スクリプト側で良きに計らえないのが悪い。

Some purchases

そういうわけで、左右のバランスが壊れているイヤホンを破棄し、新調した。SONY MDR-XB50というやつだ。

実を言うとオーディオ機器の良し悪しというのは全然さっぱりわからないので、別にこれが欲しかったとかそういうわけではなく、単に Amazon を見てて適当に決めただけだ。

それから、万が一イヤホンではなく PC の方に問題がある可能性もあるのでiBUFFALO USBオーディオ変換ケーブルなるものも注文した。これはいわゆる USB DAC と呼ばれるもので、USB 経由で音声データを取り出すのだが D/A 変換が PC の外で行われるためにノイズが軽減されるのだそうだ。ただしこの手のデバイスのお値段は正にピンきりで、注文したのは相当下のグレードだ。

で、とりあえず直接イヤホンを PC につなげてみたところ、バランスは元に戻ったので、やっぱりイヤホンが断線していたみたいだ。そういうわけで USB DAC は別に使わなくてもいいかなということに。別にノイズが乗るわけでもないし。

ついでなので、4GB のメモリも注文した。現在の PC のメモリも 4G なので、合わせて 8G だーわっほいと思っていたのだが、開けてみたらなんと 2G+2G の構成なのだった。そういうわけで 8G ではなく 6G になってしまった。

Save to

Firefox に Save File to という素敵な拡張がある。これはリンクや、メディアファイルに対するコンテキストメニューにホームディレクトリの任意のディレクトリツリーを展開し、選択したメニュー項目のパスへ直接ダウンロードする機能を提供する。つまり、とりあえず ~/Downloads に落として、落とし終わったら適当なところに移動…という手間を省ける。

似たようなものは Chrome にはないのだろうかと探してみたのだが、ないようなので作った。

本家には保存ダイアログにまで割り込んだり、サブメニューを左右交互に展開させるような芸の細かいオプションがあるが、残念ながら Chrome の拡張にそこまでの自由度はないので勝手に移植物としてはかなり不完全。

Promise and Generator #2

そういうわけでちまちまといじっている。

とりあえず vi コマンドを回す部分に関しては修正した。これで非同期の処理だろうが同期の処理だろうが不自然なく呼べるようになった。それはいいのだが、vi コマンド群は本丸ではない。qeema が発生するキーボードイベントから、各 vi コマンドのハンドラに達するまで、せいぜい 4〜5 の関数がネストするだけであり、ただそれを Promise を使うようにすれば済む。

難しいのは ex コマンドの方なのだった。

ex コマンドは、ex コマンド列をコンパイルして中間コードの配列に落とし、それを逐一実行するという構造になっている。なので、修正するとしたら ex コマンドごとに Promise をつなげていく、ex コマンド自体はそれぞれ resolve() でコマンドの終了を通知するといった形になる。

ただいくつか面倒な点がある。

  • write、read、edit などバックグラウンドに処理を投げるファイルシステム系のコマンドは、読み書きの進捗イベントをバックグラウンドから複数回返される。従来は、この複数回返されるメッセージというのは ex コマンドのハンドラの外で処理していた。というのも非同期的な ex コマンドを実行する際は一旦そのコマンドの同期的な部分のみを実行したあと executor を一時停止し、バックグラウンドから処理完了メッセージが到着したら executor.resume() で再開するようになっていたからだ。これは処理が分散しているといえばそうなので、若干不自然ではある。

    個々の ex コマンドを Promise によって駆動するのであれば、複数回返されるメッセージの扱いというものも ex コマンドのハンドラ内で完結できるわけで、そうすべきだと思う。具体的にはハンドラ内で long-lived connection をその都度行い、コマンド完了時に閉じればいい

  • シグナルの扱い。シグナルというと若干語弊があるのだけど、つまりやはりファイルシステム系の時間がかかるコマンドの実行中、[cci]^C[/cci] が押されたらキャンセル扱いにする処理のことだ。これも Promise 化によって中身がかなり変わる。

ちなみに非同期で実行される ex コマンドとしては

  • cd
  • edit
  • read
  • c オプションが付加された s
  • 非同期とマークされたオプションの値の変更を含んだ set
  • write

となっている。また、レジスタを指定できる ex コマンドで [cci]*[/cci] レジスタが指定された場合も非同期になる。レジスタを指定できる ex コマンドは、

  • delete
  • put
  • yank
  • @
  • *

となっている。非同期とマークされたオプションは以下のとおり。

  • fullscreen
  • syncsize
  • columns
  • lines

Promise and Generator

Migemo Server for Google Chrome™ というものがある。これ自体は migemo のライブラリのように動作し、外部の拡張からのリクエストを受け入れ、適切な結果を返す。

これに対応してみようかなとコードを頭の中で組み立ててみたのだけど、すぐに行き詰まってしまった。というのも拡張から拡張への通信というものは非同期に行われるからだ。一方で wasavi がキー入力を処理する構造は同期ベースで、非同期な動作を組み入れるのはとっても大変なのだ。

この辺を、Generator と Promise を組み合わせて使うようにすればとてもすっきり書けるのだが。なぜ今までそうしなかったかと言えばすなわち Presto Opera でも動かすためだ。Opera 12 は Promise の Polyfill は動くが、Generator は無理なのだ。

しかし、もう wasavi/0.6.657 で Presto Opera のサポートは終了した。従っていよいよそのへんを書き直す頃合いだ。これは割と大掛かりな仕事になるかもしれない。

Mount a windows share folder

Windows マシンを Windows10 にした際に HDD も新調して 2T の広さになったのだが、はっきり言って全然使ってない。というか、Windows マシン自体をほとんど使ってない。

もったいないので、ファイルサーバ代わりにしたい。つまり、Linux (xubuntu) 側から samba で恒久的にマウントしたい。恒久的というのは、xubuntu のファイルマネージャである Thunar 上からも一応 Windows の共有フォルダにオンデマンドでアクセスできるのだが、どこにマウントしているのかよくわからなく、Thunar の中で閉じているのが困るので。そうではなく単純に fstab に記述する形でマウントしたい。

というわけで文書を参考にマウント。