【问题标题】:Mozilla extension: How to get a window object in Background scriptMozilla 扩展:如何在后台脚本中获取窗口对象
【发布时间】:2016-03-09 17:03:41
【问题描述】:

我想在 Firefox Extension 中使用不同的 XPCOM 接口,这里是取自他们的API 的示例:

var domWindowUtils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                     .getInterface(Components.interfaces.nsIDOMWindowUtils);

但我无法在后台脚本中使用它,因为对象 Window 未定义:

window.QueryInterface is not a function

请指引我正确的方向。

附:后台脚本在全局范围内实际可用的是什么?我似乎在文档中找不到任何线索。

【问题讨论】:

    标签: javascript firefox firefox-addon mozilla


    【解决方案1】:

    问题在于 Firefox 扩展不能在任何特定窗口的上下文中运行。因此,他们通常没有定义 window 对象,或者如果您不熟悉编写扩展代码,它被定义为您不期望的东西。如果您从编写 JavaScript 以在 HTML 页面中使用的角度来处理此问题,则尤其如此。扩展在更大的上下文中运行,包括整个浏览器以及所有窗口和选项卡。因此,没有自动合适的窗口用作window 对象。在扩展的上下文中,每个 HTML 页面只是整体的一部分。

    您可以通过使用nsIWindowMediator 获取每个主浏览器窗口。以下函数 from MDN 将为每个打开的窗口运行一次您传递给它的函数:

    Components.utils.import("resource://gre/modules/Services.jsm");
    function forEachOpenWindow(todo)  // Apply a function to all open browser windows
    {
        var windows = Services.wm.getEnumerator("navigator:browser");
        while (windows.hasMoreElements())
          todo(windows.getNext().QueryInterface(Components.interfaces.nsIDOMWindow));
    }
    

    您通常希望找到用户最近访问的浏览器/标签的window。以下代码将定义 window 变量并将其设置为最近使用的浏览器/选项卡。它可以在附加 SDK 中工作,也可以在覆盖/引导扩展中工作,具体取决于您取消注释的部分。

    有关在 Firefox 扩展程序中使用 Windows 的更多信息,您应该查看Working with windows in chrome code,也许还有Tabbed browser

    if (window === null || typeof window !== "object") {
        //If you do not already have a window reference, you need to obtain one:
        //  Add a "/" to un-comment the code appropriate for your add-on type.
        /* Add-on SDK:
        var window = require('sdk/window/utils').getMostRecentBrowserWindow();
        //*/
        /* Overlay and bootstrap (from almost any context/scope):
        var window=Components.classes["@mozilla.org/appshell/window-mediator;1"]
                             .getService(Components.interfaces.nsIWindowMediator)
                             .getMostRecentWindow("navigator:browser");        
        //*/
    }
    

    交替使用Services.jsm访问nsIWindowMediator

    /* Overlay and bootstrap:
    Components.utils.import("resource://gre/modules/Services.jsm");
    //*/
    if (window === null || typeof window !== "object") {
        //If you do not already have a window reference, you need to obtain one:
        //  Add a "/" to un-comment the code appropriate for your add-on type.
        /* Add-on SDK:
        var window = require('sdk/window/utils').getMostRecentBrowserWindow();
        //*/
        /* Overlay and bootstrap (from almost any context/scope):
        var window = Services.wm.getMostRecentWindow("navigator:browser");
        //*/
    }
    

    以下是一些可能有用的附加变量,具体取决于您正在执行的操作:

    if (typeof document === "undefined") {
        //If there is no document defined, get it
        var document = window.content.document;
    }
    
    if (typeof gBrowser === "undefined") {
        //If there is no gBrowser defined, get it
        var gBrowser = window.gBrowser;
    }
    
    var tab = gBrowser.selectedTab;
    var browserForTab = gBrowser.getBrowserForTab( tab );
    var notificationBox = gBrowser.getNotificationBox( browserForTab );
    var ownerDocument = gBrowser.ownerDocument;
    

    注意:此答案的内容主要取自我的答案 herehere,但基于 MDN 的代码。对我来说,遍历所有打开的浏览器窗口的代码起源于 original article MDN 文章 How to convert an overlay extension to restartless 所依据的。

    【讨论】:

      【解决方案2】:

      一种快速而肮脏的测试方式,有时是真正的应用程序是Services.wm.getMostRecentWindow('navigator:browser'),或者您可以使用null 或任何其他windowType

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-02-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-06
        • 2012-08-24
        相关资源
        最近更新 更多