cfx to jpm

Firefox の拡張を Add on SDK ベースで作る際、cfx というツールを使うことになる。これは python で書かれたスクリプトだ。このツールが、拡張の基本的なディレクトリ構成を作成したり、テストしたり、xpi をビルドするといった開発のサイクルをサポートしてくれる。

しかし、Mozilla 的にはこの cfx は既に deprecated である。この後継は jpm というツールになっている。jpm とは Node.js で動かす javascript のスクリプトだ。たぶん JetPackManager ということなのだろう。じゃあ cfx は何の略なんだろ。CuddleFisheXtension?

ところでなぜ cfx がダメで、jpm に移行しなければならないかという理由はよく分からない。jpm だと npm ベースなので更新が簡単だとか、activate/deactivate する必要がないとか細々した理由はあるようだけど、しかしそれらは別に技術的に cfx で実現不可能なものとは思えない。技術的な理由じゃないとすると、Mozilla 内の政治的な理由なのかもしれない。

ともあれ基本的には両者とも jetpack の仕組みに準じたツールであるので、移行したとしてもそれほど開発サイクルに変更はない。両者の違いはせいぜい 1 ページに収まる程度のものだ。

しかしながらじゃあすぐ移行しようという気にはなぜかならない。どういうわけか jpm で作った拡張は AMO に載せてもらえないとかいう期間が長かったからかもしれない(長かったというか、今もそうなのだと思う)。この措置は本当に意味が分からないが、企業や団体や組織の行動のうち、外部から見て何の意味があるのかよく分からないものはやはり政治的な理由が根底にあったりするものなので、まあそういうことなんだろう。

ここまでつらつらと書いてきて、なんだか Mozilla という団体がまともなブラウザも作れず、シェアも右肩下がりなくせして、内部の政治闘争だけは一生懸命なろくでもない奴らに思えてきたが、たぶん、きっと、おそらく、そんなことはないのです。

weblioPane fixed

Firefox の拡張に weblioPane というのがあって便利に使っていたのだが、最近になって(おそらく Firefox 40 のリリース以降)使用できなくなって困っていた。しかしなかなか新しいバージョンに更新される気配もないので勝手に直してみた。

https://github.com/akahuku/webliopane-fx40fixed

この拡張が参照している weblio の API についてのドキュメントが欲しいのだけど、見つからなかった。

WebExtensions…?

何やら物議をかもしている例の件。自作の拡張にはどういう影響があるのか考えてみる。

Firefox 版の wasavi や赤福プラスは Addon SDK ベースで作っているのだが、SDK の提供するモジュールをそのまま使っているのではない。抽象的なラッパーを挟んでいる。ラッパーが Chrome と Presto Opera と Firefox の差異を吸収して、アプリケーション内にはブラウザ固有のコードはほとんどない。

したがって、仮に WebExension ベースに移行するとしても、変更する必要があるのは Firefox 版のラッパーだけだ。そもそも WebExtensions が Chrome の拡張ベースだし、ラッパーも Chrome の拡張をベースにしたインターフェースにしてあるので、変更によりむしろコード量は少なくなるかもしれない。

一方で、SDK ベースのままにするという選択肢もある。ただ、SDK 自体は廃止は免れるということなのだけれど、それは [cci]require(‘chrome’)[/cci] していないものに限られるという。

ラッパーはもちろんこれを使っている。

  • XMLHttpRequest – SDK が提供するそれは upload プロパティをサポートしていない
  • FormData – SDK はこれを提供していない
  • Blob – SDK はこれを提供していない

つまるところ、なぜ [cci]require(‘chrome’)[/cci] を使っているのかといえば、SDK が提供する API が全般的に中途半端だからなのだ。それなのに Cu/Ci の使用を今さら咎められても困るのだが、この辺を何とかしないといけない。

Everything becomes Blink

Microsoft Edge が Chrome と Firefox の両方の拡張をサポートするかもしれない? という噂について、そんなことができるのかなと訝しんだ記事を以前書いた。

