| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 cr.define('options.network', function() { | 5 cr.define('options.network', function() { |
| 6 | 6 |
| 7 var ArrayDataModel = cr.ui.ArrayDataModel; | 7 var ArrayDataModel = cr.ui.ArrayDataModel; |
| 8 var List = cr.ui.List; | 8 var List = cr.ui.List; |
| 9 var ListItem = cr.ui.ListItem; | 9 var ListItem = cr.ui.ListItem; |
| 10 var ListSingleSelectionModel = cr.ui.ListSingleSelectionModel; |
| 10 var Menu = cr.ui.Menu; | 11 var Menu = cr.ui.Menu; |
| 11 var MenuItem = cr.ui.MenuItem; | 12 var MenuItem = cr.ui.MenuItem; |
| 12 var ControlledSettingIndicator = options.ControlledSettingIndicator; | 13 var ControlledSettingIndicator = options.ControlledSettingIndicator; |
| 13 | 14 |
| 14 /** | 15 /** |
| 15 * Network settings constants. These enums usually match their C++ | 16 * Network settings constants. These enums usually match their C++ |
| 16 * counterparts. | 17 * counterparts. |
| 17 */ | 18 */ |
| 18 function Constants() {} | 19 function Constants() {} |
| 19 | 20 |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 this.subtitle = null; | 283 this.subtitle = null; |
| 283 if (this.data.iconType) | 284 if (this.data.iconType) |
| 284 this.iconType = this.data.iconType; | 285 this.iconType = this.data.iconType; |
| 285 this.addEventListener('click', function() { | 286 this.addEventListener('click', function() { |
| 286 this.showMenu(); | 287 this.showMenu(); |
| 287 }); | 288 }); |
| 288 }, | 289 }, |
| 289 | 290 |
| 290 /** | 291 /** |
| 291 * Retrieves the ID for the menu. | 292 * Retrieves the ID for the menu. |
| 292 * @private | |
| 293 */ | 293 */ |
| 294 getMenuName_: function() { | 294 getMenuName: function() { |
| 295 return this.data_.key + '-network-menu'; | 295 return this.data_.key + '-network-menu'; |
| 296 }, | 296 }, |
| 297 | 297 |
| 298 /** | 298 /** |
| 299 * Creates a popup menu for the control. | 299 * Creates a popup menu for the control. |
| 300 * @return {Element} The newly created menu. | 300 * @return {Element} The newly created menu. |
| 301 */ | 301 */ |
| 302 createMenu: function() { | 302 createMenu: function() { |
| 303 if (this.data.menu) { | 303 if (this.data.menu) { |
| 304 var menu = this.ownerDocument.createElement('div'); | 304 var menu = this.ownerDocument.createElement('div'); |
| 305 menu.id = this.getMenuName_(); | 305 menu.id = this.getMenuName(); |
| 306 menu.className = 'network-menu'; | 306 menu.className = 'network-menu'; |
| 307 menu.hidden = true; | 307 menu.hidden = true; |
| 308 Menu.decorate(menu); | 308 Menu.decorate(menu); |
| 309 for (var i = 0; i < this.data.menu.length; i++) { | 309 for (var i = 0; i < this.data.menu.length; i++) { |
| 310 var entry = this.data.menu[i]; | 310 var entry = this.data.menu[i]; |
| 311 createCallback_(menu, null, entry.label, entry.command); | 311 createCallback_(menu, null, entry.label, entry.command); |
| 312 } | 312 } |
| 313 return menu; | 313 return menu; |
| 314 } | 314 } |
| 315 return null; | 315 return null; |
| 316 }, | 316 }, |
| 317 | 317 |
| 318 canUpdateMenu: function() { | 318 canUpdateMenu: function() { |
| 319 return false; | 319 return false; |
| 320 }, | 320 }, |
| 321 | 321 |
| 322 /** | 322 /** |
| 323 * Displays a popup menu. | 323 * Displays a popup menu. |
| 324 */ | 324 */ |
| 325 showMenu: function() { | 325 showMenu: function() { |
| 326 var rebuild = false; | 326 var rebuild = false; |
| 327 // Force a rescan if opening the menu for WiFi networks to ensure the | 327 // Force a rescan if opening the menu for WiFi networks to ensure the |
| 328 // list is up to date. Networks are periodically rescanned, but depending | 328 // list is up to date. Networks are periodically rescanned, but depending |
| 329 // on timing, there could be an excessive delay before the first rescan | 329 // on timing, there could be an excessive delay before the first rescan |
| 330 // unless forced. | 330 // unless forced. |
| 331 var rescan = !activeMenu_ && this.data_.key == 'wifi'; | 331 var rescan = !activeMenu_ && this.data_.key == 'wifi'; |
| 332 if (!this.menu_) { | 332 if (!this.menu_) { |
| 333 rebuild = true; | 333 rebuild = true; |
| 334 var existing = $(this.getMenuName_()); | 334 var existing = $(this.getMenuName()); |
| 335 if (existing) { | 335 if (existing) { |
| 336 if (this.updateMenu()) | 336 if (this.updateMenu()) |
| 337 return; | 337 return; |
| 338 closeMenu_(); | 338 closeMenu_(); |
| 339 } | 339 } |
| 340 this.menu_ = this.createMenu(); | 340 this.menu_ = this.createMenu(); |
| 341 this.menu_.addEventListener('mousedown', function(e) { | 341 this.menu_.addEventListener('mousedown', function(e) { |
| 342 // Prevent blurring of list, which would close the menu. | 342 // Prevent blurring of list, which would close the menu. |
| 343 e.preventDefault(); | 343 e.preventDefault(); |
| 344 }, true); | 344 }); |
| 345 var parent = $('network-menus'); | 345 var parent = $('network-menus'); |
| 346 if (existing) | 346 if (existing) |
| 347 parent.replaceChild(this.menu_, existing); | 347 parent.replaceChild(this.menu_, existing); |
| 348 else | 348 else |
| 349 parent.appendChild(this.menu_); | 349 parent.appendChild(this.menu_); |
| 350 } | 350 } |
| 351 var top = this.offsetTop + this.clientHeight; | 351 var top = this.offsetTop + this.clientHeight; |
| 352 var menuId = this.getMenuName_(); | 352 var menuId = this.getMenuName(); |
| 353 if (menuId != activeMenu_ || rebuild) { | 353 if (menuId != activeMenu_ || rebuild) { |
| 354 closeMenu_(); | 354 closeMenu_(); |
| 355 activeMenu_ = menuId; | 355 activeMenu_ = menuId; |
| 356 this.menu_.style.setProperty('top', top + 'px'); | 356 this.menu_.style.setProperty('top', top + 'px'); |
| 357 this.menu_.hidden = false; | 357 this.menu_.hidden = false; |
| 358 } | 358 } |
| 359 if (rescan) | 359 if (rescan) |
| 360 chrome.send('refreshNetworks'); | 360 chrome.send('refreshNetworks'); |
| 361 }, | 361 }, |
| 362 }; | 362 }; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 if (candidateURL) | 407 if (candidateURL) |
| 408 this.iconURL = candidateURL; | 408 this.iconURL = candidateURL; |
| 409 else | 409 else |
| 410 this.iconType = this.data.key; | 410 this.iconType = this.data.key; |
| 411 | 411 |
| 412 this.showSelector(); | 412 this.showSelector(); |
| 413 | 413 |
| 414 if (policyManaged) | 414 if (policyManaged) |
| 415 this.showManagedNetworkIndicator(); | 415 this.showManagedNetworkIndicator(); |
| 416 | 416 |
| 417 if (activeMenu_ == this.getMenuName_()) { | 417 if (activeMenu_ == this.getMenuName()) { |
| 418 // Menu is already showing and needs to be updated. Explicitly calling | 418 // Menu is already showing and needs to be updated. Explicitly calling |
| 419 // show menu will force the existing menu to be replaced. The call | 419 // show menu will force the existing menu to be replaced. The call |
| 420 // is deferred in order to ensure that position of this element has | 420 // is deferred in order to ensure that position of this element has |
| 421 // beem properly updated. | 421 // beem properly updated. |
| 422 var self = this; | 422 var self = this; |
| 423 setTimeout(function() {self.showMenu();}, 0); | 423 setTimeout(function() {self.showMenu();}, 0); |
| 424 } | 424 } |
| 425 }, | 425 }, |
| 426 | 426 |
| 427 /** | 427 /** |
| 428 * Creates a menu for selecting, configuring or disconnecting from a | 428 * Creates a menu for selecting, configuring or disconnecting from a |
| 429 * network. | 429 * network. |
| 430 * @return {Element} The newly created menu. | 430 * @return {Element} The newly created menu. |
| 431 */ | 431 */ |
| 432 createMenu: function() { | 432 createMenu: function() { |
| 433 var menu = this.ownerDocument.createElement('div'); | 433 var menu = this.ownerDocument.createElement('div'); |
| 434 menu.id = this.getMenuName_(); | 434 menu.id = this.getMenuName(); |
| 435 menu.className = 'network-menu'; | 435 menu.className = 'network-menu'; |
| 436 menu.hidden = true; | 436 menu.hidden = true; |
| 437 Menu.decorate(menu); | 437 Menu.decorate(menu); |
| 438 var addendum = []; | 438 var addendum = []; |
| 439 if (this.data_.key == 'wifi') { | 439 if (this.data_.key == 'wifi') { |
| 440 addendum.push({label: loadTimeData.getString('joinOtherNetwork'), | 440 addendum.push({label: loadTimeData.getString('joinOtherNetwork'), |
| 441 command: 'add', | 441 command: 'add', |
| 442 data: {networkType: Constants.TYPE_WIFI, | 442 data: {networkType: Constants.TYPE_WIFI, |
| 443 servicePath: ''}}); | 443 servicePath: ''}}); |
| 444 } else if (this.data_.key == 'cellular') { | 444 } else if (this.data_.key == 'cellular') { |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 return menu; | 557 return menu; |
| 558 }, | 558 }, |
| 559 | 559 |
| 560 /** | 560 /** |
| 561 * Determines if a menu can be updated on the fly. Menus that cannot be | 561 * Determines if a menu can be updated on the fly. Menus that cannot be |
| 562 * updated are fully regenerated using createMenu. The advantage of | 562 * updated are fully regenerated using createMenu. The advantage of |
| 563 * updating a menu is that it can preserve ordering of networks avoiding | 563 * updating a menu is that it can preserve ordering of networks avoiding |
| 564 * entries from jumping around after an update. | 564 * entries from jumping around after an update. |
| 565 */ | 565 */ |
| 566 canUpdateMenu: function() { | 566 canUpdateMenu: function() { |
| 567 return this.data_.key == 'wifi' && activeMenu_ == this.getMenuName_(); | 567 return this.data_.key == 'wifi' && activeMenu_ == this.getMenuName(); |
| 568 }, | 568 }, |
| 569 | 569 |
| 570 /** | 570 /** |
| 571 * Updates an existing menu. Updated menus preserve ordering of prior | 571 * Updates an existing menu. Updated menus preserve ordering of prior |
| 572 * entries. During the update process, the ordering may differ from the | 572 * entries. During the update process, the ordering may differ from the |
| 573 * preferred ordering as determined by the network library. If the | 573 * preferred ordering as determined by the network library. If the |
| 574 * ordering becomes potentially out of sync, then the updated menu is | 574 * ordering becomes potentially out of sync, then the updated menu is |
| 575 * marked for disposal on close. Reopening the menu will force a | 575 * marked for disposal on close. Reopening the menu will force a |
| 576 * regeneration, which will in turn fix the ordering. | 576 * regeneration, which will in turn fix the ordering. |
| 577 * @return {boolean} True if successfully updated. | 577 * @return {boolean} True if successfully updated. |
| 578 */ | 578 */ |
| 579 updateMenu: function() { | 579 updateMenu: function() { |
| 580 if (!this.canUpdateMenu()) | 580 if (!this.canUpdateMenu()) |
| 581 return false; | 581 return false; |
| 582 var oldMenu = $(this.getMenuName_()); | 582 var oldMenu = $(this.getMenuName()); |
| 583 var group = oldMenu.getElementsByClassName('network-menu-group')[0]; | 583 var group = oldMenu.getElementsByClassName('network-menu-group')[0]; |
| 584 if (!group) | 584 if (!group) |
| 585 return false; | 585 return false; |
| 586 var newMenu = this.createMenu(); | 586 var newMenu = this.createMenu(); |
| 587 var discardOnClose = false; | 587 var discardOnClose = false; |
| 588 var oldNetworkButtons = this.extractNetworkConnectButtons_(oldMenu); | 588 var oldNetworkButtons = this.extractNetworkConnectButtons_(oldMenu); |
| 589 var newNetworkButtons = this.extractNetworkConnectButtons_(newMenu); | 589 var newNetworkButtons = this.extractNetworkConnectButtons_(newMenu); |
| 590 for (var key in oldNetworkButtons) { | 590 for (var key in oldNetworkButtons) { |
| 591 if (newNetworkButtons[key]) { | 591 if (newNetworkButtons[key]) { |
| 592 group.replaceChild(newNetworkButtons[key].button, | 592 group.replaceChild(newNetworkButtons[key].button, |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 var NetworkList = cr.ui.define('list'); | 750 var NetworkList = cr.ui.define('list'); |
| 751 | 751 |
| 752 NetworkList.prototype = { | 752 NetworkList.prototype = { |
| 753 __proto__: List.prototype, | 753 __proto__: List.prototype, |
| 754 | 754 |
| 755 /** @inheritDoc */ | 755 /** @inheritDoc */ |
| 756 decorate: function() { | 756 decorate: function() { |
| 757 List.prototype.decorate.call(this); | 757 List.prototype.decorate.call(this); |
| 758 this.startBatchUpdates(); | 758 this.startBatchUpdates(); |
| 759 this.autoExpands = true; | 759 this.autoExpands = true; |
| 760 this.addEventListener('blur', this.onBlur_); | |
| 761 this.dataModel = new ArrayDataModel([]); | 760 this.dataModel = new ArrayDataModel([]); |
| 761 this.selectionModel = new ListSingleSelectionModel(); |
| 762 this.addEventListener('blur', this.onBlur_.bind(this)); |
| 763 this.selectionModel.addEventListener('change', |
| 764 this.onSelectionChange_.bind(this)); |
| 762 | 765 |
| 763 // Wi-Fi control is always visible. | 766 // Wi-Fi control is always visible. |
| 764 this.update({key: 'wifi', networkList: []}); | 767 this.update({key: 'wifi', networkList: []}); |
| 765 | 768 |
| 766 if (airplaneModeAvailable_()) { | 769 if (airplaneModeAvailable_()) { |
| 767 this.update({key: 'airplaneMode', | 770 this.update({key: 'airplaneMode', |
| 768 subtitle: loadTimeData.getString('airplaneModeLabel'), | 771 subtitle: loadTimeData.getString('airplaneModeLabel'), |
| 769 command: function() { | 772 command: function() { |
| 770 chrome.send('toggleAirplaneMode'); | 773 chrome.send('toggleAirplaneMode'); |
| 771 }}); | 774 }}); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 796 * When the list loses focus, unselect all items in the list and close the | 799 * When the list loses focus, unselect all items in the list and close the |
| 797 * active menu. | 800 * active menu. |
| 798 * @private | 801 * @private |
| 799 */ | 802 */ |
| 800 onBlur_: function() { | 803 onBlur_: function() { |
| 801 this.selectionModel.unselectAll(); | 804 this.selectionModel.unselectAll(); |
| 802 closeMenu_(); | 805 closeMenu_(); |
| 803 }, | 806 }, |
| 804 | 807 |
| 805 /** | 808 /** |
| 809 * Close bubble and menu when a different list item is selected. |
| 810 * @param {Event} event Event detailing the selection change. |
| 811 * @private |
| 812 */ |
| 813 onSelectionChange_: function(event) { |
| 814 OptionsPage.hideBubble(); |
| 815 // A list item may temporarily become unselected while it is constructing |
| 816 // its menu. The menu should therefore only be closed if a different item |
| 817 // is selected, not when the menu's owner item is deselected. |
| 818 if (activeMenu_) { |
| 819 for (var i = 0; i < event.changes.length; ++i) { |
| 820 if (event.changes[i].selected) { |
| 821 var item = this.dataModel.item(event.changes[i].index); |
| 822 if (!item.getMenuName || item.getMenuName() != activeMenu_) { |
| 823 closeMenu_(); |
| 824 return; |
| 825 } |
| 826 } |
| 827 } |
| 828 } |
| 829 }, |
| 830 |
| 831 /** |
| 806 * Finds the index of a network item within the data model based on | 832 * Finds the index of a network item within the data model based on |
| 807 * category. | 833 * category. |
| 808 * @param {string} key Unique key for the item in the list. | 834 * @param {string} key Unique key for the item in the list. |
| 809 * @return {number} The index of the network item, or |undefined| if it is | 835 * @return {number} The index of the network item, or |undefined| if it is |
| 810 * not found. | 836 * not found. |
| 811 */ | 837 */ |
| 812 indexOf: function(key) { | 838 indexOf: function(key) { |
| 813 var size = this.dataModel.length; | 839 var size = this.dataModel.length; |
| 814 for (var i = 0; i < size; i++) { | 840 for (var i = 0; i < size; i++) { |
| 815 var entry = this.dataModel.item(i); | 841 var entry = this.dataModel.item(i); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 984 networkList.deleteItem('vpn'); | 1010 networkList.deleteItem('vpn'); |
| 985 networkList.updateToggleControl('airplaneMode', data.airplaneMode); | 1011 networkList.updateToggleControl('airplaneMode', data.airplaneMode); |
| 986 networkList.endBatchUpdates(); | 1012 networkList.endBatchUpdates(); |
| 987 }; | 1013 }; |
| 988 | 1014 |
| 989 /** | 1015 /** |
| 990 * Element for indicating a policy managed network. | 1016 * Element for indicating a policy managed network. |
| 991 * @constructor | 1017 * @constructor |
| 992 */ | 1018 */ |
| 993 function ManagedNetworkIndicator() { | 1019 function ManagedNetworkIndicator() { |
| 994 var el = cr.doc.createElement('div'); | 1020 var el = cr.doc.createElement('span'); |
| 995 el.__proto__ = ManagedNetworkIndicator.prototype; | 1021 el.__proto__ = ManagedNetworkIndicator.prototype; |
| 996 el.decorate(); | 1022 el.decorate(); |
| 997 return el; | 1023 return el; |
| 998 } | 1024 } |
| 999 | 1025 |
| 1000 ManagedNetworkIndicator.prototype = { | 1026 ManagedNetworkIndicator.prototype = { |
| 1001 __proto__: ControlledSettingIndicator.prototype, | 1027 __proto__: ControlledSettingIndicator.prototype, |
| 1002 | 1028 |
| 1003 /** @inheritDoc */ | 1029 /** @inheritDoc */ |
| 1004 decorate: function() { | 1030 decorate: function() { |
| 1005 ControlledSettingIndicator.prototype.decorate.call(this); | 1031 ControlledSettingIndicator.prototype.decorate.call(this); |
| 1006 this.controlledBy = 'policy'; | 1032 this.controlledBy = 'policy'; |
| 1007 var policyLabel = loadTimeData.getString('managedNetwork'); | 1033 var policyLabel = loadTimeData.getString('managedNetwork'); |
| 1008 this.setAttribute('textPolicy', policyLabel); | 1034 this.setAttribute('textPolicy', policyLabel); |
| 1009 this.className = 'controlled-setting-indicator'; | 1035 this.className = 'controlled-setting-indicator'; |
| 1010 // The default popup clips to the bounds of the list of networks in the | 1036 this.removeAttribute('tabindex'); |
| 1011 // drop-down because it has enforced size constraints with auto- | 1037 }, |
| 1012 // scrolling. Use a tooltip in place of the bubble popup until the | 1038 |
| 1013 // clipping issues are resolved. | 1039 /** @inheritDoc */ |
| 1014 this.setAttribute('title', policyLabel); | 1040 handleEvent: function(event) { |
| 1015 this.addEventListener('click', function(e) { | 1041 // Prevent focus blurring as that would close any currently open menu. |
| 1016 e.preventDefault(); | 1042 if (event.type == 'mousedown') |
| 1017 e.stopPropagation(); | 1043 return; |
| 1018 }); | 1044 ControlledSettingIndicator.prototype.handleEvent.call(this, event); |
| 1019 } | 1045 }, |
| 1046 |
| 1047 /** |
| 1048 * Handle mouse events received by the bubble, preventing focus blurring as |
| 1049 * that would close any currently open menu and propagation to any elements |
| 1050 * located behind the bubble. |
| 1051 * @param {Event} Mouse event. |
| 1052 */ |
| 1053 stopEvent: function(event) { |
| 1054 event.preventDefault(); |
| 1055 event.stopPropagation(); |
| 1056 }, |
| 1057 |
| 1058 /** @inheritDoc */ |
| 1059 toggleBubble_: function() { |
| 1060 if (activeMenu_ && !$(activeMenu_).contains(this)) |
| 1061 closeMenu_(); |
| 1062 ControlledSettingIndicator.prototype.toggleBubble_.call(this); |
| 1063 if (this.isShowingBubble) { |
| 1064 var bubble = OptionsPage.getVisibleBubble(); |
| 1065 bubble.addEventListener('mousedown', this.stopEvent); |
| 1066 bubble.addEventListener('click', this.stopEvent); |
| 1067 } |
| 1068 }, |
| 1020 }; | 1069 }; |
| 1021 | 1070 |
| 1022 /** | 1071 /** |
| 1023 * Updates the list of available networks and their status, filtered by | 1072 * Updates the list of available networks and their status, filtered by |
| 1024 * network type. | 1073 * network type. |
| 1025 * @param {string} category The type of network. | 1074 * @param {string} category The type of network. |
| 1026 * @param {Array} available The list of available networks and their status. | 1075 * @param {Array} available The list of available networks and their status. |
| 1027 * @param {Array} remembered The list of remmebered networks. | 1076 * @param {Array} remembered The list of remmebered networks. |
| 1028 */ | 1077 */ |
| 1029 function loadData_(category, available, remembered) { | 1078 function loadData_(category, available, remembered) { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1115 * Whether the Network list is disabled. Only used for display purpose. | 1164 * Whether the Network list is disabled. Only used for display purpose. |
| 1116 * @type {boolean} | 1165 * @type {boolean} |
| 1117 */ | 1166 */ |
| 1118 cr.defineProperty(NetworkList, 'disabled', cr.PropertyKind.BOOL_ATTR); | 1167 cr.defineProperty(NetworkList, 'disabled', cr.PropertyKind.BOOL_ATTR); |
| 1119 | 1168 |
| 1120 // Export | 1169 // Export |
| 1121 return { | 1170 return { |
| 1122 NetworkList: NetworkList | 1171 NetworkList: NetworkList |
| 1123 }; | 1172 }; |
| 1124 }); | 1173 }); |
| OLD | NEW |