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 Menu = cr.ui.Menu; | 10 var Menu = cr.ui.Menu; |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 button.appendChild(buttonLabel); | 309 button.appendChild(buttonLabel); |
310 button.addEventListener('click', entry.command); | 310 button.addEventListener('click', entry.command); |
311 MenuItem.decorate(button); | 311 MenuItem.decorate(button); |
312 menu.appendChild(button); | 312 menu.appendChild(button); |
313 } | 313 } |
314 return menu; | 314 return menu; |
315 } | 315 } |
316 return null; | 316 return null; |
317 }, | 317 }, |
318 | 318 |
| 319 canUpdateMenu: function() { |
| 320 return false; |
| 321 }, |
| 322 |
319 /** | 323 /** |
320 * Displays a popup menu. | 324 * Displays a popup menu. |
321 */ | 325 */ |
322 showMenu: function() { | 326 showMenu: function() { |
323 var rebuild = false; | 327 var rebuild = false; |
324 // Force a rescan if opening the menu for WiFi networks to ensure the | 328 // Force a rescan if opening the menu for WiFi networks to ensure the |
325 // list is up to date. Networks are periodically rescanned, but depending | 329 // list is up to date. Networks are periodically rescanned, but depending |
326 // on timing, there could be an excessive delay before the first rescan | 330 // on timing, there could be an excessive delay before the first rescan |
327 // unless forced. | 331 // unless forced. |
328 var rescan = !activeMenu_ && this.data_.key == 'wifi'; | 332 var rescan = !activeMenu_ && this.data_.key == 'wifi'; |
329 if (!this.menu_) { | 333 if (!this.menu_) { |
330 rebuild = true; | 334 rebuild = true; |
331 var existing = $(this.getMenuName_()); | 335 var existing = $(this.getMenuName_()); |
332 if (existing) | 336 if (existing) { |
| 337 if (this.updateMenu()) |
| 338 return; |
333 closeMenu_(); | 339 closeMenu_(); |
| 340 } |
334 this.menu_ = this.createMenu(); | 341 this.menu_ = this.createMenu(); |
335 this.menu_.addEventListener('mousedown', function(e) { | 342 this.menu_.addEventListener('mousedown', function(e) { |
336 // Prevent blurring of list, which would close the menu. | 343 // Prevent blurring of list, which would close the menu. |
337 e.preventDefault(); | 344 e.preventDefault(); |
338 }, true); | 345 }, true); |
339 var parent = $('network-menus'); | 346 var parent = $('network-menus'); |
340 if (existing) | 347 if (existing) |
341 parent.replaceChild(this.menu_, existing); | 348 parent.replaceChild(this.menu_, existing); |
342 else | 349 else |
343 parent.appendChild(this.menu_); | 350 parent.appendChild(this.menu_); |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
563 } else if (!separator) { | 570 } else if (!separator) { |
564 menu.appendChild(MenuItem.createSeparator()); | 571 menu.appendChild(MenuItem.createSeparator()); |
565 separator = true; | 572 separator = true; |
566 } | 573 } |
567 } | 574 } |
568 } | 575 } |
569 return menu; | 576 return menu; |
570 }, | 577 }, |
571 | 578 |
572 /** | 579 /** |
| 580 * Determines if a menu can be updated on the fly. Menus that cannot be |
| 581 * updated are fully regenerated using createMenu. The advantage of |
| 582 * updating a menu is that it can preserve ordering of networks avoiding |
| 583 * entries from jumping around after an update. |
| 584 */ |
| 585 canUpdateMenu: function() { |
| 586 return this.data_.key == 'wifi' && activeMenu_ == this.getMenuName_(); |
| 587 }, |
| 588 |
| 589 /** |
| 590 * Updates an existing menu. Updated menus preserve ordering of prior |
| 591 * entries. During the update process, the ordering may differ from the |
| 592 * preferred ordering as determined by the network library. If the |
| 593 * ordering becomes potentially out of sync, then the updated menu is |
| 594 * marked for disposal on close. Reopening the menu will force a |
| 595 * regeneration, which will in turn fix the ordering. |
| 596 * @return {boolean} True if successfully updated. |
| 597 */ |
| 598 updateMenu: function() { |
| 599 if (!this.canUpdateMenu()) |
| 600 return false; |
| 601 var oldMenu = $(this.getMenuName_()); |
| 602 var group = oldMenu.getElementsByClassName('network-menu-group')[0]; |
| 603 if (!group) |
| 604 return false; |
| 605 var newMenu = this.createMenu(); |
| 606 var discardOnClose = false; |
| 607 var oldNetworkButtons = this.extractNetworkConnectButtons_(oldMenu); |
| 608 var newNetworkButtons = this.extractNetworkConnectButtons_(newMenu); |
| 609 for (var key in oldNetworkButtons) { |
| 610 if (newNetworkButtons[key]) { |
| 611 group.replaceChild(newNetworkButtons[key].button, |
| 612 oldNetworkButtons[key].button); |
| 613 if (newNetworkButtons[key].index != oldNetworkButtons[key].index) |
| 614 discardOnClose = true; |
| 615 newNetworkButtons[key] = null; |
| 616 } else { |
| 617 // Leave item in list to prevent network items from jumping due to |
| 618 // deletions. |
| 619 oldNetworkButtons[key].disabled = true; |
| 620 discardOnClose = true; |
| 621 } |
| 622 } |
| 623 for (var key in newNetworkButtons) { |
| 624 var entry = newNetworkButtons[key]; |
| 625 if (entry) { |
| 626 group.appendChild(entry.button); |
| 627 discardOnClose = true; |
| 628 } |
| 629 } |
| 630 oldMenu.data = {discardOnClose: discardOnClose}; |
| 631 return true; |
| 632 }, |
| 633 |
| 634 /** |
| 635 * Extracts a mapping of network names to menu element and position. |
| 636 * @param {!Element} menu The menu to process. |
| 637 * @return {Object.<string, Element>} Network mapping. |
| 638 * @private |
| 639 */ |
| 640 extractNetworkConnectButtons_: function(menu) { |
| 641 var group = menu.getElementsByClassName('network-menu-group')[0]; |
| 642 var networkButtons = {}; |
| 643 if (!group) |
| 644 return networkButtons; |
| 645 var buttons = group.getElementsByClassName('network-menu-item'); |
| 646 for (var i = 0; i < buttons.length; i++) { |
| 647 var label = buttons[i].data.label; |
| 648 networkButtons[label] = {index: i, button: buttons[i]}; |
| 649 } |
| 650 return networkButtons; |
| 651 }, |
| 652 |
| 653 /** |
573 * Adds a command to a menu for modifying network settings. | 654 * Adds a command to a menu for modifying network settings. |
574 * @param {!Element} menu Parent menu. | 655 * @param {!Element} menu Parent menu. |
575 * @param {Object} data Description of the network. | 656 * @param {Object} data Description of the network. |
576 * @param {string} label Display name for the menu item. | 657 * @param {string} label Display name for the menu item. |
577 * @param {string|function} command Callback function or name | 658 * @param {string|function} command Callback function or name |
578 * of the command for |networkCommand|. | 659 * of the command for |networkCommand|. |
579 * @return {!Element} The created menu item. | 660 * @return {!Element} The created menu item. |
580 * @private | 661 * @private |
581 */ | 662 */ |
582 createCallback_: function(menu, data, label, command) { | 663 createCallback_: function(menu, data, label, command) { |
(...skipping 15 matching lines...) Expand all Loading... |
598 } else if (command != null) { | 679 } else if (command != null) { |
599 callback = function() { | 680 callback = function() { |
600 command(data); | 681 command(data); |
601 closeMenu_(); | 682 closeMenu_(); |
602 }; | 683 }; |
603 } | 684 } |
604 if (callback != null) | 685 if (callback != null) |
605 button.addEventListener('click', callback); | 686 button.addEventListener('click', callback); |
606 else | 687 else |
607 buttonLabel.classList.add('network-disabled-control'); | 688 buttonLabel.classList.add('network-disabled-control'); |
| 689 |
| 690 button.data = {label: label}; |
608 MenuItem.decorate(button); | 691 MenuItem.decorate(button); |
609 menu.appendChild(button); | 692 menu.appendChild(button); |
610 return button; | 693 return button; |
611 }, | 694 }, |
612 | 695 |
613 /** | 696 /** |
614 * Adds a menu item for connecting to a network. | 697 * Adds a menu item for connecting to a network. |
615 * @param {!Element} menu Parent menu. | 698 * @param {!Element} menu Parent menu. |
616 * @param {Object} data Description of the network. | 699 * @param {Object} data Description of the network. |
617 * @param {string=} opt_connect Optional connection method. | 700 * @param {string=} opt_connect Optional connection method. |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
991 } | 1074 } |
992 $('network-list').update(data); | 1075 $('network-list').update(data); |
993 } | 1076 } |
994 | 1077 |
995 /** | 1078 /** |
996 * Hides the currently visible menu. | 1079 * Hides the currently visible menu. |
997 * @private | 1080 * @private |
998 */ | 1081 */ |
999 function closeMenu_() { | 1082 function closeMenu_() { |
1000 if (activeMenu_) { | 1083 if (activeMenu_) { |
1001 $(activeMenu_).hidden = true; | 1084 var menu = $(activeMenu_); |
| 1085 menu.hidden = true; |
| 1086 if (menu.data && menu.data.discardOnClose) |
| 1087 menu.parentNode.removeChild(menu); |
1002 activeMenu_ = null; | 1088 activeMenu_ = null; |
1003 } | 1089 } |
1004 } | 1090 } |
1005 | 1091 |
1006 /** | 1092 /** |
1007 * Determines if the user is connected to or in the process of connecting to | 1093 * Determines if the user is connected to or in the process of connecting to |
1008 * a wireless network. | 1094 * a wireless network. |
1009 * @param {Array.<Object>} networkList List of networks. | 1095 * @param {Array.<Object>} networkList List of networks. |
1010 * @return {boolean} True if connected or connecting to a network. | 1096 * @return {boolean} True if connected or connecting to a network. |
1011 * @private | 1097 * @private |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1046 * Whether the Network list is disabled. Only used for display purpose. | 1132 * Whether the Network list is disabled. Only used for display purpose. |
1047 * @type {boolean} | 1133 * @type {boolean} |
1048 */ | 1134 */ |
1049 cr.defineProperty(NetworkList, 'disabled', cr.PropertyKind.BOOL_ATTR); | 1135 cr.defineProperty(NetworkList, 'disabled', cr.PropertyKind.BOOL_ATTR); |
1050 | 1136 |
1051 // Export | 1137 // Export |
1052 return { | 1138 return { |
1053 NetworkList: NetworkList | 1139 NetworkList: NetworkList |
1054 }; | 1140 }; |
1055 }); | 1141 }); |
OLD | NEW |