実際のところは、こういうことのようだ。
http://rockridge.hatenablog.com/entry/2015/08/16/234729
https://wiki.mozilla.org/WebExtensions

なるほど。つまり Firefox 側で Blink の拡張のインターフェース互換のフレームワークを構築すると…。しかしそうすると Addon SDK の存在意義が根底から揺らいでしまう気が。それから、Mozilla 自身が XUL を捨てたがっているというもある。しかし、Firefox 本体や既存の拡張のシステムって相当 XUL と絡み合っているわけで、そちらの存在意義も揺らいでくるような。

もしかしたら、レンダリングエンジンを servo にスイッチするタイミングでそれらも一気にグレートリセットされるのかもしれない。いやー Firefox 向けに拡張を書く人は大変だなー(他人事)。

signing akahukuplus

赤福プラスを Unlisted な拡張として AMO に提出し、署名を付けてもらった。

この際、機械的な validator が走り、ソースが検証される。この検証に引っかかった場合即時署名はされないが、AMO の中の人によるレビューを申請することはできる。一方、検証にすべて通れば即時署名が施される。いずれにしても署名された xpi は AMO の自分のアカウント内に保存されるのでそれをダウンロードして別の場所で公開すればいい。

赤福プラスがこの検証にすべて通ったわけだが、前に書いた通り検証を行う validator は本当にひどい出来なのだった。ひどい出来だし、意味のない設計方針に基づいて作られている。

たとえば validator は eval や、Function や、innerHTML や、insertAdjacentHTML や、引数がリテラルではない createElement があると即時署名を拒否する。そんなわけで

const FUN = '';
var fun = some_decrypt_function(FUN);
var f = window[fun]('alert("wow!");');

のような感じでとにかくソースからイケないメソッドやプロパティ名を隠す。すると、validator はころっと騙される。

ああ、嫌なコードだなあ。嫌だし、自動検証に対してしか提出しない場合にのみ許される手法だ。これを preliminary review とかに提出したら必ず「この処理って何やってんの?」と聞かれるし、そして拒否されるだろう。

そもそもこの手のチェックに意味があるんだろうか。eval や innerHTML 自身が悪というわけではないのだ。使い方の問題なのだ。AMO の手で署名を付けてその拡張の生殺与奪権を握っているわけなのだから、イケない拡張がイケない使い方をしているなあと判明した時点でロックダウンすればいいんじゃなかろうか。

Opera から移行して以来、努めて愛そうとしているけれど、残念ながら Mozilla にもその製品にも、本当にがっかりさせられることが多い。

Firefox 42 #2

42.0a2, e10s off

  • 新しいタブを開いてアドレスバーに適当なアドレスなり検索語句を打ち込んでエンターを押してもうんともすんとも言わない時がある
  • リンクをクリックしてもうんともすんとも言わない時がある

ここまではまあ Developer Edition だからそのうち直るのだと思う。

一方で keysnail の行く末が気になるのだけど:

eval を使ってるとだいたいレビュー結果は芳しくないものになるのはどこも同じようです。それから、innerHTML や insertAdjacentHTML を使ってもいい顔をされない。でも、プラグインのような機構を備えた拡張を作ろうとしたら、eval を使わざるを得ないわけで一律に reject されても困るよねえ。その場合、「これこれこういうわけで eval を使わざるを得ないので許してくだち!」というメッセージと共に人の手によるレビューを申請することになるんだと思うけど、その辺のフローがよく分からないというかさっぱり分からない。どうも AMO のやりたいことがよく分からない。AMO の言葉は誰にも分かんない。AMO の静かな願いも分かんない。

というか、bugzilla で validator 関連を見てみると現在進行形で署名フローの議論してたりするので、何がどうなるのが正しいのかは AMO の中の人にもまだ分からないのかもしれない。

……なんか、仕事が雑だなあ。

Firefox 42

