0

我正在编写 Firefox 插件,而不是在新窗口中打开内容,而是在新选项卡或侧边栏中打开内容。

几种打开窗口的方法:

  • window.open()
  • window.openDialog()或者...
  • 通过nsIWindowWatcher接口使用openWindow()组件形式的函数@mozilla.org/embedcomp/window-watcher;1

我覆盖了 window.open 和 window.openDialog ,它似乎可以工作,但是我openWindow()在 window-watcher 组件中覆盖函数时遇到了问题。

我覆盖了整个组件,因为我不知道如何只覆盖指定的功能。现在我实现了组件的所有功能,并以如下方式将它们重定向到内部原始组件this._WindowWatcher=Cc["@mozilla.org/embedcomp/window-watcher;1"].getService(Ci.nsIWindowWatcher)

getWindowByName : function(/* in wstring */ aTargetName, /* in nsIDOMWindow */ aCurrentWindow)  // --> nsIDOMWindow;
{
    var all_args = Array.prototype.slice.call(arguments); // convert to Array
    return this._WindowWatcher.getWindowByName.apply(this._WindowWatcher, all_args);    
},

然后我使用 XPCOMUtils.jsm 和 nsIComponentRegistrar 注册组件:

var NSGetFactory = XPCOMUtils.generateNSGetFactory([WindowWatcher]);
var WindowWatcherFactory = NSGetFactory(WindowWatcher.prototype.classID);
var nsIComponentRegistrar = Components.manager
                            .QueryInterface(Ci.nsIComponentRegistrar);
var oldCID = nsIComponentRegistrar
             .contractIDToCID("@mozilla.org/embedcomp/window-watcher;1");
nsIComponentRegistrar.registerFactory(
       WindowWatcher.prototype.classID, 
       null, 
       "@mozilla.org/embedcomp/window-watcher;1", 
       WindowWatcherFactory
);

然后,当我在 JavaScript 中直接使用 Window Watcher 时,这似乎可行:

 ww = Cc["@mozilla.org/embedcomp/window-watcher;1"]
      .getService(Ci.nsIWindowWatcher)
 var win = ww.openWindow(null, "about:home",
                     "_blank", "chrome,centerscreen", null); 

但是当 Firefox 想要在内部使用被覆盖的组件时(例如,在控制台中单击错误项上的链接;可能 Firefox 正在使用nsGlobalWindow::OpenDialog),它会导致错误:

  NS_ERROR_UNEXPECTED: Component returned failure code: 0x8000ffff 
  (NS_ERROR_UNEXPECTED) [nsIDOMJSWindow.openDialog]

我的扩展在这里(覆盖组件模块modules\window-watcher.jsm

对于测试,我在 Chrome 上下文中使用 Firebug 控制台或在Developer Assistant插件中使用 JavaScript Shell 并导入我的组件模块Components.utils.import("resource://moreICUIPlus/window-watcher.jsm");

感谢所有可能的提示。

4

1 回答 1

2

只是为了不需要浏览评论:

在 javascript 组件中重新实现(包装)@mozilla.org/embedcomp/window-watcher;1组件是不可能的,因为需要实现不可编写脚本的nsPIWindowWatcher接口。

在 C++ 组件中重新实现(包装)它是可能的,但在附加组件的上下文中不是很可行,因为需要为所有支持的操作系统/平台进行编译,并且需要为每个版本重新编译Gecko,因为二进制组件带有版本标记,如果 Gecko 版本不匹配,则不会加载。

于 2013-08-09T10:40:22.813 回答