2013-08-21 5 views
5

私はFirefox用にブートストラップされた拡張機能を持っています。 そして今、nsIContentPolicy XPCOMコンポーネントを実装したいと思います。 コンポーネントモジュールコードを書きました。 これでこのコンポーネントを登録します。 私がコンポーネントを登録したい理由は、 "content-policy"カテゴリのnsICategoryManager.addCategoryEntryに自分のコンポーネントを追加したいということです。ブートストラップされたFirefoxエクステンションにXPCOMコンポーネント(nsIContentPolicy)を実装する方法

var {Cc, Ci, Cu} = require("chrome"); 

Cu.import("resource://gre/modules/XPCOMUtils.jsm"); 

//console.error("Running interceptor"); 

function Interceptor() 
} 

Interceptor.prototype = { 

    classDescription: "DeferredTo HTTP requests Interceptor", 
    classID: "{B5B3D9A0-08FC-11E3-8253-5EF06188709B}", 
    contractID: "@deferredto.com/Interceptor;1", 
    QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy]), 

    shouldLoad : function dt_shouldLoad(aContentType, aContentLocation, aRequestOrigin, aContext, aMimeTypeGuess, aExtra) { 
     console.log("dt_shouldLoad"); 

     if (contentLocation.scheme != "http" && contentLocation.scheme != "https") 
      return Ci.nsIContentPolicy.ACCEPT; 

     let result = Ci.nsIContentPolicy.ACCEPT; 

     // we should check for TYPE_SUBDOCUMENT as well if we want frames. 
     if ((Ci.nsIContentPolicy.TYPE_DOCUMENT == aContentType) && 
      SOME_REGULAR_EXPRESSION.test(aContentLocation.spec)) { 
      // do stuff here, possibly changing result. 
     } 
     return result; 
    }, 

    shouldProcess: function ILO_shouldProcess() Ci.nsIContentPolicy.ACCEPT, 

    _xpcom_categories: [ 
     { category: "content-policy", service: true } 
    ], 
    classInfo: XPCOMUtils.generateCI(
    {classID: Components.ID("{B5B3D9A0-08FC-11E3-8253-5EF06188709B}"), 
    contractID: "@deferredto.com/Interceptor;1", 
    classDescription: "Interceptor implements nsIContentPolicy to block images that are not yet at screen @DeferredTo", 
    interfaces: [ 
        Ci.nsIContentPolicy, 
        ], 
    flags: Ci.nsIClassInfo.SINGLETON}) 
} 

var components = [Interceptor]; 

var NSGetFactory = XPCOMUtils.generateNSGetFactory([Interceptor]); 

質問:

  • それはブートストラップ拡張子からコンポーネントを登録することは可能ですか?
  • コンポーネントを再起動しない拡張機能から登録することはできますか?
  • コンポーネントなしでnsICategoryManager.addCategoryEntry "content-policy"を使用することはできますか?
  • ブートストラップされた内線番号でコンポーネントを登録するか、何らかの形で 新しい「content-policy」カテゴリエントリを追加するにはどうすればよいですか? )))私は多くのパスを試してみました「VEの

    var {Cc, Ci, Cu} = require("chrome"); 
    Cu.import("resource://deferredto/lib/interceptor.js"); 
    

    しかしなし:

は、私が活用-options.jsし、私はモジュールをインポートしようとする方法である

"requirements": { 
"sdk/page-mod": "sdk/page-mod", 
"sdk/self": "sdk/self", 
"chrome": "chrome"}, 

追加しました働くchrome.manifestファイルのリソースエントリは、ブートストラップされた拡張機能には許可されません。コンポーネントモジュールファイルへのパスは次のとおりです。restartlessですが、ちょうどあなたのSDKが希望のように、SDK、実行時にregisters an nsIContentPolicy implementationを使用していない resources/deferredto/lib/interceptor.js

答えて

3

今、私のnsIContentPolicyのsdkベースのコンポーネントはこのように見えます。 interceptor.jsファイル:

'use strict'; 

var { Class } = require('sdk/core/heritage'); 
var xpcom = require('sdk/platform/xpcom'); 
var { Cc, Ci, Cu, Cm } = require('chrome'); 
var categoryManager = Cc["@mozilla.org/categorymanager;1"] 
         .getService(Ci.nsICategoryManager); 


