Skip to content

Commit

Permalink
fix(overlay): injection errors for scroll strategy providers in lazy-…
Browse files Browse the repository at this point in the history
…loaded modules (#11213)

Fixes injection errors being thrown by the overlay-based providers that have injection tokens for the default scroll strategy. The error comes from the fact that the scroll strategies were being provided at the root, whereas the `Overlay` provider was provided normally, causing it to be missing when a module is lazy-loaded.

Fixes #10820.
  • Loading branch information
crisbeto authored and tinayuangao committed May 16, 2018
1 parent 2815607 commit 0cda47c
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 59 deletions.
25 changes: 7 additions & 18 deletions src/cdk/overlay/overlay-directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,13 @@ import {Direction, Directionality} from '@angular/cdk/bidi';
import {coerceBooleanProperty} from '@angular/cdk/coercion';
import {ESCAPE} from '@angular/cdk/keycodes';
import {TemplatePortal} from '@angular/cdk/portal';
import {ScrollDispatcher, ViewportRuler} from '@angular/cdk/scrolling';
import {
Directive,
ElementRef,
EventEmitter,
Inject,
inject,
InjectionToken,
Input,
NgZone,
OnChanges,
OnDestroy,
Optional,
Expand Down Expand Up @@ -74,20 +71,12 @@ const defaultPositionList: ConnectedPosition[] = [

/** Injection token that determines the scroll handling while the connected overlay is open. */
export const CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY =
new InjectionToken<() => ScrollStrategy>('cdk-connected-overlay-scroll-strategy', {
providedIn: 'root',
factory: CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_FACTORY,
});
new InjectionToken<() => ScrollStrategy>('cdk-connected-overlay-scroll-strategy');

/** @docs-private */
export function CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
// Store the injected deps here because we can't use the `inject` function outside
// this function's context (including the inner function).
const scrollDispatcher = inject(ScrollDispatcher);
const viewportRuler = inject(ViewportRuler);
const ngZone = inject(NgZone);
return (config?: RepositionScrollStrategyConfig) =>
new RepositionScrollStrategy(scrollDispatcher, viewportRuler, ngZone, config);
/** @docs-private @deprecated @deletion-target 7.0.0 */
export function CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_FACTORY(overlay: Overlay):
() => ScrollStrategy {
return (config?: RepositionScrollStrategyConfig) => overlay.scrollStrategies.reposition(config);
}

/**
Expand Down Expand Up @@ -394,13 +383,13 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
}


/** @docs-private @deprecated @deletion-target 7.0.0 */
/** @docs-private */
export function CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER_FACTORY(overlay: Overlay):
() => RepositionScrollStrategy {
return () => overlay.scrollStrategies.reposition();
}

/** @docs-private @deprecated @deletion-target 7.0.0 */
/** @docs-private */
export const CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER = {
provide: CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY,
deps: [Overlay],
Expand Down
5 changes: 4 additions & 1 deletion src/cdk/overlay/overlay-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ import {OverlayPositionBuilder} from './position/overlay-position-builder';
imports: [BidiModule, PortalModule, ScrollDispatchModule],
exports: [CdkConnectedOverlay, CdkOverlayOrigin, ScrollDispatchModule],
declarations: [CdkConnectedOverlay, CdkOverlayOrigin],
providers: [Overlay],
providers: [
Overlay,
CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER,
],
})
export class OverlayModule {}

Expand Down
6 changes: 5 additions & 1 deletion src/lib/autocomplete/autocomplete-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import {CommonModule} from '@angular/common';
import {OverlayModule} from '@angular/cdk/overlay';
import {MatOptionModule, MatCommonModule} from '@angular/material/core';
import {MatAutocomplete} from './autocomplete';
import {MatAutocompleteTrigger} from './autocomplete-trigger';
import {
MatAutocompleteTrigger,
MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY_PROVIDER,
} from './autocomplete-trigger';
import {MatAutocompleteOrigin} from './autocomplete-origin';

@NgModule({
Expand All @@ -24,5 +27,6 @@ import {MatAutocompleteOrigin} from './autocomplete-origin';
MatCommonModule
],
declarations: [MatAutocomplete, MatAutocompleteTrigger, MatAutocompleteOrigin],
providers: [MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY_PROVIDER],
})
export class MatAutocompleteModule {}
16 changes: 9 additions & 7 deletions src/lib/autocomplete/autocomplete-trigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import {
forwardRef,
Host,
Inject,
inject,
InjectionToken,
Input,
NgZone,
Expand Down Expand Up @@ -62,17 +61,20 @@ export const AUTOCOMPLETE_PANEL_HEIGHT = 256;

/** Injection token that determines the scroll handling while the autocomplete panel is open. */
export const MAT_AUTOCOMPLETE_SCROLL_STRATEGY =
new InjectionToken<() => ScrollStrategy>('mat-autocomplete-scroll-strategy', {
providedIn: 'root',
factory: MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY,
});
new InjectionToken<() => ScrollStrategy>('mat-autocomplete-scroll-strategy');

/** @docs-private */
export function MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
const overlay = inject(Overlay);
export function MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
return () => overlay.scrollStrategies.reposition();
}

/** @docs-private */
export const MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY_PROVIDER = {
provide: MAT_AUTOCOMPLETE_SCROLL_STRATEGY,
deps: [Overlay],
useFactory: MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY,
};

/**
* Provider that allows the autocomplete to register as a ControlValueAccessor.
* @docs-private
Expand Down
7 changes: 6 additions & 1 deletion src/lib/datepicker/datepicker-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ import {MatButtonModule} from '@angular/material/button';
import {MatDialogModule} from '@angular/material/dialog';
import {MatCalendar, MatCalendarHeader} from './calendar';
import {MatCalendarBody} from './calendar-body';
import {MatDatepicker, MatDatepickerContent} from './datepicker';
import {
MatDatepicker,
MatDatepickerContent,
MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER,
} from './datepicker';
import {MatDatepickerInput} from './datepicker-input';
import {MatDatepickerIntl} from './datepicker-intl';
import {MatDatepickerToggle, MatDatepickerToggleIcon} from './datepicker-toggle';
Expand Down Expand Up @@ -61,6 +65,7 @@ import {MatYearView} from './year-view';
],
providers: [
MatDatepickerIntl,
MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER,
],
entryComponents: [
MatDatepickerContent,
Expand Down
16 changes: 9 additions & 7 deletions src/lib/datepicker/datepicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import {
ElementRef,
EventEmitter,
Inject,
inject,
InjectionToken,
Input,
NgZone,
Expand All @@ -51,17 +50,20 @@ let datepickerUid = 0;

/** Injection token that determines the scroll handling while the calendar is open. */
export const MAT_DATEPICKER_SCROLL_STRATEGY =
new InjectionToken<() => ScrollStrategy>('mat-datepicker-scroll-strategy', {
providedIn: 'root',
factory: MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY,
});
new InjectionToken<() => ScrollStrategy>('mat-datepicker-scroll-strategy');

/** @docs-private */
export function MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
const overlay = inject(Overlay);
export function MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
return () => overlay.scrollStrategies.reposition();
}

