2017/02/02 5:24 pm
Old and New
Uncategorized,

調べものの途中でたまたま常用漢字の新字体と旧字体の なるものを見ていたのだが、この旧字体で文章を組むとどんな感じなのかしらん? とふと気になったので、ひとまず赤福プラスに組み込んでみた。


なかなか味わい深い。

当初は投稿時のコメントを旧字体に変換するようにしたのだが、「なんで旧字体なの」「うぜえ」などと、ID を出されて火炙りにされそうな勢いだったのでローカルでの表示のみを旧字体に変換するようにした。

この機能は開発バージョンでのみ有効で、オン・オフの設定もない。

2016/12/17 3:14 pm
Add-on SDK to WebExtensions #3
Uncategorized, , , ,

content script において window.Uint8Array を使おうとするとエラーになる。グローバルオブジェクトのそれを使わないといけない。両者は権限のドメインが違う、らしい。グローバルオブジェクトに Uint8Array が存在する場合はそれを、次に window に存在する場合はそれを使うようにした。

window. を前置するのをやめればいいじゃん、と思うかもしれないが、そうはいかない。赤福プラスでは window のプロパティを参照する際は必ず window を前置している。これは Presto Opera で動かすための措置で、Presto Opera の injected script では window がグローバルオブジェクトではないのである。したがって前置は必須なのだった。

それにしても、今 Presto Opera 使ってる人ってどんくらいいるのかなあ…? とはいえ赤福プラスはまだ Presto Opera もサポートしているので、動作確認のために新しい環境にも 12.16 を落としてインストール。

ところでメモやブックマークを同期しようとログインしようとしたらどうやっても弾かれるんですけど…。

Firefox の方は SDK 版から WebExtensions 版への自動更新が滞りなく行われることを確認。

さてこの SDK -> WebExtensions の作業において赤福プラスは前座でしかない。本丸は wasavi なのである。

2016/12/15 5:47 pm
Add-on SDK to WebExtensions #2
Uncategorized, , ,

一通り動くようになった。

すでに上げた Port の引数の問題の他、content script で生成した XMLHttpRequest の動きが変。

  • Referer が吐かれない
  • Cookie が送出されない
  • open() の際、相対 URL を与えるとエラーになる

同様の問題を抱えている人がいた。そのやり取りによると、

   try {
      return XPCNativeWrapper(new window.wrappedJSObject.XMLHttpRequest());
   }
   catch(evt){
      return new XMLHttpRequest();
   }

こんな感じで Firefox に限り意味の分からない書き方をすることで解決できるそうな。確かにこれでうまく行くけど…早く直してほしい。

ところでもうひとつ、ID の問題がある。Chrome のエクステンションは基本的にそれを識別する ID というものを開発者が意識する必要はない。エクステンションをローカルで crx にパッケージングした際に生成される .pem ファイルは取り扱いに気をつける必要はあるが、今日ではローカルパッケージングは zip で事足りるので .pem ファイルを生成する必要自体が基本的にない。

WebExtensions の場合は一応その流儀に倣っているが、しかしやはり Firefox の拡張らしく、ID は裏で健在だったりする。というのも署名を mozilla のサーバにつけてもらうと .web-extension-id という ID が書かれたドットファイルをもれなくプレゼントされるのである。うーんなんかイケてなくないですか。

一方で陽に ID を取り扱うこともできる。manifest.json の applications に

  "applications": {
    "gecko": {
      "id": "[email protected]",
      "strict_min_version": "42.0",
      "update_url": "https://github.com/akahuku/akahukuplus/raw/master/dist/firefox.json"
    }
  },

とこんな感じに書けばいい。ただよく分かんないことに、こう明示したとしてもやはり .web-extensions-id ファイルはプレゼントされる。いらないんですけど!

ところで上記の ID、いかにも Add on SDK 製の拡張っぽい書式だが、実際に SDK 版の赤福プラスの ID だ。というのも、おそらく流用しないと SDK 版から WebExtensions 版へのスムーズな自動更新が行えないからだ。うーんなんだかかっこ悪いなあ…。

