from electron 2 web

インターネットのリソースを無駄遣いして検索におけるUXを下げてごめんなさい

圧倒的文章力のNASAでゴミみたいなチラ裏のようなメモを量産してしまい全ての"Web開発者"にごめんなさい

「Popup ALT AttributeアドオンにおけるXUL/XPCOMからWebExtensionsへの移行」を翻訳した(原文と翻訳文)

dev.mozilla.jp

 

この記事はhttps://blog.mozilla.org/addons/2016/04/26/migrating-popup-alt-attribute-from-xulxpcom-to-webextensions/の翻訳です。

 

今日の投稿はPopup ALT Attribute40 other add-onsを 開発しているpiro氏の記事からの投稿です。彼はXUL/XPCOMアドオンからWebExtensionに移行するための考えを共有し、彼がどのよう にPopup ALT Attributeを移行したかを私たちに見せてくれました。彼のブログで全文を読むことができます。

Today’s post comes from Piro, the developer of Popup ALT Attribute, in addition to 40 other add-ons. He shares his thoughts about migrating XUL/XPCOM add-ons to WebExtensions, and shows us how he did it with Popup ALT Attribute. You can see the full text of this post on his personal blog.

***

こんにちは、アドオン開発者のみなさん。私の名前は結城洋志、ニックネームはPiro、そしてFirefoxアドオンの開発者です。

私はとても長い期間、個人的に、またビジネスで、XUL/XPCOMベースのFirefoxアドオンやThunderbirdアドオンを開発してきました。

Hello, add-on developers. My name is YUKI Hiroshi aka Piro, a developer of Firefox add-ons. For many years I developed Firefox and Thunderbird add-ons personally and for business, based on XUL and XPCOM.

私 は最近アドオンたちをWebExtensionに移行するために必要となるAPIのリサーチを始めました。Mozillaが"XUL/XPCOMベースの アドオンを2017年の終わりまでに廃止する"と告知したからです。私はいくつかのアドオンは現在使用可能なAPIだけでけしか移行できることに気づきま した。Popup ALT Attribute もそれらのアドオンの中の一つです。

I recently started to research the APIs are required to migrate my add-ons to WebExtensions, because Mozilla announced that XUL/XPCOM add-ons will be deprecated at the end of 2017. I realized that only some add-ons can be migrated with currently available APIs, and
Popup ALT Attribute is one such add-on.

Here is the story of how I migrated it.

これは私がどのようにWebExtensionに移行させたのかを綴った物語です。

What’s the add-on?

このアドオンについて

Popup ALT Attribute is an ancient add-on started in 2002, to show what is written in the alt attribute of img HTML elements on web pages. By default, Firefox shows only the title attribute as a tooltip.

Popup ALT Attribute は2002年からスタートしているとても古くからあるアドオンで、これはwebページのimg HTML要素の alt 属性を表示に書かれている内容を表示するものです。通常、Firefoxはtooltipに title 属性のみ表示します。

Initially, the add-on was implemented to replace an internal function FillInHTMLTooltip() of Firefox itself.

最初に、このアドオンはFirefox自身の FillInHTMLTooltip()内部関数を置き換える機能が実装されています。

In February 2016, I migrated it to be e10s-compatible. It is worth noting that depending on your add-on, if you can migrate it directly to WebExtensions, it will be e10s-compatible by default.

2016年1月、私はこのアドオンを e10s に対応させました。このことはあなたのアドオンの状態によって価値が変わるでしょう。もしあなたが直接WebExtensionに移行するなら、WebExtensionはデフォルトでe10sに対応しているからです。

Re-formatting in the WebExtensions style

WebExtensionスタイルに再フォーマッティング

 

I read the tutorial on how to build a new simple WebExtensions-based add-on from scratch before migration, and I realized that bootstrapped extensions are similar to WebExtensions add-ons:

私は移行する前に、どのように1からWebExtensionベースのシンプルなアドオンを作るかのチュートリアルを読み、WebExtensionはブートストラップ型拡張に似ていることに気が付きました。

  • They are dynamically installed and uninstalled.
  • They are mainly based on JavaScript code and some static manifest files.
  • 両者は動的にインストール、再インストールされる
  • 両社は主にJavaScriptコードがベースでいくつかの静的なマニフェストファイルを持っている。