/** @docs-private */
export const MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER = {
provide: MAT_DATEPICKER_SCROLL_STRATEGY,
deps: [Overlay],
useFactory: MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY,
};

// Boilerplate for applying mixins to MatDatepickerContent.
/** @docs-private */
export class MatDatepickerContentBase {
Expand Down
9 changes: 2 additions & 7 deletions src/lib/dialog/dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {ComponentPortal, ComponentType, PortalInjector, TemplatePortal} from '@a
import {Location} from '@angular/common';
import {
Inject,
inject,
Injectable,
InjectionToken,
Injector,
Expand All @@ -42,14 +41,10 @@ export const MAT_DIALOG_DEFAULT_OPTIONS =

/** Injection token that determines the scroll handling while the dialog is open. */
export const MAT_DIALOG_SCROLL_STRATEGY =
new InjectionToken<() => ScrollStrategy>('mat-dialog-scroll-strategy', {
providedIn: 'root',
factory: MAT_DIALOG_SCROLL_STRATEGY_FACTORY,
});
new InjectionToken<() => ScrollStrategy>('mat-dialog-scroll-strategy');

/** @docs-private */
export function MAT_DIALOG_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
const overlay = inject(Overlay);
export function MAT_DIALOG_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
return () => overlay.scrollStrategies.block();
}

Expand Down
6 changes: 5 additions & 1 deletion src/lib/menu/menu-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ import {MatCommonModule, MatRippleModule} from '@angular/material/core';
import {MatMenuContent} from './menu-content';
import {MatMenu} from './menu-directive';
import {MatMenuItem} from './menu-item';
import {MatMenuTrigger} from './menu-trigger';
import {
MatMenuTrigger,
MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER,
} from './menu-trigger';


@NgModule({
Expand All @@ -25,5 +28,6 @@ import {MatMenuTrigger} from './menu-trigger';
],
exports: [MatMenu, MatMenuItem, MatMenuTrigger, MatMenuContent, MatCommonModule],
declarations: [MatMenu, MatMenuItem, MatMenuTrigger, MatMenuContent],
providers: [MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER]
})
export class MatMenuModule {}
16 changes: 9 additions & 7 deletions src/lib/menu/menu-trigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import {
ElementRef,
EventEmitter,
Inject,
inject,
InjectionToken,
Input,
OnDestroy,
Expand All @@ -44,17 +43,20 @@ import {MenuPositionX, MenuPositionY} from './menu-positions';

/** Injection token that determines the scroll handling while the menu is open. */
export const MAT_MENU_SCROLL_STRATEGY =
new InjectionToken<() => ScrollStrategy>('mat-menu-scroll-strategy', {
providedIn: 'root',
factory: MAT_MENU_SCROLL_STRATEGY_FACTORY,
});
new InjectionToken<() => ScrollStrategy>('mat-menu-scroll-strategy');

/** @docs-private */
export function MAT_MENU_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
const overlay = inject(Overlay);
export function MAT_MENU_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
return () => overlay.scrollStrategies.reposition();
}