2016/05/01 7:00 am
Optimize a loading of assets
Uncategorized, , ,

赤福プラスの話。

赤福プラス 3.x はふたばの画像掲示板を開いた時に DOMContentLoaded のタイミングで一旦ドキュメントをすべて書き換える。これはなかなかアグレッシブな動作で、3.x 未満の赤福プラスや、おそらくは他の、ブラウザ上で動作するふたば閲覧エクステンションはあくまでふたばがネイティブで送出するコンテンツに何かを「付け足す」ようになっていると思う。赤福プラス 3.x はそうではなく、完全に書き換える。元のドキュメントからメタな中間 XML ドキュメントを生成し、それを XSLT によって HTML に変換・再構築し、元のドキュメントに上書きする。

さて DOMContentLoaded というのは定義としては DOM の構造を構築し終わった段階で発火するイベントで、load イベントに比べてかなり早い段階で発生する。しかし、これはドキュメントに付随するスタイルシートやスクリプトや画像や iframe で指定されるサブフレームのドキュメントをまだ読んでいない段階というわけでは *ない*。もしかしたら並行して読んでいる途中かもしれないし、そうでないかもしれない。特に最新のブラウザほど、並行動作をしている割合が高い。

このブラウザの動作は、赤福プラスの仕様とは相容れない。もしその手のアセットを読み込むとしても、それは赤福プラスが管理する文書の下で読み込まれるべきで、その前段階でネットワークアクセスが発生するのは全て無駄になるため、好ましくない。

そういうわけで、その辺りを最適化するために以前から Presto Opera では外部の script 要素の動作をブロックしたりしていた。似たようなことは Chrome の WebRequest API でもできるわけで、やってみた。

やることは、赤福プラスがページを再構築している間、そのページから発生するふたば外へのリクエストをすべてブロックすることである。そのために、

  • バックエンドの main.js にタブ ID をキーとするハッシュ initializingTabIds を用意する
  • WebRequest API によりすべてのリクエストをリスンする
  • ふたばの画像掲示板の URL がアクセスされたら、そのタブ ID を initializingTabIds に記録する
  • その他の何かがアクセスされた場合、それが属するタブ ID が initializingTabIds に含まれていれば、リクエストをキャンセルする
  • 赤福プラスのフロントエンドがページを再構築を完了したら、バックエンドへ initialized メッセージを投げる
  • バックエンドが initialized メッセージを受け取ったら、そのタブ ID を intializingTabIds から削除する

という処理を加えた。

ところで WebRequest を使うには manifest.json の permissions に “webrequest” および対象となる URL パターンを含める必要がある。今回の場合は URL は http://*/* および https://*/*/ というかなり広範囲に及ぶ強いパーミッションを必要とする。その場合 webstore での審査もけっこう時間がかかるようだ。昨日の午後提出して今審査が通った。

ちなみに Firefox 版はそういう最適化をしていないので読み込みが一番遅い。気が向いたらがんばる。

2016/04/14 7:45 pm
Mysterious bound keyword
Uncategorized, , , , ,

Firefox 46a だったか 47a だったか忘れたが、wasavi と赤福プラスが両方動かなくなったことがあって調べてみた所、

  1. 両方が使っている extension_wrapper.js 内で、それが Firefox + Add on SDK で動いているかどうかを判断している箇所があり
  2. Firefox のその該当バージョンで判断のもとになっている箇所が変更されたため

動かなくなっているということだった。

extension_wrapper.js は Chrome でも Opera でも Firefox でも共通して動くので、それぞれのブラウザのうちどれで動いているのかを判断しないといけない。Chrome なら window.chrome が存在しており、Opera なら window.opera が存在しているのでそれが判断の助けになる。。

