Skip to content

Commit 7a0d5bc

Browse files
committed
feat(core): allow more granular control over sanity checks
Allows consumers to disable individual sanity checks, rather than the all-or-nothing setup that we have at the moment. Fixes #16617.
1 parent 1c74518 commit 7a0d5bc

File tree

3 files changed

+54
-13
lines changed

3 files changed

+54
-13
lines changed

src/material/core/common-behaviors/common-module.ts

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,30 @@ import {VERSION as CDK_VERSION} from '@angular/cdk';
1818
const VERSION = new Version('0.0.0-PLACEHOLDER');
1919

2020
/** @docs-private */
21-
export function MATERIAL_SANITY_CHECKS_FACTORY(): boolean {
21+
export function MATERIAL_SANITY_CHECKS_FACTORY(): SanityChecks {
2222
return true;
2323
}
2424

2525
/** Injection token that configures whether the Material sanity checks are enabled. */
26-
export const MATERIAL_SANITY_CHECKS = new InjectionToken<boolean>('mat-sanity-checks', {
26+
export const MATERIAL_SANITY_CHECKS = new InjectionToken<SanityChecks>('mat-sanity-checks', {
2727
providedIn: 'root',
2828
factory: MATERIAL_SANITY_CHECKS_FACTORY,
2929
});
3030

31+
/**
32+
* Possible sanity checks that can be enabled. If set to
33+
* true/false, all checks will be enabled/disabled.
34+
*/
35+
export type SanityChecks = boolean | GranularSanityChecks;
36+
37+
/** Object that allows for the sanity checks to be configured granularly. */
38+
export interface GranularSanityChecks {
39+
doctype: boolean;
40+
theme: boolean;
41+
version: boolean;
42+
hammer: boolean;
43+
}
44+
3145
/**
3246
* Module that captures anything that should be loaded and/or run for *all* Angular Material
3347
* components. This includes Bidi, etc.
@@ -51,11 +65,18 @@ export class MatCommonModule {
5165
/** Reference to the global 'window' object. */
5266
private _window = typeof window === 'object' && window ? window : null;
5367

68+
/** Configured sanity checks. */
69+
private _sanityChecks: SanityChecks;
70+
5471
constructor(
55-
@Optional() @Inject(MATERIAL_SANITY_CHECKS) private _sanityChecksEnabled: boolean,
72+
@Optional() @Inject(MATERIAL_SANITY_CHECKS) sanityChecks: any,
5673
@Optional() @Inject(HAMMER_LOADER) private _hammerLoader?: HammerLoader) {
5774

58-
if (this._areChecksEnabled() && !this._hasDoneGlobalChecks) {
75+
// Note that `_sanityChecks` is typed to `any`, because AoT
76+
// throws an error if we use the `SanityChecks` type directly.
77+
this._sanityChecks = sanityChecks;
78+
79+
if (!this._hasDoneGlobalChecks) {
5980
this._checkDoctypeIsDefined();
6081
this._checkThemeIsPresent();
6182
this._checkCdkVersionMatch();
@@ -64,8 +85,13 @@ export class MatCommonModule {
6485
}
6586

6687
/** Whether any sanity checks are enabled */
67-
private _areChecksEnabled(): boolean {
68-
return this._sanityChecksEnabled && isDevMode() && !this._isTestEnv();
88+
private _isCheckEnabled(check: keyof GranularSanityChecks): boolean {
89+
if (!isDevMode() || this._isTestEnv()) {
90+
// All checks are disabled in production mode and in test environments.
91+
return false;
92+
}
93+
94+
return typeof this._sanityChecks === 'boolean' ? this._sanityChecks : this._sanityChecks[check];
6995
}
7096

7197
/** Whether the code is running in tests. */
@@ -75,7 +101,7 @@ export class MatCommonModule {
75101
}
76102

77103
private _checkDoctypeIsDefined(): void {
78-
if (this._document && !this._document.doctype) {
104+
if (this._isCheckEnabled('doctype') && this._document && !this._document.doctype) {
79105
console.warn(
80106
'Current document does not have a doctype. This may cause ' +
81107
'some Angular Material components not to behave as expected.'
@@ -86,7 +112,8 @@ export class MatCommonModule {
86112
private _checkThemeIsPresent(): void {
87113
// We need to assert that the `body` is defined, because these checks run very early
88114
// and the `body` won't be defined if the consumer put their scripts in the `head`.
89-
if (!this._document || !this._document.body || typeof getComputedStyle !== 'function') {
115+
if (!this._isCheckEnabled('theme') || !this._document || !this._document.body ||
116+
typeof getComputedStyle !== 'function') {
90117
return;
91118
}
92119

@@ -113,7 +140,7 @@ export class MatCommonModule {
113140

114141
/** Checks whether the material version matches the cdk version */
115142
private _checkCdkVersionMatch(): void {
116-
if (VERSION.full !== CDK_VERSION.full) {
143+
if (this._isCheckEnabled('version') && VERSION.full !== CDK_VERSION.full) {
117144
console.warn(
118145
'The Angular Material version (' + VERSION.full + ') does not match ' +
119146
'the Angular CDK version (' + CDK_VERSION.full + ').\n' +
@@ -128,7 +155,7 @@ export class MatCommonModule {
128155
return;
129156
}
130157

131-
if (this._areChecksEnabled() && !(this._window as any)['Hammer'] && !this._hammerLoader) {
158+
if (this._isCheckEnabled('hammer') && !(this._window as any)['Hammer'] && !this._hammerLoader) {
132159
console.warn(
133160
'Could not find HammerJS. Certain Angular Material components may not work correctly.');
134161
}

src/material/core/common-behaviors/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
export {MatCommonModule, MATERIAL_SANITY_CHECKS} from './common-module';
9+
export {
10+
MatCommonModule,
11+
MATERIAL_SANITY_CHECKS,
12+
SanityChecks,
13+
GranularSanityChecks,
14+
} from './common-module';
1015
export {CanDisable, CanDisableCtor, mixinDisabled} from './disabled';
1116
export {CanColor, CanColorCtor, mixinColor, ThemePalette} from './color';
1217
export {CanDisableRipple, CanDisableRippleCtor, mixinDisableRipple} from './disable-ripple';

tools/public_api_guard/material/core.d.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,13 @@ export declare class GestureConfig extends HammerGestureConfig {
100100
buildHammer(element: HTMLElement): HammerInstance;
101101
}
102102

103+
export interface GranularSanityChecks {
104+
doctype: boolean;
105+
hammer: boolean;
106+
theme: boolean;
107+
version: boolean;
108+
}
109+
103110
export interface HammerInput {
104111
center: {
105112
x: number;
@@ -190,7 +197,7 @@ export declare const MAT_OPTION_PARENT_COMPONENT: InjectionToken<MatOptionParent
190197
export declare const MAT_RIPPLE_GLOBAL_OPTIONS: InjectionToken<RippleGlobalOptions>;
191198

192199
export declare class MatCommonModule {
193-
constructor(_sanityChecksEnabled: boolean, _hammerLoader?: HammerLoader | undefined);
200+
constructor(sanityChecks: any, _hammerLoader?: HammerLoader | undefined);
194201
_checkHammerIsAvailable(): void;
195202
}
196203

@@ -206,7 +213,7 @@ export declare type MatDateFormats = {
206213
};
207214
};
208215

209-
export declare const MATERIAL_SANITY_CHECKS: InjectionToken<boolean>;
216+
export declare const MATERIAL_SANITY_CHECKS: InjectionToken<SanityChecks>;
210217

211218
export declare class MatLine {
212219
}
@@ -412,6 +419,8 @@ export interface RippleTarget {
412419
rippleDisabled: boolean;
413420
}
414421

422+
export declare type SanityChecks = boolean | GranularSanityChecks;
423+
415424
export declare const JAN = 0, FEB = 1, MAR = 2, APR = 3, MAY = 4, JUN = 5, JUL = 6, AUG = 7, SEP = 8, OCT = 9, NOV = 10, DEC = 11;
416425

417426
export declare function setLines(lines: QueryList<MatLine>, element: ElementRef<HTMLElement>): void;

0 commit comments

Comments
 (0)