3

特定のネットワーク負荷の検出と中止に依存する既存の Firefox 拡張機能を拡張しようとしていnsIContentPolicyます (結果として生じる UI アクション、つまりタブ ナビゲーションをブロックするため)。次に、そのリソースのロードを内部的に処理します。まれな状況では、ロードを処理した後で、ロードをまったく中断すべきではなかったことが判明したため、無視するようにフラグを立てて再開します。

e10s/マルチプロセスでは、親 (コンテンツ ポリシーが実行されている場所) がメッセージを子 (コンテンツの UI を処理している) に送信して、ロードを再開する必要があることを意味します。今日、それは以下によって行われます:

function findMessageManager(aContext) {
  // With e10s off, context is a <browser> with a direct reference to
  // the docshell loaded therein.
  var docShell = aContext && aContext.docShell;

  if (!docShell) {
    // But with e10s on, context is a content window and we have to work hard
    // to find the docshell, from which we can find the message manager.
    docShell = aContext
        .QueryInterface(Ci.nsIInterfaceRequestor)
        .getInterface(Ci.nsIWebNavigation)
        .QueryInterface(Ci.nsIDocShellTreeItem).rootTreeItem;
  }

  try {
    return docShell
        .QueryInterface(Ci.nsIInterfaceRequestor)
        .getInterface(Ci.nsIContentFrameMessageManager);
  } catch (e) {
    return null;
  }
};

e10sは非常に複雑であるため、これは非常に複雑です。しかし、それは機能します。親でオブジェクトを生成し、その上で を呼び出す.sendAsyncMessage()addMessageListener()、フレーム/子スクリプトのハンドラーがそれを受け取り、必要な処理を実行します。


より良い判断 (この負荷をブロックして処理しますか?) を行うためのより多くの情報が表示されるため、からnsIContentPolicyに切り替えたいと思います。http-on-modify-requestそのオブザーバー内で私ができること:

var browser = httpChannel
    .notificationCallbacks.getInterface(Ci.nsILoadContext)
    .topFrameElement;

これにより、ある種のメッセージマネージャーであり、.messageManagerメソッドを持つオブジェクトが得られます。しかし、それを使用すると、メッセージが消え、子供に見られることはありません。.sendAsyncMessage().sendAsyncMessage()


コンテキスト: https://github.com/greasemonkey/greasemonkey/issues/2280

4

2 に答える 2

2

これは原則として機能するはずですが、docshell ツリーのトラバーサルは e10 と非 e10 で異なることを行う可能性があるため、注意が必要です。e10s ではrootTreeItem->nsIContentFrameMessageManagerは、フレーム スクリプトに相当する MM を提供し、 の MM をtopFrameElement.frameLoader.messageManager提供する必要があります<browser>。これは、ほとんどそれに対応する親側です。

潜在的な混乱の原因:

  • e10s オンとオフ
  • プロセス MM とフレーム MM の階層
  • メッセージの間違ったフレームでリッスンする (すべてのフレームで登録すると、デバッグの目的に役立つ場合があります)
于 2016-02-11T21:11:59.197 に答える
-1

これは、コンテンツ メッセージ マネージャーを見つけるために使用する関数です。

function contentMMFromContentWindow_Method2(aContentWindow) {
    if (!gCFMM) {
        gCFMM = aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                              .getInterface(Ci.nsIDocShell)
                              .QueryInterface(Ci.nsIInterfaceRequestor)
                              .getInterface(Ci.nsIContentFrameMessageManager);
    }
    return gCFMM;

}

そのため、そのリクエストをトリガーしたコンテンツ ウィンドウを取得してから、この関数を使用します。

于 2016-02-12T04:16:58.923 に答える