Skip to content

Commit

Permalink
fix(overlay): make config immutable for existing refs
Browse files Browse the repository at this point in the history
This changes makes the OverlayConfig instance in OverlatRef immutable.
Calling `getConfig` will now return a clone of the config to make clear
that it cannot be modified directly to change the state of the overlay.
This also updates the `updateSize` method to accept a partial config to
apply to the existing config (and make a new config instance).

This *also* tightens up the typings on Portal.attach

BREAKING CHANGE: OverlayRef.getConfig returns a clone of the config
object.

BREAKING CHANGE: OverlayRef.updateSize now accepts a OverlaySizeConfig
rather than being based on the existing config object.
  • Loading branch information
jelbourn committed Sep 27, 2017
1 parent 0d9f786 commit 3bbbb17
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 33 deletions.
2 changes: 1 addition & 1 deletion src/cdk/overlay/overlay-directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ export class ConnectedOverlayDirective implements OnDestroy, OnChanges {
}

this._position.withDirection(this.dir);
this._overlayRef.getConfig().direction = this.dir;
this._overlayRef.setDirection(this.dir);
this._initEscapeListener();

if (!this._overlayRef.hasAttached()) {
Expand Down
86 changes: 57 additions & 29 deletions src/cdk/overlay/overlay-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@
* found in the LICENSE file at https://angular.io/license
*/

import {NgZone} from '@angular/core';
import {PortalHost, Portal} from '@angular/cdk/portal';
import {OverlayConfig} from './overlay-config';
import {Direction} from '@angular/cdk/bidi';
import {ComponentPortal, Portal, PortalHost, TemplatePortal} from '@angular/cdk/portal';
import {ComponentRef, EmbeddedViewRef, NgZone} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {Subject} from 'rxjs/Subject';
import {OverlayConfig} from './overlay-config';

export type ImmutableObject<T> = {
readonly [P in keyof T]: T[P];
};

/**
* Reference to an overlay that has been created with the Overlay service.
Expand All @@ -26,7 +30,7 @@ export class OverlayRef implements PortalHost {
constructor(
private _portalHost: PortalHost,
private _pane: HTMLElement,
private _config: OverlayConfig,
private _config: ImmutableObject<OverlayConfig>,
private _ngZone: NgZone) {

if (_config.scrollStrategy) {
Expand All @@ -39,8 +43,14 @@ export class OverlayRef implements PortalHost {
return this._pane;
}

attach<T>(portal: ComponentPortal<T>): ComponentRef<T>;
attach<T>(portal: TemplatePortal<T>): EmbeddedViewRef<T>;
attach(portal: any): any;

/**
* Attaches the overlay to a portal instance and adds the backdrop.
* Attaches content, given via a Portal, to the overlay.
* If the overlay is configured to have a backdrop, it will be created.
*
* @param portal Portal instance to which to attach the overlay.
* @returns The portal attachment result.
*/
Expand All @@ -53,8 +63,8 @@ export class OverlayRef implements PortalHost {

// Update the pane element with the given configuration.
this._updateStackingOrder();
this.updateSize();
this.updateDirection();
this._updateElementSize();
this._updateElementDirection();
this.updatePosition();

if (this._config.scrollStrategy) {
Expand Down Expand Up @@ -107,9 +117,7 @@ export class OverlayRef implements PortalHost {
return detachmentResult;
}

/**
* Cleans up the overlay from the DOM.
*/
/** Cleans up the overlay from the DOM. */
dispose(): void {
if (this._config.positionStrategy) {
this._config.positionStrategy.dispose();
Expand All @@ -127,34 +135,29 @@ export class OverlayRef implements PortalHost {
this._detachments.complete();
}

/**
* Checks whether the overlay has been attached.
*/
/** Whether the overlay has attached content. */
hasAttached(): boolean {
return this._portalHost.hasAttached();
}

/**
* Returns an observable that emits when the backdrop has been clicked.
*/
/** Gets an observable that emits when the backdrop has been clicked. */
backdropClick(): Observable<void> {
return this._backdropClick.asObservable();
}

/** Returns an observable that emits when the overlay has been attached. */
/** Gets an observable that emits when the overlay has been attached. */
attachments(): Observable<void> {
return this._attachments.asObservable();
}

/** Returns an observable that emits when the overlay has been detached. */
/** Gets an observable that emits when the overlay has been detached. */
detachments(): Observable<void> {
return this._detachments.asObservable();
}

/**
* Gets the current config of the overlay.
*/
getConfig(): OverlayConfig {
/** Gets the the current overlay configuration, which is immutable. */
getConfig(): ImmutableObject<OverlayConfig> {
// Clone the config so that it cannot be modified outside of this class.
return this._config;
}

Expand All @@ -165,13 +168,25 @@ export class OverlayRef implements PortalHost {
}
}

/** Update the size properties of the overlay. */
updateSize(sizeConfig: OverlaySizeConfig) {
this._config = {...this._config, ...sizeConfig};
this._updateElementSize();
}

/** Sets the LTR/RTL direction for the overlay. */
setDirection(dir: Direction) {
this._config = {...this._config, direction: dir};
this._updateElementDirection();
}

/** Updates the text direction of the overlay panel. */
private updateDirection() {
private _updateElementDirection() {
this._pane.setAttribute('dir', this._config.direction!);
}

/** Updates the size of the overlay based on the overlay config. */
updateSize() {
/** Updates the size of the overlay element based on the overlay config. */
private _updateElementSize() {
if (this._config.width || this._config.width === 0) {
this._pane.style.width = formatCssUnit(this._config.width);
}
Expand Down Expand Up @@ -220,10 +235,12 @@ export class OverlayRef implements PortalHost {
this._backdropElement.addEventListener('click', () => this._backdropClick.next(null));

// Add class to fade-in the backdrop after one frame.
requestAnimationFrame(() => {
if (this._backdropElement) {
this._backdropElement.classList.add('cdk-overlay-backdrop-showing');
}
this._ngZone.runOutsideAngular(() => {
requestAnimationFrame(() => {
if (this._backdropElement) {
this._backdropElement.classList.add('cdk-overlay-backdrop-showing');
}
});
});
}

Expand Down Expand Up @@ -284,3 +301,14 @@ export class OverlayRef implements PortalHost {
function formatCssUnit(value: number | string) {
return typeof value === 'string' ? value as string : `${value}px`;
}


/** Size properties for an overlay. */
export interface OverlaySizeConfig {
width?: number | string;
height?: number | string;
minWidth?: number | string;
minHeight?: number | string;
maxWidth?: number | string;
maxHeight?: number | string;
}
4 changes: 4 additions & 0 deletions src/cdk/portal/portal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ export abstract class BasePortalHost implements PortalHost {
return !!this._attachedPortal;
}

attach<T>(portal: ComponentPortal<T>): ComponentRef<T>;
attach<T>(portal: TemplatePortal<T>): EmbeddedViewRef<T>;
attach(portal: any): any;

attach(portal: Portal<any>): any {
if (!portal) {
throwNullPortalError();
Expand Down
2 changes: 1 addition & 1 deletion src/cdk/scrolling/scrolling.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
### Scrolling

Some things to help with scrollling.
Some things to help with scrollling.
3 changes: 1 addition & 2 deletions src/lib/autocomplete/autocomplete-trigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,7 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
this._overlayRef = this._overlay.create(this._getOverlayConfig());
} else {
/** Update the panel width, in case the host width has changed */
this._overlayRef.getConfig().width = this._getHostWidth();
this._overlayRef.updateSize();
this._overlayRef.updateSize({width: this._getHostWidth()});
}

if (this._overlayRef && !this._overlayRef.hasAttached()) {
Expand Down

0 comments on commit 3bbbb17

Please sign in to comment.