编程语言
首页 > 编程语言> > javascript-Firefox插件SDK获取选项卡ID

javascript-Firefox插件SDK获取选项卡ID

作者:互联网

我正在尝试使用SDK(版本1.6)构建Firefox附加组件,但是我遇到了扩展程序正在打开的Tabs问题.

我想获取aContext(节点)处于打开状态的选项卡.为此,我一直在“获取”节点的窗口,然后使用SDK中的Tab Utils,特别是getTabForContentWindow().有时这不起作用,从getTabForContentWindow()返回的Tab为null.是否有更好,更健壮的方法来获取节点的Tab?

另外,我在the Tab Utils page上注意到,它表示“不稳定”.我应该避免使用Tab Utils SDK吗?

以下是来自main.js的代码:

const {Cc, Ci, Cr, Cu, Cm, components} = require("chrome");
const { XPCOMUtils } = Cu.import("resource://gre/modules/XPCOMUtils.jsm");
var winUtils = require('sdk/window/utils');
var tabUtils = require('sdk/tabs/utils');

let policy =
{
    classDescription: "my content policy",
    classID: components.ID("{2DA54ECA-FBDD-11E3-B3B1-695C1D5D46B0}"),
    contractID: "@www.com/policy;1",
    xpcom_categories: ["content-policy"],

    init: function()
    {
        let registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
        registrar.registerFactory(this.classID, this.classDescription, this.contractID, this);

        let catMan = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
        for each (let category in this.xpcom_categories)
            catMan.addCategoryEntry(category, this.contractID, this.contractID, false, true);
    },

    // nsIContentPolicy interface implementation
    shouldLoad: function(aContentType, aContentLocation, aRequestOrigin, aContext, aMimeTypeGuess, aExtra, aRequestPrincipal) {

        console.log("*****");
        console.log("aContentLocation.spec [" + aContentLocation.spec + "] ");
        console.log("aContentType [" + aContentType + "] ");
        if (aContext instanceof components.interfaces.nsIDOMNode) {            
            var node = aContext.QueryInterface(components.interfaces.nsIDOMNode);
            var win = getWindow(node);
            if (win) {
                console.log("window found" );
                var selectedTab = tabUtils.getTabForContentWindow(win);                
                if (selectedTab) {
                    console.log("tab found" );
                    var tabId = tabUtils.getTabId(selectedTab);
                    console.log("Node's tabId:" + tabId);
                } else {
                    console.log("tab undefined" );
                }
            } else {
                console.log("win undefined" );
            } 
        }
        return Ci.nsIContentPolicy.ACCEPT;

    },

    shouldProcess: function(contentType, contentLocation, requestOrigin, node, mimeTypeGuess, extra) {
        return Ci.nsIContentPolicy.ACCEPT;
    },

    // nsIFactory interface implementation
    createInstance: function(outer, iid) {
        if (outer)
            throw Cr.NS_ERROR_NO_AGGREGATION;
        return this.QueryInterface(iid);
    },

    // nsISupports interface implementation
    QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy, Ci.nsIFactory])
};

policy.init();

var scheduleCheckFilterUpdates = function() {
    var tabs = require("sdk/tabs");
    tabs.open("http://wikipedia.org");
}
require('sdk/timers').setTimeout(scheduleCheckFilterUpdates, 1000);

function getWindow(node) {
    if ("ownerDocument" in node && node.ownerDocument)
        node = node.ownerDocument;

    if ("defaultView" in node)
        return node.defaultView;

    return null;
}

解决方法:

您应该记住:

