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

Side by Side Diff: chrome/browser/resources/settings/settings_action_menu.js

Issue 2402553002: MD Settings: Implementing modal popup/action menus. (Closed)
Patch Set: Remove recursion. 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) {
52 if (e.target == this) {
53 this.close();
54 e.stopPropagation();
55 }
56 }.bind(this));
57
58 this.addEventListener('keydown', function(e) {
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 {?HTMLElement} 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 // Storing the focused index before searching, to avoid infinite loop if all
84 // options are disabled.
85 var previousFocusedIndex = Math.max(this.focusedIndex_, 0);
86
87 var nextOption = null;
88 do {
89 // Advance index.
90 var numOptions = this.options_.length;
91 this.focusedIndex_ =
92 (numOptions + this.focusedIndex_ + step) % numOptions;
93
94 // Adjust index in case item is disabled/hidden.
95 nextOption = this.options_[this.focusedIndex_];
96 } while ((!nextOption || nextOption.disabled || nextOption.hidden) &&
97 this.focusedIndex_ != previousFocusedIndex);
98
99 return previousFocusedIndex != this.focusedIndex_ ? nextOption : null;
100 },
101
102 /**
103 * Shows the menu anchored to the given element.
104 * @param {!Element} anchorElement
105 */
106 showAtLocation: function(anchorElement) {
Dan Beam 2016/10/13 19:02:50 ah, nevermind can we just rename this to show() o
dpapad 2016/10/13 19:17:41 Renamed to showAt().
107 var rect = anchorElement.getBoundingClientRect();
108
109 // Ensure that the correct item is focused when the dialog is shown, by
110 // setting the 'autofocus' attribute.
111 this.focusedIndex_ = -1;
112 var nextOption = this.getNextOption_(1);
113 var nextOption = this.options_[this.focusedIndex_];
114 for (var option of this.options_)
115 option.removeAttribute('autofocus');
116 if (nextOption !== null)
117 nextOption.setAttribute('autofocus', true);
118
119 this.showModal();
120
121 if (new settings.DirectionDelegateImpl().isRtl()) {
122 var right = window.innerWidth - rect.left - this.offsetWidth;
123 this.style.right = right + 'px';
124 } else {
125 var left = rect.right - this.offsetWidth;
126 this.style.left = left + 'px';
127 }
128
129 // Attempt to show the menu starting from the top of the rectangle and
130 // extending downwards. If that does not fit within the window, fallback to
131 // starting from the bottom and extending upwards.
132 var top = rect.top + this.offsetHeight <= window.innerHeight ?
133 rect.top :
134 rect.bottom - this.offsetHeight - Math.max(
135 rect.bottom - window.innerHeight, 0);
136
137 this.style.top = top + 'px';
138 },
139 });
OLDNEW
« no previous file with comments | « chrome/browser/resources/settings/settings_action_menu.html ('k') | chrome/browser/resources/settings/settings_resources.grd » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698