My add-on was easily re-formatted as a WebExtensions add-on, because I already migrated it to bootstrapped.

私はすでにこのアドオンをbootstrapped型アドオンに移行していたため、容易にWebExtensionに再構成することができました。

This is the initial version of the manifest.json I wrote. There were no localization and options UI:

これは私が書いた初期のバージョンの manifest.json です。これはlocalizationやオプション用のUIがありません

<code>{
  "manifest_version": 2,
  "name": "Popup ALT Attribute",
  "version": "4.0a1",
  "description": "Popups alternate texts of images or others like NetscapeCommunicator(Navigator) 4.x, and show long descriptions in the multi-row tooltip.",
  "icons": { "32": "icons/icon.png" },
  "applications": {
    "gecko": { "id": "{61FD08D8-A2CB-46c0-B36D-3F531AC53C12}",
               "strict_min_version": "48.0a1" }
  },
  "content_scripts": [
    { "all_frames": true,
      "matches": ["&lt;all_urls&gt;"],
      "js": ["content_scripts/content.js"],
      "run_at": "document_start" }
  ]
}</code>

 

I had already separated the main script to a frame script and a loader for it. On the other hand, manifest.json can have some manifest keys to describe how scripts are loaded. It means that I don’t need to put my custom loaders in the package anymore. Actually, a script for any web page can be loaded with the content_scripts rule in the above sample. See the documentation for content_scripts for more details.

私 はすでにmain scriptをフレームスクリプトloaderに分けていました。一方、 manifest.json はどのようにロードされたかを述べるための いくつかのマニフェストキーを持ちました。これはパッケージに自作したカスタムloaderを何も追加する必要のないことを示しています。実際、上記のサ ンプルに含まれている content_scripts ルールによってどんなwebページにもスクリプトをロードすることができます。 content_scripts の詳細はドキュメントをご覧ください。

So finally only 3 files were left.

そして最後には、3つのファイルにすることができました。

Before:

<code>+ install.rdf
+ icon.png
+ [components]
+ [modules]
+ [content]
    + content-utils.js</code>

And after:

<code>+ manifest.json (migrated from install.rdf)
+ [icons]
|   + icon.png (moved)
+ [content_scripts]
    + content.js (moved and migrated from content-utils.js)</code>

And I still had to isolate my frame script from XPCOM.

そして、私はまだ、XPCOMから自分のフレームスクリプトを分離する必要があります。

  • The script touched nsIPrefBranch and some XPCOM components via XPConnect, so they were temporarily commented out.
  • scriptはnsIPrefBranchやXPConnectを通していくつかのXPCOMとつながっています。そのためそれらを一時的にコメントアウトします。
  • User preferences were not available and only default configurations were there as fixed values.
  • ユーザープレファレンスは使用不可になり、値を固定し、デフォルト設定のみ使用可能になります。
  • Some constant properties accessed, like Ci.nsIDOMNode.ELEMENT_NODE, had to be replaced as Node.ELEMENT_NODE.
  • Ci.nsIDOMNode.ELEMENT_NODEのように、いくつかの定数のプロパティにアクセスされるXPCOMコンポーネントNode.ELEMENT_NODEのような形に置き換えました。
  • The listener for mousemove events from web pages was attached to the global namespace for a frame script, but it was re-attached to the document itself of each web page, because the script was now executed on each web page directly.
  • webページから mousemove eventsを取得するリスナーはフレームスクリプトのグローバル名前空間にアタッチされますが、しかしこれはそれぞれのページのdocument自身に再アタッチされます。なぜなら現在 scriptはwebページで直接実行されるからです。

Localization

ローカライズ

For the old install.rdf I had a localized description. In WebExtensions add-ons I had to do it in different way. See how to localize messages for details. In short I did the following:

xpcomアドオンのinstall.rdfでは、説明をローカライズしていました。webextensionでは異なった方法でローカライズする必要があります。詳細はhow to localize messagesをご覧ください。以下で簡単な説明を行います:

Added files to define localized descriptions:

ローカライズした説明を記述するためにファイルを追加します

<code>+ manifest.json
+ [icons]
+ [content_scripts]
+ [_locales]
    + [en_US]
    |   + messages.json (added)
    + [ja]
        + messages.json (added)</code>

Note, en_US is different from en-US in install.rdf.

en_USinstall.rdfのバージョンのen-USと異なることに注意してください。

