Mercurial > powerbox
view extension/modules/content-injector.js @ 5:c01a64fefbf5 default tip
Added mock 'capability request' page.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Fri, 07 Aug 2009 14:20:28 -0700 |
parents | 1c02976d8809 |
children |
line wrap: on
line source
var EXPORTED_SYMBOLS = ["init"]; const Cc = Components.classes; const Ci = Components.interfaces; const Cu = Components.utils; const REQUEST_BOX_NAME = "powerbox_superpower_request"; const REQUEST_BOX_TEXT = "This web page wants superpowers."; const REQUEST_BOX_BUTTON_TEXT = "Huh?"; Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); function getParentChromeWindow(window) { var mainWindow = window.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIWebNavigation) .QueryInterface(Ci.nsIDocShellTreeItem) .rootTreeItem .QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDOMWindow); return mainWindow.wrappedJSObject; } function showRequestNotificationBox(window, caps, callback) { var tabbrowser = getParentChromeWindow(window).getBrowser(); var browser = tabbrowser.getBrowserForDocument(window.document); if (browser) { var nBox = tabbrowser.getNotificationBox(browser); var oldNotification = nBox.getNotificationWithValue(REQUEST_BOX_NAME); if (oldNotification) nBox.removeNotification(oldNotification); function onClickButton() { // TODO: Implement a real callback. const CAP_URI = "chrome://powerbox/content/request.html"; tabbrowser.selectedTab = tabbrowser.addTab(CAP_URI); } nBox.appendNotification(REQUEST_BOX_TEXT, REQUEST_BOX_NAME, null, nBox.PRIORITY_INFO_MEDIUM, [{accessKey: null, callback: onClickButton, label: REQUEST_BOX_BUTTON_TEXT, popup: null}]); } } 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); showRequestNotificationBox(window, caps, callback); }; } // Taken from Firebug's content/firebug/tabWatcher.js. function safeGetName(request) { try { return request.name; } catch (exc) { return null; } } var listener = { QueryInterface : XPCOMUtils.generateQI([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference]), // Much of this is taken from Firebug's content/firebug/tabWatcher.js, // specifically the FrameProgressListener object. onStateChange : function (aWebProgress, aRequest, aStateFlags, aStatus) { if (aStateFlags & Ci.nsIWebProgressListener.STATE_IS_REQUEST && aStateFlags & Ci.nsIWebProgressListener.STATE_START) { // We need to get the hook in as soon as the new DOMWindow is // created, but before it starts executing any scripts in the // page. After lengthy analysis, it seems that the start of // these "dummy" requests is the only state that works. // TODO: Firebug's code mentions that XHTML doesn't dispatch // any of these dummy requests, so we should probably use the // Firebug's XHTML workaround here. var safeName = safeGetName(aRequest); var window = aWebProgress.DOMWindow; if (window && window.wrappedJSObject && (safeName == "about:layout-dummy-request" || safeName == "about:document-onload-blocker")) { // TODO: Firebug's code mentions that about:blank causes strange // behavior here; I don't think it should apply to our use case, // though. 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(window) { var tabbrowser = window.getBrowser(); function addListener(browser) { browser.addProgressListener(listener, Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT); } tabbrowser.tabContainer.addEventListener( "TabOpen", function onTabOpen(event) { addListener(event.target.linkedBrowser); }, false ); tabbrowser.browsers.forEach(function(browser) { addListener(browser); }); }