防止 xulrunner 中的浏览器位置更改

发布于 2024-11-10 06:05:34 字数 1346 浏览 0 评论 0原文

我一直在阅读和使用 https://developer.mozilla.org/en/XUL_School/ Intercepting_Page_Loads 但似乎可以做我需要的事情。

我正在研究 Chromeless,试图防止主 xulbrowser 元素被导航离开,例如链接不应该工作,window.location.href="http://www.example.com/"也不应该工作。

我假设我可以通过 browser.webProgress.addProgressListener 来做到这一点,然后监听 onProgressChange ,但我不知道如何区分资源请求和 < code>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 将其注册到“内容策略”类别”。

有什么想法吗?

I've been reading and hacking around with https://developer.mozilla.org/en/XUL_School/Intercepting_Page_Loads but can seem to do what I need.

I'm working on Chromeless, trying to prevent the main xulbrowser element from ever being navigated away from, e.g., links should not work, neither should window.location.href="http://www.example.com/".

I'm assuming I can do this via browser.webProgress.addProgressListener and then listen to onProgressChange but I can't figure out how to differentiate between a resource request and the browser changing locations (it seems that onLocationChange is too late as the document is already being unloaded).

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

Another option that sounds promising is the nsIContentPolicy.shouldLoad() method but I really have no clue how to "create an XPCOM component that extends nsIContentPolicy and register it to the "content-policy" category using the nsICategoryManager."

Any Ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

多像笑话 2024-11-17 06:05:34

我从 mozilla 的 #xulrunner irc 频道获得了有关此问题的帮助。

结果解决方案如下。

注意:这是一个在 Mozilla Chromeless 中使用的模块,require("chrome")require("xpcom") 位在正常情况下将不可用 https://github.com

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 上拉取请求: /mozilla/chromeless/pull/114

I got help on this from the mozilla's #xulrunner irc channel.

Resulting solution follows.

Note: this is a module for use in Mozilla Chromeless, the require("chrome") and require("xpcom") bits will NOT be available under normal circumstances.

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

Pull Request on github for those that are interested: https://github.com/mozilla/chromeless/pull/114

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文