summaryrefslogtreecommitdiff
path: root/xpfe/test/winopen.js
blob: 11548c441d5e84770949aaa0b0d3340b10c52f71 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
// target for window.open()
const KID_URL       = "child-window.html";

// formats final results
const SERVER_URL    = "http://jrgm.mcom.com/cgi-bin/window-open-2.0/openreport.pl";

// let system settle between each window.open
const OPENER_DELAY  = 1000;   

// three phases: single open/close; overlapped open/close; open-all/close-all
var PHASE_ONE     = 10; 
var PHASE_TWO     = 0; 
var PHASE_THREE   = 0; 

// keep this many windows concurrently open during overlapped phase
var OVERLAP_COUNT = 3;

// repeat three phases CYCLES times    
var CYCLES        = 1;  

// autoclose flag
var AUTOCLOSE = 1;

// Chrome url for child windows.
var KID_CHROME   = null;
var SAVED_CHROME = null;

// URL options and correspnding vars.
const options = [ [ "phase1", "PHASE_ONE", false ],
                  [ "phase2", "PHASE_TWO", false ],
                  [ "phase3", "PHASE_THREE", false ],
                  [ "overlap", "OVERLAP_COUNT", false ],
                  [ "cycles", "CYCLES", false ],
                  [ "chrome", "KID_CHROME", true ],
                  [ "close", "AUTOCLOSE", false ] ];

// Note: You can attach search options to the url for this file to control
// any of the options in the array above.  E.g., specifying
// mozilla --chrome "file:///D|/mozilla/xpfe/test/winopen.xul?phase1=16&close=0"
// will run this script with PHASE_ONE=16 and AUTOCLOSE=0.
//
// On Win32, you must enclose the --chrome option in quotes in order pass funny Win32 shell
// characters such as '&' or '|'!

var opts = window.location.search.substring(1).split( '&' );
for ( opt in opts ) {
    for ( var i in options ) {
        if ( opts[opt].indexOf( options[i][0]+"=" ) == 0 ) {
            var newVal = opts[opt].split( '=' )[ 1 ];
            // wrap with quotes, if required.
            if ( options[i][2] ) {
                newVal = '"' + newVal + '"';
            }
            eval( options[i][1] + "=" + newVal + ";" );
        }
    }
}

var prefs = null;

if ( KID_CHROME ) {
    // Reset browser.chromeURL so it points to KID_CHROME.
    // This will cause window.open in openWindow to open that chrome.
    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
    prefs = Components.classes["@mozilla.org/preferences-service;1"]
              .getService( Components.interfaces.nsIPrefBranch );
    SAVED_CHROME = prefs.getCharPref( "browser.chromeURL" );
    prefs.setCharPref( "browser.chromeURL", KID_CHROME );
}

const CYCLE_SIZE    = PHASE_ONE + PHASE_TWO + PHASE_THREE;
const MAX_INDEX     = CYCLE_SIZE * CYCLES;  // total number of windows to open

var windowList      = [];   // handles to opened windows
var startingTimes   = [];   // time that window.open is called
var openingTimes    = [];   // time that child window took to fire onload
var closingTimes    = [];   // collect stats for case of closing >1 windows
var currentIndex    = 0;       


function childIsOpen(aTime) {
    openingTimes[currentIndex] = aTime - startingTimes[currentIndex];
    updateDisplay(currentIndex, openingTimes[currentIndex]);
    reapWindows(currentIndex);
    currentIndex++;
    if (currentIndex < MAX_INDEX)
        scheduleNextWindow();
    else
        window.setTimeout(reportResults, OPENER_DELAY);
}


function updateDisplay(index, time) {
    var formIndex = document.getElementById("formIndex");
    if (formIndex) 
        formIndex.setAttribute("value", index+1);
    var formTime  = document.getElementById("formTime");
    if (formTime) 
        formTime.setAttribute("value", time);
}


function scheduleNextWindow() {
    window.setTimeout(openWindow, OPENER_DELAY);
}


function closeOneWindow(aIndex) {
    var win = windowList[aIndex];
    // no-op if window is already closed
    if (win && !win.closed) {
	win.close();
	windowList[aIndex] = null;
    }
}    


function closeAllWindows(aRecordTimeToClose) {
    var timeToClose = (new Date()).getTime();
    var count = 0;
    for (var i = 0; i < windowList.length; i++) {
	if (windowList[i])
	    count++;
	closeOneWindow(i);
    }
    if (aRecordTimeToClose && count > 0) {
        timeToClose = (new Date()).getTime() - timeToClose;
        closingTimes.push(parseInt(timeToClose/count));
    }
}    


