Mozilla's getting a new look. What do you think? https://mzl.la/brandsurvey

Interaction between privileged and non-privileged pages

データを非特権ドキュメントから chrome へ送る

ウェブページから拡張機能へデータを送るのに簡単な方法は、カスタム DOM イベントを利用する方法です。あなたの拡張機能の browser.xul オーバーレイで、カスタム DOM イベントをリッスンするコードを書いてください。この例ではイベントに MyExtensionEvent という名前を付けます。

var myExtension = {
  myListener: function(evt) {
    alert("Received from web page: " +
          evt.target.getAttribute("attribute1") + "/" + 
          evt.target.getAttribute("attribute2"));
  }
}
document.addEventListener("MyExtensionEvent", function(e) { myExtension.myListener(e); }, false, true);

ウェブページ (非特権コード) からのデータは、attribute1attribute2 の値です。alert() をリスナの中でトリガし、データをウェブページから送るには、ウェブページに次のようなコードを書いてください。

if ("createEvent" in document) {
  var element = document.createElement("MyExtensionDataElement");
  element.setAttribute("attribute1", "foobar");
  element.setAttribute("attribute2", "hello world");
  document.documentElement.appendChild(element);

  var evt = document.createEvent("Events");
  evt.initEvent("MyExtensionEvent", true, false);
  element.dispatchEvent(evt);
}

このコードは、<MyExtensionDataElement/> のように自由な名前の要素を作成し、ウェブページの DOM に挿入します。値は、要素の中の二つの属性に設定されています。名前はあなたの自由につけられますが、ここでは attribute1attribute2 を選びました。最後に、コードは MyExtensionEvent というカスタムイベントを作成し、発行 (dispatch)します。これは、onclick ハンドラでキャッチできる標準の DOM click イベントと同じようなものです。イベントはウェブページから浮上し、拡張機能 (特権コード) に到達し、あなたのリスナがキャッチ、イベントが発生した DOM 要素から属性値を読み出します。

あなたの拡張機能のオーバーレイが browser.xul と直接やり取りできない場合、例えば サイドバー内にある場合は、以下のようにすれば簡単にトップレベルドキュメントにイベントリスナを追加できます。 (子ウィンドウからトップレベルドキュメントの要素にアクセスする も参照してください)

var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                  .getInterface(Components.interfaces.nsIWebNavigation)
                  .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
                  .rootTreeItem
                  .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                  .getInterface(Components.interfaces.nsIDOMWindow);
mainWindow.document.addEventListener("MyExtensionEvent", function(e) { myExtension.myListener(e); }, false, true);

もし、大量のデータを渡す必要があるならば、独自要素の単なる属性ではなく、CDATA セクションを利用することを検討してください。

chrome から非特権ドキュメントへデータを送る

ウェブページに (リターンコードなどの) 答えを返すには、拡張機能からイベントターゲット要素 (サンプルでは <MyExtensionDataElement/>) に属性を設定するか、子要素を追加します。

作成した要素は削除してもかまいませんし、ウェブページが読み込まれる時に一度だけ作成し、そのつど再利用するのも良いでしょう。

セキュリティーノート

  • あなたの拡張機能からウェブページの JavaScript 関数を呼ばないでください。これを行うと、セキュリティーホールの元になり、悪意のあるウェブページがブラウザにコード、たとえばローカルファイルの削除などを拡張された権限 (あなたの拡張機能のように) で実行させることが可能になります。
  • イベントの発生元を event.target.ownerDocument.location で確認し、あなたのサーバのページ以外からのイベントであればすべて拡張機能のほうで無視することを強くお勧めします。

資料

Mozillazine Forum での議論

ドキュメントのタグと貢献者

タグ: 
 このページの貢献者: Shoot, Mgjbot, Shimono
 最終更新者: Shoot,