OLD | NEW |
1 (function() { | 1 (function() { |
2 'use strict'; | 2 'use strict'; |
3 | 3 |
4 Polymer({ | 4 Polymer({ |
5 is: 'iron-dropdown', | 5 is: 'iron-dropdown', |
6 | 6 |
7 behaviors: [ | 7 behaviors: [ |
8 Polymer.IronControlState, | 8 Polymer.IronControlState, |
9 Polymer.IronA11yKeysBehavior, | 9 Polymer.IronA11yKeysBehavior, |
10 Polymer.IronOverlayBehavior, | 10 Polymer.IronOverlayBehavior, |
(...skipping 16 matching lines...) Expand all Loading... |
27 * vertically relative to the dropdown trigger. | 27 * vertically relative to the dropdown trigger. |
28 */ | 28 */ |
29 verticalAlign: { | 29 verticalAlign: { |
30 type: String, | 30 type: String, |
31 value: 'top', | 31 value: 'top', |
32 reflectToAttribute: true | 32 reflectToAttribute: true |
33 }, | 33 }, |
34 | 34 |
35 /** | 35 /** |
36 * A pixel value that will be added to the position calculated for the | 36 * A pixel value that will be added to the position calculated for the |
37 * given `horizontalAlign`. Use a negative value to offset to the | 37 * given `horizontalAlign`, in the direction of alignment. You can thi
nk |
38 * left, or a positive value to offset to the right. | 38 * of it as increasing or decreasing the distance to the side of the |
| 39 * screen given by `horizontalAlign`. |
| 40 * |
| 41 * If `horizontalAlign` is "left", this offset will increase or decrea
se |
| 42 * the distance to the left side of the screen: a negative offset will |
| 43 * move the dropdown to the left; a positive one, to the right. |
| 44 * |
| 45 * Conversely if `horizontalAlign` is "right", this offset will increa
se |
| 46 * or decrease the distance to the right side of the screen: a negativ
e |
| 47 * offset will move the dropdown to the right; a positive one, to the
left. |
39 */ | 48 */ |
40 horizontalOffset: { | 49 horizontalOffset: { |
41 type: Number, | 50 type: Number, |
42 value: 0, | 51 value: 0, |
43 notify: true | 52 notify: true |
44 }, | 53 }, |
45 | 54 |
46 /** | 55 /** |
47 * A pixel value that will be added to the position calculated for the | 56 * A pixel value that will be added to the position calculated for the |
48 * given `verticalAlign`. Use a negative value to offset towards the | 57 * given `verticalAlign`, in the direction of alignment. You can think |
49 * top, or a positive value to offset towards the bottom. | 58 * of it as increasing or decreasing the distance to the side of the |
| 59 * screen given by `verticalAlign`. |
| 60 * |
| 61 * If `verticalAlign` is "top", this offset will increase or decrease |
| 62 * the distance to the top side of the screen: a negative offset will |
| 63 * move the dropdown upwards; a positive one, downwards. |
| 64 * |
| 65 * Conversely if `verticalAlign` is "bottom", this offset will increas
e |
| 66 * or decrease the distance to the bottom side of the screen: a negati
ve |
| 67 * offset will move the dropdown downwards; a positive one, upwards. |
50 */ | 68 */ |
51 verticalOffset: { | 69 verticalOffset: { |
52 type: Number, | 70 type: Number, |
53 value: 0, | 71 value: 0, |
54 notify: true | 72 notify: true |
55 }, | 73 }, |
56 | 74 |
57 /** | 75 /** |
58 * The element that should be used to position the dropdown when | 76 * The element that should be used to position the dropdown when |
59 * it is opened. | 77 * it is opened. |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 }, | 157 }, |
140 | 158 |
141 /** | 159 /** |
142 * The element that should be focused when the dropdown opens. | 160 * The element that should be focused when the dropdown opens. |
143 */ | 161 */ |
144 get _focusTarget() { | 162 get _focusTarget() { |
145 return this.focusTarget || this.containedElement; | 163 return this.focusTarget || this.containedElement; |
146 }, | 164 }, |
147 | 165 |
148 /** | 166 /** |
| 167 * Whether the text direction is RTL |
| 168 */ |
| 169 _isRTL: function() { |
| 170 return window.getComputedStyle(this).direction == 'rtl'; |
| 171 }, |
| 172 |
| 173 /** |
149 * The element that should be used to position the dropdown when | 174 * The element that should be used to position the dropdown when |
150 * it opens, if no position target is configured. | 175 * it opens, if no position target is configured. |
151 */ | 176 */ |
152 get _defaultPositionTarget() { | 177 get _defaultPositionTarget() { |
153 var parent = Polymer.dom(this).parentNode; | 178 var parent = Polymer.dom(this).parentNode; |
154 | 179 |
155 if (parent.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { | 180 if (parent.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { |
156 parent = parent.host; | 181 parent = parent.host; |
157 } | 182 } |
158 | 183 |
(...skipping 10 matching lines...) Expand all Loading... |
169 | 194 |
170 return this._positionRectMemo; | 195 return this._positionRectMemo; |
171 }, | 196 }, |
172 | 197 |
173 /** | 198 /** |
174 * The horizontal offset value used to position the dropdown. | 199 * The horizontal offset value used to position the dropdown. |
175 */ | 200 */ |
176 get _horizontalAlignTargetValue() { | 201 get _horizontalAlignTargetValue() { |
177 var target; | 202 var target; |
178 | 203 |
179 if (this.horizontalAlign === 'right') { | 204 // In RTL, the direction flips, so what is "right" in LTR becomes "lef
t". |
| 205 var isRTL = this._isRTL(); |
| 206 if ((!isRTL && this.horizontalAlign === 'right') || |
| 207 (isRTL && this.horizontalAlign === 'left')) { |
180 target = document.documentElement.clientWidth - this._positionRect.r
ight; | 208 target = document.documentElement.clientWidth - this._positionRect.r
ight; |
181 } else { | 209 } else { |
182 target = this._positionRect.left; | 210 target = this._positionRect.left; |
183 } | 211 } |
184 | 212 |
185 target += this.horizontalOffset; | 213 target += this.horizontalOffset; |
186 | 214 |
187 return Math.max(target, 0); | 215 return Math.max(target, 0); |
188 }, | 216 }, |
189 | 217 |
190 /** | 218 /** |
191 * The vertical offset value used to position the dropdown. | 219 * The vertical offset value used to position the dropdown. |
192 */ | 220 */ |
193 get _verticalAlignTargetValue() { | 221 get _verticalAlignTargetValue() { |
194 var target; | 222 var target; |
195 | 223 |
196 if (this.verticalAlign === 'bottom') { | 224 if (this.verticalAlign === 'bottom') { |
197 target = document.documentElement.clientHeight - this._positionRect.
bottom; | 225 target = document.documentElement.clientHeight - this._positionRect.
bottom; |
198 } else { | 226 } else { |
199 target = this._positionRect.top; | 227 target = this._positionRect.top; |
200 } | 228 } |
201 | 229 |
202 target += this.verticalOffset; | 230 target += this.verticalOffset; |
203 | 231 |
204 return Math.max(target, 0); | 232 return Math.max(target, 0); |
205 }, | 233 }, |
206 | 234 |
207 /** | 235 /** |
| 236 * The horizontal align value, accounting for the RTL/LTR text direction
. |
| 237 */ |
| 238 get _localeHorizontalAlign() { |
| 239 // In RTL, "left" becomes "right". |
| 240 if (this._isRTL()) { |
| 241 return this.horizontalAlign === 'right' ? 'left' : 'right'; |
| 242 } else { |
| 243 return this.horizontalAlign; |
| 244 } |
| 245 }, |
| 246 |
| 247 /** |
208 * Called when the value of `opened` changes. | 248 * Called when the value of `opened` changes. |
209 * | 249 * |
210 * @param {boolean} opened True if the dropdown is opened. | 250 * @param {boolean} opened True if the dropdown is opened. |
211 */ | 251 */ |
212 _openedChanged: function(opened) { | 252 _openedChanged: function(opened) { |
213 if (opened && this.disabled) { | 253 if (opened && this.disabled) { |
214 this.cancel(); | 254 this.cancel(); |
215 } else { | 255 } else { |
216 this.cancelAnimation(); | 256 this.cancelAnimation(); |
217 this._prepareDropdown(); | 257 this._prepareDropdown(); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 * and vertical alignment, and re-memoizes these values for the sake | 385 * and vertical alignment, and re-memoizes these values for the sake |
346 * of behavior in `IronFitBehavior`. | 386 * of behavior in `IronFitBehavior`. |
347 */ | 387 */ |
348 _updateOverlayPosition: function() { | 388 _updateOverlayPosition: function() { |
349 this._positionRectMemo = null; | 389 this._positionRectMemo = null; |
350 | 390 |
351 if (!this.positionTarget) { | 391 if (!this.positionTarget) { |
352 return; | 392 return; |
353 } | 393 } |
354 | 394 |
355 this.style[this.horizontalAlign] = | 395 this.style[this._localeHorizontalAlign] = |
356 this._horizontalAlignTargetValue + 'px'; | 396 this._horizontalAlignTargetValue + 'px'; |
357 | 397 |
358 this.style[this.verticalAlign] = | 398 this.style[this.verticalAlign] = |
359 this._verticalAlignTargetValue + 'px'; | 399 this._verticalAlignTargetValue + 'px'; |
360 | 400 |
361 // NOTE(cdata): We re-memoize inline styles here, otherwise | 401 // NOTE(cdata): We re-memoize inline styles here, otherwise |
362 // calling `refit` from `IronFitBehavior` will reset inline styles | 402 // calling `refit` from `IronFitBehavior` will reset inline styles |
363 // to whatever they were when the dropdown first opened. | 403 // to whatever they were when the dropdown first opened. |
364 if (this._fitInfo) { | 404 if (this._fitInfo) { |
365 this._fitInfo.inlineStyle[this.horizontalAlign] = | 405 this._fitInfo.inlineStyle[this.horizontalAlign] = |
(...skipping 11 matching lines...) Expand all Loading... |
377 // NOTE(cdata): This is async so that it can attempt the focus after | 417 // NOTE(cdata): This is async so that it can attempt the focus after |
378 // `display: none` is removed from the element. | 418 // `display: none` is removed from the element. |
379 this.async(function() { | 419 this.async(function() { |
380 if (this._focusTarget) { | 420 if (this._focusTarget) { |
381 this._focusTarget.focus(); | 421 this._focusTarget.focus(); |
382 } | 422 } |
383 }); | 423 }); |
384 } | 424 } |
385 }); | 425 }); |
386 })(); | 426 })(); |
OLD | NEW |