※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。



  • e10s対応拡張機能を作成する際は、install.rdf に以下の記述をする。
<em:multiprocessCompatible>true</em:multiprocessCompatible>
  • これを記述していないと、互換性維持の為のラッパーである CPOWs が勝手に起動しておかしな動作をして悩む事になりかねない。自分はこれで数時間無駄にしたぞちくしょう

  • e10sではChromeプロセスとContentプロセスに分離する。
  • Chromeプロセスで動作するメインのスクリプトをChromeスクリプトと呼ぶ。これは今までの拡張機能そのままのもの。
  • Contentプロセスの中で動作する、Webコンテンツに直接アクセスできるスクリプトの事をFrameスクリプトと呼ぶ。
  • ChromeプロセスとContentプロセスを繋ぐのがメッセージマネージャ。
  • メッセージマネージャは階層構造になってて、全体を・ウィンドウごとに・タブごとに、管理している。
  • Message manager overview - Mozilla | MDN

  • ContentプロセスにFrameスクリプトを読み込ませるには、Chromeスクリプト内でメッセージマネージャのloadFrameScriptを使う。
// 全てのウィンドウ及びタブなら
var globalMM = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager);
// var globalMM = Services.mm;
globalMM.loadFrameScript("chrome://sample/content/frame-script.js", true);
// アクティブなウィンドウのみでなら
var windowMM = window.messageManager;
windowMM.loadFrameScript("chrome://sample/content/frame-script.js", true);
// アクティブなウィンドウのアクティブなタブのみでなら
var browserMM = gBrowser.selectedBrowser.messageManager;
browserMM.loadFrameScript("chrome://sample/content/frame-script.js", true); 


  • FrameスクリプトからChromeスクリプトへ情報を送る場合は
// frame script
sendAsyncMessage("addon-id@sample", {})
sendSyncMessage("addon-id@sample", {}) 
// chrome script
messageManager.addMessageListener("addon-id@sample", listener); 
  • ChromeスクリプトからFrameスクリプトへ情報を送る場合は
// chrome script
globalMM.broadcastAsyncMessage("addon-id@sample", {})
windowMM.broadcastAsyncMessage("addon-id@sample", {})
browserMM.sendAsyncMessage("addon-id@sample", {}) 
// frame script
addMessageListener("addon-id@sample", listener); 

  • Frameスクリプト内で、webサイトのwindowオブジェクトはグローバルオブジェクトの content プロパティに格納されている。
// frame script
var document = content.document;
var url = content.location.href; 

フレームスクリプトの制限

フレームスクリプト内でも Components オブジェクトにアクセスは出来るが、使用できない物が意外と多くある。
制限されている物を使おうとすると例外エラーが発生する。
  • ファイルの読み書きが出来ない
  • クッキーの読み書きが出来ない(Services.cookies が使えない)
  • 検索が使えない(Services.search が使えない)
  • ダウンロードが使えない(Services.downloads が使えない)
  • セッションストアが使えない
  • ブラウザUIやXUL関連も駄目だろう
    • ウィンドウ監視は無理(Services.wm が使えない)
    • プロンプトも駄目(Services.prompt が使えない)


サンプル

コンテンツのDOMContentLoadedイベントがあったらURLをChromeプロセスに送り、受け取ったらContentプロセスのイベントが発生したタブに受け取ったとメッセージを返すサンプル
// chrome script
var listener = {
    receiveMessage(message) {
        console.log("[Chromeプロセス]\nname: " + message.name + "\ndata.url: " + message.data.url);
        message.target.messageManager.sendAsyncMessage("sample:SendMessage", {
            text : "受け取りました",
        });
    }
};
window.messageManager.addMessageListener("sample:DOMContentLoaded", listener);
window.messageManager.loadFrameScript("chrome://sample/content/frame.js", true); 
// frame script
var listener = {
	receiveMessage(message) {
		console.log("[Contentプロセス]\nname: " + message.name + "\ndata.text: " + message.data.text);
	},
};
addMessageListener("sample:SendMessage", listener);
addEventListener("DOMContentLoaded", function(event) {
    sendAsyncMessage("sample:DOMContentLoaded", {
        url : content.location.href,
    });
}, false); 
このサンプルではaddMessageListener登録にnsIMessageListenerオブジェクトを作成して登録しているが、単なる関数でもいい。