xpcom/jetpack 观察所有文档加载

发布于 2024-09-07 19:20:12 字数 1563 浏览 6 评论 0原文

我编写了一个基于 Mozilla Jetpack 的插件,该插件必须在加载文档时运行。对于“顶级文档”,这主要使用此代码(OserverService = require('observer-service')):

    this.endDocumentLoadCallback = function (subject, data) {
        console.log('loaded: '+subject.location);
        try {
            server.onEndDocumentLoad(subject);
        }
        catch (e) {
            console.error(formatTraceback(e));
        }
    };
    ObserverService.add("EndDocumentLoad", this.endDocumentLoadCallback);

但是当用户使用中键单击或打开新选项卡时不会调用回调(更重要的是!)对于框架。即使这个主题我也只是通过阅读另一个扩展的源代码而不是通过文档来了解的。

那么如何注册一个在每次加载文档时真正被调用的回调呢?

编辑:这似乎做了我想要的:

function callback (event) {
    // this is the content document of the loaded page.
    var doc = event.originalTarget;

    if (doc instanceof Ci.nsIDOMNSHTMLDocument) {
        // is this an inner frame?
        if (doc.defaultView.frameElement) {
            // Frame within a tab was loaded.
            console.log('!!! loaded frame:',doc.location.href);
        }
        else {
            console.log('!!! loaded top level document:',doc.location.href);
        }
    }
}

var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
var mainWindow = wm.getMostRecentWindow("navigator:browser");
mainWindow.gBrowser.addEventListener("load", callback, true);

从这里部分获取:https://developer.mozilla.org/en/XUL_School/Intercepting_Page_Loads

I write a Mozilla Jetpack based add-on that has to run whenever a document is loaded. For "toplevel documents" this mostly works using this code (OserverService = require('observer-service')):

    this.endDocumentLoadCallback = function (subject, data) {
        console.log('loaded: '+subject.location);
        try {
            server.onEndDocumentLoad(subject);
        }
        catch (e) {
            console.error(formatTraceback(e));
        }
    };
    ObserverService.add("EndDocumentLoad", this.endDocumentLoadCallback);

But the callback doesn't get called when the user opens a new tab using middle click or (more importantly!) for frames. And even this topic I only got through reading the source of another extension and not through the documentation.

So how do I register a callback that really gets called every time a document is loaded?

Edit: This seems to do what I want:

function callback (event) {
    // this is the content document of the loaded page.
    var doc = event.originalTarget;

    if (doc instanceof Ci.nsIDOMNSHTMLDocument) {
        // is this an inner frame?
        if (doc.defaultView.frameElement) {
            // Frame within a tab was loaded.
            console.log('!!! loaded frame:',doc.location.href);
        }
        else {
            console.log('!!! loaded top level document:',doc.location.href);
        }
    }
}

var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
var mainWindow = wm.getMostRecentWindow("navigator:browser");
mainWindow.gBrowser.addEventListener("load", callback, true);

Got it partially from here: https://developer.mozilla.org/en/XUL_School/Intercepting_Page_Loads

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

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

发布评论

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

评论(2

陌伤ぢ 2024-09-14 19:20:12

@kizzx2 你最好使用 #jetpack

对于最初的问题:为什么不使用选项卡浏览器模块。像这样的事情:

var browser = require("tab-browser");

exports.main = function main(options, callbacks) {
initialize(function (config) {
    browser.whenContentLoaded(
        function(window) {
           // something to do with the window
           // e.g., if (window.locations.href === "something")
        }
    );
});

比你所做的更干净恕我直言,并且(直到我们有官方 pageMods 模块)受支持的方式来做到这一点。

@kizzx2 you are better served with #jetpack

To the original question: why don't you use tab-browser module. Something like this:

var browser = require("tab-browser");

exports.main = function main(options, callbacks) {
initialize(function (config) {
    browser.whenContentLoaded(
        function(window) {
           // something to do with the window
           // e.g., if (window.locations.href === "something")
        }
    );
});

Much cleaner than what you do IMHO and (until we have official pageMods module) the supported way how to do this.

计㈡愣 2024-09-14 19:20:12

从 Addon SDK 1.0 开始,执行此操作的正确方法是使用 page-mod 模块。

(在底层,它是使用 document-element-inserted 观察者服务通知实现的,您可以在常规扩展中使用它,或者如果 page-mod 不适合您。)

As of Addon SDK 1.0, the proper way to do this is to use the page-mod module.

(Under the hood it's implemented using the document-element-inserted observer service notification, you can use it in a regular extension or if page-mod doesn't suit you.)

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