/** @docs-private */
export const MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER = {
provide: MAT_MENU_SCROLL_STRATEGY,
deps: [Overlay],
useFactory: MAT_MENU_SCROLL_STRATEGY_FACTORY,
};

/** Default top padding of the menu panel. */
export const MENU_PANEL_TOP_PADDING = 8;

Expand Down
8 changes: 6 additions & 2 deletions src/lib/tooltip/tooltip-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ import {OverlayModule} from '@angular/cdk/overlay';
import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {MatCommonModule} from '@angular/material/core';
import {MatTooltip, TooltipComponent} from './tooltip';

import {
MatTooltip,
TooltipComponent,
MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER,
} from './tooltip';

@NgModule({
imports: [
Expand All @@ -22,5 +25,6 @@ import {MatTooltip, TooltipComponent} from './tooltip';
exports: [MatTooltip, TooltipComponent, MatCommonModule],
declarations: [MatTooltip, TooltipComponent],
entryComponents: [TooltipComponent],
providers: [MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER]
})
export class MatTooltipModule {}
16 changes: 9 additions & 7 deletions src/lib/tooltip/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import {
Directive,
ElementRef,
Inject,
inject,
InjectionToken,
Input,
NgZone,
Expand Down Expand Up @@ -60,17 +59,20 @@ export function getMatTooltipInvalidPositionError(position: string) {

/** Injection token that determines the scroll handling while a tooltip is visible. */
export const MAT_TOOLTIP_SCROLL_STRATEGY =
new InjectionToken<() => ScrollStrategy>('mat-tooltip-scroll-strategy', {
providedIn: 'root',
factory: MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY,
});
new InjectionToken<() => ScrollStrategy>('mat-tooltip-scroll-strategy');

/** @docs-private */
export function MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
const overlay = inject(Overlay);
export function MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
return () => overlay.scrollStrategies.reposition({scrollThrottle: SCROLL_THROTTLE_MS});
}

/** @docs-private */
export const MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER = {
provide: MAT_TOOLTIP_SCROLL_STRATEGY,
deps: [Overlay],
useFactory: MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY,
};

/** Default `matTooltip` options that can be overridden. */
export interface MatTooltipDefaultOptions {
showDelay: number;
Expand Down

0 comments on commit 0cda47c

Please sign in to comment.