Mercurial > hg > config
comparison chrome/pageloader.js @ 208:3f290bcae11a
wtf
| author | Jeff Hammel <jhammel@mozilla.com> |
|---|---|
| date | Mon, 13 Feb 2012 16:24:06 -0800 |
| parents | beca399c3a16 |
| children |
comparison
equal
deleted
inserted
replaced
| 207:7bad4b7281f2 | 208:3f290bcae11a |
|---|---|
| 1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | |
| 2 /* ***** BEGIN LICENSE BLOCK ***** | |
| 3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | |
| 4 * | |
| 5 * The contents of this file are subject to the Mozilla Public License Version | |
| 6 * 1.1 (the "License"); you may not use this file except in compliance with | |
| 7 * the License. You may obtain a copy of the License at | |
| 8 * http://www.mozilla.org/MPL/ | |
| 9 * | |
| 10 * Software distributed under the License is distributed on an "AS IS" basis, | |
| 11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |
| 12 * for the specific language governing rights and limitations under the | |
| 13 * License. | |
| 14 * | |
| 15 * The Original Code is tp. | |
| 16 * | |
| 17 * The Initial Developer of the Original Code is | |
| 18 * Mozilla Corporation. | |
| 19 * Portions created by the Initial Developer are Copyright (C) 2007 | |
| 20 * the Initial Developer. All Rights Reserved. | |
| 21 * | |
| 22 * Contributor(s): | |
| 23 * Rob Helmer <rhelmer@mozilla.com> | |
| 24 * Vladimir Vukicevic <vladimir@mozilla.com> | |
| 25 * | |
| 26 * Alternatively, the contents of this file may be used under the terms of | |
| 27 * either the GNU General Public License Version 2 or later (the "GPL"), or | |
| 28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), | |
| 29 * in which case the provisions of the GPL or the LGPL are applicable instead | |
| 30 * of those above. If you wish to allow use of your version of this file only | |
| 31 * under the terms of either the GPL or the LGPL, and not to allow others to | |
| 32 * use your version of this file under the terms of the MPL, indicate your | |
| 33 * decision by deleting the provisions above and replace them with the notice | |
| 34 * and other provisions required by the GPL or the LGPL. If you do not delete | |
| 35 * the provisions above, a recipient may use your version of this file under | |
| 36 * the terms of any one of the MPL, the GPL or the LGPL. | |
| 37 * | |
| 38 * ***** END LICENSE BLOCK ***** */ | |
| 39 | |
| 40 try { | |
| 41 if (Cc === undefined) { | |
| 42 var Cc = Components.classes; | |
| 43 var Ci = Components.interfaces; | |
| 44 } | |
| 45 } catch (ex) {} | |
| 46 | |
| 47 var NUM_CYCLES = 5; | |
| 48 | |
| 49 var pageFilterRegexp = null; | |
| 50 var reportFormat = "js"; | |
| 51 var useBrowser = true; | |
| 52 var winWidth = 1024; | |
| 53 var winHeight = 768; | |
| 54 | |
| 55 var doRenderTest = false; | |
| 56 | |
| 57 var pages; | |
| 58 var pageIndex; | |
| 59 var start_time; | |
| 60 var cycle; | |
| 61 var report; | |
| 62 var renderReport; | |
| 63 var noisy = false; | |
| 64 var timeout = -1; | |
| 65 var delay = 250; | |
| 66 var timeoutEvent = -1; | |
| 67 var running = false; | |
| 68 var forceCC = true; | |
| 69 var reportRSS = false; | |
| 70 | |
| 71 var useMozAfterPaint = false; | |
| 72 var gPaintWindow = window; | |
| 73 var gPaintListener = false; | |
| 74 | |
| 75 //when TEST_DOES_OWN_TIMING, we need to store the time from the page as MozAfterPaint can be slower than pageload | |
| 76 var gTime = -1; | |
| 77 var gStartTime = -1; | |
| 78 | |
| 79 var content; | |
| 80 | |
| 81 var TEST_DOES_OWN_TIMING = 1; | |
| 82 | |
| 83 var browserWindow = null; | |
| 84 | |
| 85 // the io service | |
| 86 var gIOS = null; | |
| 87 | |
| 88 function plInit() { | |
| 89 if (running) { | |
| 90 return; | |
| 91 } | |
| 92 running = true; | |
| 93 | |
| 94 cycle = 0; | |
| 95 | |
| 96 try { | |
| 97 var args = window.arguments[0].wrappedJSObject; | |
| 98 | |
| 99 var manifestURI = args.manifest; | |
| 100 var startIndex = 0; | |
| 101 var endIndex = -1; | |
| 102 if (args.startIndex) startIndex = parseInt(args.startIndex); | |
| 103 if (args.endIndex) endIndex = parseInt(args.endIndex); | |
| 104 if (args.numCycles) NUM_CYCLES = parseInt(args.numCycles); | |
| 105 if (args.format) reportFormat = args.format; | |
| 106 if (args.width) winWidth = parseInt(args.width); | |
| 107 if (args.height) winHeight = parseInt(args.height); | |
| 108 if (args.filter) pageFilterRegexp = new RegExp(args.filter); | |
| 109 if (args.noisy) noisy = true; | |
| 110 if (args.timeout) timeout = parseInt(args.timeout); | |
| 111 if (args.delay) delay = parseInt(args.delay); | |
| 112 if (args.mozafterpaint) useMozAfterPaint = true; | |
| 113 if (args.rss) reportRSS = true; | |
| 114 | |
| 115 forceCC = !args.noForceCC; | |
| 116 doRenderTest = args.doRender; | |
| 117 | |
| 118 if (forceCC && | |
| 119 !window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) | |
| 120 .getInterface(Components.interfaces.nsIDOMWindowUtils) | |
| 121 .garbageCollect) { | |
| 122 forceCC = false; | |
| 123 } | |
| 124 | |
| 125 gIOS = Cc["@mozilla.org/network/io-service;1"] | |
| 126 .getService(Ci.nsIIOService); | |
| 127 if (args.offline) | |
| 128 gIOS.offline = true; | |
| 129 var fileURI = gIOS.newURI(manifestURI, null, null); | |
| 130 pages = plLoadURLsFromURI(fileURI); | |
| 131 | |
| 132 if (!pages) { | |
| 133 dumpLine('tp: could not load URLs, quitting'); | |
| 134 plStop(true); | |
| 135 } | |
| 136 | |
| 137 if (pages.length == 0) { | |
| 138 dumpLine('tp: no pages to test, quitting'); | |
| 139 plStop(true); | |
| 140 } | |
| 141 | |
| 142 if (startIndex < 0) | |
| 143 startIndex = 0; | |
| 144 if (endIndex == -1 || endIndex >= pages.length) | |
| 145 endIndex = pages.length-1; | |
| 146 if (startIndex > endIndex) { | |
| 147 dumpLine("tp: error: startIndex >= endIndex"); | |
| 148 plStop(true); | |
| 149 } | |
| 150 | |
| 151 pages = pages.slice(startIndex,endIndex+1); | |
| 152 var pageUrls = pages.map(function(p) { return p.url.spec.toString(); }); | |
| 153 report = new Report(pageUrls); | |
| 154 | |
| 155 if (doRenderTest) | |
| 156 renderReport = new Report(pageUrls); | |
| 157 | |
| 158 pageIndex = 0; | |
| 159 | |
| 160 if (args.useBrowserChrome) { | |
| 161 var wwatch = Cc["@mozilla.org/embedcomp/window-watcher;1"] | |
| 162 .getService(Ci.nsIWindowWatcher); | |
| 163 var blank = Cc["@mozilla.org/supports-string;1"] | |
| 164 .createInstance(Ci.nsISupportsString); | |
| 165 blank.data = "about:blank"; | |
| 166 browserWindow = wwatch.openWindow | |
| 167 (null, "chrome://browser/content/", "_blank", | |
| 168 "chrome,all,dialog=no,width=" + winWidth + ",height=" + winHeight, blank); | |
| 169 | |
| 170 gPaintWindow = browserWindow; | |
| 171 // get our window out of the way | |
| 172 window.resizeTo(10,10); | |
| 173 | |
| 174 var browserLoadFunc = function (ev) { | |
| 175 browserWindow.removeEventListener('load', browserLoadFunc, true); | |
| 176 | |
| 177 // do this half a second after load, because we need to be | |
| 178 // able to resize the window and not have it get clobbered | |
| 179 // by the persisted values | |
| 180 setTimeout(function () { | |
| 181 browserWindow.resizeTo(winWidth, winHeight); | |
| 182 browserWindow.moveTo(0, 0); | |
| 183 browserWindow.focus(); | |
| 184 | |
| 185 content = browserWindow.getBrowser(); | |
| 186 | |
| 187 // Load the frame script for e10s / IPC message support | |
| 188 if (content.getAttribute("remote") == "true") { | |
| 189 let contentScript = "data:,function _contentLoadHandler(e) { " + | |
| 190 " if (e.originalTarget.defaultView == content) { " + | |
| 191 " content.wrappedJSObject.tpRecordTime = function(t, s) { sendAsyncMessage('PageLoader:RecordTime', { time: t, startTime: s }); }; "; | |
| 192 if (useMozAfterPaint) { | |
| 193 contentScript += "" + | |
| 194 "function _contentPaintHandler() { " + | |
| 195 " var utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowUtils); " + | |
| 196 " if (utils.isMozAfterPaintPending) { " + | |
| 197 " addEventListener('MozAfterPaint', function(e) { " + | |
| 198 " removeEventListener('MozAfterPaint', arguments.callee, true); " + | |
| 199 " sendAsyncMessage('PageLoader:MozAfterPaint', {}); " + | |
| 200 " }, true); " + | |
| 201 " } else { " + | |
| 202 " sendAsyncMessage('PageLoader:MozAfterPaint', {}); " + | |
| 203 " } " + | |
| 204 "}; " + | |
| 205 "content.wrappedJSObject.setTimeout(_contentPaintHandler, 0); "; | |
| 206 } else { | |
| 207 contentScript += " sendAsyncMessage('PageLoader:Load', {}); "; | |
| 208 } | |
| 209 contentScript += "" + | |
| 210 " }" + | |
| 211 "} " + | |
| 212 "addEventListener('load', _contentLoadHandler, true); "; | |
| 213 content.messageManager.loadFrameScript(contentScript, false); | |
| 214 } | |
| 215 if (reportRSS) { | |
| 216 initializeMemoryCollector(plLoadPage, 100); | |
| 217 } else { | |
| 218 setTimeout(plLoadPage, 100); | |
| 219 } | |
| 220 }, 500); | |
| 221 }; | |
| 222 | |
| 223 browserWindow.addEventListener('load', browserLoadFunc, true); | |
| 224 } else { | |
| 225 gPaintWindow = window; | |
| 226 window.resizeTo(winWidth, winHeight); | |
| 227 | |
| 228 content = document.getElementById('contentPageloader'); | |
| 229 | |
| 230 if (reportRSS) { | |
| 231 initializeMemoryCollector(plLoadPage, delay); | |
| 232 } else { | |
| 233 setTimeout(plLoadPage, delay); | |
| 234 } | |
| 235 } | |
| 236 } catch(e) { | |
| 237 dumpLine(e); | |
| 238 plStop(true); | |
| 239 } | |
| 240 } | |
| 241 | |
| 242 function plPageFlags() { | |
| 243 return pages[pageIndex].flags; | |
| 244 } | |
| 245 | |
| 246 // load the current page, start timing | |
| 247 var removeLastAddedListener = null; | |
| 248 var removeLastAddedMsgListener = null; | |
| 249 function plLoadPage() { | |
| 250 var pageName = pages[pageIndex].url.spec; | |
| 251 | |
| 252 if (removeLastAddedListener) | |
| 253 removeLastAddedListener(); | |
| 254 | |
| 255 if (removeLastAddedMsgListener) | |
| 256 removeLastAddedMsgListener(); | |
| 257 | |
| 258 if (plPageFlags() & TEST_DOES_OWN_TIMING) { | |
| 259 // if the page does its own timing, use a capturing handler | |
| 260 // to make sure that we can set up the function for content to call | |
| 261 | |
| 262 content.addEventListener('load', plLoadHandlerCapturing, true); | |
| 263 removeLastAddedListener = function() { | |
| 264 content.removeEventListener('load', plLoadHandlerCapturing, true); | |
| 265 if (useMozAfterPaint) { | |
| 266 content.removeEventListener("MozAfterPaint", plPaintedCapturing, true); | |
| 267 gPaintHandler = false; | |
| 268 } | |
| 269 }; | |
| 270 } else { | |
| 271 // if the page doesn't do its own timing, use a bubbling handler | |
| 272 // to make sure that we're called after the page's own onload() handling | |
| 273 | |
| 274 // XXX we use a capturing event here too -- load events don't bubble up | |
| 275 // to the <browser> element. See bug 390263. | |
| 276 content.addEventListener('load', plLoadHandler, true); | |
| 277 removeLastAddedListener = function() { | |
| 278 content.removeEventListener('load', plLoadHandler, true); | |
| 279 if (useMozAfterPaint) { | |
| 280 gPaintWindow.removeEventListener("MozAfterPaint", plPainted, true); | |
| 281 gPaintHandler = false; | |
| 282 } | |
| 283 }; | |
| 284 } | |
| 285 | |
| 286 // If the test browser is remote (e10s / IPC) we need to use messages to watch for page load | |
| 287 if (content.getAttribute("remote") == "true") { | |
| 288 content.messageManager.addMessageListener('PageLoader:Load', plLoadHandlerMessage); | |
| 289 content.messageManager.addMessageListener('PageLoader:RecordTime', plRecordTimeMessage); | |
| 290 if (useMozAfterPaint) | |
| 291 content.messageManager.addMessageListener('PageLoader:MozAfterPaint', plPaintHandler); | |
| 292 removeLastAddedMsgListener = function() { | |
| 293 content.messageManager.removeMessageListener('PageLoader:Load', plLoadHandlerMessage); | |
| 294 content.messageManager.removeMessageListener('PageLoader:RecordTime', plRecordTimeMessage); | |
| 295 if (useMozAfterPaint) | |
| 296 content.messageManager.removeMessageListener('PageLoader:MozAfterPaint', plPaintHandler); | |
| 297 }; | |
| 298 } | |
| 299 | |
| 300 if (timeout > 0) { | |
| 301 timeoutEvent = setTimeout('loadFail()', timeout); | |
| 302 } | |
| 303 if (reportRSS) { | |
| 304 collectMemory(startAndLoadURI, pageName); | |
| 305 } else { | |
| 306 startAndLoadURI(pageName); | |
| 307 } | |
| 308 } | |
| 309 | |
| 310 function startAndLoadURI(pageName) { | |
| 311 start_time = Date.now(); | |
| 312 content.loadURI(pageName); | |
| 313 } | |
| 314 | |
| 315 function loadFail() { | |
| 316 var pageName = pages[pageIndex].url.spec; | |
| 317 dumpLine("__FAILTimeout exceeded on " + pageName + "__FAIL") | |
| 318 plStop(true); | |
| 319 } | |
| 320 | |
| 321 function plNextPage() { | |
| 322 if (pageIndex < pages.length-1) { | |
| 323 pageIndex++; | |
| 324 | |
| 325 if (forceCC) { | |
| 326 var tccstart = new Date(); | |
| 327 window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) | |
| 328 .getInterface(Components.interfaces.nsIDOMWindowUtils) | |
| 329 .garbageCollect(); | |
| 330 var tccend = new Date(); | |
| 331 report.recordCCTime(tccend - tccstart); | |
| 332 } | |
| 333 | |
| 334 setTimeout(plLoadPage, delay); | |
| 335 } else { | |
| 336 plStop(false); | |
| 337 } | |
| 338 } | |
| 339 | |
| 340 function plRecordTime(time) { | |
| 341 var pageName = pages[pageIndex].url.spec; | |
| 342 var i = pageIndex | |
| 343 if (i < pages.length-1) { | |
| 344 i++; | |
| 345 } else { | |
| 346 i = 0; | |
| 347 } | |
| 348 var nextName = pages[i].url.spec; | |
| 349 report.recordTime(pageIndex, time); | |
| 350 if (noisy) { | |
| 351 dumpLine("Cycle " + (cycle+1) + ": loaded " + pageName + " (next: " + nextName + ")"); | |
| 352 } | |
| 353 } | |
| 354 | |
| 355 function plLoadHandlerCapturing(evt) { | |
| 356 // make sure we pick up the right load event | |
| 357 if (evt.type != 'load' || | |
| 358 evt.originalTarget.defaultView.frameElement) | |
| 359 return; | |
| 360 | |
| 361 //set the tpRecordTime function (called from test pages we load to store a global time. | |
| 362 content.contentWindow.wrappedJSObject.tpRecordTime = function (time, startTime) { | |
| 363 gTime = time; | |
| 364 gStartTime = startTime; | |
| 365 setTimeout(plWaitForPaintingCapturing, 0); | |
| 366 } | |
| 367 | |
| 368 content.removeEventListener('load', plLoadHandlerCapturing, true); | |
| 369 | |
| 370 setTimeout(plWaitForPaintingCapturing, 0); | |
| 371 } | |
| 372 | |
| 373 function plWaitForPaintingCapturing() { | |
| 374 if (gPaintListener) | |
| 375 return; | |
| 376 | |
| 377 var utils = gPaintWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) | |
| 378 .getInterface(Components.interfaces.nsIDOMWindowUtils); | |
| 379 | |
| 380 if (utils.isMozAfterPaintPending && useMozAfterPaint) { | |
| 381 if (gPaintListener == false) | |
| 382 gPaintWindow.addEventListener("MozAfterPaint", plPaintedCapturing, true); | |
| 383 gPaintListener = true; | |
| 384 return; | |
| 385 } | |
| 386 | |
| 387 _loadHandlerCapturing(); | |
| 388 } | |
| 389 | |
| 390 function plPaintedCapturing() { | |
| 391 gPaintWindow.removeEventListener("MozAfterPaint", plPaintedCapturing, true); | |
| 392 gPaintListener = false; | |
| 393 _loadHandlerCapturing(); | |
| 394 } | |
| 395 | |
| 396 function _loadHandlerCapturing() { | |
| 397 if (timeout > 0) { | |
| 398 clearTimeout(timeoutEvent); | |
| 399 } | |
| 400 | |
| 401 if (!(plPageFlags() & TEST_DOES_OWN_TIMING)) { | |
| 402 dumpLine("tp: Capturing onload handler used with page that doesn't do its own timing?"); | |
| 403 plStop(true); | |
| 404 } | |
| 405 | |
| 406 if (useMozAfterPaint) { | |
| 407 if (gStartTime != null && gStartTime >= 0) { | |
| 408 gTime = (new Date()) - gStartTime; | |
| 409 gStartTime = -1; | |
| 410 } | |
| 411 } | |
| 412 | |
| 413 // set up the function for content to call | |
| 414 if (gTime >= 0) { | |
| 415 plRecordTime(gTime); | |
| 416 gTime = -1; | |
| 417 setTimeout(plNextPage, delay); | |
| 418 }; | |
| 419 } | |
| 420 | |
| 421 // the onload handler | |
| 422 function plLoadHandler(evt) { | |
| 423 // make sure we pick up the right load event | |
| 424 if (evt.type != 'load' || | |
| 425 evt.originalTarget.defaultView.frameElement) | |
| 426 return; | |
| 427 | |
| 428 content.removeEventListener('load', plLoadHandler, true); | |
| 429 setTimeout(waitForPainted, 0); | |
| 430 } | |
| 431 | |
| 432 // This is called after we have received a load event, now we wait for painted | |
| 433 function waitForPainted() { | |
| 434 | |
| 435 var utils = gPaintWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) | |
| 436 .getInterface(Components.interfaces.nsIDOMWindowUtils); | |
| 437 | |
| 438 if (!utils.isMozAfterPaintPending || !useMozAfterPaint) { | |
| 439 _loadHandler(); | |
| 440 return; | |
| 441 } | |
| 442 | |
| 443 if (gPaintListener == false) | |
| 444 gPaintWindow.addEventListener("MozAfterPaint", plPainted, true); | |
| 445 gPaintListener = true; | |
| 446 } | |
| 447 | |
| 448 function plPainted() { | |
| 449 gPaintWindow.removeEventListener("MozAfterPaint", plPainted, true); | |
| 450 gPaintListener = false; | |
| 451 _loadHandler(); | |
| 452 } | |
| 453 | |
| 454 function _loadHandler() { | |
| 455 if (timeout > 0) { | |
| 456 clearTimeout(timeoutEvent); | |
| 457 } | |
| 458 var docElem; | |
| 459 if (browserWindow) | |
| 460 docElem = browserWindow.frames["content"].document.documentElement; | |
| 461 else | |
| 462 docElem = content.contentDocument.documentElement; | |
| 463 var width; | |
| 464 if ("getBoundingClientRect" in docElem) { | |
| 465 width = docElem.getBoundingClientRect().width; | |
| 466 } else if ("offsetWidth" in docElem) { | |
| 467 width = docElem.offsetWidth; | |
| 468 } | |
| 469 | |
| 470 var end_time = Date.now(); | |
| 471 var time = (end_time - start_time); | |
| 472 | |
| 473 // does this page want to do its own timing? | |
| 474 // if so, we shouldn't be here | |
| 475 if (plPageFlags() & TEST_DOES_OWN_TIMING) { | |
| 476 dumpLine("tp: Bubbling onload handler used with page that does its own timing?"); | |
| 477 plStop(true); | |
| 478 } | |
| 479 | |
| 480 plRecordTime(time); | |
| 481 | |
| 482 if (doRenderTest) | |
| 483 runRenderTest(); | |
| 484 | |
| 485 plNextPage(); | |
| 486 } | |
| 487 | |
| 488 // the onload handler used for remote (e10s) browser | |
| 489 function plLoadHandlerMessage(message) { | |
| 490 _loadHandlerMessage(); | |
| 491 } | |
| 492 | |
| 493 // the mozafterpaint handler for remote (e10s) browser | |
| 494 function plPaintHandler(message) { | |
| 495 _loadHandlerMessage(); | |
| 496 } | |
| 497 | |
| 498 // the core handler for remote (e10s) browser | |
| 499 function _loadHandlerMessage() { | |
| 500 if (timeout > 0) { | |
| 501 clearTimeout(timeoutEvent); | |
| 502 } | |
| 503 | |
| 504 var time = -1; | |
| 505 | |
| 506 // does this page want to do its own timing? | |
| 507 if ((plPageFlags() & TEST_DOES_OWN_TIMING)) { | |
| 508 if (typeof(gStartTime) != "number") | |
| 509 gStartTime = Date.parse(gStartTime); | |
| 510 | |
| 511 if (gTime >= 0) { | |
| 512 if (useMozAfterPaint && gStartTime >= 0) { | |
| 513 gTime = Date.now() - gStartTime; | |
| 514 gStartTime = -1; | |
| 515 } else if (useMozAfterPaint) { | |
| 516 gTime = -1; | |
| 517 } | |
| 518 time = gTime; | |
| 519 gTime = -1; | |
| 520 } | |
| 521 | |
| 522 } else { | |
| 523 var end_time = Date.now(); | |
| 524 time = (end_time - start_time); | |
| 525 } | |
| 526 | |
| 527 if (time >= 0) { | |
| 528 plRecordTime(time); | |
| 529 if (doRenderTest) | |
| 530 runRenderTest(); | |
| 531 | |
| 532 plNextPage(); | |
| 533 } | |
| 534 } | |
| 535 | |
| 536 // the record time handler used for remote (e10s) browser | |
| 537 function plRecordTimeMessage(message) { | |
| 538 gTime = message.json.time; | |
| 539 if (useMozAfterPaint) { | |
| 540 gStartTime = message.json.startTime; | |
| 541 } | |
| 542 _loadHandlerMessage(); | |
| 543 } | |
| 544 | |
| 545 function runRenderTest() { | |
| 546 const redrawsPerSample = 500; | |
| 547 | |
| 548 if (!Ci.nsIDOMWindowUtils) | |
| 549 return; | |
| 550 | |
| 551 var win; | |
| 552 | |
| 553 if (browserWindow) | |
| 554 win = content.contentWindow; | |
| 555 else | |
| 556 win = window; | |
| 557 var wu = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); | |
| 558 | |
| 559 var start = Date.now(); | |
| 560 for (var j = 0; j < redrawsPerSample; j++) | |
| 561 wu.redraw(); | |
| 562 var end = Date.now(); | |
| 563 | |
| 564 renderReport.recordTime(pageIndex, end - start); | |
| 565 } | |
| 566 | |
| 567 function plStop(force) { | |
| 568 if (reportRSS) { | |
| 569 collectMemory(plStopAll, force); | |
| 570 } else { | |
| 571 plStopAll(force); | |
| 572 } | |
| 573 } | |
| 574 | |
| 575 function plStopAll(force) { | |
| 576 try { | |
| 577 if (force == false) { | |
| 578 pageIndex = 0; | |
| 579 if (cycle < NUM_CYCLES-1) { | |
| 580 cycle++; | |
| 581 setTimeout(plLoadPage, delay); | |
| 582 return; | |
| 583 } | |
| 584 | |
| 585 var formats = reportFormat.split(","); | |
| 586 | |
| 587 if (!renderReport) { | |
| 588 for each (var fmt in formats) | |
| 589 dumpLine(report.getReport(fmt)); | |
| 590 } | |
| 591 else { | |
| 592 dumpLine ("*************** Render report *******************"); | |
| 593 for each (var fmt in formats) | |
| 594 dumpLine(renderReport.getReport(fmt)); | |
| 595 } | |
| 596 } | |
| 597 } catch (e) { | |
| 598 dumpLine(e); | |
| 599 } | |
| 600 | |
| 601 if (reportRSS) { | |
| 602 stopMemCollector(); | |
| 603 } | |
| 604 | |
| 605 if (content) { | |
| 606 content.removeEventListener('load', plLoadHandlerCapturing, true); | |
| 607 content.removeEventListener('load', plLoadHandler, true); | |
| 608 if (useMozAfterPaint) | |
| 609 content.removeEventListener("MozAfterPaint", plPaintedCapturing, true); | |
| 610 content.removeEventListener("MozAfterPaint", plPainted, true); | |
| 611 | |
| 612 if (content.getAttribute("remote") == "true") { | |
| 613 content.messageManager.removeMessageListener('PageLoader:Load', plLoadHandlerMessage); | |
| 614 content.messageManager.removeMessageListener('PageLoader:RecordTime', plRecordTimeMessage); | |
| 615 if (useMozAfterPaint) | |
| 616 content.messageManager.removeMessageListener('PageLoader:MozAfterPaint', plPaintHandler); | |
| 617 | |
| 618 content.messageManager.loadFrameScript("data:,removeEventListener('load', _contentLoadHandler, true);", false); | |
| 619 } | |
| 620 } | |
| 621 | |
| 622 if (MozillaFileLogger) | |
| 623 MozillaFileLogger.close(); | |
| 624 | |
| 625 goQuitApplication(); | |
| 626 } | |
| 627 | |
| 628 /* Returns array */ | |
| 629 function plLoadURLsFromURI(manifestUri) { | |
| 630 var fstream = Cc["@mozilla.org/network/file-input-stream;1"] | |
| 631 .createInstance(Ci.nsIFileInputStream); | |
| 632 var uriFile = manifestUri.QueryInterface(Ci.nsIFileURL); | |
| 633 | |
| 634 fstream.init(uriFile.file, -1, 0, 0); | |
| 635 var lstream = fstream.QueryInterface(Ci.nsILineInputStream); | |
| 636 | |
| 637 var d = []; | |
| 638 | |
| 639 var lineNo = 0; | |
| 640 var line = {value:null}; | |
| 641 var more; | |
| 642 do { | |
| 643 lineNo++; | |
| 644 more = lstream.readLine(line); | |
| 645 var s = line.value; | |
| 646 | |
| 647 // strip comments | |
| 648 s = s.replace(/#.*/, ''); | |
| 649 | |
| 650 // strip leading and trailing whitespace | |
| 651 s = s.replace(/^\s*/, '').replace(/\s*$/, ''); | |
| 652 | |
| 653 if (!s) | |
| 654 continue; | |
| 655 | |
| 656 var flags = 0; | |
| 657 var urlspec = s; | |
| 658 | |
| 659 // split on whitespace, and figure out if we have any flags | |
| 660 var items = s.split(/\s+/); | |
| 661 if (items[0] == "include") { | |
| 662 if (items.length != 2) { | |
| 663 dumpLine("tp: Error on line " + lineNo + " in " + manifestUri.spec + ": include must be followed by the manifest to include!"); | |
| 664 return null; | |
| 665 } | |
| 666 | |
| 667 var subManifest = gIOS.newURI(items[1], null, manifestUri); | |
| 668 if (subManifest == null) { | |
| 669 dumpLine("tp: invalid URI on line " + manifestUri.spec + ":" + lineNo + " : '" + line.value + "'"); | |
| 670 return null; | |
| 671 } | |
| 672 | |
| 673 var subItems = plLoadURLsFromURI(subManifest); | |
| 674 if (subItems == null) | |
| 675 return null; | |
| 676 d = d.concat(subItems); | |
| 677 } else { | |
| 678 if (items.length == 2) { | |
| 679 if (items[0].indexOf("%") != -1) | |
| 680 flags |= TEST_DOES_OWN_TIMING; | |
| 681 | |
| 682 urlspec = items[1]; | |
| 683 } else if (items.length != 1) { | |
| 684 dumpLine("tp: Error on line " + lineNo + " in " + manifestUri.spec + ": whitespace must be %-escaped!"); | |
| 685 return null; | |
| 686 } | |
| 687 | |
| 688 var url = gIOS.newURI(urlspec, null, manifestUri); | |
| 689 | |
| 690 if (pageFilterRegexp && !pageFilterRegexp.test(url.spec)) | |
| 691 continue; | |
| 692 | |
| 693 d.push({ url: url, | |
| 694 flags: flags }); | |
| 695 } | |
| 696 } while (more); | |
| 697 | |
| 698 return d; | |
| 699 } | |
| 700 | |
| 701 function dumpLine(str) { | |
| 702 if (MozillaFileLogger) | |
| 703 MozillaFileLogger.log(str + "\n"); | |
| 704 dump(str); | |
| 705 dump("\n"); | |
| 706 } |
