2013-08-21 72 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」類別條目 ?

我已經加入到線束options.js

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

這就是我嘗試導入模塊:

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

我已經試過許多路徑)))但沒有作品。 chrome.manifest文件中的資源項不允許引導擴展名。組件模塊文件的路徑如下: 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是這樣的:

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

Adblock Plus,在運行時可以重新啓動但不使用SDK,registers an nsIContentPolicy implementation,就像您的SDK一樣。在運行時可能會有幾個SDK附加組件註冊組件,但我不知道任何開源組件,我建議從頭開始注意。

有關該ABP實現什麼改變,使其與SDK工作的幾點:

  • 的品類經理通過Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager)可用。
  • 組件註冊商應該可以通過從chrome模塊然後components.manager.getService(Ci.nsIComponentRegistrar)需要components
  • 作爲Adblock Plus,您必須自己註銷您的組件on unload
  • 由於Bug 753687由於您無法同步註銷您的組件和類別條目,因此卸載部分也有點欺騙。 Adblock Plus因此使用Util.runAsync進行異步處理,它只是向主線程發送一個可運行的(事件,如果你喜歡的話)。我不認爲你可以在這裏使用任何SDK的東西,因爲在任何異步代碼有機會運行之前SDK都會清理乾淨,所以你需要自己使用一個低級別的XPCOM可運行(或定時器)。
  • 您的代碼將在運行時註冊您的組件。你不會碰harness-options或類似的東西。

(我還實施了generic component register功能我自己,但是這又不是SDK代碼,並且將需要適應在SDK中運行,就像ABP之一。它也是非常相似的ABP一個)

+2

最後我發現這個Firefox附加組件SDK解決方案: [平臺/ XPCOM組件(https://開頭的插件。 mozilla.org/en-US/developers/docs/sdk/latest/modules/sdk/platform/xpcom.html)。 –

+1

不知道這一點。很高興知道。關於類別的評論,特別是卸載部分,仍然存在。 ;) – nmaier

+0

可能是這個新模塊。我之前調查過這個問題,並且Add-on SDK是第一個要檢查的地方。 –

相關問題