// nsIDOMNode 
const TYPE_DOCUMENT_NODE  = Ci.nsIDOMNode.DOCUMENT_NODE; 


/// Interceptor 


var contractId = "@deferredto.com/Interceptor;1"; 

var Interceptor = Class({ 
    extends: xpcom.Unknown, 
    interfaces: [ 'nsIContentPolicy' ], 
    get wrappedJSObject() this, 

    shouldLoad : function dt_shouldLoad(contentType, contentLocation, requestOrigin, context, mimeTypeGuess, extra) { 

     let result = Ci.nsIContentPolicy.ACCEPT; 

     return result; 
    }, 

    shouldProcess: function() Ci.nsIContentPolicy.ACCEPT 
}); 

var factory = xpcom.Factory({ 
    contract: contractId, 
    Component: Interceptor, 
    unregister: false // see https://bugzilla.mozilla.org/show_bug.cgi?id=753687 
}); 

/// unload 
var unload = require("sdk/system/unload"); 

unload.when(function() { 
    function trueUnregister() { 
    categoryManager.deleteCategoryEntry("content-policy", contractId, false); 
    try { 
     console.log("xpcom.isRegistered(factory)=" + xpcom.isRegistered(factory)); 
     console.log("trueUnregister"); 
     xpcom.unregister(factory); 
     console.log("xpcom.isRegistered(factory)=" + xpcom.isRegistered(factory)); 
    } catch (ex) { 
     Cu.reportError(ex); 
    }  
    } 
    if ("dispatch" in Cu) { 
    console.log('"dispatch" in Cu'); 
    Cu.dispatch(trueUnregister, trueUnregister); 
    } else { 
    console.log('"dispatch" not! in Cu'); 
    Cu.import("resource://gre/modules/Services.jsm"); 
    Services.tm.mainThread.dispatch(trueUnregister, 0); 
    } 
}); 


//xpcom.register(factory); 

var interceptor = Cc[contractId].createInstance(Ci.nsIContentPolicy); 

categoryManager.deleteCategoryEntry("content-policy", contractId, false); 
categoryManager.addCategoryEntry("content-policy", contractId, contractId, false, true); 

そして、あなたはこのようにSDKからそれを使用することができます: [プラットフォーム/ XPCOMモジュール](HTTPS://アドオン

var interceptor = require("./interceptor"); 
3

自分好みプラス、。実行時にコンポーネントを登録するSDKアドオンはおそらくいくつかありますが、私は自分の頭の上を見るために推奨するオープンソースのものを知らない。

ABPの実装とそれがSDKで動作するように変更することについて、いくつかのポイント:

  • カテゴリマネージャーがCc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager)経由で入手可能です。
  • コンポーネントのレジストラは、モジュールのcomponentsを要求し、次にcomponents.manager.getService(Ci.nsIComponentRegistrar)を要求することで利用可能になります。
  • Adblock Plusでは、自分でコンポーネントの登録を解除する必要がありますon unload
  • Bug 753687のため、コンポーネントとカテゴリエントリの同期登録を解除することはできないため、アンロード部分はちょっとおかしなことです。したがって、Adblock PlusはUtil.runAsyncを使用して非同期処理を行います。メインスレッドには、実行可能なイベント(必要に応じてイベント)が送出されます。非同期コードが実行される前にSDKがクリーンアップするので、ここでSDKのものは使用できないと思うので、低レベルのXPCOM実行可能ファイル(またはタイマー)を自分で使用する必要があります。
  • 実行時にコードがコンポーネントを登録します。あなたはharness-optionsやそのようなものには触れません。

(私もgeneric component register機能を自分で実装し、それが再びSDKコードではありません、とだけABPの1のように、SDKで実行するように適応する必要があります。また、ABPと非常によく似ています)

+2

最後に、私はこのためのFirefoxアドオンSDKの解決策を見つけました。 mozilla.org/en-US/developers/docs/sdk/latest/modules/sdk/platform/xpcom.html)。 –

+1

それを知らなかった。知っておいてよかった。カテゴリに関するコメント、特にアンロード部分は依然として存在します。 ;) – nmaier

+0

おそらく、この新しいモジュールです。私は前にこの問題を調査し、アドオンSDKが最初に確認していました。 –

関連する問題