2013-08-21 34 views
5

Tôi có một phần mở rộng bootstrapped cho Firefox. Và bây giờ tôi muốn thực hiện thành phần nsIContentPolicy XPCOM. Tôi đã viết mã mô-đun thành phần. Và bây giờ tôi muốn đăng ký thành phần này. Lý do tôi muốn đăng ký thành phần là tôi muốn thêm thành phần của mình vào nsICategoryManager.addCategoryEntry với danh mục "chính sách nội dung".Cách triển khai thành phần XPCOM (nsIContentPolicy) trong phần mở rộng Firefox được khởi động trước

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

Câu hỏi:

  • Có thể đăng ký các thành phần từ phần mở rộng bootstrapped?
  • Có thể đăng ký thành phần từ tiện ích mở rộng không khởi động lại không?
  • Có thể sử dụng nsICategoryManager.addCategoryEntry "content-policy" nếu không có thành phần không?
  • Cách đăng ký thành phần trong phần mở rộng được khởi động hoặc bằng cách nào đó thêm mục nhập danh mục "chính sách nội dung" mới?

tôi đã thêm vào khai thác-options.js

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

Đó là cách tôi cố gắng nhập mô-đun:

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

Tôi đã thử nhiều con đường))) Nhưng không ai công trinh. mục nhập tài nguyên trong tệp chrome.manifest không được phép cho tiện ích mở rộng được khởi động. Đường dẫn đến tệp mô-đun thành phần là: resources/deferredto/lib/interceptor.js

Trả lời

3

Bây giờ, thành phần dựa trên sdk nsIContentPolicy của tôi trông giống như thế này. Nộp 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); 

Và bạn có thể sử dụng nó từ sdk như thế này:

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

Adblock Plus, khởi động lại nhưng không sử dụng SDK, registers an nsIContentPolicy implementation khi chạy, giống như SDK của bạn. Có thể có một vài tiện ích bổ sung SDK đăng ký thành phần trong thời gian chạy, nhưng tôi không biết bất kỳ mã nguồn mở nào mà tôi khuyên bạn nên xem xét phần đầu của tôi.

Một vài điểm liên quan đến việc thực hiện ABP và những gì để thay đổi để làm cho nó làm việc với SDK:

  • Người quản lý loại có sẵn qua Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager).
  • Công ty đăng ký thành phần phải có sẵn bằng cách yêu cầu cũng components từ mô-đun chrome và sau đó components.manager.getService(Ci.nsIComponentRegistrar).
  • Là Adblock Plus, bạn phải tự hủy đăng ký thành phần của mình on unload.
  • Phần tải không may là một chút lừa đảo, vì bạn không thể hủy đăng ký đồng bộ thành phần của bạn và mục nhập danh mục, do Bug 753687. Adblock Plus do đó nó không đồng bộ bằng cách sử dụng Util.runAsync, mà chỉ cần gửi một runnable (sự kiện, nếu bạn thích) vào chủ đề chính. Tôi không nghĩ rằng bạn có thể sử dụng bất kỳ thứ SDK nào ở đây, vì SDK sẽ dọn sạch trước khi bất kỳ mã async nào có cơ hội chạy, vì vậy, bạn cần sử dụng chính sách XPCOM (hoặc hẹn giờ) cấp thấp.
  • Mã của bạn sẽ đăng ký thành phần của bạn khi chạy. Bạn sẽ không chạm vào harness-options hoặc bất kỳ thứ gì như thế.

(Tôi cũng đã tự thực hiện chức năng generic component register, nhưng lại không phải là mã SDK và cần được điều chỉnh để chạy trong SDK, giống như mã ABP. Nó cũng rất giống với ABP .)

+2

Cuối cùng tôi tìm thấy giải pháp Firefox Addon SDK cho việc này: [nền tảng/XPCOM mô-đun] (https: // addons. mozilla.org/en-US/developers/docs/sdk/latest/modules/sdk/platform/xpcom.html). –

+1

Không nhận thức được điều đó. Tốt để biết. Các ý kiến ​​về các loại, đặc biệt là phần dỡ hàng, vẫn đứng. ;) – nmaier

+0

Có thể là mô-đun mới này. Tôi đã điều tra vấn đề trước và SDK bổ sung là nơi đầu tiên để kiểm tra. –