我一直在阅读和浏览https://developer.mozilla.org/en/XUL_School/Intercepting_Page_Loads,但似乎可以做我需要的。
我正在研究Chromeless,试图阻止主xulbrowser元素被导航,例如,链接不应该工作,window.location.href="http://www.example.com/"
也不应该。{/ p>
我假设我可以通过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将其注册到”content-policy“类别。” p>
任何想法?
答案 0 :(得分:0)
我从mozilla的#xulrunner irc频道得到了帮助。
结果解决方案如下。
注意:这是一个在Mozilla Chromeless中使用的模块,require("chrome")
和require("xpcom")
位在正常情况下将无法使用。
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);
}
在github上为那些感兴趣的人提取请求:https://github.com/mozilla/chromeless/pull/114