2013-08-21 16 views
5

Ho un'estensione bootstrapped per Firefox. E ora voglio implementare il componente nsIContentPolicy XPCOM. Ho scritto un codice modulo componente. E ora voglio registrare questo componente. Il motivo per cui voglio registrare il componente è che voglio aggiungere il mio componente a nsICategoryManager.addCategoryEntry con la categoria "content-policy".Come implementare il componente XPCOM (nsIContentPolicy) nell'estensione per Firefox avviata

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]); 

Domande:

  • E 'possibile registrare il componente dalla estensione bootstrap?
  • È possibile registrare il componente dall'estensione senza riavvio?
  • È possibile utilizzare nsICategoryManager.addCategoryEntry "content-policy" senza componente ?
  • Come registrare il componente nell'estensione bootstrapped o in qualche modo aggiungere la voce di categoria "content-policy" ?

ho aggiunto di imbrigliare-options.js

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

è così che si tenta di importare il modulo:

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

'ho provato molti percorsi))) Ma nessuno lavori. la voce della risorsa nel file chrome.manifest non è consentita per le estensioni bootstrap. Il percorso del file modulo componente è: resources/deferredto/lib/interceptor.js

risposta

3

Ora il mio componente basato su sdksi presenta così. File 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); 

E si può utilizzare da SDK così:

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

Adblock Plus, che è restartless ma non utilizzando l'SDK, registers an nsIContentPolicy implementation in fase di esecuzione, proprio come il vostro SDK avrebbe fatto. Probabilmente ci sono alcuni componenti aggiuntivi di SDK che registrano componenti in fase di esecuzione, ma non conosco quelli open source che consiglierei di guardare in cima alla mia testa.

Alcuni punti che riguardano che l'attuazione SOA e cosa cambiare per farlo funzionare con l'SDK:

  • Il gestore categoria è disponibile tramite Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager).
  • Il registrar componente deve essere disponibile richiedendo anche components dal modulo chrome e quindi components.manager.getService(Ci.nsIComponentRegistrar).
  • Come Adblock Plus, è necessario annullare la registrazione del componente on unload.
  • Anche la parte di scaricamento è un po 'ingannevole, poiché non è possibile annullare la registrazione in modo sincrono del componente e della voce della categoria, a causa di Bug 753687. Adblock Plus pertanto esegue la sincronizzazione asincrona utilizzando Util.runAsync, che invia un evento eseguibile (evento, se lo desideri) al thread principale. Non penso che tu possa utilizzare qualsiasi materiale dell'SDK qui, poiché l'SDK pulirà prima che qualsiasi codice asincrono abbia la possibilità di essere eseguito, quindi avrai bisogno di usare un runnable (o timer) XPCOM di basso livello.
  • Il codice registrerà il componente in fase di esecuzione. Non toccherà harness-options o qualcosa del genere.

(ho anche implementato una funzione generic component register me, ma di nuovo non è codice SDK e avrebbe bisogno di essere adattato per funzionare nel SDK, come quella ABP. Inoltre è molto simile a quello ABP .)

+2

finalmente ho trovato la soluzione Firefox Addon SDK per questo: [Platform/XPCOM modulo] (https: // addons. mozilla.org/en-US/developers/docs/sdk/latest/modules/sdk/platform/xpcom.html). –

+1

Non ne ero a conoscenza. Buono a sapersi. I commenti sulle categorie, in particolare sulla parte di scarico, continuano a sussistere. ;) – nmaier

+0

Probabilmente questo nuovo modulo. Ho analizzato il problema prima e l'add-on SDK era il primo posto da verificare. –