一方 Add on SDK の PageMod における content script かどうか、というのを判断するためのあんしんあんぜんな方法はないように思える。とりあえずのところ、self.on が存在し、それが function であり、かつその toString() の値が “function on (.*?) { [native code] }” とかそんな感じになっていればまあたぶんきっと SDK ベースの content script だろう…というような判断をしている。”[native code]” がミソなのだが、これが最適解というわけでは全然ない。

これが、今回動かなくなってしまったのである。それは、self.on の toString() の値が “function bound on (” というように、謎のキーワード bound が入るようになっていたからだ。bound……って何?

2016/03/14 1:15 am
Tegaki #2
Uncategorized, ,

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 やペンサイズを変更するためのショートカットなどを追加。

2016/03/12 4:39 am
Tegaki
Uncategorized,

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

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

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

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

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

* * *

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

2015/09/18 9:44 pm
cfx to jpm #3
Uncategorized, , , ,

wasavi も 0.6.580 から jpm でビルドするようにした。ただこれらのツールは、ビルド時だけではなく実行時にも影響を及ぼす。大昔は Add on SDK のライブラリは個々の拡張に同梱されていたが(このため wasavi でも Firefox 版だけやたらサイズがでかくなるという問題がかつてあった)最近は SDK のライブラリは Firefox 自身が保持するようになっている。困ったことにこのライブラリが、cfx でビルドされたかあるいは jpm かで微妙に動作を変える。

たとえば cfx の require() に比べて jpm のそれはより commonjs に準拠しているようになっていて、cfx では基準のディレクトリが常に lib なのだが(正確には、エントリポイントスクリプトの dirname かもしれない。未確認)、jpm では require() を実行したソースが位置するパスが基準になるのである。つまり lib/foo とか lib/bar とかだったりと可変なのだ。

これで何が困るのかといえば、wasavi や akahukuplus はソースの共通化のために require() の polyfill を定義しているのだが、ある関数を呼び出した際にその呼び出し元のソースファイルのパスを得るという標準的な方法がないことだ。

標準的な方法がないということは、標準的ではない方法を使わざるを得ないということで、具体的には (new Error).stack が返す文字列を取得して解析するしかない。しかしこれは非常に脆弱で、各ブラウザベンダがこのプロパティが返す文字列の内容をちょっとでも変えたら即破綻する。文字列ではなく、もっと構造化されたオブジェクトでスタックフレーム情報を返してくれればもうちょっとましなのだけど…。

さて、cfx から jpm への移行で最後に残ったのは赤福プラスだ。これも移行してみた。また、最近は絵文字が unicode のコードポイントにやたら導入されている状況を鑑みたり鑑みなかったりしつつ、コメント中の絵文字は twitter のそれと同様の画像で置き換えるようにしてみた。

akahukuplus-emoji

2015/08/17 3:58 am
signing akahukuplus
Uncategorized, ,

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

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

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

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

const FUN = '<an encrypted string of "Function">';
var fun = some_decrypt_function(FUN);
var f = window[fun]('alert("wow!");');

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

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

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

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

2015/02/17 11:35 pm
Some spices for Qeema
Uncategorized, , , ,

Qeema によってキーボード周りを wasavi と赤福プラスで共通化したのだけど、キーボードの扱い方は両者でかなり異なる。

赤福プラスはいくつかのキーボードショートカットを定義しているが、それ以外に関しては手を付けない。一方 wasavi は全てのキー入力をリスンし、全てのキー入力を消費し(つまりデフォルトアクションをキャンセルし)、自前の処理を行う。この中で、全てのキー入力というのは composition events によって発生したものも含まれる。

ところが、composition events というのは単なる通知イベントなので、DOM の定義上はキャンセルできないのである。なので、qeema 側で compositionstart の時点での入力文字列を覚えておき、compositionend で復帰するようにしている。

ついでに、Presto Opera での composition events エミュレーションをできるだけシンプルな構造に書きなおした。まあ、いまさらこれをブラッシュアップしたところで誰も幸せにならないんですけどね……。

アーカイブ