javascript - In a Firefox restartless add-on, how do I run code when a new window opens (listen for window open)? -
i starting build restartless firefox add-on , having trouble setting bootstrap.js. seems agree core of bootstrap.js pretty boilerplate code, along these lines:
const cc = components.classes; const ci = components.interfaces; function startup() { let wm = cc["@mozilla.org/appshell/window-mediator;1"].getservice(ci.nsiwindowmediator); let windows = wm.getenumerator("navigator:browser"); while (windows.hasmoreelements()) { let domwindow = windows.getnext().queryinterface(ci.nsidomwindow); // can control happens domwindow.document } } function shutdown() {} function install() {} function uninstall() {}
this code works , can control things in existing windows. example, domwindow.alert("text")
creates standard alert saying "text" on every window open.
however, can't find code allow me things in new windows; i.e. created after script runs. correct way handle creation of new windows , gain control on them, point "text" alert 1 when created?
edit: using nswindowmediator class , code sample mdn, have this:
var windowlistener = { onopenwindow: function (awindow) { try { let domwindow = awindow.queryinterface(ci.nsiinterfacerequestor).getinterface(ci.nsidomwindowinternal || ci.nsidomwindow); domwindow.addeventlistener("load", function () { domwindow.removeeventlistener("load", arguments.callee, false); //window has loaded stuff domwindow.alert("text"); }, false); } catch (err) { services.prompt.alert(null, "error", err); } }, onclosewindow: function (awindow) {}, onwindowtitlechange: function (awindow, atitle) {} }; function startup(adata, areason) { // load existing windows try { let wm = cc["@mozilla.org/appshell/window-mediator;1"].getservice(ci.nsiwindowmediator); let windows = wm.getenumerator("navigator:browser"); while (windows.hasmoreelements()) { let domwindow = windows.getnext().queryinterface(ci.nsidomwindow); loadintowindow(domwindow); } } catch (err) { services.prompt.alert(null, "error", err); } services.wm.addlistener(windowlistener); }
however, there still no output onopenwindow call - "text" alert not appear, nor error alert in catch block. can confirm onopenwindow being entered; if put services.prompt.alert()
@ beginning of onopenwindow, alert when create new window. unfortunately, infinite loop of alerts , have no idea why.
however, can't find code allow me things in new windows; i.e. created after script runs. correct way handle creation of new windows , gain control on them, point "text" alert 1 when created?
the correct way act on each window when opens use addlistener()
nsiwindowmediator. example code below this. nsiwindowmediator included in services.jsm , accessed through services.wm.addlistener(windowlistener)
. in order use window listener, have pass nsiwindowmediatorlistener (ref2) object. nsiwindowmediatorlistener contains 3 keys: onopenwindow
, onclosewindow
, , onwindowtitlechange
. each should defined function called when appropriate event occurs.
the mdn document how convert overlay extension restartless in "step 9: bootstrap.js" contains example of basic bootstrap.js run code in function loadintowindow(window)
each open browser window , browser window opens in future. have used code modified in couple of different add-ons. example substantially similar code using. example (slightly modified):
const ci = components.interfaces; components.utils.import("resource://gre/modules/services.jsm"); function startup(data,reason) { // load add-ons module(s): components.utils.import("chrome://myaddon/content/mymodule.jsm"); // whatever initial startup stuff needed add-on. // code in module loaded. mymodule.startup(); // make changes firefox ui hook in add-on foreachopenwindow(loadintowindow); // listen windows open in future services.wm.addlistener(windowlistener); } function shutdown(data,reason) { if (reason == app_shutdown) return; // unload ui each window foreachopenwindow(unloadfromwindow); // stop listening new windows open. services.wm.removelistener(windowlistener); // whatever shutdown stuff need on add-on disable mymodule.shutdown(); // unload module(s) loaded specific extension. // use same url module(s) when loaded: components.utils.unload("chrome://myaddon/content/mymodule.jsm"); // hack warning: addon manager not clear add-on related caches // on update. in order update images , locales, // caches need clearing here. services.obs.notifyobservers(null, "chrome-flush-caches", null); } function install(data,reason) { } function uninstall(data,reason) { } function loadintowindow(window) { /* call/move ui construction function here */ } function unloadfromwindow(window) { /* call/move ui tear down function here */ } function foreachopenwindow(todo) { // apply function open browser windows var windows = services.wm.getenumerator("navigator:browser"); while (windows.hasmoreelements()) todo(windows.getnext().queryinterface(ci.nsidomwindow)); } var windowlistener = { onopenwindow: function(xulwindow) { var window = xulwindow.queryinterface(ci.nsiinterfacerequestor) .getinterface(ci.nsidomwindow); function onwindowload() { window.removeeventlistener("load",onwindowload); // add ui changes if browser window if (window.document.documentelement.getattribute("windowtype") == "navigator:browser") loadintowindow(window); } window.addeventlistener("load",onwindowload); }, onclosewindow: function(xulwindow) { }, onwindowtitlechange: function(xulwindow, newtitle) { } };
while there quite bit more might want in bootstrap.js code, above organized reasonably , keeps of code load firefox ui within loadintowindow(window)
, unloading ui within unloadfromwindow(window)
. however, should noted ui elements should adding/removing once (e.g. australis widgets, buttons) , other elements (e.g. direct changes firefox dom) have added once in each window.
unfortunately, infinite loop of alerts , have no idea why.
one of significant differences between example , using test type of window has opened. done acting on newly opened windows browser windows instead of newly opened windows:
if (window.document.documentelement.getattribute("windowtype") == "navigator:browser") loadintowindow(window);
the problem describe of getting infinite loop of alert()
popups caused not checking make sure acting on browser windows. alert()
popup window. thus, calling alert()
every alert()
window open which, of course, opens alert()
window on call alert()
. infinite loop.
additional references:
1. working windows in chrome code
Comments
Post a Comment