1 // Copyright (c) 2012 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 cr.define('options.network', function() {
6 var ArrayDataModel = cr.ui.ArrayDataModel;
8 var ListItem = cr.ui.ListItem;
9 var ListSingleSelectionModel = cr.ui.ListSingleSelectionModel;
10 var Menu = cr.ui.Menu;
11 var MenuItem = cr.ui.MenuItem;
12 var ControlledSettingIndicator = options.ControlledSettingIndicator;
15 * Network settings constants. These enums usually match their C++
18 function Constants() {}
20 // Cellular activation states:
21 Constants.ACTIVATION_STATE_UNKNOWN = 0;
22 Constants.ACTIVATION_STATE_ACTIVATED = 1;
23 Constants.ACTIVATION_STATE_ACTIVATING = 2;
24 Constants.ACTIVATION_STATE_NOT_ACTIVATED = 3;
25 Constants.ACTIVATION_STATE_PARTIALLY_ACTIVATED = 4;
28 * Order in which controls are to appear in the network list sorted by key.
30 Constants.NETWORK_ORDER = ['Ethernet',
38 * ID of the menu that is currently visible.
42 var activeMenu_ = null;
45 * Indicates if cellular networks are available.
49 var cellularAvailable_ = false;
52 * Indicates if cellular networks are enabled.
56 var cellularEnabled_ = false;
59 * Indicates if cellular device supports network scanning.
63 var cellularSupportsScan_ = false;
66 * Indicates if WiMAX networks are available.
70 var wimaxAvailable_ = false;
73 * Indicates if WiMAX networks are enabled.
77 var wimaxEnabled_ = false;
80 * Indicates if mobile data roaming is enabled.
84 var enableDataRoaming_ = false;
87 * Icon to use when not connected to a particular type of network.
88 * @type {!Object.<string, string>} Mapping of network type to icon data url.
91 var defaultIcons_ = {};
94 * Returns the display name for 'network'.
95 * @param {Object} data The network data dictionary.
97 function getNetworkName(data) {
98 if (data.Type == 'Ethernet')
99 return loadTimeData.getString('ethernetName');
104 * Create an element in the network list for controlling network
106 * @param {Object} data Description of the network list or command.
109 function NetworkListItem(data) {
110 var el = cr.doc.createElement('li');
112 for (var key in data)
113 el.data_[key] = data[key];
114 NetworkListItem.decorate(el);
119 * Decorate an element as a NetworkListItem.
120 * @param {!Element} el The element to decorate.
122 NetworkListItem.decorate = function(el) {
123 el.__proto__ = NetworkListItem.prototype;
127 NetworkListItem.prototype = {
128 __proto__: ListItem.prototype,
131 * Description of the network group or control.
132 * @type {Object.<string,Object>}
138 * Element for the control's subtitle.
145 * Icon for the network control.
152 * Indicates if in the process of connecting to a network.
159 * Description of the network control.
167 * Text label for the subtitle.
172 this.subtitle_.textContent = text;
173 this.subtitle_.hidden = !text;
177 * URL for the network icon.
180 set iconURL(iconURL) {
181 this.icon_.style.backgroundImage = url(iconURL);
185 * Type of network icon. Each type corresponds to a CSS rule.
189 if (defaultIcons_[type])
190 this.iconURL = defaultIcons_[type];
192 this.icon_.classList.add('network-' + type.toLowerCase());
196 * Indicates if the network is in the process of being connected.
199 set connecting(state) {
200 this.connecting_ = state;
202 this.icon_.classList.add('network-connecting');
204 this.icon_.classList.remove('network-connecting');
208 * Indicates if the network is in the process of being connected.
212 return this.connecting_;
216 * Set the direction of the text.
217 * @param {string} direction The direction of the text, e.g. 'ltr'.
219 setSubtitleDirection: function(direction) {
220 this.subtitle_.dir = direction;
224 * Indicate that the selector arrow should be shown.
226 showSelector: function() {
227 this.subtitle_.classList.add('network-selector');
231 * Adds an indicator to show that the network is policy managed.
233 showManagedNetworkIndicator: function() {
234 this.appendChild(new ManagedNetworkIndicator());
238 decorate: function() {
239 ListItem.prototype.decorate.call(this);
240 this.className = 'network-group';
241 this.icon_ = this.ownerDocument.createElement('div');
242 this.icon_.className = 'network-icon';
243 this.appendChild(this.icon_);
244 var textContent = this.ownerDocument.createElement('div');
245 textContent.className = 'network-group-labels';
246 this.appendChild(textContent);
247 var categoryLabel = this.ownerDocument.createElement('div');
249 if (this.data_.key == 'addConnection')
250 title = 'addConnectionTitle';
252 title = this.data_.key.toLowerCase() + 'Title';
253 categoryLabel.className = 'network-title';
254 categoryLabel.textContent = loadTimeData.getString(title);
255 textContent.appendChild(categoryLabel);
256 this.subtitle_ = this.ownerDocument.createElement('div');
257 this.subtitle_.className = 'network-subtitle';
258 textContent.appendChild(this.subtitle_);
263 * Creates a control that displays a popup menu when clicked.
264 * @param {Object} data Description of the control.
266 function NetworkMenuItem(data) {
267 var el = new NetworkListItem(data);
268 el.__proto__ = NetworkMenuItem.prototype;
273 NetworkMenuItem.prototype = {
274 __proto__: NetworkListItem.prototype,
277 * Popup menu element.
284 decorate: function() {
285 this.subtitle = null;
286 if (this.data.iconType)
287 this.iconType = this.data.iconType;
288 this.addEventListener('click', function() {
294 * Retrieves the ID for the menu.
296 getMenuName: function() {
297 return this.data_.key.toLowerCase() + '-network-menu';
301 * Creates a popup menu for the control.
302 * @return {Element} The newly created menu.
304 createMenu: function() {
305 if (this.data.menu) {
306 var menu = this.ownerDocument.createElement('div');
307 menu.id = this.getMenuName();
308 menu.className = 'network-menu';
311 for (var i = 0; i < this.data.menu.length; i++) {
312 var entry = this.data.menu[i];
313 createCallback_(menu, null, entry.label, entry.command);
320 canUpdateMenu: function() {
325 * Displays a popup menu.
327 showMenu: function() {
329 // Force a rescan if opening the menu for WiFi networks to ensure the
330 // list is up to date. Networks are periodically rescanned, but depending
331 // on timing, there could be an excessive delay before the first rescan
333 var rescan = !activeMenu_ && this.data_.key == 'WiFi';
336 var existing = $(this.getMenuName());
338 if (this.updateMenu())
342 this.menu_ = this.createMenu();
343 this.menu_.addEventListener('mousedown', function(e) {
344 // Prevent blurring of list, which would close the menu.
347 var parent = $('network-menus');
349 parent.replaceChild(this.menu_, existing);
351 parent.appendChild(this.menu_);
353 var top = this.offsetTop + this.clientHeight;
354 var menuId = this.getMenuName();
355 if (menuId != activeMenu_ || rebuild) {
357 activeMenu_ = menuId;
358 this.menu_.style.setProperty('top', top + 'px');
359 this.menu_.hidden = false;
362 chrome.send('refreshNetworks');
367 * Creates a control for selecting or configuring a network connection based
368 * on the type of connection (e.g. wifi versus vpn).
369 * @param {Object} data Description of the network.
370 * @param {string} data.key Item key.
371 * @param {Array.<Object>} data.networkList Description of the network.
374 function NetworkSelectorItem(data) {
375 var el = new NetworkMenuItem(data);
376 el.__proto__ = NetworkSelectorItem.prototype;
381 NetworkSelectorItem.prototype = {
382 __proto__: NetworkMenuItem.prototype,
385 decorate: function() {
386 // TODO(kevers): Generalize method of setting default label.
387 var policyManaged = false;
388 this.subtitle = loadTimeData.getString('OncStateNotConnected');
389 var list = this.data_.networkList;
390 var candidateURL = null;
391 for (var i = 0; i < list.length; i++) {
392 var networkDetails = list[i];
393 if (networkDetails.ConnectionState == 'Connecting' ||
394 networkDetails.ConnectionState == 'Connected') {
395 this.subtitle = getNetworkName(networkDetails);
396 this.setSubtitleDirection('ltr');
397 policyManaged = networkDetails.policyManaged;
398 candidateURL = networkDetails.iconURL;
399 // Only break when we see a connecting network as it is possible to
400 // have a connected network and a connecting network at the same
402 if (networkDetails.ConnectionState == 'Connecting') {
403 this.connecting = true;
410 this.iconURL = candidateURL;
412 this.iconType = this.data.key;
417 this.showManagedNetworkIndicator();
419 if (activeMenu_ == this.getMenuName()) {
420 // Menu is already showing and needs to be updated. Explicitly calling
421 // show menu will force the existing menu to be replaced. The call
422 // is deferred in order to ensure that position of this element has
423 // beem properly updated.
425 setTimeout(function() {self.showMenu();}, 0);
430 * Creates a menu for selecting, configuring or disconnecting from a
432 * @return {Element} The newly created menu.
434 createMenu: function() {
435 var menu = this.ownerDocument.createElement('div');
436 menu.id = this.getMenuName();
437 menu.className = 'network-menu';
441 if (this.data_.key == 'WiFi') {
442 addendum.push({label: loadTimeData.getString('joinOtherNetwork'),
444 data: {Type: 'WiFi', servicePath: ''}});
445 } else if (this.data_.key == 'Cellular') {
446 if (cellularEnabled_ && cellularSupportsScan_) {
448 label: loadTimeData.getString('otherCellularNetworks'),
449 command: createAddConnectionCallback_('Cellular'),
450 addClass: ['other-cellulars'],
453 addendum.push(entry);
456 var label = enableDataRoaming_ ? 'disableDataRoaming' :
458 var disabled = !loadTimeData.getValue('loggedInAsOwner');
459 var entry = {label: loadTimeData.getString(label),
462 entry.command = null;
464 loadTimeData.getString('dataRoamingDisableToggleTooltip');
467 entry.command = function() {
468 options.Preferences.setBooleanPref(
469 'cros.signed.data_roaming_enabled',
470 !enableDataRoaming_, true);
471 // Force revalidation of the menu the next time it is displayed.
475 addendum.push(entry);
477 var list = this.data.rememberedNetworks;
478 if (list && list.length > 0) {
479 var callback = function(list) {
480 $('remembered-network-list').clear();
481 var dialog = options.PreferredNetworks.getInstance();
482 PageManager.showPageByName('preferredNetworksPage', false);
484 chrome.send('coreOptionsUserMetricsAction',
485 ['Options_NetworkShowPreferred']);
487 addendum.push({label: loadTimeData.getString('preferredNetworks'),
492 var networkGroup = this.ownerDocument.createElement('div');
493 networkGroup.className = 'network-menu-group';
494 list = this.data.networkList;
495 var empty = !list || list.length == 0;
497 for (var i = 0; i < list.length; i++) {
499 this.createNetworkOptionsCallback_(networkGroup, data);
500 if (data.ConnectionState == 'Connected') {
501 if (data.Type == 'VPN') {
504 var i18nKey = 'disconnectNetwork';
505 addendum.push({label: loadTimeData.getString(i18nKey),
506 command: 'disconnect',
512 if (this.data_.key == 'WiFi' || this.data_.key == 'Wimax' ||
513 this.data_.key == 'Cellular') {
515 if (this.data_.key == 'WiFi') {
516 addendum.push({label: loadTimeData.getString('turnOffWifi'),
517 command: function() {
518 chrome.send('disableWifi');
521 } else if (this.data_.key == 'Wimax') {
522 addendum.push({label: loadTimeData.getString('turnOffWimax'),
523 command: function() {
524 chrome.send('disableWimax');
527 } else if (this.data_.key == 'Cellular') {
528 addendum.push({label: loadTimeData.getString('turnOffCellular'),
529 command: function() {
530 chrome.send('disableCellular');
536 menu.appendChild(networkGroup);
537 if (addendum.length > 0) {
538 var separator = false;
540 menu.appendChild(MenuItem.createSeparator());
543 for (var i = 0; i < addendum.length; i++) {
544 var value = addendum[i];
546 var item = createCallback_(menu, value.data, value.label,
549 item.title = value.tooltip;
551 item.classList.add(value.addClass);
553 } else if (!separator) {
554 menu.appendChild(MenuItem.createSeparator());
563 * Determines if a menu can be updated on the fly. Menus that cannot be
564 * updated are fully regenerated using createMenu. The advantage of
565 * updating a menu is that it can preserve ordering of networks avoiding
566 * entries from jumping around after an update.
568 canUpdateMenu: function() {
569 return this.data_.key == 'WiFi' && activeMenu_ == this.getMenuName();
573 * Updates an existing menu. Updated menus preserve ordering of prior
574 * entries. During the update process, the ordering may differ from the
575 * preferred ordering as determined by the network library. If the
576 * ordering becomes potentially out of sync, then the updated menu is
577 * marked for disposal on close. Reopening the menu will force a
578 * regeneration, which will in turn fix the ordering.
579 * @return {boolean} True if successfully updated.
581 updateMenu: function() {
582 if (!this.canUpdateMenu())
584 var oldMenu = $(this.getMenuName());
585 var group = oldMenu.getElementsByClassName('network-menu-group')[0];
588 var newMenu = this.createMenu();
589 var discardOnClose = false;
590 var oldNetworkButtons = this.extractNetworkConnectButtons_(oldMenu);
591 var newNetworkButtons = this.extractNetworkConnectButtons_(newMenu);
592 for (var key in oldNetworkButtons) {
593 if (newNetworkButtons[key]) {
594 group.replaceChild(newNetworkButtons[key].button,
595 oldNetworkButtons[key].button);
596 if (newNetworkButtons[key].index != oldNetworkButtons[key].index)
597 discardOnClose = true;
598 newNetworkButtons[key] = null;
600 // Leave item in list to prevent network items from jumping due to
602 oldNetworkButtons[key].disabled = true;
603 discardOnClose = true;
606 for (var key in newNetworkButtons) {
607 var entry = newNetworkButtons[key];
609 group.appendChild(entry.button);
610 discardOnClose = true;
613 oldMenu.data = {discardOnClose: discardOnClose};
618 * Extracts a mapping of network names to menu element and position.
619 * @param {!Element} menu The menu to process.
620 * @return {Object.<string, Element>} Network mapping.
623 extractNetworkConnectButtons_: function(menu) {
624 var group = menu.getElementsByClassName('network-menu-group')[0];
625 var networkButtons = {};
627 return networkButtons;
628 var buttons = group.getElementsByClassName('network-menu-item');
629 for (var i = 0; i < buttons.length; i++) {
630 var label = buttons[i].data.label;
631 networkButtons[label] = {index: i, button: buttons[i]};
633 return networkButtons;
637 * Adds a menu item for showing network details.
638 * @param {!Element} parent The parent element.
639 * @param {Object} data Description of the network.
642 createNetworkOptionsCallback_: function(parent, data) {
643 var menuItem = createCallback_(parent,
645 getNetworkName(data),
648 if (data.policyManaged)
649 menuItem.appendChild(new ManagedNetworkIndicator());
650 if (data.ConnectionState == 'Connected' ||
651 data.ConnectionState == 'Connecting') {
652 var label = menuItem.getElementsByClassName(
653 'network-menu-item-label')[0];
654 label.classList.add('active-network');
660 * Creates a button-like control for configurating internet connectivity.
661 * @param {Object} data Description of the network control.
662 * @param {string} data.key Item key.
663 * @param {string} data.subtitle Subtitle.
664 * @param {function} data.command Item callback.
667 function NetworkButtonItem(data) {
668 var el = new NetworkListItem(data);
669 el.__proto__ = NetworkButtonItem.prototype;
674 NetworkButtonItem.prototype = {
675 __proto__: NetworkListItem.prototype,
678 decorate: function() {
679 if (this.data.subtitle)
680 this.subtitle = this.data.subtitle;
682 this.subtitle = null;
683 if (this.data.command)
684 this.addEventListener('click', this.data.command);
685 if (this.data.iconURL)
686 this.iconURL = this.data.iconURL;
687 else if (this.data.iconType)
688 this.iconType = this.data.iconType;
689 if (this.data.policyManaged)
690 this.showManagedNetworkIndicator();
695 * Adds a command to a menu for modifying network settings.
696 * @param {!Element} menu Parent menu.
697 * @param {!Object} data Description of the network.
698 * @param {!string} label Display name for the menu item.
699 * @param {?(string|function)} command Callback function or name
700 * of the command for |networkCommand|.
701 * @param {?string=} opt_iconURL Optional URL to an icon for the menu item.
702 * @return {!Element} The created menu item.
705 function createCallback_(menu, data, label, command, opt_iconURL) {
706 var button = menu.ownerDocument.createElement('div');
707 button.className = 'network-menu-item';
709 var buttonIcon = menu.ownerDocument.createElement('div');
710 buttonIcon.className = 'network-menu-item-icon';
711 button.appendChild(buttonIcon);
713 buttonIcon.style.backgroundImage = url(opt_iconURL);
715 var buttonLabel = menu.ownerDocument.createElement('span');
716 buttonLabel.className = 'network-menu-item-label';
717 buttonLabel.textContent = label;
718 button.appendChild(buttonLabel);
720 if (typeof command == 'string') {
721 var type = data.Type;
722 var path = data.servicePath;
723 callback = function() {
724 chrome.send('networkCommand',
725 [type, path, command]);
728 } else if (command != null) {
730 callback = function() {
735 callback = function() {
741 if (callback != null)
742 button.addEventListener('click', callback);
744 buttonLabel.classList.add('network-disabled-control');
746 button.data = {label: label};
747 MenuItem.decorate(button);
748 menu.appendChild(button);
753 * A list of controls for manipulating network connectivity.
756 var NetworkList = cr.ui.define('list');
758 NetworkList.prototype = {
759 __proto__: List.prototype,
762 decorate: function() {
763 List.prototype.decorate.call(this);
764 this.startBatchUpdates();
765 this.autoExpands = true;
766 this.dataModel = new ArrayDataModel([]);
767 this.selectionModel = new ListSingleSelectionModel();
768 this.addEventListener('blur', this.onBlur_.bind(this));
769 this.selectionModel.addEventListener('change',
770 this.onSelectionChange_.bind(this));
772 // Wi-Fi control is always visible.
773 this.update({key: 'WiFi', networkList: []});
776 label: loadTimeData.getString('addConnectionWifi'),
777 command: createAddConnectionCallback_('WiFi')
780 label: loadTimeData.getString('addConnectionVPN'),
781 command: createAddConnectionCallback_('VPN')
783 this.update({key: 'addConnection',
784 iconType: 'add-connection',
785 menu: [entryAddWifi, entryAddVPN]
788 var prefs = options.Preferences.getInstance();
789 prefs.addEventListener('cros.signed.data_roaming_enabled',
791 enableDataRoaming_ = event.value.value;
793 this.endBatchUpdates();
797 * When the list loses focus, unselect all items in the list and close the
801 onBlur_: function() {
802 this.selectionModel.unselectAll();
807 * Close bubble and menu when a different list item is selected.
808 * @param {Event} event Event detailing the selection change.
811 onSelectionChange_: function(event) {
812 PageManager.hideBubble();
813 // A list item may temporarily become unselected while it is constructing
814 // its menu. The menu should therefore only be closed if a different item
815 // is selected, not when the menu's owner item is deselected.
817 for (var i = 0; i < event.changes.length; ++i) {
818 if (event.changes[i].selected) {
819 var item = this.dataModel.item(event.changes[i].index);
820 if (!item.getMenuName || item.getMenuName() != activeMenu_) {
830 * Finds the index of a network item within the data model based on
832 * @param {string} key Unique key for the item in the list.
833 * @return {number} The index of the network item, or |undefined| if it is
836 indexOf: function(key) {
837 var size = this.dataModel.length;
838 for (var i = 0; i < size; i++) {
839 var entry = this.dataModel.item(i);
840 if (entry.key == key)
847 * Updates a network control.
848 * @param {Object.<string,string>} data Description of the entry.
850 update: function(data) {
851 this.startBatchUpdates();
852 var index = this.indexOf(data.key);
853 if (index == undefined) {
854 // Find reference position for adding the element. We cannot hide
855 // individual list elements, thus we need to conditionally add or
856 // remove elements and cannot rely on any element having a fixed index.
857 for (var i = 0; i < Constants.NETWORK_ORDER.length; i++) {
858 if (data.key == Constants.NETWORK_ORDER[i]) {
863 var referenceIndex = -1;
864 for (var i = 0; i < this.dataModel.length; i++) {
865 var entry = this.dataModel.item(i);
866 if (entry.sortIndex < data.sortIndex)
871 if (referenceIndex == -1) {
872 // Prepend to the start of the list.
873 this.dataModel.splice(0, 0, data);
874 } else if (referenceIndex == this.dataModel.length) {
875 // Append to the end of the list.
876 this.dataModel.push(data);
878 // Insert after the reference element.
879 this.dataModel.splice(referenceIndex + 1, 0, data);
882 var entry = this.dataModel.item(index);
883 data.sortIndex = entry.sortIndex;
884 this.dataModel.splice(index, 1, data);
886 this.endBatchUpdates();
890 createItem: function(entry) {
891 if (entry.networkList)
892 return new NetworkSelectorItem(entry);
894 return new NetworkButtonItem(entry);
896 return new NetworkMenuItem(entry);
901 * Deletes an element from the list.
902 * @param {string} key Unique identifier for the element.
904 deleteItem: function(key) {
905 var index = this.indexOf(key);
906 if (index != undefined)
907 this.dataModel.splice(index, 1);
911 * Updates the state of a toggle button.
912 * @param {string} key Unique identifier for the element.
913 * @param {boolean} active Whether the control is active.
915 updateToggleControl: function(key, active) {
916 var index = this.indexOf(key);
917 if (index != undefined) {
918 var entry = this.dataModel.item(index);
919 entry.iconType = active ? 'control-active' :
927 * Sets the default icon to use for each network type if disconnected.
928 * @param {!Object.<string, string>} data Mapping of network type to icon
931 NetworkList.setDefaultNetworkIcons = function(data) {
932 defaultIcons_ = Object.create(data);
936 * Chrome callback for updating network controls.
937 * @param {Object} data Description of available network devices and their
938 * corresponding state.
940 NetworkList.refreshNetworkData = function(data) {
941 var networkList = $('network-list');
942 networkList.startBatchUpdates();
943 cellularAvailable_ = data.cellularAvailable;
944 cellularEnabled_ = data.cellularEnabled;
945 cellularSupportsScan_ = data.cellularSupportsScan;
946 wimaxAvailable_ = data.wimaxAvailable;
947 wimaxEnabled_ = data.wimaxEnabled;
949 // Only show Ethernet control if connected.
950 var ethernetConnection = getConnection_(data.wiredList);
951 if (ethernetConnection) {
952 var type = String('Ethernet');
953 var path = ethernetConnection.servicePath;
954 var ethernetOptions = function() {
955 chrome.send('networkCommand',
956 [type, path, 'options']);
958 networkList.update({key: 'Ethernet',
959 subtitle: loadTimeData.getString('OncStateConnected'),
960 iconURL: ethernetConnection.iconURL,
961 command: ethernetOptions,
962 policyManaged: ethernetConnection.policyManaged});
964 networkList.deleteItem('Ethernet');
967 if (data.wifiEnabled)
968 loadData_('WiFi', data.wirelessList, data.rememberedList);
970 addEnableNetworkButton_('WiFi', 'enableWifi', 'WiFi');
972 // Only show cellular control if available.
973 if (data.cellularAvailable) {
974 if (data.cellularEnabled)
975 loadData_('Cellular', data.wirelessList, data.rememberedList);
977 addEnableNetworkButton_('Cellular', 'enableCellular', 'Cellular');
979 networkList.deleteItem('Cellular');
982 // Only show wimax control if available. Uses cellular icons.
983 if (data.wimaxAvailable) {
984 if (data.wimaxEnabled)
985 loadData_('Wimax', data.wirelessList, data.rememberedList);
987 addEnableNetworkButton_('Wimax', 'enableWimax', 'Cellular');
989 networkList.deleteItem('Wimax');
992 // Only show VPN control if there is at least one VPN configured.
993 if (data.vpnList.length > 0)
994 loadData_('VPN', data.vpnList, data.rememberedList);
996 networkList.deleteItem('VPN');
997 networkList.endBatchUpdates();
1001 * Replaces a network menu with a button for reenabling the type of network.
1002 * @param {string} name The type of network (WiFi, Cellular or Wimax).
1003 * @param {string} command The command for reenabling the network.
1004 * @param {string} type of icon (WiFi or Cellular).
1007 function addEnableNetworkButton_(name, command, icon) {
1008 var subtitle = loadTimeData.getString('networkDisabled');
1009 var enableNetwork = function() {
1010 chrome.send(command);
1012 var networkList = $('network-list');
1013 networkList.update({key: name,
1016 command: enableNetwork});
1020 * Element for indicating a policy managed network.
1023 function ManagedNetworkIndicator() {
1024 var el = cr.doc.createElement('span');
1025 el.__proto__ = ManagedNetworkIndicator.prototype;
1030 ManagedNetworkIndicator.prototype = {
1031 __proto__: ControlledSettingIndicator.prototype,
1034 decorate: function() {
1035 ControlledSettingIndicator.prototype.decorate.call(this);
1036 this.controlledBy = 'policy';
1037 var policyLabel = loadTimeData.getString('managedNetwork');
1038 this.setAttribute('textPolicy', policyLabel);
1039 this.removeAttribute('tabindex');
1043 handleEvent: function(event) {
1044 // Prevent focus blurring as that would close any currently open menu.
1045 if (event.type == 'mousedown')
1047 ControlledSettingIndicator.prototype.handleEvent.call(this, event);
1051 * Handle mouse events received by the bubble, preventing focus blurring as
1052 * that would close any currently open menu and preventing propagation to
1053 * any elements located behind the bubble.
1054 * @param {Event} Mouse event.
1056 stopEvent: function(event) {
1057 event.preventDefault();
1058 event.stopPropagation();
1062 toggleBubble_: function() {
1063 if (activeMenu_ && !$(activeMenu_).contains(this))
1065 ControlledSettingIndicator.prototype.toggleBubble_.call(this);
1066 if (this.showingBubble) {
1067 var bubble = PageManager.getVisibleBubble();
1068 bubble.addEventListener('mousedown', this.stopEvent);
1069 bubble.addEventListener('click', this.stopEvent);
1075 * Updates the list of available networks and their status, filtered by
1077 * @param {string} type The type of network.
1078 * @param {Array} available The list of available networks and their status.
1079 * @param {Array} remembered The list of remmebered networks.
1081 function loadData_(type, available, remembered) {
1082 var data = {key: type};
1083 var availableNetworks = [];
1084 for (var i = 0; i < available.length; i++) {
1085 if (available[i].Type == type)
1086 availableNetworks.push(available[i]);
1088 data.networkList = availableNetworks;
1090 var rememberedNetworks = [];
1091 for (var i = 0; i < remembered.length; i++) {
1092 if (remembered[i].Type == type)
1093 rememberedNetworks.push(remembered[i]);
1095 data.rememberedNetworks = rememberedNetworks;
1097 $('network-list').update(data);
1101 * Hides the currently visible menu.
1104 function closeMenu_() {
1106 var menu = $(activeMenu_);
1108 if (menu.data && menu.data.discardOnClose)
1109 menu.parentNode.removeChild(menu);
1115 * Fetches the active connection.
1116 * @param {Array.<Object>} networkList List of networks.
1117 * @return {boolean} True if connected or connecting to a network.
1120 function getConnection_(networkList) {
1123 for (var i = 0; i < networkList.length; i++) {
1124 var entry = networkList[i];
1125 if (entry.ConnectionState == 'Connected' ||
1126 entry.ConnectionState == 'Connecting')
1133 * Create a callback function that adds a new connection of the given type.
1134 * @param {string} type An ONC network type
1135 * @return {function()} The created callback.
1138 function createAddConnectionCallback_(type) {
1140 chrome.send('networkCommand', [type, '', 'add']);
1145 * Whether the Network list is disabled. Only used for display purpose.
1148 cr.defineProperty(NetworkList, 'disabled', cr.PropertyKind.BOOL_ATTR);
1152 NetworkList: NetworkList