// close some, none, or all open windows in the list
function reapWindows() {
    var modIndex = currentIndex % CYCLE_SIZE;
    if (modIndex < PHASE_ONE-1) {
	// first phase in each "cycle", are single open/close sequences
	closeOneWindow(currentIndex);
    } 
    else if (PHASE_ONE-1 <= modIndex && modIndex < PHASE_ONE+PHASE_TWO-1) {
	// next phase in each "cycle", keep N windows concurrently open
	closeOneWindow(currentIndex - OVERLAP_COUNT);
    }
    else if (modIndex == PHASE_ONE+PHASE_TWO-1) {
	// end overlapping windows cycle; close all windows
	closeAllWindows(false);
    }
    else if (PHASE_ONE+PHASE_TWO <= modIndex && modIndex < CYCLE_SIZE-1) {
	// do nothing; keep adding windows
    }
    else if (modIndex == CYCLE_SIZE-1) {
	// end open-all/close-all phase; close windows, recording time to close
	closeAllWindows(true);
    }
}

function calcMedian( numbers ) {
    if ( numbers.length == 0 ) {
        return 0;
    } else if ( numbers.length == 1 ) {
        return numbers[0];
    } else if ( numbers.length == 2 ) {
        return ( numbers[0] + numbers[1] ) / 2;
    } else {
        numbers.sort( function (a,b){ return a-b; } );
        var n = Math.floor( numbers.length / 2 );
        return numbers.length % 2 ? numbers[n] : ( numbers[n-1] + numbers[n] ) / 2;
    }
}

function reportResults() {
    //XXX need to create a client-side method to do this?
    var opening = openingTimes.join(':'); // times for each window open
    var closing = closingTimes.join(':'); // these are for >1 url, as a group
    //var ua = escape(navigator.userAgent).replace(/\+/g, "%2B"); // + == ' ', on servers
    //var reportURL = SERVER_URL + 
    //    "?opening="    + opening + 
    //    "&closing="    + closing + 
    //    "&maxIndex="   + MAX_INDEX + 
    //    "&cycleSize="  + CYCLE_SIZE + 
	//"&ua="         + ua;
    //window.open(reportURL, "test-results");
    var avgOpenTime = 0;
    var minOpenTime = 99999;
    var maxOpenTime = 0;
    var medOpenTime = calcMedian( openingTimes.slice(1) );
    // ignore first open
    for (i = 1; i < MAX_INDEX; i++) {
        avgOpenTime += openingTimes[i];
        if ( minOpenTime > openingTimes[i] ) {
            minOpenTime = openingTimes[i];
        }
        if ( maxOpenTime < openingTimes[i] ) {
            maxOpenTime = openingTimes[i];
        }
    }
    avgOpenTime = Math.round(avgOpenTime / (MAX_INDEX - 1));
    dump("openingTimes="+openingTimes.slice(1)+"\n");
    dump("avgOpenTime:" + avgOpenTime + "\n" );
    dump("minOpenTime:" + minOpenTime + "\n" );
    dump("maxOpenTime:" + maxOpenTime + "\n" );
    dump("medOpenTime:" + medOpenTime + "\n" );
    dump("__xulWinOpenTime:" + medOpenTime + "\n");
    // Close the root window, if required.
    if ( AUTOCLOSE ) {
        window.close();
    } else {
        document.getElementById("formTimes").value = openingTimes.slice(1);
        document.getElementById("formAvg").value   = avgOpenTime;
        document.getElementById("formMin").value   = minOpenTime;
        document.getElementById("formMax").value   = maxOpenTime;
        document.getElementById("formMed").value   = medOpenTime;
        document.getElementById("formAgain").setAttribute( "disabled", "false" );
    }
}

function tryAgain() {
    document.getElementById("formAgain").setAttribute( "disabled", "true" );
    windowList      = [];
    startingTimes   = [];
    openingTimes    = [];
    closingTimes    = [];
    currentIndex    = 0;       
    openWindow();
}

function restoreChromeURL() {
    // Restore browser.chromeURL pref.
    if ( KID_CHROME && SAVED_CHROME.length ) {
        netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
        prefs.setCharPref( "browser.chromeURL", SAVED_CHROME );
    }
}

function openWindow() {
    startingTimes[currentIndex] = (new Date()).getTime();
    var path   = window.location.pathname.substring( 0, window.location.pathname.lastIndexOf('/') );
    var url    = window.location.protocol + "//" + 
                 window.location.hostname + path + "/" +
                 KID_URL;
    windowList[currentIndex] = window.open(url, currentIndex);
}