fix(connected-position): error if none of the initial positions fit in viewport (#3189)

Fixes an error in the `recalculateLastPosition` method that gets thrown if none of the element's positions fit inside the viewport.
These changes default to the first preferred position, if there was no previously-matched position.

Relates #3183.
This commit is contained in:
Kristiyan Kostadinov
2017-02-23 01:37:55 +01:00
committed by mmalerba
parent f8fde132bf
commit a306a8e669
2 changed files with 29 additions and 3 deletions
@@ -261,6 +261,32 @@ describe('ConnectedPositionStrategy', () => {
'Expected overlay to be re-aligned to the trigger in the previous position.');
});
it('should default to the initial position, if no positions fit in the viewport', () => {
// Use the fake viewport ruler because we don't know *exactly* how big the viewport is.
fakeViewportRuler.fakeRect = {
top: 0, left: 0, width: 500, height: 500, right: 500, bottom: 500
};
positionBuilder = new OverlayPositionBuilder(fakeViewportRuler);
// Make the origin element taller than the viewport.
originElement.style.height = '1000px';
originElement.style.top = '0';
originRect = originElement.getBoundingClientRect();
strategy = positionBuilder.connectedTo(
fakeElementRef,
{originX: 'start', originY: 'top'},
{overlayX: 'start', overlayY: 'bottom'});
strategy.apply(overlayElement);
strategy.recalculateLastPosition();
let overlayRect = overlayElement.getBoundingClientRect();
expect(overlayRect.bottom).toBe(originRect.top,
'Expected overlay to be re-aligned to the trigger in the initial position.');
});
it('should position a panel properly when rtl', () => {
// must make the overlay longer than the origin to properly test attachment
overlayElement.style.width = `500px`;
@@ -151,10 +151,10 @@ export class ConnectedPositionStrategy implements PositionStrategy {
const originRect = this._origin.getBoundingClientRect();
const overlayRect = this._pane.getBoundingClientRect();
const viewportRect = this._viewportRuler.getViewportRect();
const lastPosition = this._lastConnectedPosition || this._preferredPositions[0];
let originPoint = this._getOriginConnectionPoint(originRect, this._lastConnectedPosition);
let overlayPoint =
this._getOverlayPoint(originPoint, overlayRect, viewportRect, this._lastConnectedPosition);
let originPoint = this._getOriginConnectionPoint(originRect, lastPosition);
let overlayPoint = this._getOverlayPoint(originPoint, overlayRect, viewportRect, lastPosition);
this._setElementPosition(this._pane, overlayPoint);
}