1// Copyright 2013 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 5var NetworkUI = (function() { 6 'use strict'; 7 8 // Properties to display in the network state table. Each entry can be either 9 // a single state field or an array of state fields. If more than one is 10 // specified then the first non empty value is used. 11 var NETWORK_STATE_FIELDS = [ 12 'GUID', 13 'Name', 14 'Type', 15 'ConnectionState', 16 'connectable', 17 'ErrorState', 18 'WiFi.Security', 19 ['Cellular.NetworkTechnology', 20 'EAP.EAP'], 21 'Cellular.ActivationState', 22 'Cellular.RoamingState', 23 'Cellular.OutOfCredits', 24 'WiFi.SignalStrength' 25 ]; 26 27 var FAVORITE_STATE_FIELDS = [ 28 'GUID', 29 'Name', 30 'Type', 31 'profile_path', 32 'visible', 33 'onc_source' 34 ]; 35 36 var LOG_LEVEL_CLASSNAME = { 37 'Error': 'network-log-level-error', 38 'User': 'network-log-level-user', 39 'Event': 'network-log-level-event', 40 'Debug': 'network-log-level-debug' 41 }; 42 43 var LOG_LEVEL_CHECKBOX = { 44 'Error': 'log-error', 45 'User': 'log-user', 46 'Event': 'log-event', 47 'Debug': 'log-debug' 48 }; 49 50 /** 51 * Create a tag of log level. 52 * 53 * @param {string} level A string that represents log level. 54 * @return {DOMElement} The created span element. 55 */ 56 var createLevelTag = function(level) { 57 var tag = document.createElement('span'); 58 tag.className = 'network-level-tag'; 59 tag.textContent = level; 60 tag.classList.add(LOG_LEVEL_CLASSNAME[level]); 61 return tag; 62 }; 63 64 /** 65 * Creates an element that contains the time, the event, the level and 66 * the description of the given log entry. 67 * 68 * @param {Object} logEntry An object that represents a single line of log. 69 * @return {DOMElement} The created p element that represents the log entry. 70 */ 71 var createLogEntryText = function(logEntry) { 72 var level = logEntry['level']; 73 if (!$(LOG_LEVEL_CHECKBOX[level]).checked) 74 return null; 75 var res = document.createElement('p'); 76 var textWrapper = document.createElement('span'); 77 var fileinfo = ''; 78 if ($('log-fileinfo').checked) 79 fileinfo = logEntry['file']; 80 var timestamp = ''; 81 if ($('log-timedetail').checked) 82 timestamp = logEntry['timestamp']; 83 else 84 timestamp = logEntry['timestampshort']; 85 textWrapper.textContent = loadTimeData.getStringF( 86 'logEntryFormat', 87 timestamp, 88 fileinfo, 89 logEntry['event'], 90 logEntry['description']); 91 res.appendChild(createLevelTag(level)); 92 res.appendChild(textWrapper); 93 return res; 94 }; 95 96 /** 97 * Create event log entries. 98 * 99 * @param {Array.<string>} logEntries A array of strings that each string 100 * represents a log event in JSON format. 101 */ 102 var createEventLog = function(logEntries) { 103 var container = $('network-log-container'); 104 container.textContent = ''; 105 for (var i = 0; i < logEntries.length; ++i) { 106 var entry = createLogEntryText(JSON.parse(logEntries[i])); 107 if (entry) 108 container.appendChild(entry); 109 } 110 }; 111 112 /** 113 * Create a cell with a button for expanding a network state table row. 114 * 115 * @param {string} guid The GUID identifying the network. 116 * @return {DOMElement} The created td element that displays the given value. 117 */ 118 var createStateTableExpandButton = function(guid) { 119 var cell = document.createElement('td'); 120 cell.className = 'state-table-expand-button-cell'; 121 var button = document.createElement('button'); 122 button.addEventListener('click', function(event) { 123 toggleExpandRow(event.target, guid); 124 }); 125 button.className = 'state-table-expand-button'; 126 button.textContent = '+'; 127 cell.appendChild(button); 128 return cell; 129 }; 130 131 /** 132 * Create a cell in network state table. 133 * 134 * @param {string} value Content in the cell. 135 * @return {DOMElement} The created td element that displays the given value. 136 */ 137 var createStateTableCell = function(value) { 138 var cell = document.createElement('td'); 139 cell.textContent = value || ''; 140 return cell; 141 }; 142 143 /** 144 * Create a row in the network state table. 145 * 146 * @param {Array} stateFields The state fields to use for the row. 147 * @param {Object} state Property values for the network or favorite. 148 * @return {DOMElement} The created tr element that contains the network 149 * state information. 150 */ 151 var createStateTableRow = function(stateFields, state) { 152 var row = document.createElement('tr'); 153 row.className = 'state-table-row'; 154 var guid = state.GUID; 155 row.appendChild(createStateTableExpandButton(guid)); 156 for (var i = 0; i < stateFields.length; ++i) { 157 var field = stateFields[i]; 158 var value = ''; 159 if (typeof field == 'string') { 160 value = networkConfig.getValueFromProperties(state, field); 161 } else { 162 for (var j = 0; j < field.length; ++j) { 163 value = networkConfig.getValueFromProperties(state, field[j]); 164 if (value) 165 break; 166 } 167 } 168 if (field == 'GUID') 169 value = value.slice(0, 8); 170 row.appendChild(createStateTableCell(value)); 171 } 172 return row; 173 }; 174 175 /** 176 * Create table for networks or favorites. 177 * 178 * @param {string} tablename The name of the table to be created. 179 * @param {Array} stateFields The list of fields for the table. 180 * @param {Array} states An array of network or favorite states. 181 */ 182 var createStateTable = function(tablename, stateFields, states) { 183 var table = $(tablename); 184 var oldRows = table.querySelectorAll('.state-table-row'); 185 for (var i = 0; i < oldRows.length; ++i) 186 table.removeChild(oldRows[i]); 187 states.forEach(function(state) { 188 table.appendChild(createStateTableRow(stateFields, state)); 189 }); 190 }; 191 192 /** 193 * This callback function is triggered when the network log is received. 194 * 195 * @param {Object} data A JSON structure of event log entries. 196 */ 197 var getNetworkLogCallback = function(data) { 198 createEventLog(JSON.parse(data)); 199 }; 200 201 /** 202 * This callback function is triggered when visible networks are received. 203 * 204 * @param {Array} data A list of network state information for each 205 * visible network. 206 */ 207 var onVisibleNetworksReceived = function(states) { 208 createStateTable('network-state-table', NETWORK_STATE_FIELDS, states); 209 }; 210 211 /** 212 * This callback function is triggered when favorite networks are received. 213 * 214 * @param {Object} data A list of network state information for each 215 * favorite network. 216 */ 217 var onFavoriteNetworksReceived = function(states) { 218 createStateTable('favorite-state-table', FAVORITE_STATE_FIELDS, states); 219 }; 220 221 /** 222 * Toggle the button state and add or remove a row displaying the complete 223 * state information for a row. 224 * 225 * @param {DOMElement} btn The button that was clicked. 226 * @param {string} guid GUID identifying the network. 227 */ 228 var toggleExpandRow = function(btn, guid) { 229 var cell = btn.parentNode; 230 var row = cell.parentNode; 231 if (btn.textContent == '-') { 232 btn.textContent = '+'; 233 row.parentNode.removeChild(row.nextSibling); 234 } else { 235 btn.textContent = '-'; 236 var expandedRow = createExpandedRow(guid, row); 237 row.parentNode.insertBefore(expandedRow, row.nextSibling); 238 } 239 }; 240 241 /** 242 * Creates the expanded row for displaying the complete state as JSON. 243 * 244 * @param {Object} state Property values for the network or favorite. 245 * @param {DOMElement} baseRow The unexpanded row associated with the new row. 246 * @return {DOMElement} The created tr element for the expanded row. 247 */ 248 var createExpandedRow = function(guid, baseRow) { 249 var expandedRow = document.createElement('tr'); 250 expandedRow.className = 'state-table-row'; 251 var emptyCell = document.createElement('td'); 252 emptyCell.style.border = 'none'; 253 expandedRow.appendChild(emptyCell); 254 var detailCell = document.createElement('td'); 255 detailCell.className = 'state-table-expanded-cell'; 256 detailCell.colSpan = baseRow.childNodes.length - 1; 257 expandedRow.appendChild(detailCell); 258 networkConfig.getProperties(guid, function(state) { 259 if (networkConfig.lastError) 260 detailCell.textContent = networkConfig.lastError; 261 else 262 detailCell.textContent = JSON.stringify(state, null, '\t'); 263 }); 264 return expandedRow; 265 }; 266 267 /** 268 * Requests a network log update. 269 */ 270 var requestLog = function() { 271 chrome.send('NetworkUI.getNetworkLog'); 272 }; 273 274 /** 275 * Requests an update of all network info. 276 */ 277 var requestNetworks = function() { 278 networkConfig.getNetworks( 279 { 'type': 'All', 'visible': true }, 280 onVisibleNetworksReceived); 281 networkConfig.getNetworks( 282 { 'type': 'All', 'configured': true }, 283 onFavoriteNetworksReceived); 284 }; 285 286 /** 287 * Sets refresh rate if the interval is found in the url. 288 */ 289 var setRefresh = function() { 290 var interval = parseQueryParams(window.location)['refresh']; 291 if (interval && interval != '') 292 setInterval(requestNetworks, parseInt(interval) * 1000); 293 }; 294 295 /** 296 * Get network information from WebUI. 297 */ 298 document.addEventListener('DOMContentLoaded', function() { 299 $('log-refresh').onclick = requestLog; 300 $('log-error').checked = true; 301 $('log-error').onclick = requestLog; 302 $('log-user').checked = true; 303 $('log-user').onclick = requestLog; 304 $('log-event').checked = true; 305 $('log-event').onclick = requestLog; 306 $('log-debug').checked = false; 307 $('log-debug').onclick = requestLog; 308 $('log-fileinfo').checked = false; 309 $('log-fileinfo').onclick = requestLog; 310 $('log-timedetail').checked = false; 311 $('log-timedetail').onclick = requestLog; 312 setRefresh(); 313 requestLog(); 314 requestNetworks(); 315 }); 316 317 return { 318 getNetworkLogCallback: getNetworkLogCallback 319 }; 320})(); 321