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 }