>并非所有请求都来自窗口. (后台请求)
>并非所有来自窗口的请求实际上都来自选项卡.运行代码时,您可以看到例如请求浏览器窗口本身加载的chrome://browser/skin/tabbrowser/tab-separator.png之类的东西(在本例中将在UI中使用).还请记住,并非所有顶级窗口实际上都是浏览器窗口(browser.xul).
>即使是选项卡导航,初始加载(aContentLocation.spec [http://wikipedia.org/])仍将从正在构造的尚未完全关联的新的尚未完全初始化的内容窗口中产生任何标签.此时的选项卡仍然是:空白,只有在可以完全构造完该窗口后,才会交换新窗口(维基百科):未阻止请求,DNS已解析,重定向以及最终响应实际生成的数据,并且可以将这些数据制作成一个窗口.例如.如果我的网络中断,则在分配给选项卡之前将放弃Wikipedia窗口,而是创建连接错误文档和窗口.

最后一点也记录在the nsIContentPolicy interface本身中:

 /**
   * Should the resource at this location be loaded?
   * ShouldLoad will be called before loading the resource at aContentLocation
   * to determine whether to start the load at all.
   *
   * @param aContentType      the type of content being tested. This will be one
   *                          one of the TYPE_* constants.
   *
   * @param aContentLocation  the location of the content being checked; must
   *                          not be null
   *
   * @param aRequestOrigin    OPTIONAL. the location of the resource that
   *                          initiated this load request; can be null if
   *                          inapplicable
   *
   * @param aContext          OPTIONAL. the nsIDOMNode or nsIDOMWindow that
   *                          initiated the request, or something that can QI
   *                          to one of those; can be null if inapplicable.
   *                          Note that for navigation events (new windows and
   *                          link clicks), this is the NEW window.
   *
   * @param aMimeTypeGuess    OPTIONAL. a guess for the requested content's
   *                          MIME type, based on information available to
   *                          the request initiator (e.g., an OBJECT's type
   *                          attribute); does not reliably reflect the
   *                          actual MIME type of the requested content
   *
   * @param aExtra            an OPTIONAL argument, pass-through for non-Gecko
   *                          callers to pass extra data to callees.
   *
   * @param aRequestPrincipal an OPTIONAL argument, defines the principal that
   *                          caused the load. This is optional only for
   *                          non-gecko code: all gecko code should set this
   *                          argument.  For navigation events, this is
   *                          the principal of the page that caused this load.
   *
   * @return ACCEPT or REJECT_*
   *
   * @note shouldLoad can be called while the DOM and layout of the document
   * involved is in an inconsistent state.  This means that implementors of
   * this method MUST NOT do any of the following:
   * 1)  Modify the DOM in any way (e.g. setting attributes is a no-no).
   * 2)  Query any DOM properties that depend on layout (e.g. offset*
   *     properties).
   * 3)  Query any DOM properties that depend on style (e.g. computed style).
   * 4)  Query any DOM properties that depend on the current state of the DOM
   *     outside the "context" node (e.g. lengths of node lists).
   * 5)  [JavaScript implementations only] Access properties of any sort on any
   *     object without using XPCNativeWrapper (either explicitly or
   *     implicitly).  Due to various DOM0 things, this leads to item 4.
   * If you do any of these things in your shouldLoad implementation, expect
   * unpredictable behavior, possibly including crashes, content not showing
   * up, content showing up doubled, etc.  If you need to do any of the things
   * above, do them off timeout or event.
   */
  short shouldLoad(in nsContentPolicyType aContentType,
                   in nsIURI        aContentLocation,
                   in nsIURI        aRequestOrigin,
                   in nsISupports   aContext,
                   in ACString      aMimeTypeGuess,
                   in nsISupports   aExtra,
                   [optional] in nsIPrincipal  aRequestPrincipal);

结论

据我所知,Tab Utils可以按预期工作,@ Notidart的答案中的代码也是如此.期望将新文档立即分配给错误的选项卡.

Also, I noticed on the Tab Utils page, that it states it’s ‘unstable’. Should I avoid using Tab Utils SDK?

好吧,这取决于您的个人喜好.从本质上讲,“不稳定”意味着API可以再次更改,甚至可以在更高版本的浏览器中再次删除.替代方法,例如使用window.gBrowser,至少与SDK API一样不稳定(也可以随时更改),因此恕我直言,避免使用此SDK API不会有任何好处,只要它没有被发现有问题即可以某种方式(但是如果可以,您仍然可以切换到其他方式).

标签:firefox,firefox-addon,firefox-addon-sdk,javascript
来源: https://codeday.me/bug/20191121/2052819.html