Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / resources / chromeos / network_ui / network_ui.js
blob467e3c2c69df4195391fc252ac2ee138497f998a
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     /** @type {chrome.networkingPrivate.NetworkStateProperties} */ var
201         defaultState;
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',
208                                   defaultState.Name,
209                                   defaultState.ConnectionState);
210       icon.networkState = defaultState;
211     } else {
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;
216     }
218     createStateTable('network-state-table', NETWORK_STATE_FIELDS, states);
219   };
221   /**
222    * This callback function is triggered when favorite networks are received.
223    *
224    * @param {!Array<!chrome.networkingPrivate.NetworkStateProperties>} states
225    *     A list of network state information for each favorite network.
226    */
227   var onFavoriteNetworksReceived = function(states) {
228     createStateTable('favorite-state-table', FAVORITE_STATE_FIELDS, states);
229   };
231   /**
232    * Toggles the button state and add or remove a row displaying the complete
233    * state information for a row.
234    *
235    * @param {!HTMLElement} btn The button that was clicked.
236    * @param {string} guid GUID identifying the network.
237    */
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);
244     } else {
245       btn.textContent = '-';
246       var expandedRow = createExpandedRow(guid, row);
247       row.parentNode.insertBefore(expandedRow, row.nextSibling);
248     }
249   };
251   /**
252    * Creates the expanded row for displaying the complete state as JSON.
253    *
254    * @param {string} guid The GUID identifying the network.
255    * @param {!HTMLTableRowElement} baseRow The unexpanded row associated with
256    *     the new row.
257    * @return {!HTMLTableRowElement} The created tr element for the expanded row.
258    */
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;
273       else
274         detailCell.textContent = JSON.stringify(state, null, '\t');
275     };
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); });
286     } else {
287       chrome.networkingPrivate.getProperties(guid, function(properties) {
288         showDetail(properties, chrome.runtime.lastError); });
289     }
290     return expandedRow;
291   };
293   /**
294    * Callback invoked by Chrome after a getShillProperties call.
295    *
296    * @param {Array} args The requested Shill properties. Will contain
297    *     just the 'GUID' and 'ShillError' properties if the call failed.
298    */
299   var getShillPropertiesResult = function(args) {
300     var properties = args.shift();
301     var guid = properties['GUID'];
302     if (!guid) {
303       console.error('No GUID in getShillPropertiesResult');
304       return;
305     }
307     var detailCell = document.querySelector('td#' + idFromGuid(guid));
308     if (!detailCell) {
309       console.error('No cell for GUID: ' + guid);
310       return;
311     }
313     if (properties['ShillError'])
314       detailCell.textContent = properties['ShillError'];
315     else
316       detailCell.textContent = JSON.stringify(properties, null, '\t');
318   };
320   /**
321    * Requests an update of all network info.
322    */
323   var requestNetworks = function() {
324     chrome.networkingPrivate.getNetworks(
325         {'networkType': 'All', 'visible': true}, onVisibleNetworksReceived);
326     chrome.networkingPrivate.getNetworks(
327         {'networkType': 'All', 'configured': true}, onFavoriteNetworksReceived);
328   };
330   /**
331    * Sets refresh rate if the interval is found in the url.
332    */
333   var setRefresh = function() {
334     var interval = parseQueryParams(window.location)['refresh'];
335     if (interval && interval != '')
336       setInterval(requestNetworks, parseInt(interval, 10) * 1000);
337   };
339   /**
340    * Gets network information from WebUI.
341    */
342   document.addEventListener('DOMContentLoaded', function() {
343     $('refresh').onclick = requestNetworks;
344     setRefresh();
345     requestNetworks();
346   });
348   return {
349     getShillPropertiesResult: getShillPropertiesResult
350   };
351 })();