English locale, _locales/en_US/messages.json です:

<code>{
  "name": { "message": "Popup ALT Attribute" },
  "description": { "message": "Popups alternate texts of images or others like NetscapeCommunicator(Navigator) 4.x, and show long descriptions in the multi-row tooltip." }
}</code>

Japanese locale, _locales/ja/messages.json was also included. And, I had to update my manifest.json to embed localized messages:

日本用のlocale, _locales/ja/messages.jsonもまた含まれています。そして、manifest.jsonローカライズされた言葉を埋め込むために修正する必要があります。

<code>{
  "manifest_version": 2,
  "name": "__MSG_name__",
  "version": "4.0a1",
  "description": "__MSG_description__",
  "default_locale": "en_US",
  ...</code>

__MSG_****__ in string values are automatically replaced to localized messages. You need to specify the default locale manually via the default_locale key.

__MSG_****__文字列変数は自動的にローカライズされたメッセージに置き換えられます。default_localeキーを通して、手動でデフォルトロケールを設定することが必要です。

Sadly, Firefox 45 does not support the localization feature, so you need to use Nightly 48.0a1 or newer to try localization.

残念ながら、firefox45ではローカライゼーション機能はサポートされていません。そのためlocalizationを行うには Nightly 48.0a1以上のバージョンが必要になります。

User preferences

ユーザープレファレンス

Currently, WebExtensions does not provide any feature completely compatible to nsIPrefBranch. Instead, there are simple storage APIs. It can be used like an alternative of nsIPrefBranch to set/get user preferences. This add-on had no configuration UI but had some secret preferences to control its advanced features, so I did it for future migrations of my other add-ons, as a trial.

現在、WebExtensionsはnsIPrefBranchと互換性 を持っている機能を提供していません。しかし、代わりに、シンプルなストレージAPIを持っています。これはuser preferencesをset/getするための nsIPrefBranch の代わりに使えます。このアドオンはUIの設定をもっていません。しかし拡 張的な機能をコントロールするためにいくつかのsecret preferencesをもっています。そのため私の他のアドオンの移行のために試験的に挑戦しました。

Then I encountered a large limitation: the storage API is not available in content scripts. I had to create a background script just to access the storage, and communicate with it via the inter-sandboxes messaging system. [Updated 4/27/16: bug 1197346 has been fixed on Nightly 49.0a1, so now you don’t need any hack to access the storage system from content scripts anymore. Now, my library (Configs.js) just provides easy access for configuration values instead of the native storage API.]

そして私は大きな壁にぶつかります。ストレージAPIコンテンツスクリプトでは使用可能ではないのです。私はストレージにアクセスするだけのため にバックグラウンドスクリプトを作成することが必要で、さらに内部サンドボックスメッセージシステムを通してコンテンツスクリプトとコミュニケーションを とる必要があります。(更新情報: bug 1197346Nightly 49.0a1では修正されています。そのためコンテンツスクリプトからストレージシステムにアクセスするようなハックはもう必要ありません。現在、私はネイティブなストレージAPIの代わりに設定値に簡単にアクセスできるようなライブラリ(configs.js)を提供しています。)

Finally, I created a tiny library to do that. I don’t describe how I did it here, but if you hope to know details, please see the source. There are just 177 lines.

最後に私はそれを行うために小さなライブラリを作成しました。私はここでは説明しませんが、もしあなたが詳細を知りたいなら、ソースコードをご覧ください。177行のライブラリがあります。

I had to update my manifest.json to use the library from both the background page and the content script, like:

私は二つのバックグラウンドスクリプトやコンテンツスクリプトを使用するために自分のmanifest.jsonを更新する必要がありました。

<code>  "background": {
    "scripts": [
      "common/Configs.js", /* the library itself */
      "common/common.js"   /* codes to use the library */
    ]
  },
  "content_scripts": [
    { "all_frames": true,
      "matches": ["&lt;all_urls&gt;"],
      "js": [
        "common/Configs.js", /* the library itself */
        "common/common.js",  /* codes to use the library */
        "content_scripts/content.js"
      ],
      "run_at": "document_start" }
  ]</code>

Scripts listed in the same section share a namespace for the section. I didn’t have to write any code like require() to load a script from others. Instead, I had to be careful about the listing order of scripts, and wrote a script requiring a library after the library itself, in each list.

同じセクションに記載されているスクリプトはセクションの名前空間を 共有しています。他からscriptをロードするためにrequire()のようなも のは必要ありません。代わりに、私は各リストのscriptの並び順に気を付け、ライブラリを必要とするスクリプトが、必要とされるライブラリ自身の後に なるように書く必要があります。

One last problem was: how to do something like the about:config or the MCD — general methods to control secret preferences across add-ons.

そして最後の障害に当たります。about:cofigやMCDに当たる動作を実現するにはどうすればいいのか・・・一般的な方法はアドオン全体にわたる秘密のプレファレンスを制御することです。

For my business clients, I usually provide add-ons and use MCD to lock their configurations. (There are some common requirements for business use of Firefox, so combinations of add-ons and MCD are more reasonable than creating private builds of Firefox with different configurations for each client.)

私の仕事の顧客に対して、大抵アドオンを提供して、彼らの設定をロックするためにMCDを使用しま した。(Firefoxをビジネスで使用するためにいくつかの共通の要件として、アドオンとMCDの組み合わせは、それぞれの顧客用に異なった設定の Firefoxプライベートビルドを作成するよりもかけるコストが少なくて済みます。)

I think I still have to research around this point.

私はまだこの当たりを探る必要があると考えました。

Options UI

WebExtensions provides a feature to create options pages for add-ons. It is also not supported on Firefox 45, so you need to use Nightly 48.0a1 for now. As I previously said, this add-on didn’t have its configuration UI, but I implemented it as a trial.

WebExtensions はアドオンに対してオプションページを作成する機能を提供しています。これも同じく、Firefox45ではサポートされていません。そのため現在あなた はNightly 48.0a1を使用する必要があります。前に私が言った通り、このアドオンはコンフィグ用にUIを持ちません。しかし私は勉強用に試してみました。

In XUL/XPCOM add-ons, rich UI elements like <checkbox>, <textbox>, <menulist>, and more are available, but these are going away at the end of next year. So I had to implement a custom configuration UI based on pure HTML and JavaScript. (If you need more rich UI elements, some known libraries for web applications will help you.)

Xul/XPCOMアドオンでは、<checkbox>, <textbox>, <menulist>や 他にもリッチなUI要素が使用可能です。しかしこれらは来年末までに使用不可能になります。なので私は純粋なHTMLとJavascriptベースのカス タム設定用UIを実装する必要がありました。(もしあなたがもっとリッチなUIの要素を必要とするならWebApplication用のライブラリなどが 助けてくれるでしょう。)

On this step I created two libraries:

このステップで私は2つのライブラリを作成しました。

Conclusion

終わりに

I’ve successfully migrated my Popup ALT Attribute add-on from XUL/XPCOM to WebExtensions. Now it is just a branch but I’ll release it after Firefox 48 is available.

私は自分のPopup ALT AttributeアドオンをXUL/XPCOMからWebExtensionsに移行することに成功しました。現在ここのブランチにありますが、Firefox48が使用可能になってからリリースしようと思っています。

Here are reasons why I could do it:

これが私が移行することのできた理由です

  • It was a bootstrapped add-on, so I had already isolated the add-on from all destructive changes.
  • The core implementation of the add-on was similar to a simple user script. Essential actions of the add-on were enclosed inside the content area, and no privilege was required to do that.
  • これがブートストラップ型拡張でした、そのため既にアドオンに破壊的な変更を行う必要がありませんでした。
  • このアドオンの中心の実装はシンプルなユーザースクリプトに似ていました。アドオンの中心的な動作は、コンテンツスクリプト中で動作します。そしてこれを行うために、特権を必要としていません。

However, it is a rare case for me. My other 40+ add-ons require some privilege, and/or they work outside the content area. Most of my cases are such non-typical add-ons.

しかし、これは珍しいケースです。私の他の40以上のアドオンはいくつかの特権を必要とし、コンテンツエリアの外側で動作します。私のアドオンのほとんどは、このような非典型的なアドオンです。

I have to do triage, plan, and request new APIs not only for me but for other XUL/XPCOM add-on developers also.

私にはtriageしたり計画を立てたり複数新しいAPIをリクエストすることが必要です。これは私だけではなく、他のアドオン開発者も同じでしょう。

Thank you for reading.

読んで頂きありがとうございます。