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/settings/settings_action_menu.js

Issue 2402553002: MD Settings: Implementing modal popup/action menus. (Closed)
Patch Set: Fix test breakage caused by compiler suppress hack. Created 4 years, 2 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
(Empty)
1 // Copyright 2016 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.
4
5 Polymer({
6 is: 'settings-action-menu',
7 extends: 'dialog',
8
9 /**
10 * List of all options in this action menu.
11 * @private {?NodeList<!Element>}
12 */
13 options_: null,
14
15 /**
16 * Index of the currently focused item.
17 * @private {number}
18 */
19 focusedIndex_: -1,
20
21 /**
22 * Reference to the bound window's resize listener, such that it can be
23 * removed on detach.
24 * @private {?Function}
25 */
26 onWindowResize_: null,
27
28 hostAttributes: {
29 tabindex: 0,
30 },
31
32 /** override */
33 attached: function() {
34 this.options_ = this.querySelectorAll('.dropdown-item');
35
36 this.onWindowResize_ = function() {
37 if (this.open)
38 this.close();
39 }.bind(this);
40
41 window.addEventListener('resize', this.onWindowResize_);
42 },
43
44 /** override */
45 detached: function() {
46 window.removeEventListener('resize', this.onWindowResize_);
47 },
48
49 /** @override */
50 ready: function() {
51 this.addEventListener('click', function(e) {
Dan Beam 2016/10/14 03:51:13 should this be equivalent to on-tap in some way?
Dan Beam 2016/10/14 03:51:13 can you move these both to: listeners: { 'click
dpapad 2016/10/14 17:39:23 Done.
dpapad 2016/10/14 17:49:09 Changed to tap, even though both seemed to work us
52 if (e.target == this) {
53 this.close();
54 e.stopPropagation();
55 }
56 }.bind(this));
57
58 this.addEventListener('keydown', function(e) {
Dan Beam 2016/10/14 03:51:13 can we use iron-a11y-keys-behavior? behaviors: [P
dpapad 2016/10/14 17:39:23 What is the benefit in doing this? By reading the
59 if (e.key == 'Tab') {
60 this.close();
61 return;
62 }
63
64 if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp')
65 return;
66
67 var nextOption = this.getNextOption_(e.key == 'ArrowDown' ? 1 : - 1);
68 if (nextOption)
69 nextOption.focus();
70
71 e.preventDefault();
72 }.bind(this));
73 },
74
75 /**
76 * @param {number} step -1 for getting previous option (up), 1 for getting
77 * next option (down).
78 * @return {?Element} The next focusable option, taking into account
79 * disabled/hidden attributes, or null if no focusable option exists.
80 * @private
81 */
82 getNextOption_: function(step) {
83 // Using a counter to ensure no infinite loop occurs if all elements are
84 // hidden/disabled.
85 var counter = 0;
86 var nextOption = null;
87 var numOptions = this.options_.length;
88
89 do {
90 this.focusedIndex_ =
91 (numOptions + this.focusedIndex_ + step) % numOptions;
92 nextOption = this.options_[this.focusedIndex_];
93 if (nextOption.disabled || nextOption.hidden)
94 nextOption = null;
95 counter++;
96 } while (!nextOption && counter < numOptions);
97
98 return nextOption;
99 },
100
101 /**
102 * Shows the menu anchored to the given element.
103 * @param {!Element} anchorElement
104 */
105 showAt: function(anchorElement) {
106 var rect = anchorElement.getBoundingClientRect();
107
108 // Ensure that the correct item is focused when the dialog is shown, by
109 // setting the 'autofocus' attribute.
110 this.focusedIndex_ = -1;
111 var nextOption = this.getNextOption_(1);
112
113 /** @suppress {checkTypes} */
114 (function() {
115 for (var option of this.options_)
116 option.removeAttribute('autofocus');
117 }.bind(this))();
Dan Beam 2016/10/14 03:51:13 why can't you just use NodeList#forEach? https://d
dpapad 2016/10/14 17:39:23 Because compiler..... (ERROR) Error in: settings_a
118
119 if (nextOption !== null)
Dan Beam 2016/10/14 03:51:13 if (nextOption)
dpapad 2016/10/14 17:39:23 Done.
120 nextOption.setAttribute('autofocus', true);
121
122 this.showModal();
123
124 if (new settings.DirectionDelegateImpl().isRtl()) {
125 var right = window.innerWidth - rect.left - this.offsetWidth;
126 this.style.right = right + 'px';
127 } else {
128 var left = rect.right - this.offsetWidth;
129 this.style.left = left + 'px';
130 }
131
132 // Attempt to show the menu starting from the top of the rectangle and
133 // extending downwards. If that does not fit within the window, fallback to
134 // starting from the bottom and extending upwards.
135 var top = rect.top + this.offsetHeight <= window.innerHeight ?
136 rect.top :
137 rect.bottom - this.offsetHeight - Math.max(
138 rect.bottom - window.innerHeight, 0);
139
140 this.style.top = top + 'px';
141 },
142 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698