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

Side by Side Diff: ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.js

Issue 2814743007: [cr-action-menu] Allow configurable anchors. (Closed)
Patch Set: Created 3 years, 8 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
« no previous file with comments | « chrome/test/data/webui/cr_elements/cr_action_menu_test.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 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 Polymer({ 5 Polymer({
6 is: 'cr-action-menu', 6 is: 'cr-action-menu',
7 extends: 'dialog', 7 extends: 'dialog',
8 8
9 /** 9 /**
10 * List of all options in this action menu. 10 * List of all options in this action menu.
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 } while (!nextOption && counter < numOptions); 144 } while (!nextOption && counter < numOptions);
145 145
146 return nextOption; 146 return nextOption;
147 }, 147 },
148 148
149 /** @override */ 149 /** @override */
150 close: function() { 150 close: function() {
151 // Removing 'resize' and 'popstate' listeners when dialog is closed. 151 // Removing 'resize' and 'popstate' listeners when dialog is closed.
152 this.removeListeners_(); 152 this.removeListeners_();
153 HTMLDialogElement.prototype.close.call(this); 153 HTMLDialogElement.prototype.close.call(this);
154 this.anchorElement_.focus(); 154 if (this.anchorElement_)
155 this.anchorElement_.focus();
156
155 this.anchorElement_ = null; 157 this.anchorElement_ = null;
156 }, 158 },
157 159
158 /** 160 /**
159 * Shows the menu anchored to the given element. 161 * Shows the menu anchored to the given element.
160 * @param {!Element} anchorElement 162 * @param {!Element} anchorElement
161 */ 163 */
162 showAt: function(anchorElement) { 164 showAt: function(anchorElement) {
163 this.anchorElement_ = anchorElement; 165 this.anchorElement_ = anchorElement;
166 var rect = this.anchorElement_.getBoundingClientRect();
167
168 this.showAtPosition({
169 top: rect.top,
170 left: rect.left,
171 height: rect.height,
172 width: rect.width,
173 anchorPositionX: -1,
dpapad 2017/04/12 17:12:32 Please explain this with a comment.
calamity 2017/04/13 04:34:24 Done.
174 });
175 },
176
177 /**
178 * Shows the menu anchored to the given box.
179 * @param {{
180 * top: number,
181 * left: number,
182 * bottom: (number| undefined),
dpapad 2017/04/12 17:12:32 Where is config.bottom and config.right used?
calamity 2017/04/13 04:34:22 Oops, these were supposed to change to width/heigh
183 * right: (number| undefined),
184 * anchorPositionX: (number| undefined),
185 * anchorPositionY: (number| undefined),
186 * minX: (number| undefined),
187 * minY: (number| undefined),
188 * maxX: (number| undefined),
189 * maxY: (number| undefined),
190 * }} config
191 */
dpapad 2017/04/12 17:12:32 Can we make a typedef for this? Such that clients
calamity 2017/04/13 04:34:23 Done.
192 showAtPosition: function(config) {
193 /**
194 * @param {number|undefined} value
195 * @param {number} defaultValue
196 * @return {number}
197 */
198 var defaultIfUndefined =
199 function(value, defaultValue) {
dpapad 2017/04/12 17:12:32 Can fit in previous line?
calamity 2017/04/13 04:34:23 Done.
200 return value == undefined ? defaultValue : value;
201 }
202
203 var top = config.top;
204 var left = config.left;
205 var bottom = top + defaultIfUndefined(config.height, 0);
206 var right = left + defaultIfUndefined(config.width, 0);
207 var anchorPositionX = defaultIfUndefined(config.anchorPositionX, 1);
208 var anchorPositionY = defaultIfUndefined(config.anchorPositionY, 1);
209 var minX = defaultIfUndefined(config.minX, 0);
210 var maxX = defaultIfUndefined(config.maxX, window.innerWidth);
211 var minY = defaultIfUndefined(config.minY, 0);
212 var maxY = defaultIfUndefined(config.maxY, window.innerHeight);
213
164 this.boundClose_ = this.boundClose_ || function() { 214 this.boundClose_ = this.boundClose_ || function() {
165 if (this.open) 215 if (this.open)
166 this.close(); 216 this.close();
167 }.bind(this); 217 }.bind(this);
168 window.addEventListener('resize', this.boundClose_); 218 window.addEventListener('resize', this.boundClose_);
169 window.addEventListener('popstate', this.boundClose_); 219 window.addEventListener('popstate', this.boundClose_);
170 220
171 // Reset position to prevent previous values from affecting layout. 221 // Reset position to prevent previous values from affecting layout.
172 this.style.left = ''; 222 this.style.left = '';
173 this.style.right = ''; 223 this.style.right = '';
174 this.style.top = ''; 224 this.style.top = '';
175 225
176 this.showModal(); 226 this.showModal();
177 227
178 var rect = this.anchorElement_.getBoundingClientRect(); 228 function getStartPointWithAnchor(
dpapad 2017/04/12 17:12:32 @param annotations missing for this function. Also
calamity 2017/04/13 04:34:22 Done.
179 if (getComputedStyle(this.anchorElement_).direction == 'rtl') { 229 start, end, length, anchorPosition, min, max) {
180 var right = window.innerWidth - rect.left - this.offsetWidth; 230 var startPoint = (start + end - length) / 2 +
181 this.style.right = right + 'px'; 231 (start - end + length) * anchorPosition / 2;
182 } else { 232 if (startPoint + length > max)
183 var left = rect.right - this.offsetWidth; 233 startPoint = end - length;
184 this.style.left = left + 'px'; 234 if (startPoint < min)
235 startPoint = start;
236 return startPoint;
185 } 237 }
186 238
187 // Attempt to show the menu starting from the top of the rectangle and 239 // Flip the X anchor in RTL.
dpapad 2017/04/12 17:12:32 Has this logic been preserved in the new code? It
calamity 2017/04/13 04:34:22 Yes, this behavior is what getStartPointWithAnchor
188 // extending downwards. If that does not fit within the window, fallback to 240 var rtl = getComputedStyle(this).direction == 'rtl';
189 // starting from the bottom and extending upwards. 241 if (rtl)
190 var top = rect.top + this.offsetHeight <= window.innerHeight ? rect.top : 242 anchorPositionX *= -1;
191 rect.bottom -
192 this.offsetHeight - Math.max(rect.bottom - window.innerHeight, 0);
193 243
194 this.style.top = top + 'px'; 244 var menuLeft = getStartPointWithAnchor(
245 left, right, this.offsetWidth, anchorPositionX, minX, maxX);
246
247 if (rtl) {
248 var menuRight = window.innerWidth - menuLeft - this.offsetWidth;
249 this.style.right = menuRight + 'px';
250 } else {
251 this.style.left = menuLeft + 'px';
252 }
253
254 var menuTop = getStartPointWithAnchor(
255 top, bottom, this.offsetHeight, anchorPositionY, minY, maxY);
256 this.style.top = menuTop + 'px';
195 }, 257 },
196 }); 258 });
OLDNEW
« no previous file with comments | « chrome/test/data/webui/cr_elements/cr_action_menu_test.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698