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 /** @type {chrome.networkingPrivate.NetworkStateProperties} */ var
202 if (states.length > 0)
203 defaultState = states[0];
204 var icon = /** @type {CrNetworkIconElement} */($('default-network-icon'));
205 if (defaultState && defaultState.Type != CrOnc.Type.VPN) {
206 $('default-network-text').textContent =
207 loadTimeData.getStringF('defaultNetworkText',
209 defaultState.ConnectionState);
210 icon.networkState = defaultState;
212 $('default-network-text').textContent =
213 loadTimeData.getString('noNetworkText');
214 // Show the disconnected wifi icon if there are no networks.
215 icon.networkType = CrOnc.Type.WIFI;
218 createStateTable('network-state-table', NETWORK_STATE_FIELDS, states);
222 * This callback function is triggered when favorite networks are received.
224 * @param {!Array<!chrome.networkingPrivate.NetworkStateProperties>} states
225 * A list of network state information for each favorite network.
227 var onFavoriteNetworksReceived = function(states) {
228 createStateTable('favorite-state-table', FAVORITE_STATE_FIELDS, states);
232 * Toggles the button state and add or remove a row displaying the complete
233 * state information for a row.
235 * @param {!HTMLElement} btn The button that was clicked.
236 * @param {string} guid GUID identifying the network.
238 var toggleExpandRow = function(btn, guid) {
239 var cell = btn.parentNode;
240 var row = /** @type {!HTMLTableRowElement} */(cell.parentNode);
241 if (btn.textContent == '-') {
242 btn.textContent = '+';
243 row.parentNode.removeChild(row.nextSibling);
245 btn.textContent = '-';
246 var expandedRow = createExpandedRow(guid, row);
247 row.parentNode.insertBefore(expandedRow, row.nextSibling);
252 * Creates the expanded row for displaying the complete state as JSON.
254 * @param {string} guid The GUID identifying the network.
255 * @param {!HTMLTableRowElement} baseRow The unexpanded row associated with
257 * @return {!HTMLTableRowElement} The created tr element for the expanded row.
259 var createExpandedRow = function(guid, baseRow) {
260 var expandedRow = createTableRowElement();
261 expandedRow.className = 'state-table-row';
262 var emptyCell = createTableCellElement();
263 emptyCell.style.border = 'none';
264 expandedRow.appendChild(emptyCell);
265 var detailCell = createTableCellElement();
266 detailCell.id = idFromGuid(guid);
267 detailCell.className = 'state-table-expanded-cell';
268 detailCell.colSpan = baseRow.childNodes.length - 1;
269 expandedRow.appendChild(detailCell);
270 var showDetail = function(state, error) {
271 if (error && error.message)
272 detailCell.textContent = error.message;
274 detailCell.textContent = JSON.stringify(state, null, '\t');
276 var selected = $('get-property-format').selectedIndex;
277 var selectedId = $('get-property-format').options[selected].value;
278 if (selectedId == 'shill') {
279 chrome.send('getShillProperties', [guid]);
280 } else if (selectedId == 'state') {
281 chrome.networkingPrivate.getState(guid, function(properties) {
282 showDetail(properties, chrome.runtime.lastError); });
283 } else if (selectedId == 'managed') {
284 chrome.networkingPrivate.getManagedProperties(guid, function(properties) {
285 showDetail(properties, chrome.runtime.lastError); });
287 chrome.networkingPrivate.getProperties(guid, function(properties) {
288 showDetail(properties, chrome.runtime.lastError); });
294 * Callback invoked by Chrome after a getShillProperties call.
296 * @param {Array} args The requested Shill properties. Will contain
297 * just the 'GUID' and 'ShillError' properties if the call failed.
299 var getShillPropertiesResult = function(args) {
300 var properties = args.shift();
301 var guid = properties['GUID'];
303 console.error('No GUID in getShillPropertiesResult');
307 var detailCell = document.querySelector('td#' + idFromGuid(guid));
309 console.error('No cell for GUID: ' + guid);
313 if (properties['ShillError'])
314 detailCell.textContent = properties['ShillError'];
316 detailCell.textContent = JSON.stringify(properties, null, '\t');
321 * Requests an update of all network info.
323 var requestNetworks = function() {
324 chrome.networkingPrivate.getNetworks(
325 {'networkType': 'All', 'visible': true}, onVisibleNetworksReceived);
326 chrome.networkingPrivate.getNetworks(
327 {'networkType': 'All', 'configured': true}, onFavoriteNetworksReceived);
331 * Sets refresh rate if the interval is found in the url.
333 var setRefresh = function() {
334 var interval = parseQueryParams(window.location)['refresh'];
335 if (interval && interval != '')
336 setInterval(requestNetworks, parseInt(interval, 10) * 1000);
340 * Gets network information from WebUI.
342 document.addEventListener('DOMContentLoaded', function() {
343 $('refresh').onclick = requestNetworks;
349 getShillPropertiesResult: getShillPropertiesResult