Mercurial > powerbox
diff extension/modules/content-injector.js @ 2:889c2fd4c9cf
window.powerbox.request() is now available on every content window.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Thu, 06 Aug 2009 14:53:41 -0700 |
parents | |
children | 413435fc6202 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extension/modules/content-injector.js Thu Aug 06 14:53:41 2009 -0700 @@ -0,0 +1,72 @@ +var EXPORTED_SYMBOLS = ["init"]; + +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cu = Components.utils; + +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); + +function buildRequestor(window) { + return function request(caps, callback) { + if (!(typeof(caps) == "object" || + typeof(caps) == "string")) + throw new Error("Must provide capabilities as first parameter."); + + if (typeof(callback) != "function") + throw new Error("Must provide callback as second parameter"); + + if (typeof(caps) == "object") + caps = new XPCSafeJSObjectWrapper(caps); + callback = new XPCSafeJSObjectWrapper(callback); + + // TODO: Present UI to user and inject requested capabilities. + }; +} + +var listener = { + QueryInterface : XPCOMUtils.generateQI([Ci.nsIWebProgressListener, + Ci.nsISupportsWeakReference]), + + onStateChange : function (aWebProgress, aRequest, + aStateFlags, aStatus) { + // STATE_START is too early, doc is still the old page. + // STATE_STOP is inconviently late (it's onload) + if (!(aStateFlags & Ci.nsIWebProgressListener.STATE_TRANSFERRING)) + return; + + var window = aWebProgress.DOMWindow; + + if (window.wrappedJSObject) { + var sandbox = Cu.Sandbox(window); + sandbox.importFunction(buildRequestor(window)); + sandbox.window = window.wrappedJSObject; + + function setupPowerbox() { + window.powerbox = {request: request}; + } + + Cu.evalInSandbox("(" + setupPowerbox.toString() + ")();", sandbox); + } + }, + + // stubs for the nsIWebProgressListener interfaces which we don't use. + onProgressChange : function() { }, + onLocationChange : function() { }, + onStatusChange : function() { }, + onSecurityChange : function() { } +}; + +function init() { + // WebProgressListener for getting notification of new doc loads. + // XXX Ugh. Since we're a chrome overlay, it would be nice to just + // use gBrowser.addProgressListener(). But that isn't sending + // STATE_TRANSFERRING, and the earliest we can get at the page is + // STATE_STOP (which is onload, and is inconviently late). + // We'll use the docloader service instead, but that means we need to + // filter out loads for other windows. + var docsvc = Cc["@mozilla.org/docloaderservice;1"]. + getService(Ci.nsIWebProgress); + + docsvc.addProgressListener(listener, + Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT); +}