はてなスクリーンショットが Firefox 44 で動かなくなった

結構、便利に使わせてもらってる「はてなスクリーンショット拡張」。

でも、Firefox 44 では動かなくなってしまった。
人力検索でも似たような質問が……

ちょっと前から気になっては いたんだ

64bit 版が使いたくて Developer Edition とかβ版を試していたのだけれど、Developer Edition では 42.0a2 くらいから、β版は 44.0b2 で、はてなスクリーンショットが動かないことに気が付いていた。
2015年の9月くらいのことで、かれこれ四ヶ月が経とうとしている。

安定板でも 43.0 から 64bit 版がダウンロードできるようになったので、そっちに逃げていたのだけれど、43.0.4 → 44.0 のアップデートで、安定板でも はてなスクリーンショットが動かなくなった。

同じようなタイミングで、人力検索でも同じような質問が上がる。
他にも動かなくなったアドオンがあって本当に不自由してたこともあり、気合を入れて調べてみた (Firefox のアドオンとか作ったことないし)。

経緯とか細かいことは後で書くとして、動かなくなった理由と、その対策を以下に。

どうして動かなくなったのか

Firefox 44 での修正

Firefox 44 から javascript のエンジン (SpiderMonkey) に下位非互換の修正が入ってる。

JavaScript
Breaking changes in let and const. Firefox 44 finally brings the let and const implementation up to standard, which also means some backward-incompatible changes had to be implemented. Read the linked blog post for the details.

https://blog.mozilla.org/addons/2015/12/29/compatibility-for-firefox-44/

Many add-ons are currently broken on Nightly (Firefox 44) due to some changes that were done in the way let and const behave. These changes were introduced to make Firefox compliant with the final ES6 standard. These changes can lead to JS errors that break your code entirely, so we suggest you test your add-ons extensively to make sure they continue to work.

https://blog.mozilla.org/addons/2015/10/14/breaking-changes-let-const-firefox-nightly-44/

let と const の挙動が ES6 標準と違ってたのを FF44 (の SpiderMonkey) で修正したよ、ということらしい。

はてなスクリーンショットが踏んだ地雷

00-utils.jsm というソースの末尾にはこんなコードがある。

var EXPORTED_SYMBOLS = [m for (m in new Iterator(this, true))
                          if (m[0] !== "_" && m !== "EXPORTED_SYMBOLS")];

このソースの global scope な変数を外部に export するための変数 EXPORTED_SYMBOLS の内容を、逐一列挙するのではなく、this のプロパティを列挙して突っ込む、という「これで export し忘れがなくなるじゃん」という小細工。
それが、この地雷を踏んだ。

ES6 global lexical bindings are not properties
The biggest incompatibility is that ES6 let and const bindings, unlike their legacy counterparts, are no longer properties on the global object. Instead, they are bindings in the global lexical scope directly below the global object.

https://blog.mozilla.org/addons/2015/10/14/breaking-changes-let-const-firefox-nightly-44/

let や const で宣言した変数が this のプロパティじゃなくなってしまったので EXPORTED_SYMBOLS に登録されず、const なオブジェクトが外部から利用できなくなって、こんなエラーを吐くようになっていた。

ReferenceError: PrefService is not defined              53-Prefs.js:22:17

動くようにするためには

アドオンのソースを修正する必要があります。
編集対象は、これを書いている時点での最新「はてなスクリーンショット拡張 1.0.7.1-signed.1-let-fixed @2013-3-31」です。

ソースを修正する

%Firefox Profile%/extensions/screenshot@hatena.ne.jp/resources/modules/00-utils.jsm の末尾に以下の 38行を追加。

/*
   for Firefox 44 or later.

   c.f.
   https://blog.mozilla.org/addons/2015/10/14/breaking-changes-let-const-firefox-nightly-44/
   let and const bindings, unlike their legacy counterparts, are no longer properties on the global object.
 */
if (! EXPORTED_SYMBOLS.includes('Cc')) {   // Firefox 44 or later ?
   EXPORTED_SYMBOLS.push(
       'Cc',
       'Ci',
       'Cr',
       'Cu',
       'OS_TARGET',
       'IS_WIN',
       'IS_MAC',
       'IS_OSX',
       'Application',
       'PrefetchService',
       'DirectoryService',
       'ObserverService',
       'StorageService',
       'IOService',
       'HistoryService',
       'BookmarksService',
       'PrefService',
       'CookieManager',
       'CookieService',
       'PromptService',
       'CryptoHash',
       'XUL_NS',
       'XBL_NS',
       'XHTML_NS',
       'XML_NS',
       'XMLNS_NS',
       'getService'
   );
}

