Mercurial > powerbox
comparison extension/modules/content-injector.js @ 4:1c02976d8809
Changed to Firebug's progress listener, which allows us to inject our code before any scripts are executed on target pages.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Thu, 06 Aug 2009 17:18:45 -0700 |
parents | 413435fc6202 |
children | c01a64fefbf5 |
comparison
equal
deleted
inserted
replaced
3:413435fc6202 | 4:1c02976d8809 |
---|---|
58 | 58 |
59 showRequestNotificationBox(window, caps, callback); | 59 showRequestNotificationBox(window, caps, callback); |
60 }; | 60 }; |
61 } | 61 } |
62 | 62 |
63 // Taken from Firebug's content/firebug/tabWatcher.js. | |
64 function safeGetName(request) { | |
65 try { | |
66 return request.name; | |
67 } catch (exc) { | |
68 return null; | |
69 } | |
70 } | |
71 | |
63 var listener = { | 72 var listener = { |
64 QueryInterface : XPCOMUtils.generateQI([Ci.nsIWebProgressListener, | 73 QueryInterface : XPCOMUtils.generateQI([Ci.nsIWebProgressListener, |
65 Ci.nsISupportsWeakReference]), | 74 Ci.nsISupportsWeakReference]), |
66 | 75 |
76 // Much of this is taken from Firebug's content/firebug/tabWatcher.js, | |
77 // specifically the FrameProgressListener object. | |
67 onStateChange : function (aWebProgress, aRequest, | 78 onStateChange : function (aWebProgress, aRequest, |
68 aStateFlags, aStatus) { | 79 aStateFlags, aStatus) { |
69 // STATE_START is too early, doc is still the old page. | 80 if (aStateFlags & Ci.nsIWebProgressListener.STATE_IS_REQUEST && |
70 // STATE_STOP is inconviently late (it's onload) | 81 aStateFlags & Ci.nsIWebProgressListener.STATE_START) { |
71 if (!(aStateFlags & Ci.nsIWebProgressListener.STATE_TRANSFERRING)) | 82 // We need to get the hook in as soon as the new DOMWindow is |
72 return; | 83 // created, but before it starts executing any scripts in the |
84 // page. After lengthy analysis, it seems that the start of | |
85 // these "dummy" requests is the only state that works. | |
73 | 86 |
74 var window = aWebProgress.DOMWindow; | 87 // TODO: Firebug's code mentions that XHTML doesn't dispatch |
88 // any of these dummy requests, so we should probably use the | |
89 // Firebug's XHTML workaround here. | |
90 var safeName = safeGetName(aRequest); | |
91 var window = aWebProgress.DOMWindow; | |
92 if (window && window.wrappedJSObject && | |
93 (safeName == "about:layout-dummy-request" || | |
94 safeName == "about:document-onload-blocker")) { | |
95 // TODO: Firebug's code mentions that about:blank causes strange | |
96 // behavior here; I don't think it should apply to our use case, | |
97 // though. | |
98 var sandbox = Cu.Sandbox(window); | |
99 sandbox.importFunction(buildRequestor(window)); | |
100 sandbox.window = window.wrappedJSObject; | |
75 | 101 |
76 if (window.wrappedJSObject) { | 102 function setupPowerbox() { |
77 var sandbox = Cu.Sandbox(window); | 103 window.powerbox = {request: request}; |
78 sandbox.importFunction(buildRequestor(window)); | 104 } |
79 sandbox.window = window.wrappedJSObject; | |
80 | 105 |
81 function setupPowerbox() { | 106 Cu.evalInSandbox("(" + setupPowerbox.toString() + ")();", sandbox); |
82 window.powerbox = {request: request}; | |
83 } | 107 } |
84 | |
85 Cu.evalInSandbox("(" + setupPowerbox.toString() + ")();", sandbox); | |
86 } | 108 } |
87 }, | 109 }, |
88 | 110 |
89 // stubs for the nsIWebProgressListener interfaces which we don't use. | 111 // Stubs for the nsIWebProgressListener interfaces which we don't use. |
90 onProgressChange : function() { }, | 112 onProgressChange : function() { }, |
91 onLocationChange : function() { }, | 113 onLocationChange : function() { }, |
92 onStatusChange : function() { }, | 114 onStatusChange : function() { }, |
93 onSecurityChange : function() { } | 115 onSecurityChange : function() { } |
94 }; | 116 }; |
95 | 117 |
96 function init() { | 118 function init(window) { |
97 // WebProgressListener for getting notification of new doc loads. | 119 var tabbrowser = window.getBrowser(); |
98 // XXX Ugh. Since we're a chrome overlay, it would be nice to just | |
99 // use gBrowser.addProgressListener(). But that isn't sending | |
100 // STATE_TRANSFERRING, and the earliest we can get at the page is | |
101 // STATE_STOP (which is onload, and is inconviently late). | |
102 // We'll use the docloader service instead, but that means we need to | |
103 // filter out loads for other windows. | |
104 var docsvc = Cc["@mozilla.org/docloaderservice;1"]. | |
105 getService(Ci.nsIWebProgress); | |
106 | 120 |
107 docsvc.addProgressListener(listener, | 121 function addListener(browser) { |
108 Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT); | 122 browser.addProgressListener(listener, |
123 Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT); | |
124 } | |
125 | |
126 tabbrowser.tabContainer.addEventListener( | |
127 "TabOpen", | |
128 function onTabOpen(event) { addListener(event.target.linkedBrowser); }, | |
129 false | |
130 ); | |
131 | |
132 tabbrowser.browsers.forEach(function(browser) { addListener(browser); }); | |
109 } | 133 } |