JavaScript
firefox

Firefoxのエクステンションに関して

More than 3 years have passed since last update.

先日Chromeに関して書きましたが、本日は第二弾と評してFirefoxに関して書いていきます。

せっかくなので、ChromeのエクステンションとFireFoxのエクステンションの比較なんかも書いていければと思ってます。

まずはFirefoxに関して

歴史的には1998年にNetscapeがソースコードをオープンソース化したのがきっかけ。
IEが急激に伸びていたので、それを恐れてオープンソースにしたんですね。
Phoenix→ Firebird→Mozilla Firefoxと、商標の問題等で名前を変えながら進化してきたみたいです。

先日公開された世界のブラウザシェアにおいては、Firefoxは13%。IE,chromeにつぐ第3位。

まぁ開発者に絞って言うと、Chrome or Firefoxって感じですかね。

ちなみに開発者にとっては当たり前ですが、各ブラウザにおいてHTMLやCSSを解釈するレンダリングエンジンが異なります。なので各ブラウザで解釈が違うケースがあり、ベンダープレフィックスによって対応する事が必要だったりします。

Firefoxの特徴としては、Netscape等の歴史的背景もあり、拡張機能の豊富さやセキュリティ面の配慮が挙げられるかと思います。
Firefoxはユーザ情報でマネタイズしてないですしね。

最近何かと話題じゃないか?

7月にCEOが代わってから何かと話題にあがってます。

  • Firefoxのデフォルト検索エンジンをGoogle→Yahooに変更(参考記事)

  • iOS版のFirefoxが作られるかも!?(参考記事)

  • リアルタイムコミュニケーション Firefox Helloなどを搭載したFirefox 34リリース(参考記事)

  • 開発者向けFirefox Developer Editionのリリース(参考記事)

Yahooに変えた事はユーザ体験として何とも言いがたいですが、攻める姿勢はいいですねw
Chromeとのシェアの取り合いだと思うので、何処まで盛り返せるか見ものです。

アドオンを開発してみる

Firefoxの開発方法は大きく3パターン

  • SDKを使う方法
  • XULベースの拡張機能
  • ブートストラップ型のXULベースの拡張機能

XULってXMLを元にMozillaが開発しているユーザインターフェース言語。
独自言語を使っているので、SDKを使う場合より多くの事ができる。

まぁでもSDK使いますよねw
さすがにFirefoxの為に言語は取得したくない・・・w

インストール

Macで開発する場合、SDKとPythonのインストールが必要です。
公式のチュートリアルページが分かりやすいのでここみてやって下さい。

ディレクトリ構成

|-data
  |-content_frame.js
  |-popup.html
  |-icon.png
|-lib
  |-main.js
|-package.json

chromeでいうmanifest.json的なのがFirefoxではpackage.jsonとなってます。
lib以下にはmain.jsというchromeでいうbackground.jsのような
バックグラウンドで動作するjsが存在します。

設定ファイル

{
  "name": "Hoge",
  "title": "Fuga",
  "id": "hogehoge",
  "description": "a basic add-on",
  "author": "",
  "license": "MPL 2.0",
  "version": "0.1",
  "permissions": {
    "cross-domain-content": ["後で説明"]
  }
}

中身はこんな感じ。
chromeの時だとブラウザアクションに対しての処理をする場合、permissionをかなり設定していたのにFirefoxだとここでは設定しません。

コードをちょっと解説

簡単なチュートリアルはググってもらうとすぐ出るんで、ちょっとだけコードの解説を。

Chromeと比較してFirefoxは以下の事を意識する必要があります。

  • main.js以外ではsdkは使えない(tabの操作やstorageの操作等)
  • main.js以外ではXMLHttpRequestの利用禁止
  • content_scriptとのデータのやり取りはworkerを使用して実装 chrome見たいに適当にmessageのやり取りはできない

おいおいおい・・・
さすがよりセキュアなブラウザですが、ちょっと厳しすぎやしませんか?w
ChromeからFirefoxに移ると設計がかなり狂いますwww

var {Cc, CC, Ci, Cu, Components} = require("chrome");
var notifications = require("sdk/notifications");
var data = require("sdk/self").data;
var storage = require("sdk/simple-storage").storage;
var Request = require("sdk/request").Request;
var tabs = require("sdk/tabs");
var tab = tabs.activeTab;
var url = require("sdk/url");
var buttons = require('sdk/ui/button/action');
var array = require('sdk/util/array');

var button = buttons.ActionButton({
  id: "hogeButton",
  label: "hoge!",
  icon: {
    "16": "./icon.png",
    "32": "./icon.png"
  },
  onClick: openAccountLists
});

そう、Require無双ww
基本使うSDKはrequireしないと使えないんです。
まぁ無駄なもの読み込まなくていいと思うんですけどね。

例えばChromeでいうところのchrome.storageはsimple-storageという名で存在してたり、
勿論微妙に違います。

詳しくは公式ドキュメントを読むのが一番。

何が面倒くさいってこういうstorageもmain.jsしか使えない。
わざわざ〇〇.port.emit("update", data)を使ってmain.jsとやり取りを発生させる必要があります。

面倒くさい、、、

ちなみにmain.jsとcontentScriptとのやり取りはこんな感じ

スクリーンショット 2014-12-03 19.55.24.png

コードと合わせて解説すると、popup.htmlを呼ぶ際にContentScriptFileとしてpopup.jsを呼び出す。
popup.jsとのメッセージのやり取りをするメソッドとして、"call"を設定。

main.js

function openAccountLists(state) {
  var accountLists = require("sdk/panel").Panel({
    position: {
      right: 0,
      top: 0
    },
    width: 400,
    height: 400,
    contentURL: data.url("popup.html"),
    contentScriptFile: [
      data.url("popup.js")
    ]
  });

  accountLists.on("call", function(name) {
    var str = "hey!" + name;
    console.log(str);
  });

  accountLists.show();
}

popup.js

self.port.emit("call", "Mr.Moriyama")

log

console.log: Hoge: "hey!Mr.Moriyama"

こんな感じでやり取りできます。

また上記でも記載した「main.js以外ではXMLHttpRequestの利用禁止」に関してですが、
実はpackage.jsonに記載したurl先だけ許可するといった設定が可能です。
"cross-domain-content": ["後で説明"] ここにurlを入れると可能になります。

ただし、wildcard指定はできませんw
chromeだと普通にできたので、この辺もFirefoxならではですね。
ちなみに"sdk/request"というXMLHttpRequestをモジュール化したsdkが存在します。

実際に開発してみて

もしマルチブラウザで展開するエクステンションを作りたいなら、
Firefox→chromeの方が絶対良いです。

冒頭でもお伝えしたとおり、Firefoxの方がルールが厳しいのでFirefoxに合わせるのが無難ですね。