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

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

Issue 2980463002: Revert of [cr-action-menu] Use clientWidth for rtl flipping. (Closed)
Patch Set: Created 3 years, 5 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 /** 5 /**
6 * @typedef {{ 6 * @typedef {{
7 * top: number, 7 * top: number,
8 * left: number, 8 * left: number,
9 * width: (number|undefined), 9 * width: (number|undefined),
10 * height: (number|undefined), 10 * height: (number|undefined),
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 */ 82 */
83 function getDefaultShowConfig() { 83 function getDefaultShowConfig() {
84 var doc = document.scrollingElement; 84 var doc = document.scrollingElement;
85 return { 85 return {
86 top: 0, 86 top: 0,
87 left: 0, 87 left: 0,
88 height: 0, 88 height: 0,
89 width: 0, 89 width: 0,
90 anchorAlignmentX: AnchorAlignment.AFTER_START, 90 anchorAlignmentX: AnchorAlignment.AFTER_START,
91 anchorAlignmentY: AnchorAlignment.AFTER_START, 91 anchorAlignmentY: AnchorAlignment.AFTER_START,
92 minX: 0, 92 minX: doc.scrollLeft,
93 minY: 0, 93 minY: doc.scrollTop,
94 maxX: 0, 94 maxX: doc.scrollLeft + window.innerWidth,
95 maxY: 0, 95 maxY: doc.scrollTop + window.innerHeight,
96 }; 96 };
97 } 97 }
98 98
99 Polymer({ 99 Polymer({
100 is: 'cr-action-menu', 100 is: 'cr-action-menu',
101 extends: 'dialog', 101 extends: 'dialog',
102 102
103 /** 103 /**
104 * The element which the action menu will be anchored to. Also the element 104 * The element which the action menu will be anchored to. Also the element
105 * where focus will be returned after the menu is closed. Only populated if 105 * where focus will be returned after the menu is closed. Only populated if
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 * Shows the menu anchored to the given element. 246 * Shows the menu anchored to the given element.
247 * @param {!Element} anchorElement 247 * @param {!Element} anchorElement
248 * @param {ShowConfig=} opt_config 248 * @param {ShowConfig=} opt_config
249 */ 249 */
250 showAt: function(anchorElement, opt_config) { 250 showAt: function(anchorElement, opt_config) {
251 this.anchorElement_ = anchorElement; 251 this.anchorElement_ = anchorElement;
252 // Scroll the anchor element into view so that the bounding rect will be 252 // Scroll the anchor element into view so that the bounding rect will be
253 // accurate for where the menu should be shown. 253 // accurate for where the menu should be shown.
254 this.anchorElement_.scrollIntoViewIfNeeded(); 254 this.anchorElement_.scrollIntoViewIfNeeded();
255 255
256 // Save the scroll position that ensures the anchor element is onscreen.
257 var doc = document.scrollingElement;
258 var scrollLeft = doc.scrollLeft;
259 var scrollTop = doc.scrollTop;
260
261 // Reset position so that layout isn't affected by the previous position,
262 // and so that the dialog is positioned at the top-start corner of the
263 // document.
264 this.resetStyle_();
265
266 // Show the dialog which will focus the top-start of the body. This makes
267 // the client rect calculation relative to the top-start of the body.
268 this.showModal();
269
256 var rect = this.anchorElement_.getBoundingClientRect(); 270 var rect = this.anchorElement_.getBoundingClientRect();
257 this.showAtPosition(/** @type {ShowConfig} */ (Object.assign( 271 this.positionDialog_(/** @type {ShowConfig} */ (Object.assign(
258 { 272 {
259 top: rect.top, 273 top: rect.top,
260 left: rect.left, 274 left: rect.left,
261 height: rect.height, 275 height: rect.height,
262 width: rect.width, 276 width: rect.width,
263 // Default to anchoring towards the left. 277 // Default to anchoring towards the left.
264 anchorAlignmentX: AnchorAlignment.BEFORE_END, 278 anchorAlignmentX: AnchorAlignment.BEFORE_END,
279 minX: scrollLeft,
280 minY: scrollTop,
281 maxX: scrollLeft + window.innerWidth,
282 maxY: scrollTop + window.innerHeight,
265 }, 283 },
266 opt_config))); 284 opt_config)));
285
286 // Restore the scroll position.
287 doc.scrollTop = scrollTop;
288 doc.scrollLeft = scrollLeft;
289
290 this.addCloseListeners_();
267 }, 291 },
268 292
269 /** 293 /**
270 * Shows the menu anchored to the given box. The anchor alignment is 294 * Shows the menu anchored to the given box. The anchor alignment is
271 * specified as an X and Y alignment which represents a point in the anchor 295 * specified as an X and Y alignment which represents a point in the anchor
272 * where the menu will align to, which can have the menu either before or 296 * where the menu will align to, which can have the menu either before or
273 * after the given point in each axis. Center alignment places the center of 297 * after the given point in each axis. Center alignment places the center of
274 * the menu in line with the center of the anchor. Coordinates are relative to 298 * the menu in line with the center of the anchor.
275 * the top-left of the viewport.
276 * 299 *
277 * y-start 300 * y-start
278 * _____________ 301 * _____________
279 * | | 302 * | |
280 * | | 303 * | |
281 * | CENTER | 304 * | CENTER |
282 * x-start | x | x-end 305 * x-start | x | x-end
283 * | | 306 * | |
284 * |anchor box | 307 * |anchor box |
285 * |___________| 308 * |___________|
286 * 309 *
287 * y-end 310 * y-end
288 * 311 *
289 * For example, aligning the menu to the inside of the top-right edge of 312 * For example, aligning the menu to the inside of the top-right edge of
290 * the anchor, extending towards the bottom-left would use a alignment of 313 * the anchor, extending towards the bottom-left would use a alignment of
291 * (BEFORE_END, AFTER_START), whereas centering the menu below the bottom 314 * (BEFORE_END, AFTER_START), whereas centering the menu below the bottom
292 * edge of the anchor would use (CENTER, AFTER_END). 315 * edge of the anchor would use (CENTER, AFTER_END).
293 * 316 *
294 * @param {!ShowConfig} config 317 * @param {!ShowConfig} config
295 */ 318 */
296 showAtPosition: function(config) { 319 showAtPosition: function(config) {
297 // Save the scroll position of the viewport.
298 var doc = document.scrollingElement;
299 var scrollLeft = doc.scrollLeft;
300 var scrollTop = doc.scrollTop;
301
302 // Reset position so that layout isn't affected by the previous position,
303 // and so that the dialog is positioned at the top-start corner of the
304 // document.
305 this.resetStyle_(); 320 this.resetStyle_();
306 this.showModal(); 321 this.showModal();
307 322 this.positionDialog_(config);
308 config.top += scrollTop;
309 config.left += scrollLeft;
310
311 this.positionDialog_(/** @type {ShowConfig} */ (Object.assign(
312 {
313 minX: scrollLeft,
314 minY: scrollTop,
315 maxX: scrollLeft + doc.clientWidth,
316 maxY: scrollTop + doc.clientHeight,
317 },
318 config)));
319
320 // Restore the scroll position.
321 doc.scrollTop = scrollTop;
322 doc.scrollLeft = scrollLeft;
323 this.addCloseListeners_(); 323 this.addCloseListeners_();
324 }, 324 },
325 325
326 /** @private */ 326 /** @private */
327 resetStyle_: function() { 327 resetStyle_: function() {
328 this.style.left = ''; 328 this.style.left = '';
329 this.style.right = ''; 329 this.style.right = '';
330 this.style.top = '0'; 330 this.style.top = '0';
331 }, 331 },
332 332
333 /** 333 /**
334 * Position the dialog using the coordinates in config. Coordinates are
335 * relative to the top-left of the viewport when scrolled to (0, 0).
336 * @param {!ShowConfig} config 334 * @param {!ShowConfig} config
337 * @private 335 * @private
338 */ 336 */
339 positionDialog_: function(config) { 337 positionDialog_: function(config) {
340 var c = Object.assign(getDefaultShowConfig(), config); 338 var c = Object.assign(getDefaultShowConfig(), config);
341 339
342 var top = c.top; 340 var top = c.top;
343 var left = c.left; 341 var left = c.left;
344 var bottom = top + c.height; 342 var bottom = top + c.height;
345 var right = left + c.width; 343 var right = left + c.width;
346 344
347 // Flip the X anchor in RTL. 345 // Flip the X anchor in RTL.
348 var rtl = getComputedStyle(this).direction == 'rtl'; 346 var rtl = getComputedStyle(this).direction == 'rtl';
349 if (rtl) 347 if (rtl)
350 c.anchorAlignmentX *= -1; 348 c.anchorAlignmentX *= -1;
351 349
352 var menuLeft = getStartPointWithAnchor( 350 var menuLeft = getStartPointWithAnchor(
353 left, right, this.offsetWidth, c.anchorAlignmentX, c.minX, c.maxX); 351 left, right, this.offsetWidth, c.anchorAlignmentX, c.minX, c.maxX);
354 352
355 if (rtl) { 353 if (rtl) {
356 var menuRight = 354 var menuRight = document.body.scrollWidth - menuLeft - this.offsetWidth;
357 document.scrollingElement.clientWidth - menuLeft - this.offsetWidth;
358 this.style.right = menuRight + 'px'; 355 this.style.right = menuRight + 'px';
359 } else { 356 } else {
360 this.style.left = menuLeft + 'px'; 357 this.style.left = menuLeft + 'px';
361 } 358 }
362 359
363 var menuTop = getStartPointWithAnchor( 360 var menuTop = getStartPointWithAnchor(
364 top, bottom, this.offsetHeight, c.anchorAlignmentY, c.minY, c.maxY); 361 top, bottom, this.offsetHeight, c.anchorAlignmentY, c.minY, c.maxY);
365 this.style.top = menuTop + 'px'; 362 this.style.top = menuTop + 'px';
366 }, 363 },
367 364
368 /** 365 /**
369 * @private 366 * @private
370 */ 367 */
371 addCloseListeners_: function() { 368 addCloseListeners_: function() {
372 this.boundClose_ = this.boundClose_ || function() { 369 this.boundClose_ = this.boundClose_ || function() {
373 if (this.open) 370 if (this.open)
374 this.close(); 371 this.close();
375 }.bind(this); 372 }.bind(this);
376 window.addEventListener('resize', this.boundClose_); 373 window.addEventListener('resize', this.boundClose_);
377 window.addEventListener('popstate', this.boundClose_); 374 window.addEventListener('popstate', this.boundClose_);
378 }, 375 },
379 }); 376 });
380 })(); 377 })();
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