1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5/* Counter accessor for Name Node. */ 6function getCounterNameFromCounterNode(node) { 7 return node.childNodes[1]; 8} 9 10/* Counter accessor for Value Node. */ 11function getCounterValueFromCounterNode(node) { 12 return node.childNodes[3]; 13} 14 15/* Counter accessor for Delta Node. */ 16function getCounterDeltaFromCounterNode(node) { 17 return node.childNodes[5]; 18} 19 20/* Timer accessor for Name Node. */ 21function getTimerNameFromTimerNode(node) { 22 return node.childNodes[1]; 23} 24 25/* Timer accessor for Value Node. */ 26function getTimerValueFromTimerNode(node) { 27 return node.childNodes[3]; 28} 29 30/* Timer accessor for Time Node. */ 31function getTimerTimeFromTimerNode(node) { 32 return node.childNodes[5]; 33} 34 35/* Timer accessor for Average Time Node. */ 36function getTimerAvgTimeFromTimerNode(node) { 37 return node.childNodes[7]; 38} 39 40/* Do the filter work. Hide all nodes matching node.*/ 41function filterMatching(text, nodelist, functionToGetNameNode) { 42 var showAll = text.length == 0; 43 for (var i = 0, node; node = nodelist[i]; i++) { 44 var name = functionToGetNameNode(node).innerHTML.toLowerCase(); 45 if (showAll || name.indexOf(text) >= 0) 46 node.style.display = 'table-row'; 47 else 48 node.style.display = 'none'; 49 } 50} 51 52/* Hides or shows counters based on the user's current filter selection. */ 53function doFilter() { 54 var filter = $('filter'); 55 var text = filter.value.toLowerCase(); 56 var nodes = document.getElementsByName('counter'); 57 filterMatching(text, nodes, getCounterNameFromCounterNode); 58 var nodes = document.getElementsByName('timer'); 59 filterMatching(text, nodes, getTimerNameFromTimerNode); 60} 61 62/* Colors the counters based on increasing or decreasing value. */ 63function doColor() { 64 var nodes = document.getElementsByName('counter'); 65 for (var i = 0, node; node = nodes[i]; i++) { 66 var child = getCounterDeltaFromCounterNode(node); 67 var delta = child.innerHTML; 68 if (delta > 0) 69 child.style.color = 'Green'; 70 else if (delta == 0) 71 child.style.color = 'Black'; 72 else 73 child.style.color = 'Red'; 74 } 75} 76 77/* Counters with no values are null. Remove them. */ 78function removeNullValues() { 79 var nodes = document.getElementsByName('counter'); 80 for (var i = nodes.length - 1; i >= 0; i--) { 81 var node = nodes[i]; 82 var value = getCounterValueFromCounterNode(node).innerHTML; 83 if (value == 'null') 84 node.parentNode.removeChild(node); 85 } 86 var nodes = document.getElementsByName('timer'); 87 for (var i = 0, node; node = nodes[i]; i++) { 88 var valueNode = getTimerValueFromTimerNode(node); 89 if (valueNode.innerHTML == 'null') 90 valueNode.innerHTML = ''; 91 } 92} 93 94/* Compute the average time for timers */ 95function computeTimes() { 96 var nodes = document.getElementsByName('timer'); 97 for (var i = 0, node; node = nodes[i]; i++) { 98 var count = getTimerValueFromTimerNode(node).innerHTML; 99 if (count.length > 0) { 100 var time = getTimerTimeFromTimerNode(node).innerHTML; 101 var avg = getTimerAvgTimeFromTimerNode(node); 102 avg.innerHTML = Math.round(time / count * 100) / 100; 103 } 104 } 105} 106 107/* All the work we do onload. */ 108function onLoadWork() { 109 // This is the javascript code that processes the template: 110 var input = new JsEvalContext(templateData); 111 var output = $('t'); 112 jstProcess(input, output); 113 114 // Add handlers to dynamically created HTML elements. 115 var elements = document.getElementsByName('string-sort'); 116 for (var i = 0; i < elements.length; ++i) 117 elements[i].onclick = function() { sortTable('string'); }; 118 119 elements = document.getElementsByName('number-sort'); 120 for (i = 0; i < elements.length; ++i) 121 elements[i].onclick = function() { sortTable('number'); }; 122 123 doColor(); 124 removeNullValues(); 125 computeTimes(); 126 127 var filter = $('filter'); 128 filter.onkeyup = doFilter; 129 filter.focus(); 130} 131 132// The function should only be used as the event handler 133// on a table cell element. To use it, put it in a <td> element: 134// <td onclick="sort('string')" ...> 135// 136// The function sorts rows after the row with onclick event handler. 137// 138// type: the data type, 'string', 'number' 139function sortTable(type) { 140 var cell = event.target; 141 var cnum = cell.cellIndex; 142 143 var row = cell.parentNode; 144 var startIndex = row.rowIndex + 1; 145 146 var tbody = row.parentNode; 147 var table = tbody.parentNode; 148 149 var rows = new Array(); 150 151 var indexes = new Array(); 152 // skip the first row 153 for (var i = startIndex; i < table.rows.length; i++) 154 rows.push(table.rows[i]); 155 156 // a, b are strings 157 function compareStrings(a, b) { 158 if (a == b) return 0; 159 if (a < b) return -1; 160 return 1; 161 } 162 163 // a, b are numbers 164 function compareNumbers(a, b) { 165 var x = isNaN(a) ? 0 : a; 166 var y = isNaN(b) ? 0 : b; 167 return x - y; 168 } 169 170 var sortFunc; 171 if (type === 'string') { 172 sortFunc = function(a, b) { 173 var x = a.cells[cnum].innerText; 174 var y = b.cells[cnum].innerText; 175 return compareStrings(x, y); 176 }; 177 178 } else if (type === 'number') { 179 sortFunc = function(a, b) { 180 var x = parseFloat(a.cells[cnum].innerText); 181 var y = parseFloat(b.cells[cnum].innerText); 182 return compareNumbers(x, y); 183 }; 184 } 185 186 rows.sort(sortFunc); 187 188 // change tables 189 if (cell._reverse) { 190 for (var i = rows.length - 1; i >= 0; i--) 191 tbody.appendChild(rows[i]); 192 cell._reverse = false; 193 } else { 194 for (var i = 0; i < rows.length; i++) 195 tbody.appendChild(rows[i]); 196 cell._reverse = true; 197 } 198} 199 200document.addEventListener('DOMContentLoaded', onLoadWork); 201