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 the current SIM lock type of the cellular device.
70 var cellularSimLockType_
= '';
73 * Indicates whether the SIM card is absent on the cellular device.
77 var cellularSimAbsent_
= false;
80 * Indicates if WiMAX networks are available.
84 var wimaxAvailable_
= false;
87 * Indicates if WiMAX networks are enabled.
91 var wimaxEnabled_
= false;
94 * Indicates if mobile data roaming is enabled.
98 var enableDataRoaming_
= false;
101 * Icon to use when not connected to a particular type of network.
102 * @type {!Object.<string, string>} Mapping of network type to icon data url.
105 var defaultIcons_
= {};
108 * Returns the display name for 'network'.
109 * @param {Object} data The network data dictionary.
111 function getNetworkName(data
) {
112 if (data
.Type
== 'Ethernet')
113 return loadTimeData
.getString('ethernetName');
118 * Create an element in the network list for controlling network
120 * @param {Object} data Description of the network list or command.
122 * @extends {cr.ui.ListItem}
124 function NetworkListItem(data
) {
125 var el
= cr
.doc
.createElement('li');
127 for (var key
in data
)
128 el
.data_
[key
] = data
[key
];
129 NetworkListItem
.decorate(el
);
134 * @param {string} action An action to send to coreOptionsUserMetricsAction.
136 function sendChromeMetricsAction(action
) {
137 chrome
.send('coreOptionsUserMetricsAction', [action
]);
141 * Decorate an element as a NetworkListItem.
142 * @param {!Element} el The element to decorate.
144 NetworkListItem
.decorate = function(el
) {
145 el
.__proto__
= NetworkListItem
.prototype;
149 NetworkListItem
.prototype = {
150 __proto__
: ListItem
.prototype,
153 * Description of the network group or control.
154 * @type {Object.<string,Object>}
160 * Element for the control's subtitle.
167 * Icon for the network control.
174 * Indicates if in the process of connecting to a network.
181 * Description of the network control.
189 * Text label for the subtitle.
194 this.subtitle_
.textContent
= text
;
195 this.subtitle_
.hidden
= !text
;
199 * URL for the network icon.
202 set iconURL(iconURL
) {
203 this.icon_
.style
.backgroundImage
= url(iconURL
);
207 * Type of network icon. Each type corresponds to a CSS rule.
211 if (defaultIcons_
[type
])
212 this.iconURL
= defaultIcons_
[type
];
214 this.icon_
.classList
.add('network-' + type
.toLowerCase());
218 * Indicates if the network is in the process of being connected.
221 set connecting(state
) {
222 this.connecting_
= state
;
224 this.icon_
.classList
.add('network-connecting');
226 this.icon_
.classList
.remove('network-connecting');
230 * Indicates if the network is in the process of being connected.
234 return this.connecting_
;
238 * Set the direction of the text.
239 * @param {string} direction The direction of the text, e.g. 'ltr'.
241 setSubtitleDirection: function(direction
) {
242 this.subtitle_
.dir
= direction
;
246 * Indicate that the selector arrow should be shown.
248 showSelector: function() {
249 this.subtitle_
.classList
.add('network-selector');
253 * Adds an indicator to show that the network is policy managed.
255 showManagedNetworkIndicator: function() {
256 this.appendChild(new ManagedNetworkIndicator());
260 decorate: function() {
261 ListItem
.prototype.decorate
.call(this);
262 this.className
= 'network-group';
263 this.icon_
= this.ownerDocument
.createElement('div');
264 this.icon_
.className
= 'network-icon';
265 this.appendChild(this.icon_
);
266 var textContent
= this.ownerDocument
.createElement('div');
267 textContent
.className
= 'network-group-labels';
268 this.appendChild(textContent
);
269 var categoryLabel
= this.ownerDocument
.createElement('div');
271 if (this.data_
.key
== 'addConnection')
272 title
= 'addConnectionTitle';
274 title
= this.data_
.key
.toLowerCase() + 'Title';
275 categoryLabel
.className
= 'network-title';
276 categoryLabel
.textContent
= loadTimeData
.getString(title
);
277 textContent
.appendChild(categoryLabel
);
278 this.subtitle_
= this.ownerDocument
.createElement('div');
279 this.subtitle_
.className
= 'network-subtitle';
280 textContent
.appendChild(this.subtitle_
);
285 * Creates a control that displays a popup menu when clicked.
286 * @param {Object} data Description of the control.
288 * @extends {NetworkListItem}
290 function NetworkMenuItem(data
) {
291 var el
= new NetworkListItem(data
);
292 el
.__proto__
= NetworkMenuItem
.prototype;
297 NetworkMenuItem
.prototype = {
298 __proto__
: NetworkListItem
.prototype,
301 * Popup menu element.
308 decorate: function() {
309 this.subtitle
= null;
310 if (this.data
.iconType
)
311 this.iconType
= this.data
.iconType
;
312 this.addEventListener('click', function() {
318 * Retrieves the ID for the menu.
320 getMenuName: function() {
321 return this.data_
.key
.toLowerCase() + '-network-menu';
325 * Creates a popup menu for the control.
326 * @return {Element} The newly created menu.
328 createMenu: function() {
329 if (this.data
.menu
) {
330 var menu
= this.ownerDocument
.createElement('div');
331 menu
.id
= this.getMenuName();
332 menu
.className
= 'network-menu';
335 for (var i
= 0; i
< this.data
.menu
.length
; i
++) {
336 var entry
= this.data
.menu
[i
];
337 createCallback_(menu
, null, entry
.label
, entry
.command
);
344 canUpdateMenu: function() {
349 * Displays a popup menu.
351 showMenu: function() {
353 // Force a rescan if opening the menu for WiFi networks to ensure the
354 // list is up to date. Networks are periodically rescanned, but depending
355 // on timing, there could be an excessive delay before the first rescan
357 var rescan
= !activeMenu_
&& this.data_
.key
== 'WiFi';
360 var existing
= $(this.getMenuName());
362 if (this.updateMenu())
366 this.menu_
= this.createMenu();
367 this.menu_
.addEventListener('mousedown', function(e
) {
368 // Prevent blurring of list, which would close the menu.
371 var parent
= $('network-menus');
373 parent
.replaceChild(this.menu_
, existing
);
375 parent
.appendChild(this.menu_
);
377 var top
= this.offsetTop
+ this.clientHeight
;
378 var menuId
= this.getMenuName();
379 if (menuId
!= activeMenu_
|| rebuild
) {
381 activeMenu_
= menuId
;
382 this.menu_
.style
.setProperty('top', top
+ 'px');
383 this.menu_
.hidden
= false;
386 // TODO(stevenjb): chrome.networkingPrivate.requestNetworkScan
387 chrome
.send('requestNetworkScan');
393 * Creates a control for selecting or configuring a network connection based
394 * on the type of connection (e.g. wifi versus vpn).
395 * @param {{key: string, networkList: Array.<Object>}} data Description of the
398 * @extends {NetworkMenuItem}
400 function NetworkSelectorItem(data
) {
401 var el
= new NetworkMenuItem(data
);
402 el
.__proto__
= NetworkSelectorItem
.prototype;
407 NetworkSelectorItem
.prototype = {
408 __proto__
: NetworkMenuItem
.prototype,
411 decorate: function() {
412 // TODO(kevers): Generalize method of setting default label.
413 var policyManaged
= false;
414 this.subtitle
= loadTimeData
.getString('OncConnectionStateNotConnected');
415 var list
= this.data_
.networkList
;
416 var candidateURL
= null;
417 for (var i
= 0; i
< list
.length
; i
++) {
418 var networkDetails
= list
[i
];
419 if (networkDetails
.ConnectionState
== 'Connecting' ||
420 networkDetails
.ConnectionState
== 'Connected') {
421 this.subtitle
= getNetworkName(networkDetails
);
422 this.setSubtitleDirection('ltr');
423 policyManaged
= networkDetails
.policyManaged
;
424 candidateURL
= networkDetails
.iconURL
;
425 // Only break when we see a connecting network as it is possible to
426 // have a connected network and a connecting network at the same
428 if (networkDetails
.ConnectionState
== 'Connecting') {
429 this.connecting
= true;
436 this.iconURL
= candidateURL
;
438 this.iconType
= this.data
.key
;
443 this.showManagedNetworkIndicator();
445 if (activeMenu_
== this.getMenuName()) {
446 // Menu is already showing and needs to be updated. Explicitly calling
447 // show menu will force the existing menu to be replaced. The call
448 // is deferred in order to ensure that position of this element has
449 // beem properly updated.
451 setTimeout(function() {self
.showMenu();}, 0);
456 * Creates a menu for selecting, configuring or disconnecting from a
458 * @return {!Element} The newly created menu.
460 createMenu: function() {
461 var menu
= this.ownerDocument
.createElement('div');
462 menu
.id
= this.getMenuName();
463 menu
.className
= 'network-menu';
467 if (this.data_
.key
== 'WiFi') {
469 label
: loadTimeData
.getString('joinOtherNetwork'),
470 command
: createAddConnectionCallback_('WiFi'),
473 } else if (this.data_
.key
== 'Cellular') {
474 if (cellularEnabled_
&& cellularSupportsScan_
) {
476 label
: loadTimeData
.getString('otherCellularNetworks'),
477 command
: createAddConnectionCallback_('Cellular'),
478 addClass
: ['other-cellulars'],
483 var label
= enableDataRoaming_
? 'disableDataRoaming' :
485 var disabled
= !loadTimeData
.getValue('loggedInAsOwner');
486 var entry
= {label
: loadTimeData
.getString(label
),
489 entry
.command
= null;
491 loadTimeData
.getString('dataRoamingDisableToggleTooltip');
494 entry
.command = function() {
495 options
.Preferences
.setBooleanPref(
496 'cros.signed.data_roaming_enabled',
497 !enableDataRoaming_
, true);
498 // Force revalidation of the menu the next time it is displayed.
502 addendum
.push(entry
);
504 var list
= this.data
.rememberedNetworks
;
505 if (list
&& list
.length
> 0) {
506 var callback = function(list
) {
507 $('remembered-network-list').clear();
508 var dialog
= options
.PreferredNetworks
.getInstance();
509 PageManager
.showPageByName('preferredNetworksPage', false);
511 sendChromeMetricsAction('Options_NetworkShowPreferred');
513 addendum
.push({label
: loadTimeData
.getString('preferredNetworks'),
518 var networkGroup
= this.ownerDocument
.createElement('div');
519 networkGroup
.className
= 'network-menu-group';
520 list
= this.data
.networkList
;
521 var empty
= !list
|| list
.length
== 0;
523 for (var i
= 0; i
< list
.length
; i
++) {
525 this.createNetworkOptionsCallback_(networkGroup
, data
);
526 if (data
.ConnectionState
== 'Connected') {
527 if (data
.Type
== 'VPN') {
528 var disconnectCallback = function() {
529 sendChromeMetricsAction('Options_NetworkDisconnectVPN');
530 // TODO(stevenjb): chrome.networkingPrivate.startDisconnect
531 chrome
.send('startDisconnect', [data
.servicePath
]);
535 addendum
.push({label
: loadTimeData
.getString('disconnectNetwork'),
536 command
: disconnectCallback
,
542 if (this.data_
.key
== 'WiFi' || this.data_
.key
== 'Wimax' ||
543 this.data_
.key
== 'Cellular') {
545 if (this.data_
.key
== 'WiFi') {
547 label
: loadTimeData
.getString('turnOffWifi'),
548 command: function() {
549 sendChromeMetricsAction('Options_NetworkWifiToggle');
550 // TODO(stevenjb): chrome.networkingPrivate.disableNetworkType
551 chrome
.send('disableNetworkType', ['WiFi']);
554 } else if (this.data_
.key
== 'Wimax') {
556 label
: loadTimeData
.getString('turnOffWimax'),
557 command: function() {
558 // TODO(stevenjb): chrome.networkingPrivate.disableNetworkType
559 chrome
.send('disableNetworkType', ['Wimax']);
562 } else if (this.data_
.key
== 'Cellular') {
564 label
: loadTimeData
.getString('turnOffCellular'),
565 command: function() {
566 // TODO(stevenjb): chrome.networkingPrivate.disableNetworkType
567 chrome
.send('disableNetworkType', ['Cellular']);
573 menu
.appendChild(networkGroup
);
574 if (addendum
.length
> 0) {
575 var separator
= false;
577 menu
.appendChild(MenuItem
.createSeparator());
580 for (var i
= 0; i
< addendum
.length
; i
++) {
581 var value
= addendum
[i
];
583 var item
= createCallback_(menu
, value
.data
, value
.label
,
586 item
.title
= value
.tooltip
;
588 item
.classList
.add(value
.addClass
);
590 } else if (!separator
) {
591 menu
.appendChild(MenuItem
.createSeparator());
600 * Determines if a menu can be updated on the fly. Menus that cannot be
601 * updated are fully regenerated using createMenu. The advantage of
602 * updating a menu is that it can preserve ordering of networks avoiding
603 * entries from jumping around after an update.
605 canUpdateMenu: function() {
606 return this.data_
.key
== 'WiFi' && activeMenu_
== this.getMenuName();
610 * Updates an existing menu. Updated menus preserve ordering of prior
611 * entries. During the update process, the ordering may differ from the
612 * preferred ordering as determined by the network library. If the
613 * ordering becomes potentially out of sync, then the updated menu is
614 * marked for disposal on close. Reopening the menu will force a
615 * regeneration, which will in turn fix the ordering.
616 * @return {boolean} True if successfully updated.
618 updateMenu: function() {
619 if (!this.canUpdateMenu())
621 var oldMenu
= $(this.getMenuName());
622 var group
= oldMenu
.getElementsByClassName('network-menu-group')[0];
625 var newMenu
= this.createMenu();
626 var discardOnClose
= false;
627 var oldNetworkButtons
= this.extractNetworkConnectButtons_(oldMenu
);
628 var newNetworkButtons
= this.extractNetworkConnectButtons_(newMenu
);
629 for (var key
in oldNetworkButtons
) {
630 if (newNetworkButtons
[key
]) {
631 group
.replaceChild(newNetworkButtons
[key
].button
,
632 oldNetworkButtons
[key
].button
);
633 if (newNetworkButtons
[key
].index
!= oldNetworkButtons
[key
].index
)
634 discardOnClose
= true;
635 newNetworkButtons
[key
] = null;
637 // Leave item in list to prevent network items from jumping due to
639 oldNetworkButtons
[key
].disabled
= true;
640 discardOnClose
= true;
643 for (var key
in newNetworkButtons
) {
644 var entry
= newNetworkButtons
[key
];
646 group
.appendChild(entry
.button
);
647 discardOnClose
= true;
650 oldMenu
.data
= {discardOnClose
: discardOnClose
};
655 * Extracts a mapping of network names to menu element and position.
656 * @param {!Element} menu The menu to process.
657 * @return {Object.<string, {index: number, button: Element}>}
661 extractNetworkConnectButtons_: function(menu
) {
662 var group
= menu
.getElementsByClassName('network-menu-group')[0];
663 var networkButtons
= {};
665 return networkButtons
;
666 var buttons
= group
.getElementsByClassName('network-menu-item');
667 for (var i
= 0; i
< buttons
.length
; i
++) {
668 var label
= buttons
[i
].data
.label
;
669 networkButtons
[label
] = {index
: i
, button
: buttons
[i
]};
671 return networkButtons
;
675 * Adds a menu item for showing network details.
676 * @param {!Element} parent The parent element.
677 * @param {Object} data Description of the network.
680 createNetworkOptionsCallback_: function(parent
, data
) {
681 var menuItem
= createCallback_(parent
,
683 getNetworkName(data
),
686 if (data
.policyManaged
)
687 menuItem
.appendChild(new ManagedNetworkIndicator());
688 if (data
.ConnectionState
== 'Connected' ||
689 data
.ConnectionState
== 'Connecting') {
690 var label
= menuItem
.getElementsByClassName(
691 'network-menu-item-label')[0];
692 label
.classList
.add('active-network');
698 * Creates a button-like control for configurating internet connectivity.
699 * @param {{key: string, subtitle: string, command: Function}} data
700 * Description of the network control.
702 * @extends {NetworkListItem}
704 function NetworkButtonItem(data
) {
705 var el
= new NetworkListItem(data
);
706 el
.__proto__
= NetworkButtonItem
.prototype;
711 NetworkButtonItem
.prototype = {
712 __proto__
: NetworkListItem
.prototype,
715 decorate: function() {
716 if (this.data
.subtitle
)
717 this.subtitle
= this.data
.subtitle
;
719 this.subtitle
= null;
720 if (this.data
.command
)
721 this.addEventListener('click', this.data
.command
);
722 if (this.data
.iconURL
)
723 this.iconURL
= this.data
.iconURL
;
724 else if (this.data
.iconType
)
725 this.iconType
= this.data
.iconType
;
726 if (this.data
.policyManaged
)
727 this.showManagedNetworkIndicator();
732 * Adds a command to a menu for modifying network settings.
733 * @param {!Element} menu Parent menu.
734 * @param {Object} data Description of the network.
735 * @param {!string} label Display name for the menu item.
736 * @param {?(string|!Function)} command Callback function or name
737 * of the command for |networkCommand|.
738 * @param {string=} opt_iconURL Optional URL to an icon for the menu item.
739 * @return {!Element} The created menu item.
742 function createCallback_(menu
, data
, label
, command
, opt_iconURL
) {
743 var button
= menu
.ownerDocument
.createElement('div');
744 button
.className
= 'network-menu-item';
746 var buttonIcon
= menu
.ownerDocument
.createElement('div');
747 buttonIcon
.className
= 'network-menu-item-icon';
748 button
.appendChild(buttonIcon
);
750 buttonIcon
.style
.backgroundImage
= url(opt_iconURL
);
752 var buttonLabel
= menu
.ownerDocument
.createElement('span');
753 buttonLabel
.className
= 'network-menu-item-label';
754 buttonLabel
.textContent
= label
;
755 button
.appendChild(buttonLabel
);
757 if (typeof command
== 'string') {
758 var type
= data
.Type
;
759 var path
= data
.servicePath
;
760 callback = function() {
761 chrome
.send('networkCommand', [type
, path
, command
]);
764 } else if (command
!= null) {
766 callback = function() {
767 (/** @type {Function} */(command
))(data
);
771 callback = function() {
772 (/** @type {Function} */(command
))();
777 if (callback
!= null)
778 button
.addEventListener('click', callback
);
780 buttonLabel
.classList
.add('network-disabled-control');
782 button
.data
= {label
: label
};
783 MenuItem
.decorate(button
);
784 menu
.appendChild(button
);
789 * A list of controls for manipulating network connectivity.
791 * @extends {cr.ui.List}
793 var NetworkList
= cr
.ui
.define('list');
795 NetworkList
.prototype = {
796 __proto__
: List
.prototype,
799 decorate: function() {
800 List
.prototype.decorate
.call(this);
801 this.startBatchUpdates();
802 this.autoExpands
= true;
803 this.dataModel
= new ArrayDataModel([]);
804 this.selectionModel
= new ListSingleSelectionModel();
805 this.addEventListener('blur', this.onBlur_
.bind(this));
806 this.selectionModel
.addEventListener('change',
807 this.onSelectionChange_
.bind(this));
809 // Wi-Fi control is always visible.
810 this.update({key
: 'WiFi', networkList
: []});
813 label
: loadTimeData
.getString('addConnectionWifi'),
814 command
: createAddConnectionCallback_('WiFi')
817 label
: loadTimeData
.getString('addConnectionVPN'),
818 command
: createAddConnectionCallback_('VPN')
820 this.update({key
: 'addConnection',
821 iconType
: 'add-connection',
822 menu
: [entryAddWifi
, entryAddVPN
]
825 var prefs
= options
.Preferences
.getInstance();
826 prefs
.addEventListener('cros.signed.data_roaming_enabled',
828 enableDataRoaming_
= event
.value
.value
;
830 this.endBatchUpdates();
834 * When the list loses focus, unselect all items in the list and close the
838 onBlur_: function() {
839 this.selectionModel
.unselectAll();
844 * Close bubble and menu when a different list item is selected.
845 * @param {Event} event Event detailing the selection change.
848 onSelectionChange_: function(event
) {
849 PageManager
.hideBubble();
850 // A list item may temporarily become unselected while it is constructing
851 // its menu. The menu should therefore only be closed if a different item
852 // is selected, not when the menu's owner item is deselected.
854 for (var i
= 0; i
< event
.changes
.length
; ++i
) {
855 if (event
.changes
[i
].selected
) {
856 var item
= this.dataModel
.item(event
.changes
[i
].index
);
857 if (!item
.getMenuName
|| item
.getMenuName() != activeMenu_
) {
867 * Finds the index of a network item within the data model based on
869 * @param {string} key Unique key for the item in the list.
870 * @return {(number|undefined)} The index of the network item, or
871 * |undefined| if it is not found.
873 indexOf: function(key
) {
874 var size
= this.dataModel
.length
;
875 for (var i
= 0; i
< size
; i
++) {
876 var entry
= this.dataModel
.item(i
);
877 if (entry
.key
== key
)
884 * Updates a network control.
885 * @param {Object.<string,string>} data Description of the entry.
887 update: function(data
) {
888 this.startBatchUpdates();
889 var index
= this.indexOf(data
.key
);
890 if (index
== undefined) {
891 // Find reference position for adding the element. We cannot hide
892 // individual list elements, thus we need to conditionally add or
893 // remove elements and cannot rely on any element having a fixed index.
894 for (var i
= 0; i
< Constants
.NETWORK_ORDER
.length
; i
++) {
895 if (data
.key
== Constants
.NETWORK_ORDER
[i
]) {
900 var referenceIndex
= -1;
901 for (var i
= 0; i
< this.dataModel
.length
; i
++) {
902 var entry
= this.dataModel
.item(i
);
903 if (entry
.sortIndex
< data
.sortIndex
)
908 if (referenceIndex
== -1) {
909 // Prepend to the start of the list.
910 this.dataModel
.splice(0, 0, data
);
911 } else if (referenceIndex
== this.dataModel
.length
) {
912 // Append to the end of the list.
913 this.dataModel
.push(data
);
915 // Insert after the reference element.
916 this.dataModel
.splice(referenceIndex
+ 1, 0, data
);
919 var entry
= this.dataModel
.item(index
);
920 data
.sortIndex
= entry
.sortIndex
;
921 this.dataModel
.splice(index
, 1, data
);
923 this.endBatchUpdates();
927 createItem: function(entry
) {
928 if (entry
.networkList
)
929 return new NetworkSelectorItem(entry
);
931 return new NetworkButtonItem(entry
);
933 return new NetworkMenuItem(entry
);
938 * Deletes an element from the list.
939 * @param {string} key Unique identifier for the element.
941 deleteItem: function(key
) {
942 var index
= this.indexOf(key
);
943 if (index
!= undefined)
944 this.dataModel
.splice(index
, 1);
948 * Updates the state of a toggle button.
949 * @param {string} key Unique identifier for the element.
950 * @param {boolean} active Whether the control is active.
952 updateToggleControl: function(key
, active
) {
953 var index
= this.indexOf(key
);
954 if (index
!= undefined) {
955 var entry
= this.dataModel
.item(index
);
956 entry
.iconType
= active
? 'control-active' :
964 * Sets the default icon to use for each network type if disconnected.
965 * @param {!Object.<string, string>} data Mapping of network type to icon
968 NetworkList
.setDefaultNetworkIcons = function(data
) {
969 defaultIcons_
= Object
.create(data
);
973 * Chrome callback for updating network controls.
974 * @param {{wiredList: Array, wirelessList: Array, vpnList: Array,
975 * rememberedList: Array, wifiAvailable: boolean, wifiEnabled: boolean,
976 * wimaxAvailable: boolean, wimaxEnabled: boolean,
977 * cellularAvailable: boolean, cellularEnabled: boolean,
978 * cellularSupportsScan: boolean}} data Description of available network
979 * devices and their corresponding state.
981 NetworkList
.refreshNetworkData = function(data
) {
982 var networkList
= $('network-list');
983 networkList
.startBatchUpdates();
984 cellularAvailable_
= data
.cellularAvailable
;
985 cellularEnabled_
= data
.cellularEnabled
;
986 cellularSupportsScan_
= data
.cellularSupportsScan
;
987 cellularSimAbsent_
= data
.cellularSimAbsent
;
988 cellularSimLockType_
= data
.cellularSimLockType
;
989 wimaxAvailable_
= data
.wimaxAvailable
;
990 wimaxEnabled_
= data
.wimaxEnabled
;
992 // Only show Ethernet control if connected.
993 var ethernetConnection
= getConnection_(data
.wiredList
);
994 if (ethernetConnection
) {
995 var type
= String('Ethernet');
996 var path
= ethernetConnection
.servicePath
;
997 var ethernetOptions = function() {
998 chrome
.send('networkCommand', [type
, path
, 'showDetails']);
1002 subtitle
: loadTimeData
.getString('OncConnectionStateConnected'),
1003 iconURL
: ethernetConnection
.iconURL
,
1004 command
: ethernetOptions
,
1005 policyManaged
: ethernetConnection
.policyManaged
}
1008 networkList
.deleteItem('Ethernet');
1011 if (data
.wifiEnabled
)
1012 loadData_('WiFi', data
.wirelessList
, data
.rememberedList
);
1014 addEnableNetworkButton_('WiFi');
1016 // Only show cellular control if available.
1017 if (data
.cellularAvailable
) {
1018 if (data
.cellularEnabled
)
1019 loadData_('Cellular', data
.wirelessList
, data
.rememberedList
);
1021 addEnableNetworkButton_('Cellular');
1023 networkList
.deleteItem('Cellular');
1026 // Only show wimax control if available. Uses cellular icons.
1027 if (data
.wimaxAvailable
) {
1028 if (data
.wimaxEnabled
)
1029 loadData_('Wimax', data
.wirelessList
, data
.rememberedList
);
1031 addEnableNetworkButton_('Wimax');
1033 networkList
.deleteItem('Wimax');
1036 // Only show VPN control if there is at least one VPN configured.
1037 if (data
.vpnList
.length
> 0)
1038 loadData_('VPN', data
.vpnList
, data
.rememberedList
);
1040 networkList
.deleteItem('VPN');
1041 networkList
.endBatchUpdates();
1045 * Replaces a network menu with a button for enabling the network type.
1046 * @param {string} type The type of network (WiFi, Cellular or Wimax).
1049 function addEnableNetworkButton_(type
) {
1050 var subtitle
= loadTimeData
.getString('networkDisabled');
1051 var icon
= (type
== 'Wimax') ? 'Cellular' : type
;
1052 var enableNetwork = function() {
1054 sendChromeMetricsAction('Options_NetworkWifiToggle');
1055 if (type
== 'Cellular') {
1056 if (cellularSimLockType_
) {
1057 chrome
.send('simOperation', ['unlock']);
1059 } else if (cellularEnabled_
&& cellularSimAbsent_
) {
1060 chrome
.send('simOperation', ['configure']);
1064 // TODO(stevenjb): chrome.networkingPrivate.enableNetworkType
1065 chrome
.send('enableNetworkType', [type
]);
1067 $('network-list').update({key
: type
,
1070 command
: enableNetwork
});
1074 * Element for indicating a policy managed network.
1076 * @extends {options.ControlledSettingIndicator}
1078 function ManagedNetworkIndicator() {
1079 var el
= cr
.doc
.createElement('span');
1080 el
.__proto__
= ManagedNetworkIndicator
.prototype;
1085 ManagedNetworkIndicator
.prototype = {
1086 __proto__
: ControlledSettingIndicator
.prototype,
1089 decorate: function() {
1090 ControlledSettingIndicator
.prototype.decorate
.call(this);
1091 this.controlledBy
= 'policy';
1092 var policyLabel
= loadTimeData
.getString('managedNetwork');
1093 this.setAttribute('textPolicy', policyLabel
);
1094 this.removeAttribute('tabindex');
1098 handleEvent: function(event
) {
1099 // Prevent focus blurring as that would close any currently open menu.
1100 if (event
.type
== 'mousedown')
1102 ControlledSettingIndicator
.prototype.handleEvent
.call(this, event
);
1106 * Handle mouse events received by the bubble, preventing focus blurring as
1107 * that would close any currently open menu and preventing propagation to
1108 * any elements located behind the bubble.
1109 * @param {Event} event Mouse event.
1111 stopEvent: function(event
) {
1112 event
.preventDefault();
1113 event
.stopPropagation();
1117 toggleBubble: function() {
1118 if (activeMenu_
&& !$(activeMenu_
).contains(this))
1120 ControlledSettingIndicator
.prototype.toggleBubble
.call(this);
1121 if (this.showingBubble
) {
1122 var bubble
= PageManager
.getVisibleBubble();
1123 bubble
.addEventListener('mousedown', this.stopEvent
);
1124 bubble
.addEventListener('click', this.stopEvent
);
1130 * Updates the list of available networks and their status, filtered by
1132 * @param {string} type The type of network.
1133 * @param {Array} available The list of available networks and their status.
1134 * @param {Array} remembered The list of remmebered networks.
1136 function loadData_(type
, available
, remembered
) {
1137 var data
= {key
: type
};
1138 var availableNetworks
= [];
1139 for (var i
= 0; i
< available
.length
; i
++) {
1140 if (available
[i
].Type
== type
)
1141 availableNetworks
.push(available
[i
]);
1143 data
.networkList
= availableNetworks
;
1145 var rememberedNetworks
= [];
1146 for (var i
= 0; i
< remembered
.length
; i
++) {
1147 if (remembered
[i
].Type
== type
)
1148 rememberedNetworks
.push(remembered
[i
]);
1150 data
.rememberedNetworks
= rememberedNetworks
;
1152 $('network-list').update(data
);
1156 * Hides the currently visible menu.
1159 function closeMenu_() {
1161 var menu
= $(activeMenu_
);
1163 if (menu
.data
&& menu
.data
.discardOnClose
)
1164 menu
.parentNode
.removeChild(menu
);
1170 * Fetches the active connection.
1171 * @param {Array.<Object>} networkList List of networks.
1175 function getConnection_(networkList
) {
1178 for (var i
= 0; i
< networkList
.length
; i
++) {
1179 var entry
= networkList
[i
];
1180 if (entry
.ConnectionState
== 'Connected' ||
1181 entry
.ConnectionState
== 'Connecting')
1188 * Create a callback function that adds a new connection of the given type.
1189 * @param {string} type An ONC network type
1190 * @return {function()} The created callback.
1193 function createAddConnectionCallback_(type
) {
1196 sendChromeMetricsAction('Options_NetworkJoinOtherWifi');
1197 else if (type
== 'VPN')
1198 sendChromeMetricsAction('Options_NetworkJoinOtherVPN');
1199 chrome
.send('networkCommand', [type
, '', 'add']);
1204 * Whether the Network list is disabled. Only used for display purpose.
1206 cr
.defineProperty(NetworkList
, 'disabled', cr
.PropertyKind
.BOOL_ATTR
);
1210 NetworkList
: NetworkList