Question

I'm writing Firefox Addon that instead of opening content in new windows could open a content in new tab or sidebar.

There are several ways to open windows:

  • window.open()
  • window.openDialog() or...
  • using openWindow() function form the component @mozilla.org/embedcomp/window-watcher;1 by nsIWindowWatcher interface

I override window.open and window.openDialog and it seems to work but I have problem with overriding openWindow() function in window-watcher component.

I override whole component because I don't know how to override only specify functions. For now I implement all functions of the component and redirect them to internal original component this._WindowWatcher=Cc["@mozilla.org/embedcomp/window-watcher;1"].getService(Ci.nsIWindowWatcher) in a way like this function:

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);    
},

Then I register the component using XPCOMUtils.jsm and 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
);

Then this seems work when I use directly Window Watcher in JavaScript:

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

But when Firefox would like internally use the overriden component (e.g. clicking link on error item in Console; probably Firefox is using nsGlobalWindow::OpenDialog), it causes error :

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

My extension is here (overriding component module in modules\window-watcher.jsm)

For tests I use Firebug Console on chrome context or JavaScript Shell in Developer Assistant addon and import my component module Components.utils.import("resource://moreICUIPlus/window-watcher.jsm");

Thanks for every possible hints.

Was it helpful?

Solution

Just so that one does not need to skim the comments:

Re-implementing (wrapping) the @mozilla.org/embedcomp/window-watcher;1 component in a javascript component is not possible, because one would need to implement the non-scriptable nsPIWindowWatcher interface.

Re-implementing (wrapping) it in a C++ component would be possible, but in context of add-ons isn't very feasible, because one would need to compile for all supported OS/platforms, and one would need to recompile for each version of Gecko, as binary-components are version-tagged and won't load if the Gecko versions don't match.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top