署名の検証をスキップするように設定する

最近の Firefox (FF43 から) はアドオンに署名を要求し、ソースの改変のチェックを行ってる。なので、配布されたアドオンを自分で勝手に修正しちゃうと動かなくなっちゃう。

推奨はされないけど、抜け道も用意はされている。

アドオン署名の強制を無効にする (上級ユーザ向け)
Firefox の設定エディタ (about:config ページ) で xpinstall.signatures.required 設定の値を false に変更することで、
この設定を上書きし、署名の強制を無効にできます。

https://support.mozilla.org/ja/kb/add-on-signing-in-firefox?as=u&utm_source=inproduct
  1. ロケーションバーで about:config を入力して ENTER
  2. 警告が出るので、「細心の注意を払って使用する」をクリック
  3. signature で絞り込み
  4. xpinstall.signatures.required を true から false に変更

# 他の署名されてないアドオンとかも動くようになっちゃうので、自己責任でプリーズ

Firefox を再起動する

Firefox が起動するときに動く処理が Firefox 44 で動かなくなってるので、修正の効果を得るには再起動する必要があります。

というわけで

とりあえず最初に気が付いたエラーの対処をしてみたら、動くようになってしまった(らっきー)。

自分で使うのは、「フォトライフにアップロード」の「一部のみ」が主で、「画面全部」をたまに使うくらいだから、その範囲でしかテストしてないのだけれど、「一部のみ」については、「クリップボードにコピー」や「URLで開く」も一応 動いてるみたい。
# 「ファイルに保存」は、元々 うまく動かないのだった (´・ω・`)



署名の検証をスキップしている、という問題はあるので、運営に取り込んでもらうようにお願いしてみよう、とは思ってる。



追記 @2016-2-3

お問い合わせ窓口から頼んでみた返事が来た。

2016/02/02 | 04:55PM JST はてなサポート窓口 ( cs@hatena.ne.jp )

こんにちは。はてなスタッフ○○と申します。
いつもはてなをご利用いただきありがとうございます。

はてなスクリーンショット拡張Firefox 44.0で正常に動作しない件で
ご不便をおかけしており申し訳ありません。
現在、修正を検討しておりますが、対応する場合もお時間をいただく見込みです。

お伝えいただいたエントリーにつきましては、開発チームに共有させていただきます。

どうぞよろしくお願いいたします。

前向きな姿勢を醸し出しつつ、開発チームに流してサポートの仕事としては終了、と。
開発チームのリソース配分が利用者から見て偏ってるように見えるからこそのお問い合わせなんだけどな。

長引きそうな予感 (´・ω・`)

アドオンのおれおれ署名の方法を調べた方が早いかもしらん……



追記2 @2016-2-25

2016/02/23 | 07:37PM JST はてなサポート窓口 ( cs@hatena.ne.jp )
 ...
今後のサービス開発計画から、ブラウザ拡張類に関して、アップデートに合わせて
継続的に改修を行っていくことが難しいとの判断に至りました。

http://q.hatena.ne.jp/1453897063#c286888

さもありなん。
最近のはてなは、公開サービスは「はてなブログ」と「はてなブックマーク」にしか向いてないのは、誰が見ても明らかだもんね。

「おれおれ署名」とかじゃなく、「AMOで配布しないアドオンの署名」という方法を取るのだそうな。
備忘録はこちら



追記3 @2016-3-10

運営から、正式に切り捨てるとの告知がでました。

はてなでは、サービスを便利にご利用いただけるツール群を「便利なツール」のページにて提供しておりましたが、現在のご利用状況を鑑み、来たる3月31日をもちましてこちらのページでのツールの提供を終了、一部のツールを廃止することといたしました。

「便利なツール」(拡張、ツールバー、アプリケーション)に掲載されているツールのうち一部の提供を終了します - はてなの日記 - 機能変更、お知らせなど

そのうち、AMO からも消えるかも。
はてなスクリーンショット拡張 :: Add-ons for Firefox

まさか、GitHub からは消さないよな...
GitHub - hatena/hatena-screenshot-xul: hatena screenshot(thumbnail) firefox addon

まあ、master は、プロファイルの extensions にはあるわけだけれども。