Mercurial > hg > config
comparison chrome/pageloader.js @ 202:0b38ce037298
Bug 661918 - Tp should wait for MozAfterPaint after onload. r=tnikkel,vlad
author | Joel Maher <jmaher@mozilla.com> |
---|---|
date | Wed, 14 Sep 2011 16:41:38 -0400 |
parents | bffb8b1b0948 |
children | 4dec1e56c677 |
comparison
equal
deleted
inserted
replaced
201:bffb8b1b0948 | 202:0b38ce037298 |
---|---|
65 var delay = 250; | 65 var delay = 250; |
66 var timeoutEvent = -1; | 66 var timeoutEvent = -1; |
67 var running = false; | 67 var running = false; |
68 var forceCC = true; | 68 var forceCC = true; |
69 | 69 |
70 var useMozAfterPaint = false; | |
71 var gPaintWindow = window; | |
72 var gPaintListener = false; | |
73 | |
74 //when TEST_DOES_OWN_TIMING, we need to store the time from the page as MozAfterPaint can be slower than pageload | |
75 var gTime = -1; | |
76 var gStartTime = -1; | |
77 | |
70 var content; | 78 var content; |
71 | 79 |
72 var TEST_DOES_OWN_TIMING = 1; | 80 var TEST_DOES_OWN_TIMING = 1; |
73 | 81 |
74 var browserWindow = null; | 82 var browserWindow = null; |
98 if (args.height) winHeight = parseInt(args.height); | 106 if (args.height) winHeight = parseInt(args.height); |
99 if (args.filter) pageFilterRegexp = new RegExp(args.filter); | 107 if (args.filter) pageFilterRegexp = new RegExp(args.filter); |
100 if (args.noisy) noisy = true; | 108 if (args.noisy) noisy = true; |
101 if (args.timeout) timeout = parseInt(args.timeout); | 109 if (args.timeout) timeout = parseInt(args.timeout); |
102 if (args.delay) delay = parseInt(args.delay); | 110 if (args.delay) delay = parseInt(args.delay); |
111 if (args.mozafterpaint) useMozAfterPaint = true; | |
112 | |
103 forceCC = !args.noForceCC; | 113 forceCC = !args.noForceCC; |
104 doRenderTest = args.doRender; | 114 doRenderTest = args.doRender; |
105 | 115 |
106 if (forceCC && | 116 if (forceCC && |
107 !window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) | 117 !window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) |
153 blank.data = "about:blank"; | 163 blank.data = "about:blank"; |
154 browserWindow = wwatch.openWindow | 164 browserWindow = wwatch.openWindow |
155 (null, "chrome://browser/content/", "_blank", | 165 (null, "chrome://browser/content/", "_blank", |
156 "chrome,all,dialog=no,width=" + winWidth + ",height=" + winHeight, blank); | 166 "chrome,all,dialog=no,width=" + winWidth + ",height=" + winHeight, blank); |
157 | 167 |
168 gPaintWindow = browserWindow; | |
158 // get our window out of the way | 169 // get our window out of the way |
159 window.resizeTo(10,10); | 170 window.resizeTo(10,10); |
160 | 171 |
161 var browserLoadFunc = function (ev) { | 172 var browserLoadFunc = function (ev) { |
162 browserWindow.removeEventListener('load', browserLoadFunc, true); | 173 browserWindow.removeEventListener('load', browserLoadFunc, true); |
171 | 182 |
172 content = browserWindow.getBrowser(); | 183 content = browserWindow.getBrowser(); |
173 | 184 |
174 // Load the frame script for e10s / IPC message support | 185 // Load the frame script for e10s / IPC message support |
175 if (content.getAttribute("remote") == "true") { | 186 if (content.getAttribute("remote") == "true") { |
176 let contentScript = "data:,addEventListener('load', function(e) { " + | 187 let contentScript = "data:,function _contentLoadHandler(e) { " + |
177 " if (e.originalTarget.defaultView == content) { " + | 188 " if (e.originalTarget.defaultView == content) { " + |
178 " sendAsyncMessage('PageLoader:Load', {}); " + | 189 " content.wrappedJSObject.tpRecordTime = function(t, s) { sendAsyncMessage('PageLoader:RecordTime', { time: t, startTime: s }); }; "; |
179 " content.wrappedJSObject.tpRecordTime = function(t) { sendAsyncMessage('PageLoader:RecordTime', { time: t }); } " + | 190 if (useMozAfterPaint) { |
191 contentScript += "" + | |
192 "function _contentPaintHandler() { " + | |
193 " var utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowUtils); " + | |
194 " if (utils.isMozAfterPaintPending) { " + | |
195 " addEventListener('MozAfterPaint', function(e) { " + | |
196 " removeEventListener('MozAfterPaint', arguments.callee, true); " + | |
197 " sendAsyncMessage('PageLoader:MozAfterPaint', {}); " + | |
198 " }, true); " + | |
199 " } else { " + | |
200 " sendAsyncMessage('PageLoader:MozAfterPaint', {}); " + | |
201 " } " + | |
202 "}; " + | |
203 "content.wrappedJSObject.setTimeout(_contentPaintHandler, 0); "; | |
204 } else { | |
205 contentScript += " sendAsyncMessage('PageLoader:Load', {}); "; | |
206 } | |
207 contentScript += "" + | |
180 " }" + | 208 " }" + |
181 "}, true);" | 209 "} " + |
210 "addEventListener('load', _contentLoadHandler, true); "; | |
182 content.messageManager.loadFrameScript(contentScript, false); | 211 content.messageManager.loadFrameScript(contentScript, false); |
183 } | 212 } |
184 | 213 |
185 setTimeout(plLoadPage, 100); | 214 setTimeout(plLoadPage, 100); |
186 }, 500); | 215 }, 500); |
187 }; | 216 }; |
188 | 217 |
189 browserWindow.addEventListener('load', browserLoadFunc, true); | 218 browserWindow.addEventListener('load', browserLoadFunc, true); |
190 } else { | 219 } else { |
220 gPaintWindow = window; | |
191 window.resizeTo(winWidth, winHeight); | 221 window.resizeTo(winWidth, winHeight); |
192 | 222 |
193 content = document.getElementById('contentPageloader'); | 223 content = document.getElementById('contentPageloader'); |
194 | 224 |
195 setTimeout(plLoadPage, delay); | 225 setTimeout(plLoadPage, delay); |
217 removeLastAddedMsgListener(); | 247 removeLastAddedMsgListener(); |
218 | 248 |
219 if (plPageFlags() & TEST_DOES_OWN_TIMING) { | 249 if (plPageFlags() & TEST_DOES_OWN_TIMING) { |
220 // if the page does its own timing, use a capturing handler | 250 // if the page does its own timing, use a capturing handler |
221 // to make sure that we can set up the function for content to call | 251 // to make sure that we can set up the function for content to call |
252 | |
222 content.addEventListener('load', plLoadHandlerCapturing, true); | 253 content.addEventListener('load', plLoadHandlerCapturing, true); |
223 removeLastAddedListener = function() { | 254 removeLastAddedListener = function() { |
224 content.removeEventListener('load', plLoadHandlerCapturing, true); | 255 content.removeEventListener('load', plLoadHandlerCapturing, true); |
256 if (useMozAfterPaint) { | |
257 content.removeEventListener("MozAfterPaint", plPaintedCapturing, true); | |
258 gPaintHandler = false; | |
259 } | |
225 }; | 260 }; |
226 } else { | 261 } else { |
227 // if the page doesn't do its own timing, use a bubbling handler | 262 // if the page doesn't do its own timing, use a bubbling handler |
228 // to make sure that we're called after the page's own onload() handling | 263 // to make sure that we're called after the page's own onload() handling |
229 | 264 |
230 // XXX we use a capturing event here too -- load events don't bubble up | 265 // XXX we use a capturing event here too -- load events don't bubble up |
231 // to the <browser> element. See bug 390263. | 266 // to the <browser> element. See bug 390263. |
232 content.addEventListener('load', plLoadHandler, true); | 267 content.addEventListener('load', plLoadHandler, true); |
233 removeLastAddedListener = function() { | 268 removeLastAddedListener = function() { |
234 content.removeEventListener('load', plLoadHandler, true); | 269 content.removeEventListener('load', plLoadHandler, true); |
270 if (useMozAfterPaint) { | |
271 gPaintWindow.removeEventListener("MozAfterPaint", plPainted, true); | |
272 gPaintHandler = false; | |
273 } | |
235 }; | 274 }; |
236 } | 275 } |
237 | 276 |
238 // If the test browser is remote (e10s / IPC) we need to use messages to watch for page load | 277 // If the test browser is remote (e10s / IPC) we need to use messages to watch for page load |
239 if (content.getAttribute("remote") == "true") { | 278 if (content.getAttribute("remote") == "true") { |
240 content.messageManager.addMessageListener('PageLoader:Load', plLoadHandlerMessage); | 279 content.messageManager.addMessageListener('PageLoader:Load', plLoadHandlerMessage); |
241 content.messageManager.addMessageListener('PageLoader:RecordTime', plRecordTimeMessage); | 280 content.messageManager.addMessageListener('PageLoader:RecordTime', plRecordTimeMessage); |
281 if (useMozAfterPaint) | |
282 content.messageManager.addMessageListener('PageLoader:MozAfterPaint', plPaintHandler); | |
242 removeLastAddedMsgListener = function() { | 283 removeLastAddedMsgListener = function() { |
243 content.messageManager.removeMessageListener('PageLoader:Load', plLoadHandlerMessage); | 284 content.messageManager.removeMessageListener('PageLoader:Load', plLoadHandlerMessage); |
244 content.messageManager.removeMessageListener('PageLoader:RecordTime', plRecordTimeMessage); | 285 content.messageManager.removeMessageListener('PageLoader:RecordTime', plRecordTimeMessage); |
286 if (useMozAfterPaint) | |
287 content.messageManager.removeMessageListener('PageLoader:MozAfterPaint', plPaintHandler); | |
245 }; | 288 }; |
246 } | 289 } |
247 | 290 |
248 if (timeout > 0) { | 291 if (timeout > 0) { |
249 timeoutEvent = setTimeout('loadFail()', timeout); | 292 timeoutEvent = setTimeout('loadFail()', timeout); |
295 function plLoadHandlerCapturing(evt) { | 338 function plLoadHandlerCapturing(evt) { |
296 // make sure we pick up the right load event | 339 // make sure we pick up the right load event |
297 if (evt.type != 'load' || | 340 if (evt.type != 'load' || |
298 evt.originalTarget.defaultView.frameElement) | 341 evt.originalTarget.defaultView.frameElement) |
299 return; | 342 return; |
343 | |
344 //set the tpRecordTime function (called from test pages we load to store a global time. | |
345 content.contentWindow.wrappedJSObject.tpRecordTime = function (time, startTime) { | |
346 gTime = time; | |
347 gStartTime = startTime; | |
348 setTimeout(plWaitForPaintingCapturing, 0); | |
349 } | |
350 | |
351 content.removeEventListener('load', plLoadHandlerCapturing, true); | |
352 | |
353 setTimeout(plWaitForPaintingCapturing, 0); | |
354 } | |
355 | |
356 function plWaitForPaintingCapturing() { | |
357 if (gPaintListener) | |
358 return; | |
359 | |
360 var utils = gPaintWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) | |
361 .getInterface(Components.interfaces.nsIDOMWindowUtils); | |
362 | |
363 if (utils.isMozAfterPaintPending && useMozAfterPaint) { | |
364 if (gPaintListener == false) | |
365 gPaintWindow.addEventListener("MozAfterPaint", plPaintedCapturing, true); | |
366 gPaintListener = true; | |
367 return; | |
368 } | |
369 | |
370 _loadHandlerCapturing(); | |
371 } | |
372 | |
373 function plPaintedCapturing() { | |
374 gPaintWindow.removeEventListener("MozAfterPaint", plPaintedCapturing, true); | |
375 gPaintListener = false; | |
376 _loadHandlerCapturing(); | |
377 } | |
378 | |
379 function _loadHandlerCapturing() { | |
300 if (timeout > 0) { | 380 if (timeout > 0) { |
301 clearTimeout(timeoutEvent); | 381 clearTimeout(timeoutEvent); |
302 } | 382 } |
303 | 383 |
304 if (!(plPageFlags() & TEST_DOES_OWN_TIMING)) { | 384 if (!(plPageFlags() & TEST_DOES_OWN_TIMING)) { |
305 dumpLine("tp: Capturing onload handler used with page that doesn't do its own timing?"); | 385 dumpLine("tp: Capturing onload handler used with page that doesn't do its own timing?"); |
306 plStop(true); | 386 plStop(true); |
307 } | 387 } |
308 | 388 |
389 if (useMozAfterPaint) { | |
390 if (gStartTime != null && gStartTime >= 0) { | |
391 gTime = (new Date()) - gStartTime; | |
392 gStartTime = -1; | |
393 } | |
394 } | |
395 | |
309 // set up the function for content to call | 396 // set up the function for content to call |
310 content.contentWindow.wrappedJSObject.tpRecordTime = function (time) { | 397 if (gTime >= 0) { |
311 plRecordTime(time); | 398 plRecordTime(gTime); |
399 gTime = -1; | |
312 setTimeout(plNextPage, delay); | 400 setTimeout(plNextPage, delay); |
313 }; | 401 }; |
314 } | 402 } |
315 | 403 |
316 // the onload handler | 404 // the onload handler |
317 function plLoadHandler(evt) { | 405 function plLoadHandler(evt) { |
318 // make sure we pick up the right load event | 406 // make sure we pick up the right load event |
319 if (evt.type != 'load' || | 407 if (evt.type != 'load' || |
320 evt.originalTarget.defaultView.frameElement) | 408 evt.originalTarget.defaultView.frameElement) |
321 return; | 409 return; |
410 | |
411 content.removeEventListener('load', plLoadHandler, true); | |
412 setTimeout(waitForPainted, 0); | |
413 } | |
414 | |
415 // This is called after we have received a load event, now we wait for painted | |
416 function waitForPainted() { | |
417 | |
418 var utils = gPaintWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) | |
419 .getInterface(Components.interfaces.nsIDOMWindowUtils); | |
420 | |
421 if (!utils.isMozAfterPaintPending || !useMozAfterPaint) { | |
422 _loadHandler(); | |
423 return; | |
424 } | |
425 | |
426 if (gPaintListener == false) | |
427 gPaintWindow.addEventListener("MozAfterPaint", plPainted, true); | |
428 gPaintListener = true; | |
429 } | |
430 | |
431 function plPainted() { | |
432 gPaintWindow.removeEventListener("MozAfterPaint", plPainted, true); | |
433 gPaintListener = false; | |
434 _loadHandler(); | |
435 } | |
436 | |
437 function _loadHandler() { | |
322 if (timeout > 0) { | 438 if (timeout > 0) { |
323 clearTimeout(timeoutEvent); | 439 clearTimeout(timeoutEvent); |
324 } | 440 } |
325 var docElem; | 441 var docElem; |
326 if (browserWindow) | 442 if (browserWindow) |
352 plNextPage(); | 468 plNextPage(); |
353 } | 469 } |
354 | 470 |
355 // the onload handler used for remote (e10s) browser | 471 // the onload handler used for remote (e10s) browser |
356 function plLoadHandlerMessage(message) { | 472 function plLoadHandlerMessage(message) { |
473 _loadHandlerMessage(); | |
474 } | |
475 | |
476 // the mozafterpaint handler for remote (e10s) browser | |
477 function plPaintHandler(message) { | |
478 _loadHandlerMessage(); | |
479 } | |
480 | |
481 // the core handler for remote (e10s) browser | |
482 function _loadHandlerMessage() { | |
357 if (timeout > 0) { | 483 if (timeout > 0) { |
358 clearTimeout(timeoutEvent); | 484 clearTimeout(timeoutEvent); |
359 } | 485 } |
360 | 486 |
487 var time = -1; | |
488 | |
361 // does this page want to do its own timing? | 489 // does this page want to do its own timing? |
362 // if so, let's bail | 490 if ((plPageFlags() & TEST_DOES_OWN_TIMING)) { |
363 if (plPageFlags() & TEST_DOES_OWN_TIMING) | 491 if (typeof(gStartTime) != "number") |
364 return; | 492 gStartTime = Date.parse(gStartTime); |
365 | 493 |
366 var end_time = Date.now(); | 494 if (gTime >= 0) { |
367 var time = (end_time - start_time); | 495 if (useMozAfterPaint && gStartTime >= 0) { |
368 | 496 gTime = Date.now() - gStartTime; |
369 plRecordTime(time); | 497 gStartTime = -1; |
370 | 498 } else if (useMozAfterPaint) { |
371 if (doRenderTest) | 499 gTime = -1; |
372 runRenderTest(); | 500 } |
373 | 501 time = gTime; |
374 plNextPage(); | 502 gTime = -1; |
503 } | |
504 | |
505 } else { | |
506 var end_time = Date.now(); | |
507 time = (end_time - start_time); | |
508 } | |
509 | |
510 if (time >= 0) { | |
511 plRecordTime(time); | |
512 if (doRenderTest) | |
513 runRenderTest(); | |
514 | |
515 plNextPage(); | |
516 } | |
375 } | 517 } |
376 | 518 |
377 // the record time handler used for remote (e10s) browser | 519 // the record time handler used for remote (e10s) browser |
378 function plRecordTimeMessage(message) { | 520 function plRecordTimeMessage(message) { |
379 plRecordTime(message.json.time); | 521 gTime = message.json.time; |
380 setTimeout(plNextPage, delay); | 522 if (useMozAfterPaint) { |
523 gStartTime = message.json.startTime; | |
524 } | |
525 _loadHandlerMessage(); | |
381 } | 526 } |
382 | 527 |
383 function runRenderTest() { | 528 function runRenderTest() { |
384 const redrawsPerSample = 500; | 529 const redrawsPerSample = 500; |
385 | 530 |
427 } catch (e) { | 572 } catch (e) { |
428 dumpLine(e); | 573 dumpLine(e); |
429 } | 574 } |
430 | 575 |
431 if (content) { | 576 if (content) { |
577 content.removeEventListener('load', plLoadHandlerCapturing, true); | |
432 content.removeEventListener('load', plLoadHandler, true); | 578 content.removeEventListener('load', plLoadHandler, true); |
433 if (content.getAttribute("remote") == "true") | 579 if (useMozAfterPaint) |
580 content.removeEventListener("MozAfterPaint", plPaintedCapturing, true); | |
581 content.removeEventListener("MozAfterPaint", plPainted, true); | |
582 | |
583 if (content.getAttribute("remote") == "true") { | |
434 content.messageManager.removeMessageListener('PageLoader:Load', plLoadHandlerMessage); | 584 content.messageManager.removeMessageListener('PageLoader:Load', plLoadHandlerMessage); |
585 content.messageManager.removeMessageListener('PageLoader:RecordTime', plRecordTimeMessage); | |
586 if (MozAfterPaint) | |
587 content.messageManager.removeMessageListener('PageLoader:MozAfterPaint', plPaintHandler); | |
588 | |
589 content.messageManager.loadFrameScript("data:,removeEventListener('load', _contentLoadHandler, true);", false); | |
590 } | |
435 } | 591 } |
436 | 592 |
437 if (MozillaFileLogger) | 593 if (MozillaFileLogger) |
438 MozillaFileLogger.close(); | 594 MozillaFileLogger.close(); |
439 | 595 |