2011-05-27 64 views
0

我一直在閱讀和剽竊https://developer.mozilla.org/en/XUL_School/Intercepting_Page_Loads,但似乎可以做我所需要的。防止瀏覽器在xulrunner中的位置變化

我正在致力於Chromeless,試圖阻止主要的xulbrowser元素被導航離開,例如,鏈接不應該工作,也不應該window.location.href="http://www.example.com/"

我假設我可以通過browser.webProgress.addProgressListener做到這一點,然後聽onProgressChange,但我無法弄清楚如何將資源請求和browser改變位置區分(似乎onLocationChange是爲時已晚,因爲該文件已經被卸載)。

browser.webProgress.addProgressListener({ 
    onLocationChange: function(){}, 
    onStatusChange: function(){}, 
    onStateChange: function(){}, 
    onSecurityChange: function(){}, 
    onProgressChange: function(){ 
     aRequest.QueryInterface(Components.interfaces.nsIHttpChannel) 
     if(/* need to check if the object triggering the event is the xulbrowser */){ 
      aRequest.cancel(Components.results.NS_BINDING_ABORTED); 
     } 
    }, 
    QueryInterface: xpcom.utils.generateQI([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference]) 
}, wo._browser.webProgress.NOTIFY_ALL); 

聽起來前途的另一種選擇是nsIContentPolicy.shouldLoad()方法,但我真的不知道如何「創建擴展nsIContentPolicy XPCOM組件並將其註冊爲‘內容政策’使用nsICategoryManager類別。」

任何想法?

回答

0

我從mozilla的#xulrunner irc頻道獲得了幫助。

得到的解決方案如下。

注意:這是在Mozilla Chromeless中使用的模塊,require("chrome")require("xpcom")位在正常情況下不可用。在github上

const {Cc, Ci, Cu, Cm, Cr} = require("chrome"); 

const xpcom = require("xpcom"); 

/*********************************************************** 
class definition 
***********************************************************/ 

var description = "Chromeless Policy XPCOM Component"; 
/* UID generated by http://www.famkruithof.net/uuid/uuidgen */ 
var classID = Components.ID("{2e946f14-72d5-42f3-95b7-4907c676cf2b}"); 
// I just made this up. Don't know if I'm supposed to do that. 
var contractID = "@mozilla.org/chromeless-policy;1"; 

//class constructor 
function ChromelessPolicy() { 
    //this.wrappedJSObject = this; 
} 

// class definition 
var ChromelessPolicy = { 

    // properties required for XPCOM registration: 
    classDescription: description, 
    classID:   classID, 
    contractID:  contractID, 
    xpcom_categories: ["content-policy"], 

    // QueryInterface implementation 
    QueryInterface: xpcom.utils.generateQI([Ci.nsIContentPolicy, 
    Ci.nsIFactory, Ci.nsISupportsWeakReference]), 

    // ...component implementation... 
    shouldLoad : function(aContentType, aContentLocation, aRequestOrigin, aContext, aMimeTypeGuess, aExtra) { 
    let result = Ci.nsIContentPolicy.ACCEPT; 
    // only filter DOCUMENTs (not SUB_DOCUMENTs, like iframes) 
    if(aContentType === Ci.nsIContentPolicy["TYPE_DOCUMENT"] 
     // block http(s) protocols... 
     && /^http(s):/.test(aContentLocation.spec)){ 
     // make sure we deny the request now 
     result = Ci.nsIContentPolicy.REJECT_REQUEST; 
    } 
    // continue loading... 
    return result; 
    }, 
    createInstance: function(outer, iid) { 
    if (outer) 
     throw Cr.NS_ERROR_NO_AGGREGATION; 
    return this.QueryInterface(iid); 
    } 
}; 

let registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar); 
try 
{ 
    Cm.nsIComponentRegistrar.registerFactory(classID, description, contractID, ChromelessPolicy); 
} 
catch (e) { 
    // Don't stop on errors - the factory might already be registered 
    Cu.reportError(e); 
} 

const categoryManager = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager); 
for each (let category in ChromelessPolicy.xpcom_categories) { 
    categoryManager.addCategoryEntry(category, ChromelessPolicy.classDescription, ChromelessPolicy.contractID, false, true); 
} 

拉動請求對於那些有興趣:https://github.com/mozilla/chromeless/pull/114