@@ -117,11 +117,10 @@ export class ConnectedPositionStrategy implements PositionStrategy {
117
117
// (top, left) coordinate for the overlay at `pos`.
118
118
let originPoint = this . _getOriginConnectionPoint ( originRect , pos ) ;
119
119
let overlayPoint = this . _getOverlayPoint ( originPoint , overlayRect , viewportRect , pos ) ;
120
- let overlayDimensions = this . _getCSSDimensions ( overlayRect , overlayPoint , pos ) ;
121
120
122
121
// If the overlay in the calculated position fits on-screen, put it there and we're done.
123
122
if ( overlayPoint . fitsInViewport ) {
124
- this . _setElementPosition ( element , overlayDimensions ) ;
123
+ this . _setElementPosition ( element , overlayRect , overlayPoint , pos ) ;
125
124
126
125
// Save the last connected position in case the position needs to be re-calculated.
127
126
this . _lastConnectedPosition = pos ;
@@ -140,8 +139,7 @@ export class ConnectedPositionStrategy implements PositionStrategy {
140
139
141
140
// If none of the preferred positions were in the viewport, take the one
142
141
// with the largest visible area.
143
- let fallbackDimensions = this . _getCSSDimensions ( overlayRect , fallbackPoint , fallbackPosition ) ;
144
- this . _setElementPosition ( element , fallbackDimensions ) ;
142
+ this . _setElementPosition ( element , overlayRect , fallbackPoint , fallbackPosition ) ;
145
143
146
144
return Promise . resolve ( null ) ;
147
145
}
@@ -159,8 +157,7 @@ export class ConnectedPositionStrategy implements PositionStrategy {
159
157
160
158
let originPoint = this . _getOriginConnectionPoint ( originRect , lastPosition ) ;
161
159
let overlayPoint = this . _getOverlayPoint ( originPoint , overlayRect , viewportRect , lastPosition ) ;
162
- let overlayPosition = this . _getCSSDimensions ( overlayRect , overlayPoint , lastPosition ) ;
163
- this . _setElementPosition ( this . _pane , overlayPosition ) ;
160
+ this . _setElementPosition ( this . _pane , overlayRect , overlayPoint , lastPosition ) ;
164
161
}
165
162
166
163
/**
@@ -304,39 +301,6 @@ export class ConnectedPositionStrategy implements PositionStrategy {
304
301
return { x, y, fitsInViewport, visibleArea} ;
305
302
}
306
303
307
- /**
308
- * Determines which CSS properties to use when positioning the overlay,
309
- * depending on the direction the element would expand in, if extra content
310
- * was added.
311
- */
312
- private _getCSSDimensions ( overlayRect : ClientRect , overlayPoint : Point ,
313
- pos : ConnectionPositionPair ) : CSSDimensionPair {
314
-
315
- const viewport = this . _viewportRuler . getViewportRect ( ) ;
316
- const x : CSSDimension = { property : null , value : null } ;
317
- const y : CSSDimension = { property : pos . overlayY === 'bottom' ? 'bottom' : 'top' , value : null } ;
318
-
319
- if ( this . _dir === 'rtl' ) {
320
- x . property = pos . overlayX === 'end' ? 'left' : 'right' ;
321
- } else {
322
- x . property = pos . overlayX === 'end' ? 'right' : 'left' ;
323
- }
324
-
325
- if ( x . property === 'left' ) {
326
- x . value = overlayPoint . x ;
327
- } else {
328
- x . value = viewport . width - ( overlayPoint . x + overlayRect . width ) ;
329
- }
330
-
331
- if ( y . property === 'top' ) {
332
- y . value = overlayPoint . y ;
333
- } else {
334
- y . value = viewport . height - ( overlayPoint . y + overlayRect . height ) ;
335
- }
336
-
337
- return { x, y} ;
338
- }
339
-
340
304
/**
341
305
* Gets the view properties of the trigger and overlay, including whether they are clipped
342
306
* or completely outside the view of any of the strategy's scrollables.
@@ -385,10 +349,47 @@ export class ConnectedPositionStrategy implements PositionStrategy {
385
349
}
386
350
387
351
/** Physically positions the overlay element to the given coordinate. */
388
- private _setElementPosition ( element : HTMLElement , dimensions : CSSDimensionPair ) {
389
- [ 'top' , 'bottom' , 'left' , 'right' ] . forEach ( prop => element . style [ prop ] = null ) ;
390
- element . style [ dimensions . x . property ] = dimensions . x . value + 'px' ;
391
- element . style [ dimensions . y . property ] = dimensions . y . value + 'px' ;
352
+ private _setElementPosition (
353
+ element : HTMLElement ,
354
+ overlayRect : ClientRect ,
355
+ overlayPoint : Point ,
356
+ pos : ConnectionPositionPair ) {
357
+ const viewport = this . _viewportRuler . getViewportRect ( ) ;
358
+
359
+ // We want to set either `top` or `bottom` based on whether the overlay wants to appear above
360
+ // or below the origin and the direction in which the element will expand.
361
+ let verticalStyleProperty = pos . overlayY === 'bottom' ? 'bottom' : 'top' ;
362
+
363
+ // When using `bottom`, we adjust the y position such that it is the distance
364
+ // from the bottom of the viewport rather than the top.
365
+ let y = verticalStyleProperty === 'top' ?
366
+ overlayPoint . y :
367
+ viewport . height - ( overlayPoint . y + overlayRect . height ) ;
368
+
369
+ // We want to set either `left` or `right` based on whether the overlay wants to appear "before"
370
+ // or "after" the origin, which determines the direction in which the element will expand.
371
+ // For the horizontal axis, the meaning of "before" and "after" change based on whether the
372
+ // page is in RTL or LTR.
373
+ let horizontalStyleProperty : string ;
374
+ if ( this . _dir === 'rtl' ) {
375
+ horizontalStyleProperty = pos . overlayX === 'end' ? 'left' : 'right' ;
376
+ } else {
377
+ horizontalStyleProperty = pos . overlayX === 'end' ? 'right' : 'left' ;
378
+ }
379
+
380
+ // When we're setting `right`, we adjust the x position such that it is the distance
381
+ // from the right edge of the viewport rather than the left edge.
382
+ let x = horizontalStyleProperty === 'left' ?
383
+ overlayPoint . x :
384
+ viewport . width - ( overlayPoint . x + overlayRect . width ) ;
385
+
386
+
387
+ // Reset any existing styles. This is necessary in case the preferred position has
388
+ // changed since the last `apply`.
389
+ [ 'top' , 'bottom' , 'left' , 'right' ] . forEach ( p => element . style [ p ] = null ) ;
390
+
391
+ element . style [ verticalStyleProperty ] = y ;
392
+ element . style [ horizontalStyleProperty ] = x ;
392
393
}
393
394
394
395
/** Returns the bounding positions of the provided element with respect to the viewport. */
@@ -427,15 +428,3 @@ interface OverlayPoint extends Point {
427
428
visibleArea ?: number ;
428
429
fitsInViewport ?: boolean ;
429
430
}
430
-
431
- /** Key-value pair, representing a CSS dimension. */
432
- interface CSSDimension {
433
- property : 'top' | 'bottom' | 'left' | 'right' ;
434
- value : number ;
435
- }
436
-
437
- /** A combination of CSS dimensions for the x and y axis. */
438
- interface CSSDimensionPair {
439
- x : CSSDimension ;
440
- y : CSSDimension ;
441
- }
0 commit comments