xpfe/test/winopen.js

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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

mercurial