Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / resources / chromeos / network_ui / network_ui.js
blob1e997b6212f45059540c544b0161ae0490c5efa4
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() {
6   'use strict';
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     'service_path',
14     'Name',
15     'Type',
16     'ConnectionState',
17     'connectable',
18     'ErrorState',
19     'WiFi.Security',
20     ['Cellular.NetworkTechnology',
21      'EAP.EAP'],
22     'Cellular.ActivationState',
23     'Cellular.RoamingState',
24     'WiFi.SignalStrength'
25   ];
27   var FAVORITE_STATE_FIELDS = [
28     'GUID',
29     'service_path',
30     'Name',
31     'Type',
32     'profile_path',
33     'visible',
34     'Source'
35   ];
37   /**
38    * Creates and returns a typed HTMLTableCellElement.
39    *
40    * @return {!HTMLTableCellElement} A new td element.
41    */
42   var createTableCellElement = function() {
43     return /** @type {!HTMLTableCellElement} */(document.createElement('td'));
44   };
46   /**
47    * Creates and returns a typed HTMLTableRowElement.
48    *
49    * @return {!HTMLTableRowElement} A new tr element.
50    */
51   var createTableRowElement = function() {
52     return /** @type {!HTMLTableRowElement} */(document.createElement('tr'));
53   };
55   /**
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.
60    *
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.
66    */
67   var getOncProperty = function(networkState, key) {
68     var dict = /** @type {!Object} */(networkState);
69     var keys = key.split('.');
70     while (keys.length > 1) {
71       var k = keys.shift();
72       dict = dict[k];
73       if (!dict || typeof dict != 'object')
74         return undefined;
75     }
76     return dict[keys.shift()];
77   };
79   /**
80    * Creates a cell with a button for expanding a network state table row.
81    *
82    * @param {string} guid The GUID identifying the network.
83    * @return {!HTMLTableCellElement} The created td element that displays the
84    *     given value.
85    */
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);
92     });
93     button.className = 'state-table-expand-button';
94     button.textContent = '+';
95     cell.appendChild(button);
96     return cell;
97   };
99   /**
100    * Creates a cell with an icon representing the network state.
101    *
102    * @param {!chrome.networkingPrivate.NetworkStateProperties} networkState The
103    *     network state properties.
104    * @return {!HTMLTableCellElement} The created td element that displays the
105    *     icon.
106    */
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);
115     return cell;
116   };
118   /**
119    * Creates a cell in the network state table.
120    *
121    * @param {*} value Content in the cell.
122    * @return {!HTMLTableCellElement} The created td element that displays the
123    *     given value.
124    */
125   var createStateTableCell = function(value) {
126     var cell = createTableCellElement();
127     cell.textContent = value || '';
128     return cell;
129   };
131   /**
132    * Creates a row in the network state table.
133    *
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.
139    */
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];
148       var value;
149       if (typeof field == 'string') {
150         value = getOncProperty(networkState, field);
151       } else {
152         for (var j = 0; j < field.length; ++j) {
153           value = getOncProperty(networkState, field[j]);
154           if (value != undefined)
155             break;
156         }
157       }
158       if (field == 'GUID')
159         value = value.slice(0, 8);
160       row.appendChild(createStateTableCell(value));
161     }
162     return row;
163   };
165   /**
166    * Creates a table for networks or favorites.
167    *
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.
172    */
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));
180     });
181   };
183   /**
184    * Returns a valid HTMLElement id from |guid|.
185    *
186    * @param {string} guid A GUID which may start with a digit.
187    * @return {string} A valid HTMLElement id.
188    */
189   var idFromGuid = function(guid) {
190     return '_' + guid.replace(/[{}]/g, '');
191   };
193   /**
194    * This callback function is triggered when visible networks are received.
195    *
196    * @param {!Array<!chrome.networkingPrivate.NetworkStateProperties>} states
197    *     A list of network state information for each visible network.
198    */
199   var onVisibleNetworksReceived = function(states) {
200     createStateTable('network-state-table', NETWORK_STATE_FIELDS, states);
201   };
203   /**
204    * This callback function is triggered when favorite networks are received.
205    *
206    * @param {!Array<!chrome.networkingPrivate.NetworkStateProperties>} states
207    *     A list of network state information for each favorite network.
208    */
209   var onFavoriteNetworksReceived = function(states) {
210     createStateTable('favorite-state-table', FAVORITE_STATE_FIELDS, states);
211   };
213   /**
214    * Toggles the button state and add or remove a row displaying the complete
215    * state information for a row.
216    *
217    * @param {!HTMLElement} btn The button that was clicked.
218    * @param {string} guid GUID identifying the network.
219    */
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);
226     } else {
227       btn.textContent = '-';
228       var expandedRow = createExpandedRow(guid, row);
229       row.parentNode.insertBefore(expandedRow, row.nextSibling);
230     }
231   };
233   /**
234    * Creates the expanded row for displaying the complete state as JSON.
235    *
236    * @param {string} guid The GUID identifying the network.
237    * @param {!HTMLTableRowElement} baseRow The unexpanded row associated with
238    *     the new row.
239    * @return {!HTMLTableRowElement} The created tr element for the expanded row.
240    */
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;
255       else
256         detailCell.textContent = JSON.stringify(state, null, '\t');
257     };
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); });
268     } else {
269       chrome.networkingPrivate.getProperties(guid, function(properties) {
270         showDetail(properties, chrome.runtime.lastError); });
271     }
272     return expandedRow;
273   };
275   /**
276    * Callback invoked by Chrome after a getShillProperties call.
277    *
278    * @param {Array} args The requested Shill properties. Will contain
279    *     just the 'GUID' and 'ShillError' properties if the call failed.
280    */
281   var getShillPropertiesResult = function(args) {
282     var properties = args.shift();
283     var guid = properties['GUID'];
284     if (!guid) {
285       console.error('No GUID in getShillPropertiesResult');
286       return;
287     }
289     var detailCell = document.querySelector('td#' + idFromGuid(guid));
290     if (!detailCell) {
291       console.error('No cell for GUID: ' + guid);
292       return;
293     }
295     if (properties['ShillError'])
296       detailCell.textContent = properties['ShillError'];
297     else
298       detailCell.textContent = JSON.stringify(properties, null, '\t');
300   };
302   /**
303    * Requests an update of all network info.
304    */
305   var requestNetworks = function() {
306     chrome.networkingPrivate.getNetworks(
307         {'networkType': chrome.networkingPrivate.NetworkType.ALL,
308          'visible': true},
309         onVisibleNetworksReceived);
310     chrome.networkingPrivate.getNetworks(
311         {'networkType': chrome.networkingPrivate.NetworkType.ALL,
312          'configured': true},
313         onFavoriteNetworksReceived);
314   };
316   /**
317    * Sets refresh rate if the interval is found in the url.
318    */
319   var setRefresh = function() {
320     var interval = parseQueryParams(window.location)['refresh'];
321     if (interval && interval != '')
322       setInterval(requestNetworks, parseInt(interval, 10) * 1000);
323   };
325   /**
326    * Gets network information from WebUI.
327    */
328   document.addEventListener('DOMContentLoaded', function() {
329     $('refresh').onclick = requestNetworks;
330     setRefresh();
331     requestNetworks();
332   });
334   return {
335     getShillPropertiesResult: getShillPropertiesResult
336   };
337 })();