Предотвращение изменения местоположения браузера в xulrunner - PullRequest
0 голосов
/ 27 мая 2011

Я читаю и хакую с https://developer.mozilla.org/en/XUL_School/Intercepting_Page_Loads, но, похоже, могу делать то, что мне нужно.

Я работаю над 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(), но я действительно понятия не имею, как «создать компонент XPCOM, расширяющий nsIContentPolicy, и зарегистрировать его в категории« content-policy »с помощью nsICategoryManager.»

Есть идеи?

1 Ответ

0 голосов
/ 28 мая 2011

Я получил справку об этом по каналу #xulrunner irc в Mozilla.

Получено следующее решение.

Примечание: это модуль для использования в 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

...