Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: chrome/browser/resources/options/inline_editable_list.js

Issue 819193003: Fix list focus after tab key in chrome://settings/autofillEditAddress page. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add tests. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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', function() { 5 cr.define('options', function() {
6 /** @const */ var DeletableItem = options.DeletableItem; 6 /** @const */ var DeletableItem = options.DeletableItem;
7 /** @const */ var DeletableItemList = options.DeletableItemList; 7 /** @const */ var DeletableItemList = options.DeletableItemList;
8 8
9 /** 9 /**
10 * Creates a new list item with support for inline editing. 10 * Creates a new list item with support for inline editing.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 DeletableItem.prototype.decorate.call(this); 78 DeletableItem.prototype.decorate.call(this);
79 79
80 this.editFields_ = []; 80 this.editFields_ = [];
81 this.addEventListener('mousedown', this.handleMouseDown_); 81 this.addEventListener('mousedown', this.handleMouseDown_);
82 this.addEventListener('keydown', this.handleKeyDown_); 82 this.addEventListener('keydown', this.handleKeyDown_);
83 this.addEventListener('focusin', this.handleFocusIn_); 83 this.addEventListener('focusin', this.handleFocusIn_);
84 }, 84 },
85 85
86 /** @override */ 86 /** @override */
87 selectionChanged: function() { 87 selectionChanged: function() {
88 this.updateEditState(); 88 if (!this.parentNode.eventsDisabled)
89 this.updateEditState();
89 }, 90 },
90 91
91 /** 92 /**
92 * Called when this element gains or loses 'lead' status. Updates editing 93 * Called when this element gains or loses 'lead' status. Updates editing
93 * mode accordingly. 94 * mode accordingly.
94 */ 95 */
95 updateLeadState: function() { 96 updateLeadState: function() {
96 // Add focusability before call to updateEditState. 97 // Add focusability before call to updateEditState.
97 if (this.lead) { 98 if (this.lead) {
98 this.setEditableValuesFocusable(true); 99 this.setEditableValuesFocusable(true);
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 /** 572 /**
572 * @constructor 573 * @constructor
573 * @extends {options.DeletableItemList} 574 * @extends {options.DeletableItemList}
574 */ 575 */
575 var InlineEditableItemList = cr.ui.define('list'); 576 var InlineEditableItemList = cr.ui.define('list');
576 577
577 InlineEditableItemList.prototype = { 578 InlineEditableItemList.prototype = {
578 __proto__: DeletableItemList.prototype, 579 __proto__: DeletableItemList.prototype,
579 580
580 /** 581 /**
582 * Event handling is disabled if > 0.
583 * @type {number}
584 * @private
585 */
586 eventsDisabledCount_: 0,
587
588 /**
581 * Focuses the input element of the placeholder if true. 589 * Focuses the input element of the placeholder if true.
582 * @type {boolean} 590 * @type {boolean}
583 * @private 591 * @private
584 */ 592 */
585 needsToFocusPlaceholder_: false, 593 needsToFocusPlaceholder_: false,
586 594
587 /** @override */ 595 /** @override */
588 decorate: function() { 596 decorate: function() {
589 DeletableItemList.prototype.decorate.call(this); 597 DeletableItemList.prototype.decorate.call(this);
590 this.setAttribute('inlineeditable', ''); 598 this.setAttribute('inlineeditable', '');
591 this.addEventListener('hasElementFocusChange', 599 this.addEventListener('hasElementFocusChange',
592 this.handleListFocusChange_); 600 this.handleListFocusChange_);
593 // <list> isn't focusable by default, but cr.ui.List defaults tabindex to 601 // <list> isn't focusable by default, but cr.ui.List defaults tabindex to
594 // 0 if it's not set. 602 // 0 if it's not set.
595 this.tabIndex = -1; 603 this.tabIndex = -1;
596 }, 604 },
597 605
598 /** 606 /**
607 * Whether events are disabled.
608 * Used to modify the list without triggering a bunch of unnecessary events.
609 * @type {boolean}
610 */
611 get eventsDisabled() {
612 return this.eventsDisabledCount_ > 0;
613 },
614 set eventsDisabled(disabled) {
615 this.eventsDisabledCount_ += disabled ? 1 : -1;
616 },
617
618 /**
599 * Called when the list hierarchy as a whole loses or gains focus; starts 619 * Called when the list hierarchy as a whole loses or gains focus; starts
600 * or ends editing for the lead item if necessary. 620 * or ends editing for the lead item if necessary.
601 * @param {Event} e The change event. 621 * @param {Event} e The change event.
602 * @private 622 * @private
603 */ 623 */
604 handleListFocusChange_: function(e) { 624 handleListFocusChange_: function(e) {
625 if (this.eventsDisabled)
626 return;
627
bondd 2015/01/15 03:04:02 This wasn't necessary.
605 var leadItem = this.getListItemByIndex(this.selectionModel.leadIndex); 628 var leadItem = this.getListItemByIndex(this.selectionModel.leadIndex);
606 if (leadItem) { 629 if (leadItem) {
607 if (e.newValue) { 630 if (e.newValue) {
608 // Add focusability before making other changes. 631 // Add focusability before making other changes.
609 leadItem.setEditableValuesFocusable(true); 632 leadItem.setEditableValuesFocusable(true);
610 leadItem.setCloseButtonFocusable(true); 633 leadItem.setCloseButtonFocusable(true);
611 leadItem.focusedColumnIndex = -1; 634 leadItem.focusedColumnIndex = -1;
612 leadItem.updateEditState(); 635 leadItem.updateEditState();
613 // Remove focusability after making other changes. 636 // Remove focusability after making other changes.
614 leadItem.setStaticValuesFocusable(false); 637 leadItem.setStaticValuesFocusable(false);
615 } else { 638 } else {
616 // Add focusability before making other changes. 639 // Add focusability before making other changes.
617 leadItem.setStaticValuesFocusable(true); 640 leadItem.setStaticValuesFocusable(true);
618 leadItem.setCloseButtonFocusable(true); 641 leadItem.setCloseButtonFocusable(true);
619 leadItem.editing = false; 642 leadItem.editing = false;
620 // Remove focusability after making other changes. 643 // Remove focusability after making other changes.
621 if (!leadItem.isPlaceholder) 644 if (!leadItem.isPlaceholder)
622 leadItem.setEditableValuesFocusable(false); 645 leadItem.setEditableValuesFocusable(false);
623 } 646 }
624 } 647 }
625 }, 648 },
626 649
627 /** @override */ 650 /** @override */
628 handleLeadChange: function(e) { 651 handleLeadChange: function(e) {
652 if (this.eventsDisabled)
653 return;
654
629 DeletableItemList.prototype.handleLeadChange.call(this, e); 655 DeletableItemList.prototype.handleLeadChange.call(this, e);
630 656
631 var focusedColumnIndex = -1; 657 var focusedColumnIndex = -1;
632 if (e.oldValue != -1) { 658 if (e.oldValue != -1) {
633 var element = this.getListItemByIndex(e.oldValue); 659 var element = this.getListItemByIndex(e.oldValue);
634 if (element) { 660 if (element) {
635 focusedColumnIndex = element.focusedColumnIndex; 661 focusedColumnIndex = element.focusedColumnIndex;
636 element.updateLeadState(); 662 element.updateLeadState();
637 } 663 }
638 } 664 }
(...skipping 19 matching lines...) Expand all
658 if (item) { 684 if (item) {
659 item.setStaticValuesFocusable(true); 685 item.setStaticValuesFocusable(true);
660 item.setCloseButtonFocusable(true); 686 item.setCloseButtonFocusable(true);
661 if (item.isPlaceholder) 687 if (item.isPlaceholder)
662 item.setEditableValuesFocusable(true); 688 item.setEditableValuesFocusable(true);
663 } 689 }
664 } 690 }
665 }, 691 },
666 692
667 /** 693 /**
694 * Set the selected index without changing the focused element on the page.
695 * Used to change the selected index when the list doesn't have focus (and
696 * doesn't want to take focus).
697 */
698 setSelectedIndexWithoutFocusing: function(index) {
699 this.eventsDisabled = true;
700 // Remove focusability from old item.
701 var oldItem = this.getListItemByIndex(this.selectionModel.leadIndex) ||
702 this.getInitialFocusableItem();
703 if (oldItem) {
704 oldItem.setEditableValuesFocusable(false);
705 oldItem.setStaticValuesFocusable(false);
706 oldItem.setCloseButtonFocusable(false);
707 oldItem.lead = false;
708 }
709
710 this.selectionModel.selectedIndex = index;
711 // Add focusability to new item.
712 var newItem = this.getListItemByIndex(index);
713 if (newItem) {
714 if (newItem.isPlaceholder)
715 newItem.setEditableValuesFocusable(true);
716 else
717 newItem.setStaticValuesFocusable(true);
718
719 newItem.setCloseButtonFocusable(true);
720 newItem.lead = true;
721 }
722 this.eventsDisabled = false;
723 },
724
725 /**
668 * Focus the placeholder's first input field. 726 * Focus the placeholder's first input field.
669 * Should only be called immediately after the list has been repopulated. 727 * Should only be called immediately after the list has been repopulated.
670 */ 728 */
671 focusPlaceholder: function() { 729 focusPlaceholder: function() {
672 // Remove focusability from initial item. 730 // Remove focusability from initial item.
673 var item = this.getInitialFocusableItem(); 731 var item = this.getInitialFocusableItem();
674 if (item) { 732 if (item) {
675 item.setStaticValuesFocusable(false); 733 item.setStaticValuesFocusable(false);
676 item.setCloseButtonFocusable(false); 734 item.setCloseButtonFocusable(false);
677 } 735 }
(...skipping 29 matching lines...) Expand all
707 this.getListItemByIndex(0)); 765 this.getListItemByIndex(0));
708 }, 766 },
709 }; 767 };
710 768
711 // Export 769 // Export
712 return { 770 return {
713 InlineEditableItem: InlineEditableItem, 771 InlineEditableItem: InlineEditableItem,
714 InlineEditableItemList: InlineEditableItemList, 772 InlineEditableItemList: InlineEditableItemList,
715 }; 773 };
716 }); 774 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698