| 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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 | 69 |
| 70 /** | 70 /** |
| 71 * By default, the dropdown will constrain scrolling on the page | 71 * By default, the dropdown will constrain scrolling on the page |
| 72 * to itself when opened. | 72 * to itself when opened. |
| 73 * Set to true in order to prevent scroll from being constrained | 73 * Set to true in order to prevent scroll from being constrained |
| 74 * to the dropdown when it opens. | 74 * to the dropdown when it opens. |
| 75 */ | 75 */ |
| 76 allowOutsideScroll: { | 76 allowOutsideScroll: { |
| 77 type: Boolean, | 77 type: Boolean, |
| 78 value: false | 78 value: false |
| 79 }, |
| 80 |
| 81 /** |
| 82 * Callback for scroll events. |
| 83 * @type {Function} |
| 84 * @private |
| 85 */ |
| 86 _boundOnCaptureScroll: { |
| 87 type: Function, |
| 88 value: function() { |
| 89 return this._onCaptureScroll.bind(this); |
| 90 } |
| 79 } | 91 } |
| 80 }, | 92 }, |
| 81 | 93 |
| 82 listeners: { | 94 listeners: { |
| 83 'neon-animation-finish': '_onNeonAnimationFinish' | 95 'neon-animation-finish': '_onNeonAnimationFinish' |
| 84 }, | 96 }, |
| 85 | 97 |
| 86 observers: [ | 98 observers: [ |
| 87 '_updateOverlayPosition(positionTarget, verticalAlign, horizontalAlign
, verticalOffset, horizontalOffset)' | 99 '_updateOverlayPosition(positionTarget, verticalAlign, horizontalAlign
, verticalOffset, horizontalOffset)' |
| 88 ], | 100 ], |
| 89 | 101 |
| 90 /** | 102 /** |
| 91 * The element that is contained by the dropdown, if any. | 103 * The element that is contained by the dropdown, if any. |
| 92 */ | 104 */ |
| 93 get containedElement() { | 105 get containedElement() { |
| 94 return Polymer.dom(this.$.content).getDistributedNodes()[0]; | 106 return Polymer.dom(this.$.content).getDistributedNodes()[0]; |
| 95 }, | 107 }, |
| 96 | 108 |
| 97 /** | 109 /** |
| 98 * The element that should be focused when the dropdown opens. | 110 * The element that should be focused when the dropdown opens. |
| 99 * @deprecated | 111 * @deprecated |
| 100 */ | 112 */ |
| 101 get _focusTarget() { | 113 get _focusTarget() { |
| 102 return this.focusTarget || this.containedElement; | 114 return this.focusTarget || this.containedElement; |
| 103 }, | 115 }, |
| 104 | 116 |
| 117 ready: function() { |
| 118 // Memoized scrolling position, used to block scrolling outside. |
| 119 this._scrollTop = 0; |
| 120 this._scrollLeft = 0; |
| 121 // Used to perform a non-blocking refit on scroll. |
| 122 this._refitOnScrollRAF = null; |
| 123 }, |
| 124 |
| 105 detached: function() { | 125 detached: function() { |
| 106 this.cancelAnimation(); | 126 this.cancelAnimation(); |
| 107 Polymer.IronDropdownScrollManager.removeScrollLock(this); | 127 Polymer.IronDropdownScrollManager.removeScrollLock(this); |
| 108 }, | 128 }, |
| 109 | 129 |
| 110 /** | 130 /** |
| 111 * Called when the value of `opened` changes. | 131 * Called when the value of `opened` changes. |
| 112 * Overridden from `IronOverlayBehavior` | 132 * Overridden from `IronOverlayBehavior` |
| 113 */ | 133 */ |
| 114 _openedChanged: function() { | 134 _openedChanged: function() { |
| 115 if (this.opened && this.disabled) { | 135 if (this.opened && this.disabled) { |
| 116 this.cancel(); | 136 this.cancel(); |
| 117 } else { | 137 } else { |
| 118 this.cancelAnimation(); | 138 this.cancelAnimation(); |
| 119 this.sizingTarget = this.containedElement || this.sizingTarget; | 139 this.sizingTarget = this.containedElement || this.sizingTarget; |
| 120 this._updateAnimationConfig(); | 140 this._updateAnimationConfig(); |
| 121 if (this.opened && !this.allowOutsideScroll) { | 141 this._saveScrollPosition(); |
| 122 Polymer.IronDropdownScrollManager.pushScrollLock(this); | 142 if (this.opened) { |
| 143 document.addEventListener('scroll', this._boundOnCaptureScroll); |
| 144 !this.allowOutsideScroll && Polymer.IronDropdownScrollManager.push
ScrollLock(this); |
| 123 } else { | 145 } else { |
| 146 document.removeEventListener('scroll', this._boundOnCaptureScroll)
; |
| 124 Polymer.IronDropdownScrollManager.removeScrollLock(this); | 147 Polymer.IronDropdownScrollManager.removeScrollLock(this); |
| 125 } | 148 } |
| 126 Polymer.IronOverlayBehaviorImpl._openedChanged.apply(this, arguments
); | 149 Polymer.IronOverlayBehaviorImpl._openedChanged.apply(this, arguments
); |
| 127 } | 150 } |
| 128 }, | 151 }, |
| 129 | 152 |
| 130 /** | 153 /** |
| 131 * Overridden from `IronOverlayBehavior`. | 154 * Overridden from `IronOverlayBehavior`. |
| 132 */ | 155 */ |
| 133 _renderOpened: function() { | 156 _renderOpened: function() { |
| 134 if (!this.noAnimations && this.animationConfig.open) { | 157 if (!this.noAnimations && this.animationConfig.open) { |
| 135 this.$.contentWrapper.classList.add('animating'); | 158 this.$.contentWrapper.classList.add('animating'); |
| 136 this.playAnimation('open'); | 159 this.playAnimation('open'); |
| 137 } else { | 160 } else { |
| 138 Polymer.IronOverlayBehaviorImpl._renderOpened.apply(this, arguments)
; | 161 Polymer.IronOverlayBehaviorImpl._renderOpened.apply(this, arguments)
; |
| 139 } | 162 } |
| 140 }, | 163 }, |
| 141 | 164 |
| 142 /** | 165 /** |
| 143 * Overridden from `IronOverlayBehavior`. | 166 * Overridden from `IronOverlayBehavior`. |
| 144 */ | 167 */ |
| 145 _renderClosed: function() { | 168 _renderClosed: function() { |
| 169 |
| 146 if (!this.noAnimations && this.animationConfig.close) { | 170 if (!this.noAnimations && this.animationConfig.close) { |
| 147 this.$.contentWrapper.classList.add('animating'); | 171 this.$.contentWrapper.classList.add('animating'); |
| 148 this.playAnimation('close'); | 172 this.playAnimation('close'); |
| 149 } else { | 173 } else { |
| 150 Polymer.IronOverlayBehaviorImpl._renderClosed.apply(this, arguments)
; | 174 Polymer.IronOverlayBehaviorImpl._renderClosed.apply(this, arguments)
; |
| 151 } | 175 } |
| 152 }, | 176 }, |
| 153 | 177 |
| 154 /** | 178 /** |
| 155 * Called when animation finishes on the dropdown (when opening or | 179 * Called when animation finishes on the dropdown (when opening or |
| 156 * closing). Responsible for "completing" the process of opening or | 180 * closing). Responsible for "completing" the process of opening or |
| 157 * closing the dropdown by positioning it or setting its display to | 181 * closing the dropdown by positioning it or setting its display to |
| 158 * none. | 182 * none. |
| 159 */ | 183 */ |
| 160 _onNeonAnimationFinish: function() { | 184 _onNeonAnimationFinish: function() { |
| 161 this.$.contentWrapper.classList.remove('animating'); | 185 this.$.contentWrapper.classList.remove('animating'); |
| 162 if (this.opened) { | 186 if (this.opened) { |
| 163 this._finishRenderOpened(); | 187 this._finishRenderOpened(); |
| 164 } else { | 188 } else { |
| 165 this._finishRenderClosed(); | 189 this._finishRenderClosed(); |
| 166 } | 190 } |
| 167 }, | 191 }, |
| 168 | 192 |
| 193 _onCaptureScroll: function() { |
| 194 if (!this.allowOutsideScroll) { |
| 195 this._restoreScrollPosition(); |
| 196 } else { |
| 197 this._refitOnScrollRAF && window.cancelAnimationFrame(this._refitOnS
crollRAF); |
| 198 this._refitOnScrollRAF = window.requestAnimationFrame(this.refit.bin
d(this)); |
| 199 } |
| 200 }, |
| 201 |
| 202 /** |
| 203 * Memoizes the scroll position of the outside scrolling element. |
| 204 * @private |
| 205 */ |
| 206 _saveScrollPosition: function() { |
| 207 if (document.scrollingElement) { |
| 208 this._scrollTop = document.scrollingElement.scrollTop; |
| 209 this._scrollLeft = document.scrollingElement.scrollLeft; |
| 210 } else { |
| 211 // Since we don't know if is the body or html, get max. |
| 212 this._scrollTop = Math.max(document.documentElement.scrollTop, docum
ent.body.scrollTop); |
| 213 this._scrollLeft = Math.max(document.documentElement.scrollLeft, doc
ument.body.scrollLeft); |
| 214 } |
| 215 }, |
| 216 |
| 217 /** |
| 218 * Resets the scroll position of the outside scrolling element. |
| 219 * @private |
| 220 */ |
| 221 _restoreScrollPosition: function() { |
| 222 if (document.scrollingElement) { |
| 223 document.scrollingElement.scrollTop = this._scrollTop; |
| 224 document.scrollingElement.scrollLeft = this._scrollLeft; |
| 225 } else { |
| 226 // Since we don't know if is the body or html, set both. |
| 227 document.documentElement.scrollTop = this._scrollTop; |
| 228 document.documentElement.scrollLeft = this._scrollLeft; |
| 229 document.body.scrollTop = this._scrollTop; |
| 230 document.body.scrollLeft = this._scrollLeft; |
| 231 } |
| 232 }, |
| 233 |
| 169 /** | 234 /** |
| 170 * Constructs the final animation config from different properties used | 235 * Constructs the final animation config from different properties used |
| 171 * to configure specific parts of the opening and closing animations. | 236 * to configure specific parts of the opening and closing animations. |
| 172 */ | 237 */ |
| 173 _updateAnimationConfig: function() { | 238 _updateAnimationConfig: function() { |
| 174 var animations = (this.openAnimationConfig || []).concat(this.closeAni
mationConfig || []); | 239 var animations = (this.openAnimationConfig || []).concat(this.closeAni
mationConfig || []); |
| 175 for (var i = 0; i < animations.length; i++) { | 240 for (var i = 0; i < animations.length; i++) { |
| 176 animations[i].node = this.containedElement; | 241 animations[i].node = this.containedElement; |
| 177 } | 242 } |
| 178 this.animationConfig = { | 243 this.animationConfig = { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 198 _applyFocus: function () { | 263 _applyFocus: function () { |
| 199 var focusTarget = this.focusTarget || this.containedElement; | 264 var focusTarget = this.focusTarget || this.containedElement; |
| 200 if (focusTarget && this.opened && !this.noAutoFocus) { | 265 if (focusTarget && this.opened && !this.noAutoFocus) { |
| 201 focusTarget.focus(); | 266 focusTarget.focus(); |
| 202 } else { | 267 } else { |
| 203 Polymer.IronOverlayBehaviorImpl._applyFocus.apply(this, arguments); | 268 Polymer.IronOverlayBehaviorImpl._applyFocus.apply(this, arguments); |
| 204 } | 269 } |
| 205 } | 270 } |
| 206 }); | 271 }); |
| 207 })(); | 272 })(); |
| OLD | NEW |