@@ -766,6 +766,12 @@ function MdPanelRef(config, $injector) {
766
766
/** @private @const {!angular.$log} */
767
767
this . _$log = $injector . get ( '$log' ) ;
768
768
769
+ /** @private @const {!angular.$window} */
770
+ this . _$window = $injector . get ( '$window' ) ;
771
+
772
+ /** @private @const {!Function} */
773
+ this . _$$rAF = $injector . get ( '$$rAF' ) ;
774
+
769
775
// Public variables.
770
776
/**
771
777
* Unique id for the panelRef.
@@ -1148,22 +1154,32 @@ MdPanelRef.prototype._addStyles = function() {
1148
1154
// correctly. This is necessary so that the panel will have a defined height
1149
1155
// and width.
1150
1156
self . _$rootScope [ '$$postDigest' ] ( function ( ) {
1151
- positionConfig . _calculatePanelPosition ( self . _panelEl ) ;
1152
- self . _panelEl . css ( 'top' , positionConfig . getTop ( ) ) ;
1153
- self . _panelEl . css ( 'bottom' , positionConfig . getBottom ( ) ) ;
1154
- self . _panelEl . css ( 'left' , positionConfig . getLeft ( ) ) ;
1155
- self . _panelEl . css ( 'right' , positionConfig . getRight ( ) ) ;
1156
-
1157
- // Use the vendor prefixed version of transform.
1158
- var prefixedTransform = self . _$mdConstant . CSS . TRANSFORM ;
1159
- self . _panelEl . css ( prefixedTransform , positionConfig . getTransform ( ) ) ;
1160
-
1157
+ self . _updatePosition ( ) ;
1161
1158
resolve ( self ) ;
1162
1159
} ) ;
1163
1160
} ) ;
1164
1161
} ;
1165
1162
1166
1163
1164
+ /**
1165
+ * Calculates and updates the position of the panel.
1166
+ * @private
1167
+ */
1168
+ MdPanelRef . prototype . _updatePosition = function ( ) {
1169
+ var positionConfig = this . _config [ 'position' ] ;
1170
+
1171
+ positionConfig . _calculatePanelPosition ( this . _panelEl ) ;
1172
+ this . _panelEl . css ( 'top' , positionConfig . getTop ( ) ) ;
1173
+ this . _panelEl . css ( 'bottom' , positionConfig . getBottom ( ) ) ;
1174
+ this . _panelEl . css ( 'left' , positionConfig . getLeft ( ) ) ;
1175
+ this . _panelEl . css ( 'right' , positionConfig . getRight ( ) ) ;
1176
+
1177
+ // Use the vendor prefixed version of transform.
1178
+ var prefixedTransform = this . _$mdConstant . CSS . TRANSFORM ;
1179
+ this . _panelEl . css ( prefixedTransform , positionConfig . getTransform ( ) ) ;
1180
+ } ;
1181
+
1182
+
1167
1183
/**
1168
1184
* Focuses on the panel or the first focus target.
1169
1185
* @private
@@ -1221,6 +1237,7 @@ MdPanelRef.prototype._createBackdrop = function() {
1221
1237
MdPanelRef . prototype . _addEventListeners = function ( ) {
1222
1238
this . _configureEscapeToClose ( ) ;
1223
1239
this . _configureClickOutsideToClose ( ) ;
1240
+ this . _configureScrollListener ( ) ;
1224
1241
} ;
1225
1242
1226
1243
@@ -1310,6 +1327,31 @@ MdPanelRef.prototype._configureClickOutsideToClose = function() {
1310
1327
} ;
1311
1328
1312
1329
1330
+ /**
1331
+ * Configures the listeners for updating the panel position on scroll.
1332
+ * @private
1333
+ */
1334
+ MdPanelRef . prototype . _configureScrollListener = function ( ) {
1335
+ var updatePosition = angular . bind ( this , this . _updatePosition ) ;
1336
+ var debouncedUpdatePosition = this . _$$rAF . throttle ( updatePosition ) ;
1337
+ var self = this ;
1338
+
1339
+ var onScroll = function ( ) {
1340
+ if ( ! self . _config [ 'disableParentScroll' ] ) {
1341
+ debouncedUpdatePosition ( ) ;
1342
+ }
1343
+ } ;
1344
+
1345
+ // Add listeners.
1346
+ this . _$window . addEventListener ( 'scroll' , onScroll , true ) ;
1347
+
1348
+ // Queue remove listeners function.
1349
+ this . _removeListeners . push ( function ( ) {
1350
+ self . _$window . removeEventListener ( 'scroll' , onScroll , true ) ;
1351
+ } ) ;
1352
+ } ;
1353
+
1354
+
1313
1355
/**
1314
1356
* Setup the focus traps. These traps will wrap focus when tabbing past the
1315
1357
* panel. When shift-tabbing, the focus will stick in place.
@@ -1460,8 +1502,8 @@ function MdPanelPosition() {
1460
1502
/** @private {boolean} */
1461
1503
this . _absolute = false ;
1462
1504
1463
- /** @private {!DOMRect } */
1464
- this . _relativeToRect ;
1505
+ /** @private {!angular.JQLite } */
1506
+ this . _relativeToEl ;
1465
1507
1466
1508
/** @private {string} */
1467
1509
this . _top = '' ;
@@ -1619,7 +1661,7 @@ MdPanelPosition.prototype.center = function() {
1619
1661
*/
1620
1662
MdPanelPosition . prototype . relativeTo = function ( element ) {
1621
1663
this . _absolute = false ;
1622
- this . _relativeToRect = getElement ( element ) [ 0 ] . getBoundingClientRect ( ) ;
1664
+ this . _relativeToEl = getElement ( element ) ;
1623
1665
return this ;
1624
1666
} ;
1625
1667
@@ -1631,7 +1673,7 @@ MdPanelPosition.prototype.relativeTo = function(element) {
1631
1673
* @returns {MdPanelPosition }
1632
1674
*/
1633
1675
MdPanelPosition . prototype . addPanelPosition = function ( xPosition , yPosition ) {
1634
- if ( ! this . _relativeToRect ) {
1676
+ if ( ! this . _relativeToEl ) {
1635
1677
throw new Error ( 'addPanelPosition can only be used with relative ' +
1636
1678
'positioning. Set relativeTo first.' ) ;
1637
1679
}
@@ -1810,14 +1852,13 @@ MdPanelPosition.prototype._calculatePanelPosition = function(panelEl) {
1810
1852
return ;
1811
1853
}
1812
1854
1813
- // TODO(ErinCoughlan): Update position on scroll.
1814
1855
// TODO(ErinCoughlan): Position panel intelligently to keep it on screen.
1815
1856
1816
1857
var panelBounds = panelEl [ 0 ] . getBoundingClientRect ( ) ;
1817
1858
var panelWidth = panelBounds . width ;
1818
1859
var panelHeight = panelBounds . height ;
1819
1860
1820
- var targetBounds = this . _relativeToRect ;
1861
+ var targetBounds = this . _relativeToEl [ 0 ] . getBoundingClientRect ( ) ;
1821
1862
1822
1863
var targetLeft = targetBounds . left ;
1823
1864
var targetRight = targetBounds . right ;
0 commit comments