Firefox Developer Edition が 42.0a2 に更新された。

  • 開発のため未署名のまま入れている拡張群がすべてブロックされてしまった。それらを動かすためにわざわざ Developer Edition を入れたんですけど……。しかしこれは単に about:config で [cci]xpinstall.signatures.required[/cci] を false にするだけだった。それにしてもどうしてデフォルト値を true にするんだ。どういう嫌がらせだ。
  • Electrolysis、あるいは e10s という Firefox をマルチプロセスにする計画があり、42.0a2 ではそれがデフォルトでオンになった。
    おそらく、wasavi などの Addon SDK ベースで作っている拡張は、e10s 環境下でも特に影響はないんだと思う。しかし困ったことに keysnail が動かなくなる。正確に言うと keysnail 自体は動くのだけど、.keysnail.js に書いたスクリプトでコンテント領域の DOM に触っている部分が軒並み動かなくなる。e10s は Firefox 自身のプロセスとコンテント領域のプロセスを分離するのがミソだということなので当然だ。
    幸いにして、今のところは e10s を有効にするかは単に about:preferences で指定できる。でも、将来的にはこれどうなるんだろう。常に有効とかになったら keysnail 死んじゃう。

be a developer #2

例の Firefox の署名周り。公式のドキュメントとしては https://dev.mozilla.jp/2015/02/extension-signing-safer-experience/ あたり。

このドキュメントには書いていないが、ものすごく重要なことがある。それは AMO に提出した拡張がレビューされるまで、月単位で待たなければならないということだ。レビューされるのが早いか、弥勒菩薩が降臨するのが早いか…という勢いである。枯れた安定した拡張ならともかく、新しく次々と更新されるホットなそれにとっては AMO はまったく頼りない場所であるということだ。

それを補うために、従来はベータチャネルというものがあって、1.0.0beta みたいに名づけたバージョンはベータ版扱いになり、アップした際の機械的なコードバリデータでのチェックでエラーさえ出なければとりあえず即 AMO 上に乗る仕組みがあった(ただし、当然 AMO がレビュー済みというお墨付きは得られない。また事前に full レビューを済ましたものでなければならない)。

今回署名周りの変更に従って、どうもこのベータチャネルのフローも変化している感じがする。コードバリデータでエラーも警告も一切でない 100 点満点の結果を出せば、おそらく従来通り即 AMO に乗るのだろう。しかし警告を出すと人の手によるコードレビューに送るフローしか選択できなくなってしまう。そして人の手によるレビューは前述の通り月単位で時間がかかるのである。したがって、「不安定かもしれないけど即公開される」というベータチャネルの意義を AMO 自身が完全にぶっ壊しているということになる。

ここで、「警告を出さないクリーンなコードにしないお前が悪いんじゃん」と思われるかもしれない。本質的にはそうだろう。しかし現実的にはコードバリデータがどうも信用できないのだ。警告ではないものにまで言いがかりをつけてくるポンコツに思えて仕方がないのだ。

たとえば以下のように、setTimeout() や setInterval() の第 1 引数に関数リテラルではないものを渡すとバリデータは警告を出す。しかも、reject severity: high という扱いで。

handler = function () { ... };
:
:
setTimeout(handler, 100);

これが何故警告の対象になるのかというとおそらく、コールバック関数を変数経由にすると、その変数の中身を外部から書き換えられてしまい、任意の関数を送り込まれる危険性がある……的なものだと思う。だからコールバックは関数リテラルで書けよとバリデータは言ってくる。

しかしこの場合、問題の本質はコールバックを変数経由にした場合にその変数が外部から操作可能なスコープにあるかどうかであって、関数リテラルで書いているかどうかではないと思うのです。そういう視点ではなく、バリデータは単に字面しか見ていない感じがする。信用できない。

ちなみにこれを

handler = function () { ... };
:
:
setTimeout(function(){handler()}, 100);

と書き換えると警告は出ないのだが、これじゃあバリデータくんが危険視するらしき危険性はまったく除去されてない。これを見逃すというのは、やはりバリデータは単に字面しか見ていない感じがする。信用できない。

Mozilla は自分のところで javascript エンジンを作っているのだから、自慢のなんとかモンキーをベースにもっとちゃんとしたバリデータを作れると思うのです。それをやっていない。バカでも作れる、grep に毛が生えたようなツールしか作っていない。

