Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 }); |
| OLD | NEW |