Я попытался отправить содержимое файла таким образом (поскольку доступ к файлу аддона был запрещен firefox из внешнего интерфейса):
index.js
var pageMod = require("sdk/page-mod");
var data = require("sdk/self").data;
pageMod.PageMod({
include: ["http://example.com/", "http://example.com/index.html"],
contentScriptFile: "./inject.js",
contentScriptWhen: "start",
onAttach: function (worker){
console.log("injector attached");
worker.port.emit("inject", {
"index.html": data.load("client/index.html"),
"main.js": data.load("client/main.js")
});
}
});
inject.js
!function () {
self.port.on("inject", function (files) {
console.log("injector trigger");
if (typeof hasRun == 'undefined') {
console.log("injecting");
hasRun = true;
window.stop();
var html = files["index.html"].replace("<script src=\"./main.js\"></script>", "<script>"+files["main.js"]+"</script>");
document.documentElement.innerHTML = html;
}
});
}();
Если я заменю HTML на привет, мир, тогда это сработает. Таким образом, HTML-код кажется недействительным, но я не получил сообщения об ошибке, и консоль показывает пустой HTML-скелет (у меня есть пустая страница). Тот же код index.html и main.js работает с плагином Chrome, который я хочу использовать в Firefox. Единственная дополнительная вещь плагина Chrome, что некоторые js-файлы отменяются, поэтому они наверняка не загружаются до остановки окна. Пробовал делать так же, но может не получилось, не знаю.
index.js
let { Ci, Cu } = require('chrome');
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
var observer = {
QueryInterface: XPCOMUtils.generateQI([
Ci.nsIObserver,
Ci.nsISupportsWeakReference
]),
observe: function (subject, topic, data) {
if (topic == "http-on-opening-request" &&
subject instanceof Ci.nsIHttpChannel) {
var uri = subject.URI;
if (uri.host == "example.com" && /some\.js/.test(uri.path))
subject.cancel();
}
}
};
Services.obs.addObserver(observer, "http-on-opening-request", true);
Subject.cancel() запускается файлом some.js. Если я добавлю ведение журнала:
console.log("cancelling", uri.path);
subject.cancel();
console.log("cancelled");
Тогда в консоли не появляется «отменено», а только «отмена, /some.js». Я не знаю, нормально ли это, но я не получил сообщения об ошибке.
Попробовав это с обычной веб-страницей HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script>
//<![CDATA[
!function (){
window.stop();
var html = '<!DOCTYPE html>\n<html>\n<head>\n <meta charset="utf-8">\n</head>\n<body>\n <script>console.log("loaded");</script>\ntext\n</body>\n</html>';
document.documentElement.innerHTML = html;
}();
//]]>
</script>
</body>
</html>
Я получил синтаксическую ошибку незавершенного строкового литерала, что еще смешнее. Я предполагаю, что код инжектора почему-то не работает должным образом, если он содержит javascript, так что я думаю, что это не проблема, связанная с аддоном. Если я использую <\/script>
, то все в порядке, но скрипт console.log("loaded");
не запускается. В хроме он работает, так что я думаю, что это проблема.
Я добавил jquery в «contentScriptFile» и использовал $("html").html(html)
вместо document.documentElement.innerHTML = html
. Теперь он запускает сценарии, но все еще не работает должным образом.
Добавлено исправление с помощью функции cancel():
let { Ci, Cu, Cr } = require('chrome');
//...
subject.cancel(Cr.NS_BINDING_ABORTED);
У отмены есть требуемый параметр состояния, но он молча терпит неудачу, когда не получает его. Теперь отмена файлов тоже работает, но плагин все равно где-то глючит. :С
Я думаю, что написанный мной инжектор работает отлично, и проблема заключается в инжектируемых файлах HTML и js. Я не собираюсь их отлаживать (поскольку $.load использует eval, так что это будет очень сложно), я отправил код разработчикам плагинов для chrome, может они как-то поправят.
person
inf3rno
schedule
19.06.2015