他にもたくさん「なんでこれが警告扱いになるのか意味わかんねーです…」というものをたくさんお出しされてとってもげんなり来る。

もっと真面目にやってほしい。

Some essential changes

wasavi 0.6.387 を github に上げた。このビルドには、いくつかの重要な変更がある。

まず、Firefox 版が Github 上で起動しない問題。前述の通り、これは wasavi をページ上に出す際の iframe に割り当てる src のドメインの問題だ。Github の CSP が data: スキームを許可していない。

そこで、iframe の src へは [cci]about:blank?wasavi-frame-source[/cci] というアドレスを割り当てることにした。当然中身は空っぽなので PageMod を経由して中身を差し込む。ちなみに about: スキームも CSP は許可していないのだが、結局 CSP の記述を実際にどう利用するかはブラウザが判断することであり、いろいろな例外があるわけで、すなわち about: 系は許されるのであり。このへんは実際に試してみないとわからないのだった。

実は Github で起動しない理由は他に、Hotkey モジュールに定義したショートカットよりもページスクリプトが消費するキー入力イベントが優先されるというのもある。しかし Firefox 版で Hotkey モジュールを使った理由というのは、それがページスクリプトよりも優先されるはずだからなのであり、実際その当時はその通り動作した。しかし現在はそうではないのである。しかし、まあ、Firefox というものは、大体において、そういうものなのでしょう、きっと。これは単に Chrome や Presto Opera と同様、keydown のフック機構を経由してキー入力を監視する方式に切り替えればいい。このくらいでは泣かないぞ。

* * *

insert モードと replace モードを総称して input モードと呼ぶ。従来はそれを実現するために、カーソル位置に重ね合わせる形で透明な textarea を配置し、それが受けたイベントを wasavi へ転送するというわけのわからない複雑さを備えた謎の機構を経由していた。なんでこんなめんどくさいことをしているのかといえば、すなわち Presto Opera のためだ。あの苦労してこさえた擬似 composition イベントは、textarea がフォーカスを持っている状態じゃないと正しく生成できないのである。

しかし、まあ、Presto Opera でありますよ。そろそろ引退させたほうがいろいろな方面が幸せになるのですよ。

というわけで input モードでは div 要素の contenteditalbe 属性を利用するようにした。これにより結構な量のコードをばっさり削除できるのである。おまけに入力のオーバーヘッドも減り、Selenium のテストも速くなり、word wrapping なども CSS での指定をそのまま使用でき、悪いものはないのである。強いて言えば前述の通り Presto Opera で IME を通した入力ができなくなるが、Presto Opera 上で wasavi を使っている人間なんて地球上にただ数人いるかいないかであり特に問題ではない(とはいえ最低限おかしくならない程度の処理は入れたが、まあ完全ではない)。

Some topics

  • [cci]cfx run[/cci] で wasavi のデバッグ用 Firefox を起動する。そうすると console への出力がそのまま端末にリダイレクトされるのだが。Firefox 自身が持っている chrome:// なんちゃらドメインの各種 javascript ソースから発生するログがあまりに多すぎる。たいていは strict モードにまつわるエラーで、中には本気でこれバグってるんじゃないの? 系のエラーメッセージもあったりする。オブジェクトの存在しないプロパティにアクセスしてたり、null のオブジェクトに触ってたり。

    ちょっと、ひどい。直したほうがいいんじゃないですか。

  • Blink Opera の wasavi では、ページフックスクリプトをいうものを有効にしていたのだが。すべて除去した。

  • Firefox 版の wasavi では、たとえば github 上で動作しない。これはなぜかといえば github のサーバから送られてくるレスポンスヘッダ内の CSP が原因だ。Firefox 版の wasavi は data スキームの内容を src にした iframe だ。しかし github のページの CSP は data スキームの iframe を許可しない。

    これ、どうしたものかなー。もしかしたら解決の糸口になるかもしれないものを一応メモ。

    Firefox Addon SDK: Loading addon file into iframe
    http://stackoverflow.com/questions/21082162/firefox-addon-sdk-loading-addon-file-into-iframe