OLD | NEW |
1 const Cc = Components.classes; | 1 const Cc = Components.classes; |
2 const Ci = Components.interfaces; | 2 const Ci = Components.interfaces; |
3 const Cr = Components.results; | 3 const Cr = Components.results; |
4 const Cu = Components.utils; | 4 const Cu = Components.utils; |
5 | 5 |
6 const MILLIS_IN_SECOND = 1000; | 6 const {Services} = Cu.import("resource://gre/modules/Services.jsm", {}); |
7 const MILLIS_IN_MINUTE = 60 * MILLIS_IN_SECOND; | |
8 const MILLIS_IN_HOUR = 60 * MILLIS_IN_MINUTE; | |
9 const MILLIS_IN_DAY = 24 * MILLIS_IN_HOUR; | |
10 | |
11 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); | |
12 Cu.import("resource://gre/modules/Services.jsm"); | |
13 | 7 |
14 const SDK = Cu.import("resource://gre/modules/commonjs/toolkit/require.js", {}); | 8 const SDK = Cu.import("resource://gre/modules/commonjs/toolkit/require.js", {}); |
15 SDK.require("sdk/tabs"); | 9 SDK.require("sdk/tabs"); |
16 | 10 |
17 function require(module) | 11 function require(module) |
18 { | 12 { |
19 let result = {}; | 13 let result = {}; |
20 result.wrappedJSObject = result; | 14 result.wrappedJSObject = result; |
21 Services.obs.notifyObservers(result, "adblockplus-require", module); | 15 Services.obs.notifyObservers(result, "adblockplus-require", module); |
22 return result.exports; | 16 return result.exports; |
(...skipping 28 matching lines...) Expand all Loading... |
51 let {ElemHide} = require("elemHide"); | 45 let {ElemHide} = require("elemHide"); |
52 let {CSSRules} = require("cssRules"); | 46 let {CSSRules} = require("cssRules"); |
53 let {IO} = require("io"); | 47 let {IO} = require("io"); |
54 let {Notification} = require("notification"); | 48 let {Notification} = require("notification"); |
55 let {Prefs} = require("prefs"); | 49 let {Prefs} = require("prefs"); |
56 let {RequestNotifier} = require("requestNotifier"); | 50 let {RequestNotifier} = require("requestNotifier"); |
57 let {Synchronizer} = require("synchronizer"); | 51 let {Synchronizer} = require("synchronizer"); |
58 let {UI} = require("ui"); | 52 let {UI} = require("ui"); |
59 let {Utils} = require("utils"); | 53 let {Utils} = require("utils"); |
60 | 54 |
61 let geckoVersion = Services.appinfo.platformVersion; | |
62 function compareGeckoVersion(version) | |
63 { | |
64 return Services.vc.compare(geckoVersion, version); | |
65 } | |
66 | |
67 function prepareFilterComponents(keepListeners) | 55 function prepareFilterComponents(keepListeners) |
68 { | 56 { |
69 let FilterNotifierGlobal = getModuleGlobal("filterNotifier"); | 57 let FilterNotifierGlobal = getModuleGlobal("filterNotifier"); |
70 | 58 |
71 this._backup = { | 59 this._backup = { |
72 subscriptions: FilterStorage.subscriptions, | 60 subscriptions: FilterStorage.subscriptions, |
73 storageKnown: FilterStorage.knownSubscriptions, | 61 storageKnown: FilterStorage.knownSubscriptions, |
74 subscriptionsKnown: Subscription.knownSubscriptions, | 62 subscriptionsKnown: Subscription.knownSubscriptions, |
75 filtersKnown: Filter.knownFilters, | 63 filtersKnown: Filter.knownFilters, |
76 listeners: FilterNotifierGlobal.listeners, | 64 listeners: FilterNotifierGlobal.listeners, |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 } | 120 } |
133 Prefs.enabled = true; | 121 Prefs.enabled = true; |
134 } | 122 } |
135 | 123 |
136 function restorePrefs() | 124 function restorePrefs() |
137 { | 125 { |
138 for (let pref in this._pbackup) | 126 for (let pref in this._pbackup) |
139 Prefs[pref] = this._pbackup[pref]; | 127 Prefs[pref] = this._pbackup[pref]; |
140 } | 128 } |
141 | 129 |
142 function setupVirtualTime(processTimers) | |
143 { | |
144 let currentTime = 100000 * MILLIS_IN_HOUR; | |
145 let startTime = currentTime; | |
146 let scheduledTasks = []; | |
147 | |
148 let modules = Array.prototype.slice.call(arguments, 1); | |
149 this._virtualTimeModules = modules; | |
150 | |
151 for (let module of this._virtualTimeModules) | |
152 { | |
153 let global = Cu.getGlobalForObject(getModuleGlobal(module)); | |
154 | |
155 // Replace Date.now() function | |
156 this["_origNow" + module] = global.Date.now; | |
157 global.Date.now = function() currentTime; | |
158 } | |
159 | |
160 // Wrap timers | |
161 if (processTimers) | |
162 { | |
163 processTimers(function wrapTimer(timer) | |
164 { | |
165 let wrapper = Object.create(timer); | |
166 let callback = timer.callback; | |
167 wrapper.handler = function() callback.notify(wrapper); | |
168 wrapper.nextExecution = currentTime + timer.delay; | |
169 scheduledTasks.push(wrapper); | |
170 timer.cancel(); | |
171 return wrapper; | |
172 }); | |
173 } | |
174 | |
175 // Register observer to track outstanding requests | |
176 this._outstandingRequests = 0; | |
177 this.observe = function(subject, topic, data) | |
178 { | |
179 let orig = this._outstandingRequests; | |
180 if (topic == "http-on-modify-request") | |
181 this._outstandingRequests++; | |
182 else if (topic == "http-on-examine-response") | |
183 this._outstandingRequests--; | |
184 }; | |
185 this.QueryInterface = XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWea
kReference]); | |
186 Services.obs.addObserver(this, "http-on-modify-request", true); | |
187 Services.obs.addObserver(this, "http-on-examine-response", true); | |
188 | |
189 this.runScheduledTasks = function(maxHours, initial, skip) | |
190 { | |
191 if (typeof maxHours != "number") | |
192 throw new Error("Numerical parameter expected"); | |
193 if (typeof initial != "number") | |
194 initial = 0; | |
195 if (typeof skip != "number") | |
196 skip = 0; | |
197 | |
198 startTime = currentTime; | |
199 if (initial >= 0) | |
200 { | |
201 this._runScheduledTasks(initial); | |
202 maxHours -= initial; | |
203 } | |
204 if (skip) | |
205 { | |
206 this._skipTasks(skip); | |
207 maxHours -= skip; | |
208 } | |
209 this._runScheduledTasks(maxHours); | |
210 } | |
211 | |
212 this._runScheduledTasks = function(maxHours) | |
213 { | |
214 let endTime = currentTime + maxHours * MILLIS_IN_HOUR; | |
215 while (true) | |
216 { | |
217 let nextTask = null; | |
218 for (let task of scheduledTasks) | |
219 { | |
220 if (!nextTask || nextTask.nextExecution > task.nextExecution) | |
221 nextTask = task; | |
222 } | |
223 if (!nextTask || nextTask.nextExecution > endTime) | |
224 break; | |
225 | |
226 currentTime = nextTask.nextExecution; | |
227 nextTask.handler(); | |
228 | |
229 // Let all asynchronous actions finish | |
230 let thread = Services.tm.currentThread; | |
231 let loopStartTime = Date.now(); | |
232 | |
233 while (this._outstandingRequests > 0 || thread.hasPendingEvents()) | |
234 { | |
235 thread.processNextEvent(true); | |
236 | |
237 if (Date.now() - loopStartTime > 5000) | |
238 throw new Error("Test stuck in a download loop"); | |
239 } | |
240 | |
241 if (nextTask.type == Components.interfaces.nsITimer.TYPE_ONE_SHOT) | |
242 scheduledTasks = scheduledTasks.filter(function(task) task != nextTask); | |
243 else | |
244 nextTask.nextExecution = currentTime + nextTask.delay; | |
245 } | |
246 | |
247 currentTime = endTime; | |
248 } | |
249 | |
250 this._skipTasks = function(hours) | |
251 { | |
252 let newTasks = []; | |
253 currentTime += hours * MILLIS_IN_HOUR; | |
254 for (let task of scheduledTasks) | |
255 { | |
256 if (task.nextExecution >= currentTime) | |
257 newTasks.push(task); | |
258 else if (task.type != Components.interfaces.nsITimer.TYPE_ONE_SHOT) | |
259 { | |
260 task.nextExecution = currentTime; | |
261 newTasks.push(task); | |
262 } | |
263 } | |
264 scheduledTasks = newTasks; | |
265 } | |
266 | |
267 this.getTimeOffset = function() (currentTime - startTime) / MILLIS_IN_HOUR; | |
268 | |
269 this.__defineGetter__("currentTime", function() currentTime); | |
270 } | |
271 | |
272 function restoreVirtualTime() | |
273 { | |
274 for (let module of this._virtualTimeModules) | |
275 { | |
276 let global = Cu.getGlobalForObject(getModuleGlobal(module)); | |
277 | |
278 // Restore Date.now() function | |
279 if ("_origNow" + module in this) | |
280 { | |
281 global.Date.now = this["_origNow" + module]; | |
282 delete this["_origNow" + module]; | |
283 } | |
284 } | |
285 | |
286 Services.obs.removeObserver(this, "http-on-modify-request", true); | |
287 Services.obs.removeObserver(this, "http-on-examine-response", true); | |
288 } | |
289 | |
290 function setupVirtualXMLHttp() | |
291 { | |
292 let host = "http://example.com"; | |
293 let requestHandlers = {}; | |
294 | |
295 let XMLHttpRequest = function() | |
296 { | |
297 this._loadHandlers = []; | |
298 this._errorHandlers = []; | |
299 }; | |
300 XMLHttpRequest.prototype = { | |
301 _path: null, | |
302 _data: null, | |
303 _queryString: null, | |
304 _loadHandlers: null, | |
305 _errorHandlers: null, | |
306 status: 0, | |
307 readyState: 0, | |
308 responseText: null, | |
309 | |
310 addEventListener: function(eventName, handler, capture) | |
311 { | |
312 let list; | |
313 if (eventName == "load") | |
314 list = this._loadHandlers; | |
315 else if (eventName == "error") | |
316 list = this._errorHandlers; | |
317 else | |
318 throw new Error("Event type " + eventName + " not supported"); | |
319 | |
320 if (list.indexOf(handler) < 0) | |
321 list.push(handler); | |
322 }, | |
323 | |
324 removeEventListener: function(eventName, handler, capture) | |
325 { | |
326 let list; | |
327 if (eventName == "load") | |
328 list = this._loadHandlers; | |
329 else if (eventName == "error") | |
330 list = this._errorHandlers; | |
331 else | |
332 throw new Error("Event type " + eventName + " not supported"); | |
333 | |
334 let index = list.indexOf(handler); | |
335 if (index >= 0) | |
336 list.splice(index, 1); | |
337 }, | |
338 | |
339 open: function(method, url, async, user, password) | |
340 { | |
341 if (method != "GET") | |
342 throw new Error("Only GET requests are currently supported"); | |
343 if (typeof async != "undefined" && !async) | |
344 throw new Error("Sync requests are not supported"); | |
345 if (typeof user != "undefined" || typeof password != "undefined") | |
346 throw new Error("User authentification is not supported"); | |
347 | |
348 let match = /^data:[^,]+,/.exec(url); | |
349 if (match) | |
350 { | |
351 this._data = decodeURIComponent(url.substr(match[0].length)); | |
352 return; | |
353 } | |
354 | |
355 if (url.substr(0, host.length) != host) | |
356 throw new Error("Unexpected URL: " + url + " (URL starting with " + host
+ "expected)"); | |
357 | |
358 this._path = url.substr(host.length); | |
359 | |
360 let queryIndex = this._path.indexOf("?"); | |
361 this._queryString = ""; | |
362 if (queryIndex >= 0) | |
363 { | |
364 this._queryString = this._path.substr(queryIndex + 1); | |
365 this._path = this._path.substr(0, queryIndex); | |
366 } | |
367 }, | |
368 | |
369 send: function(data) | |
370 { | |
371 if (!this._data && !this._path) | |
372 throw new Error("No request path set"); | |
373 if (typeof data != "undefined" && data) | |
374 throw new Error("Sending data to server is not supported"); | |
375 | |
376 Utils.runAsync(function() | |
377 { | |
378 let result = [Cr.NS_OK, 404, ""]; | |
379 if (this._data) | |
380 result = [Cr.NS_OK, 0, this._data]; | |
381 else if (this._path in requestHandlers) | |
382 result = requestHandlers[this._path]({method: "GET", path: this._path,
queryString: this._queryString}); | |
383 [this.channel.status, this.channel.responseStatus, this.responseText] =
result; | |
384 this.status = this.channel.responseStatus; | |
385 | |
386 let eventName = (this.channel.status == Cr.NS_OK ? "load" : "error"); | |
387 let event = {type: eventName}; | |
388 for (let handler of this["_" + eventName + "Handlers"]) | |
389 handler.call(this, event); | |
390 }.bind(this)); | |
391 }, | |
392 | |
393 overrideMimeType: function(mime) | |
394 { | |
395 }, | |
396 | |
397 channel: | |
398 { | |
399 status: -1, | |
400 responseStatus: 0, | |
401 loadFlags: 0, | |
402 INHIBIT_CACHING: 0, | |
403 VALIDATE_ALWAYS: 0, | |
404 QueryInterface: function() this | |
405 } | |
406 } | |
407 | |
408 this.registerHandler = function(path, handler) requestHandlers[path] = handler
; | |
409 | |
410 let modules = Array.prototype.slice.call(arguments, 1); | |
411 this._virtualXMLHttpModules = modules; | |
412 for (let module of this._virtualTimeModules) | |
413 { | |
414 let global = getModuleGlobal(module); | |
415 | |
416 // Replace XMLHttpRequest constructor | |
417 this["_origXMLHttpRequest" + module] = global.XMLHttpRequest; | |
418 global.XMLHttpRequest = XMLHttpRequest; | |
419 } | |
420 } | |
421 | |
422 function restoreVirtualXMLHttp() | |
423 { | |
424 for (let module of this._virtualXMLHttpModules) | |
425 { | |
426 let global = getModuleGlobal(module); | |
427 | |
428 // Restore XMLHttpRequest constructor | |
429 if ("_origXMLHttpRequest" + module in this) | |
430 { | |
431 global.XMLHttpRequest = this["_origXMLHttpRequest" + module]; | |
432 delete this["_origXMLHttpRequest" + module]; | |
433 } | |
434 } | |
435 } | |
436 | |
437 function showProfilingData(debuggerService) | 130 function showProfilingData(debuggerService) |
438 { | 131 { |
439 let scripts = []; | 132 let scripts = []; |
440 debuggerService.enumerateScripts({ | 133 debuggerService.enumerateScripts({ |
441 enumerateScript: function(script) | 134 enumerateScript: function(script) |
442 { | 135 { |
443 scripts.push(script); | 136 scripts.push(script); |
444 } | 137 } |
445 }); | 138 }); |
446 scripts = scripts.filter(function(script) | 139 scripts = scripts.filter(function(script) |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 return oldFinish.apply(this, arguments); | 220 return oldFinish.apply(this, arguments); |
528 } | 221 } |
529 window.addEventListener("unload", function() | 222 window.addEventListener("unload", function() |
530 { | 223 { |
531 debuggerService.off(); | 224 debuggerService.off(); |
532 }, true); | 225 }, true); |
533 debuggerService.on(); | 226 debuggerService.on(); |
534 debuggerService.flags |= debuggerService.COLLECT_PROFILE_DATA; | 227 debuggerService.flags |= debuggerService.COLLECT_PROFILE_DATA; |
535 debuggerService.clearProfileData(); | 228 debuggerService.clearProfileData(); |
536 } | 229 } |
OLD | NEW |