winopen.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. // target for window.open()
  2. const KID_URL = "child-window.html";
  3. // formats final results
  4. const SERVER_URL = "http://jrgm.mcom.com/cgi-bin/window-open-2.0/openreport.pl";
  5. // let system settle between each window.open
  6. const OPENER_DELAY = 1000;
  7. // three phases: single open/close; overlapped open/close; open-all/close-all
  8. var PHASE_ONE = 10;
  9. var PHASE_TWO = 0;
  10. var PHASE_THREE = 0;
  11. // keep this many windows concurrently open during overlapped phase
  12. var OVERLAP_COUNT = 3;
  13. // repeat three phases CYCLES times
  14. var CYCLES = 1;
  15. // autoclose flag
  16. var AUTOCLOSE = 1;
  17. // Chrome url for child windows.
  18. var KID_CHROME = null;
  19. var SAVED_CHROME = null;
  20. // URL options and correspnding vars.
  21. const options = [ [ "phase1", "PHASE_ONE", false ],
  22. [ "phase2", "PHASE_TWO", false ],
  23. [ "phase3", "PHASE_THREE", false ],
  24. [ "overlap", "OVERLAP_COUNT", false ],
  25. [ "cycles", "CYCLES", false ],
  26. [ "chrome", "KID_CHROME", true ],
  27. [ "close", "AUTOCLOSE", false ] ];
  28. // Note: You can attach search options to the url for this file to control
  29. // any of the options in the array above. E.g., specifying
  30. // mozilla --chrome "file:///D|/mozilla/xpfe/test/winopen.xul?phase1=16&close=0"
  31. // will run this script with PHASE_ONE=16 and AUTOCLOSE=0.
  32. //
  33. // On Win32, you must enclose the --chrome option in quotes in order pass funny Win32 shell
  34. // characters such as '&' or '|'!
  35. var opts = window.location.search.substring(1).split( '&' );
  36. for ( opt in opts ) {
  37. for ( var i in options ) {
  38. if ( opts[opt].indexOf( options[i][0]+"=" ) == 0 ) {
  39. var newVal = opts[opt].split( '=' )[ 1 ];
  40. // wrap with quotes, if required.
  41. if ( options[i][2] ) {
  42. newVal = '"' + newVal + '"';
  43. }
  44. eval( options[i][1] + "=" + newVal + ";" );
  45. }
  46. }
  47. }
  48. var prefs = null;
  49. if ( KID_CHROME ) {
  50. // Reset browser.chromeURL so it points to KID_CHROME.
  51. // This will cause window.open in openWindow to open that chrome.
  52. netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  53. prefs = Components.classes["@mozilla.org/preferences-service;1"]
  54. .getService( Components.interfaces.nsIPrefBranch );
  55. SAVED_CHROME = prefs.getCharPref( "browser.chromeURL" );
  56. prefs.setCharPref( "browser.chromeURL", KID_CHROME );
  57. }
  58. const CYCLE_SIZE = PHASE_ONE + PHASE_TWO + PHASE_THREE;
  59. const MAX_INDEX = CYCLE_SIZE * CYCLES; // total number of windows to open
  60. var windowList = []; // handles to opened windows
  61. var startingTimes = []; // time that window.open is called
  62. var openingTimes = []; // time that child window took to fire onload
  63. var closingTimes = []; // collect stats for case of closing >1 windows
  64. var currentIndex = 0;
  65. function childIsOpen(aTime) {
  66. openingTimes[currentIndex] = aTime - startingTimes[currentIndex];
  67. updateDisplay(currentIndex, openingTimes[currentIndex]);
  68. reapWindows(currentIndex);
  69. currentIndex++;
  70. if (currentIndex < MAX_INDEX)
  71. scheduleNextWindow();
  72. else
  73. window.setTimeout(reportResults, OPENER_DELAY);
  74. }
  75. function updateDisplay(index, time) {
  76. var formIndex = document.getElementById("formIndex");
  77. if (formIndex)
  78. formIndex.setAttribute("value", index+1);
  79. var formTime = document.getElementById("formTime");
  80. if (formTime)
  81. formTime.setAttribute("value", time);
  82. }
  83. function scheduleNextWindow() {
  84. window.setTimeout(openWindow, OPENER_DELAY);
  85. }
  86. function closeOneWindow(aIndex) {
  87. var win = windowList[aIndex];
  88. // no-op if window is already closed
  89. if (win && !win.closed) {
  90. win.close();
  91. windowList[aIndex] = null;
  92. }
  93. }
  94. function closeAllWindows(aRecordTimeToClose) {
  95. var timeToClose = (new Date()).getTime();
  96. var count = 0;
  97. for (var i = 0; i < windowList.length; i++) {
  98. if (windowList[i])
  99. count++;
  100. closeOneWindow(i);
  101. }
  102. if (aRecordTimeToClose && count > 0) {
  103. timeToClose = (new Date()).getTime() - timeToClose;
  104. closingTimes.push(parseInt(timeToClose/count));
  105. }
  106. }
  107. // close some, none, or all open windows in the list
  108. function reapWindows() {
  109. var modIndex = currentIndex % CYCLE_SIZE;
  110. if (modIndex < PHASE_ONE-1) {
  111. // first phase in each "cycle", are single open/close sequences
  112. closeOneWindow(currentIndex);
  113. }
  114. else if (PHASE_ONE-1 <= modIndex && modIndex < PHASE_ONE+PHASE_TWO-1) {
  115. // next phase in each "cycle", keep N windows concurrently open
  116. closeOneWindow(currentIndex - OVERLAP_COUNT);
  117. }
  118. else if (modIndex == PHASE_ONE+PHASE_TWO-1) {
  119. // end overlapping windows cycle; close all windows
  120. closeAllWindows(false);
  121. }
  122. else if (PHASE_ONE+PHASE_TWO <= modIndex && modIndex < CYCLE_SIZE-1) {
  123. // do nothing; keep adding windows
  124. }
  125. else if (modIndex == CYCLE_SIZE-1) {
  126. // end open-all/close-all phase; close windows, recording time to close
  127. closeAllWindows(true);
  128. }
  129. }
  130. function calcMedian( numbers ) {
  131. if ( numbers.length == 0 ) {
  132. return 0;
  133. } else if ( numbers.length == 1 ) {
  134. return numbers[0];
  135. } else if ( numbers.length == 2 ) {
  136. return ( numbers[0] + numbers[1] ) / 2;
  137. } else {
  138. numbers.sort( function (a,b){ return a-b; } );
  139. var n = Math.floor( numbers.length / 2 );
  140. return numbers.length % 2 ? numbers[n] : ( numbers[n-1] + numbers[n] ) / 2;
  141. }
  142. }
  143. function reportResults() {
  144. //XXX need to create a client-side method to do this?
  145. var opening = openingTimes.join(':'); // times for each window open
  146. var closing = closingTimes.join(':'); // these are for >1 url, as a group
  147. //var ua = escape(navigator.userAgent).replace(/\+/g, "%2B"); // + == ' ', on servers
  148. //var reportURL = SERVER_URL +
  149. // "?opening=" + opening +
  150. // "&closing=" + closing +
  151. // "&maxIndex=" + MAX_INDEX +
  152. // "&cycleSize=" + CYCLE_SIZE +
  153. //"&ua=" + ua;
  154. //window.open(reportURL, "test-results");
  155. var avgOpenTime = 0;
  156. var minOpenTime = 99999;
  157. var maxOpenTime = 0;
  158. var medOpenTime = calcMedian( openingTimes.slice(1) );
  159. // ignore first open
  160. for (i = 1; i < MAX_INDEX; i++) {
  161. avgOpenTime += openingTimes[i];
  162. if ( minOpenTime > openingTimes[i] ) {
  163. minOpenTime = openingTimes[i];
  164. }
  165. if ( maxOpenTime < openingTimes[i] ) {
  166. maxOpenTime = openingTimes[i];
  167. }
  168. }
  169. avgOpenTime = Math.round(avgOpenTime / (MAX_INDEX - 1));
  170. dump("openingTimes="+openingTimes.slice(1)+"\n");
  171. dump("avgOpenTime:" + avgOpenTime + "\n" );
  172. dump("minOpenTime:" + minOpenTime + "\n" );
  173. dump("maxOpenTime:" + maxOpenTime + "\n" );
  174. dump("medOpenTime:" + medOpenTime + "\n" );
  175. dump("__xulWinOpenTime:" + medOpenTime + "\n");
  176. // Close the root window, if required.
  177. if ( AUTOCLOSE ) {
  178. window.close();
  179. } else {
  180. document.getElementById("formTimes").value = openingTimes.slice(1);
  181. document.getElementById("formAvg").value = avgOpenTime;
  182. document.getElementById("formMin").value = minOpenTime;
  183. document.getElementById("formMax").value = maxOpenTime;
  184. document.getElementById("formMed").value = medOpenTime;
  185. document.getElementById("formAgain").setAttribute( "disabled", "false" );
  186. }
  187. }
  188. function tryAgain() {
  189. document.getElementById("formAgain").setAttribute( "disabled", "true" );
  190. windowList = [];
  191. startingTimes = [];
  192. openingTimes = [];
  193. closingTimes = [];
  194. currentIndex = 0;
  195. openWindow();
  196. }
  197. function restoreChromeURL() {
  198. // Restore browser.chromeURL pref.
  199. if ( KID_CHROME && SAVED_CHROME.length ) {
  200. netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  201. prefs.setCharPref( "browser.chromeURL", SAVED_CHROME );
  202. }
  203. }
  204. function openWindow() {
  205. startingTimes[currentIndex] = (new Date()).getTime();
  206. var path = window.location.pathname.substring( 0, window.location.pathname.lastIndexOf('/') );
  207. var url = window.location.protocol + "//" +
  208. window.location.hostname + path + "/" +
  209. KID_URL;
  210. windowList[currentIndex] = window.open(url, currentIndex);
  211. }