1 <!DOCTYPE HTML> 2 3 <html id="t"> 4 <head> 5 <title>About Stats</title> 6 7 <style> 8 body { 9 border-top: 10px solid #3B85E3; 10 color: #333; 11 font-family: Verdana, Helvetica, Arial, sans-serif; 12 } 13 body, td { 14 font-size: 11px; 15 } 16 a:link, a:visited { 17 color: #2C3EBA; 18 text-decoration: none; 19 } 20 a:hover { 21 color: red; 22 text-decoration: underline; 23 } 24 h1 { 25 border-left: 10px solid #FFF; 26 font-size: 16px; 27 font-weight: bold; 28 margin: 0; 29 padding: 0.2em; 30 color: #3B85E3; 31 } 32 h2 { 33 border-left: 10px solid #FFF; 34 font-size: 11px; 35 font-weight: normal; 36 margin: 0; 37 padding: 0 6em 0.2em 0.2em; 38 } 39 .details { 40 margin: 0.4em 1.9em 0 1.2em; 41 padding: 0 0.4em 0.3em 0; 42 white-space: nowrap; 43 } 44 .details .outer { 45 padding-right: 0; 46 vertical-align: top; 47 } 48 .details .top { 49 border-top: 2px solid #333; 50 font-weight: bold; 51 margin-top: 0.4em; 52 } 53 .details .header2 { 54 font-weight: bold; 55 padding-left: 0.9em; 56 } 57 .details .key { 58 padding-left: 1.1em; 59 vertical-align: top; 60 } 61 .details .value { 62 text-align: right; 63 color: #333; 64 font-weight: bold; 65 } 66 .details .zebra { 67 background: #EEE; 68 } 69 .lower { 70 text-transform: lowercase; 71 } 72 </style> 73 <script> 74 75 /* Counter accessor for Name Node. */ 76 function getCounterNameFromCounterNode(node) { 77 return node.childNodes[1]; 78 } 79 80 /* Counter accessor for Value Node. */ 81 function getCounterValueFromCounterNode(node) { 82 return node.childNodes[3]; 83 } 84 85 /* Counter accessor for Delta Node. */ 86 function getCounterDeltaFromCounterNode(node) { 87 return node.childNodes[5]; 88 } 89 90 /* Timer accessor for Name Node. */ 91 function getTimerNameFromTimerNode(node) { 92 return node.childNodes[1]; 93 } 94 95 /* Timer accessor for Value Node. */ 96 function getTimerValueFromTimerNode(node) { 97 return node.childNodes[3]; 98 } 99 100 /* Timer accessor for Time Node. */ 101 function getTimerTimeFromTimerNode(node) { 102 return node.childNodes[5]; 103 } 104 105 /* Timer accessor for Average Time Node. */ 106 function getTimerAvgTimeFromTimerNode(node) { 107 return node.childNodes[7]; 108 } 109 110 /* Do the filter work. Hide all nodes matching node.*/ 111 function filterMatching(text, nodelist, functionToGetNameNode) { 112 var showAll = text.length == 0; 113 for (var i = 0, node; node = nodelist[i]; i++) { 114 var name = functionToGetNameNode(node).innerHTML.toLowerCase(); 115 if (showAll || name.indexOf(text) >= 0) { 116 node.style.display = "table-row"; 117 } else { 118 node.style.display = "none"; 119 } 120 } 121 } 122 123 /* Hides or shows counters based on the user's current filter selection. */ 124 function doFilter() { 125 var filter = document.getElementById("filter"); 126 var text = filter.value.toLowerCase(); 127 var nodes = document.getElementsByName("counter"); 128 filterMatching(text, nodes, getCounterNameFromCounterNode); 129 var nodes = document.getElementsByName("timer"); 130 filterMatching(text, nodes, getTimerNameFromTimerNode); 131 } 132 133 /* Colors the counters based on increasing or decreasing value. */ 134 function doColor() { 135 var nodes = document.getElementsByName("counter"); 136 for (var i = 0, node; node = nodes[i]; i++) { 137 var child = getCounterDeltaFromCounterNode(node); 138 var delta = child.innerHTML; 139 if (delta > 0) { 140 child.style.color = "Green"; 141 } else if (delta == 0) { 142 child.style.color = "Black"; 143 } else { 144 child.style.color = "Red"; 145 } 146 } 147 } 148 149 /* Counters with no values are null. Remove them. */ 150 function removeNullValues() { 151 var nodes = document.getElementsByName("counter"); 152 for (var i = nodes.length - 1; i >= 0; i--) { 153 var node = nodes[i]; 154 var value = getCounterValueFromCounterNode(node).innerHTML; 155 if (value == "null") { 156 node.parentNode.removeChild(node); 157 } 158 } 159 var nodes = document.getElementsByName("timer"); 160 for (var i = 0, node; node = nodes[i]; i++) { 161 var value_node = getTimerValueFromTimerNode(node); 162 if (value_node.innerHTML == "null") { 163 value_node.innerHTML = ""; 164 } 165 } 166 } 167 168 /* Compute the average time for timers */ 169 function computeTimes() { 170 var nodes = document.getElementsByName("timer"); 171 for (var i = 0, node; node = nodes[i]; i++) { 172 var count = getTimerValueFromTimerNode(node).innerHTML; 173 if (count.length > 0) { 174 var time = getTimerTimeFromTimerNode(node).innerHTML; 175 var avg = getTimerAvgTimeFromTimerNode(node); 176 avg.innerHTML = Math.round(time / count * 100) / 100; 177 } 178 } 179 } 180 181 /* All the work we do onload. */ 182 function onLoadWork() { 183 doColor(); 184 removeNullValues(); 185 computeTimes(); 186 document.getElementById("filter").focus(); 187 } 188 189 // The function should only be used as the event handler 190 // on a table cell element. To use it, put it in a <td> element: 191 // <td onclick="sort('string')" ...> 192 // 193 // The function sorts rows after the row with onclick event handler. 194 // 195 // type: the data type, 'string', 'number' 196 function sort_table(type){ 197 var cell = event.target; 198 var cnum = cell.cellIndex; 199 200 var row = cell.parentNode; 201 var start_index = row.rowIndex + 1; 202 203 var tbody = row.parentNode; 204 var table = tbody.parentNode; 205 206 var rows = new Array(); 207 208 var indexes = new Array(); 209 // skip the first row 210 for (var i = start_index; i < table.rows.length; i++) 211 rows.push(table.rows[i]); 212 213 // a, b are strings 214 function compare_strings(a,b) { 215 if (a == b) return 0; 216 if (a < b) return -1; 217 return 1; 218 } 219 220 // a, b are numbers 221 function compare_numbers(a,b) { 222 var x = isNaN(a) ? 0 : a; 223 var y = isNaN(b) ? 0 : b; 224 return x - y; 225 } 226 227 var sort_func = undefined; 228 if (type === 'string') { 229 sort_func = function(a, b) { 230 var x = a.cells[cnum].innerText; 231 var y = b.cells[cnum].innerText; 232 return compare_strings(x, y); 233 } ; 234 235 } else if (type === 'number') { 236 sort_func = function(a, b) { 237 var x = parseFloat(a.cells[cnum].innerText); 238 var y = parseFloat(b.cells[cnum].innerText); 239 return compare_numbers(x, y); 240 } 241 } 242 243 rows.sort(sort_func); 244 245 // change tables 246 if (cell._reverse) { 247 for (var i = rows.length - 1; i >= 0; i--) 248 tbody.appendChild(rows[i]); 249 cell._reverse = false; 250 } else { 251 for (var i = 0; i < rows.length; i++) 252 tbody.appendChild(rows[i]); 253 cell._reverse = true; 254 } 255 } 256 257 </script> 258 </head> 259 <body onload="onLoadWork()"> 260 <div style="float: right"> 261 <br>Filter: <input id="filter" type="text" value="" onkeyup="doFilter()"> 262 </div> 263 <h1 class="lower">About Stats</h1> 264 <h2>Shhh! This page is secret!</h2><br/> 265 <table class="details" cellspacing="0" cellpadding="0" border="0"> 266 <tbody> 267 <tr> 268 <td class="outer"> 269 <table cellspacing="0" cellpadding="0" border="0"> 270 <tbody> 271 <tr> 272 <td class="top" width="100">Counters</td> 273 <td class="top value" colspan=2></td> 274 </tr> 275 <tr> 276 <td class="header2 lower" width="200" onclick="sort_table('string')">name</td> 277 <td class="header2 lower" onclick="sort_table('number')">value</td> 278 <td class="header2 lower" onclick="sort_table('number')">delta</td> 279 </tr> 280 <tr jsselect="counters" name="counter"> 281 <td class="key" width="200" jscontent="name"></td> 282 <td class="value" jscontent="value"></td> 283 <td class="value" jscontent="delta"></td> 284 </tr> 285 </tbody> 286 </table> 287 </td> 288 <td width="15"/> 289 <td class="outer"> 290 <table cellspacing="0" cellpadding="0" border="0"> 291 <tbody> 292 <tr> 293 <td class="top" width="100">Timers</td> 294 <td class="top value"></td> 295 <td class="top value" colspan=3></td> 296 </tr> 297 <tr> 298 <td class="header2 lower" width="200" onclick="sort_table('string')">name</td> 299 <td class="header2 lower" onclick="sort_table('number')">count</td> 300 <td class="header2 lower" onclick="sort_table('number')">time (ms)</td> 301 <td class="header2 lower" onclick="sort_table('number')">avg time (ms)</td> 302 </tr> 303 <tr jsselect="timers" name="timer"> 304 <td class="key" width="200" jscontent="name"></td> 305 <td class="value" jscontent="value"></td> 306 <td class="value" jscontent="time"></td> 307 <td class="value"></td> 308 </tr> 309 </tbody> 310 </table> 311 </td> 312 </tr> 313 </tbody> 314 </table><br/> 315 </body> 316 </html> 317