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.
5 var NetworkUI = (function() {
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 = [
20 ['Cellular.NetworkTechnology',
22 'Cellular.ActivationState',
23 'Cellular.RoamingState',
27 var FAVORITE_STATE_FIELDS = [
38 * Creates and returns a typed HTMLTableCellElement.
40 * @return {!HTMLTableCellElement} A new td element.
42 var createTableCellElement = function() {
43 return /** @type {!HTMLTableCellElement} */(document.createElement('td'));
47 * Creates and returns a typed HTMLTableRowElement.
49 * @return {!HTMLTableRowElement} A new tr element.
51 var createTableRowElement = function() {
52 return /** @type {!HTMLTableRowElement} */(document.createElement('tr'));
56 * Returns the ONC data property for networkState associated with a key. Used
57 * to access properties in the networkState by |key| which may may refer to a
58 * nested property, e.g. 'WiFi.Security'. If any part of a nested key is
59 * missing, this will return undefined.
61 * @param {!chrome.networkingPrivate.NetworkStateProperties} networkState The
62 * network state property dictionary.
63 * @param {string} key The ONC key for the property.
64 * @return {*} The value associated with the property or undefined if the
65 * key (any part of it) is not defined.
67 var getOncProperty = function(networkState, key) {
68 var dict = /** @type {!Object} */(networkState);
69 var keys = key.split('.');
70 while (keys.length > 1) {
73 if (!dict || typeof dict != 'object')
76 return dict[keys.shift()];
80 * Creates a cell with a button for expanding a network state table row.
82 * @param {string} guid The GUID identifying the network.
83 * @return {!HTMLTableCellElement} The created td element that displays the
86 var createStateTableExpandButton = function(guid) {
87 var cell = createTableCellElement();
88 cell.className = 'state-table-expand-button-cell';
89 var button = document.createElement('button');
90 button.addEventListener('click', function(event) {
91 toggleExpandRow(/** @type {!HTMLElement} */(event.target), guid);
93 button.className = 'state-table-expand-button';
94 button.textContent = '+';
95 cell.appendChild(button);
100 * Creates a cell with an icon representing the network state.
102 * @param {!chrome.networkingPrivate.NetworkStateProperties} networkState The
103 * network state properties.
104 * @return {!HTMLTableCellElement} The created td element that displays the
107 var createStateTableIcon = function(networkState) {
108 var cell = createTableCellElement();
109 cell.className = 'state-table-icon-cell';
110 var icon = /** @type {!CrNetworkIconElement} */(
111 document.createElement('cr-network-icon'));
112 icon.isListItem = true;
113 icon.networkState = networkState;
114 cell.appendChild(icon);
119 * Creates a cell in the network state table.
121 * @param {*} value Content in the cell.
122 * @return {!HTMLTableCellElement} The created td element that displays the
125 var createStateTableCell = function(value) {
126 var cell = createTableCellElement();
127 cell.textContent = value || '';
132 * Creates a row in the network state table.
134 * @param {Array} stateFields The state fields to use for the row.
135 * @param {!chrome.networkingPrivate.NetworkStateProperties} networkState The
136 * network state properties.
137 * @return {!HTMLTableRowElement} The created tr element that contains the
138 * network state information.
140 var createStateTableRow = function(stateFields, networkState) {
141 var row = createTableRowElement();
142 row.className = 'state-table-row';
143 var guid = networkState.GUID;
144 row.appendChild(createStateTableExpandButton(guid));
145 row.appendChild(createStateTableIcon(networkState));
146 for (var i = 0; i < stateFields.length; ++i) {
147 var field = stateFields[i];
149 if (typeof field == 'string') {
150 value = getOncProperty(networkState, field);
152 for (var j = 0; j < field.length; ++j) {
153 value = getOncProperty(networkState, field[j]);
154 if (value != undefined)
159 value = value.slice(0, 8);
160 row.appendChild(createStateTableCell(value));
166 * Creates a table for networks or favorites.
168 * @param {string} tablename The name of the table to be created.
169 * @param {!Array<string>} stateFields The list of fields for the table.
170 * @param {!Array<!chrome.networkingPrivate.NetworkStateProperties>} states
171 * An array of network or favorite states.
173 var createStateTable = function(tablename, stateFields, states) {
174 var table = $(tablename);
175 var oldRows = table.querySelectorAll('.state-table-row');
176 for (var i = 0; i < oldRows.length; ++i)
177 table.removeChild(oldRows[i]);
178 states.forEach(function(state) {
179 table.appendChild(createStateTableRow(stateFields, state));
184 * Returns a valid HTMLElement id from |guid|.
186 * @param {string} guid A GUID which may start with a digit.
187 * @return {string} A valid HTMLElement id.
189 var idFromGuid = function(guid) {
190 return '_' + guid.replace(/[{}]/g, '');
194 * This callback function is triggered when visible networks are received.
196 * @param {!Array<!chrome.networkingPrivate.NetworkStateProperties>} states
197 * A list of network state information for each visible network.
199 var onVisibleNetworksReceived = function(states) {
200 createStateTable('network-state-table', NETWORK_STATE_FIELDS, states);
204 * This callback function is triggered when favorite networks are received.
206 * @param {!Array<!chrome.networkingPrivate.NetworkStateProperties>} states
207 * A list of network state information for each favorite network.
209 var onFavoriteNetworksReceived = function(states) {
210 createStateTable('favorite-state-table', FAVORITE_STATE_FIELDS, states);
214 * Toggles the button state and add or remove a row displaying the complete
215 * state information for a row.
217 * @param {!HTMLElement} btn The button that was clicked.
218 * @param {string} guid GUID identifying the network.
220 var toggleExpandRow = function(btn, guid) {
221 var cell = btn.parentNode;
222 var row = /** @type {!HTMLTableRowElement} */(cell.parentNode);
223 if (btn.textContent == '-') {
224 btn.textContent = '+';
225 row.parentNode.removeChild(row.nextSibling);
227 btn.textContent = '-';
228 var expandedRow = createExpandedRow(guid, row);
229 row.parentNode.insertBefore(expandedRow, row.nextSibling);
234 * Creates the expanded row for displaying the complete state as JSON.
236 * @param {string} guid The GUID identifying the network.
237 * @param {!HTMLTableRowElement} baseRow The unexpanded row associated with
239 * @return {!HTMLTableRowElement} The created tr element for the expanded row.
241 var createExpandedRow = function(guid, baseRow) {
242 var expandedRow = createTableRowElement();
243 expandedRow.className = 'state-table-row';
244 var emptyCell = createTableCellElement();
245 emptyCell.style.border = 'none';
246 expandedRow.appendChild(emptyCell);
247 var detailCell = createTableCellElement();
248 detailCell.id = idFromGuid(guid);
249 detailCell.className = 'state-table-expanded-cell';
250 detailCell.colSpan = baseRow.childNodes.length - 1;
251 expandedRow.appendChild(detailCell);
252 var showDetail = function(state, error) {
253 if (error && error.message)
254 detailCell.textContent = error.message;
256 detailCell.textContent = JSON.stringify(state, null, '\t');
258 var selected = $('get-property-format').selectedIndex;
259 var selectedId = $('get-property-format').options[selected].value;
260 if (selectedId == 'shill') {
261 chrome.send('getShillProperties', [guid]);
262 } else if (selectedId == 'state') {
263 chrome.networkingPrivate.getState(guid, function(properties) {
264 showDetail(properties, chrome.runtime.lastError); });
265 } else if (selectedId == 'managed') {
266 chrome.networkingPrivate.getManagedProperties(guid, function(properties) {
267 showDetail(properties, chrome.runtime.lastError); });
269 chrome.networkingPrivate.getProperties(guid, function(properties) {
270 showDetail(properties, chrome.runtime.lastError); });
276 * Callback invoked by Chrome after a getShillProperties call.
278 * @param {Array} args The requested Shill properties. Will contain
279 * just the 'GUID' and 'ShillError' properties if the call failed.
281 var getShillPropertiesResult = function(args) {
282 var properties = args.shift();
283 var guid = properties['GUID'];
285 console.error('No GUID in getShillPropertiesResult');
289 var detailCell = document.querySelector('td#' + idFromGuid(guid));
291 console.error('No cell for GUID: ' + guid);
295 if (properties['ShillError'])
296 detailCell.textContent = properties['ShillError'];
298 detailCell.textContent = JSON.stringify(properties, null, '\t');
303 * Requests an update of all network info.
305 var requestNetworks = function() {
306 chrome.networkingPrivate.getNetworks(
307 {'networkType': chrome.networkingPrivate.NetworkType.ALL,
309 onVisibleNetworksReceived);
310 chrome.networkingPrivate.getNetworks(
311 {'networkType': chrome.networkingPrivate.NetworkType.ALL,
313 onFavoriteNetworksReceived);
317 * Sets refresh rate if the interval is found in the url.
319 var setRefresh = function() {
320 var interval = parseQueryParams(window.location)['refresh'];
321 if (interval && interval != '')
322 setInterval(requestNetworks, parseInt(interval, 10) * 1000);
326 * Gets network information from WebUI.
328 document.addEventListener('DOMContentLoaded', function() {
329 $('refresh').onclick = requestNetworks;
335 getShillPropertiesResult: getShillPropertiesResult