Skip to content

Commit 77994e9

Browse files
crisbetojelbourn
authored andcommitted
feat(core): allow more granular control over sanity checks (#16973)
Allows consumers to disable individual sanity checks, rather than the all-or-nothing setup that we have at the moment. Fixes #16617.
1 parent 28b645d commit 77994e9

File tree

3 files changed

+62
-14
lines changed

3 files changed

+62
-14
lines changed

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

Lines changed: 45 additions & 11 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 can be used to configure the sanity checks 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,21 +65,28 @@ 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();
6283
this._hasDoneGlobalChecks = true;
6384
}
6485
}
6586

66-
/** Whether any sanity checks are enabled */
67-
private _areChecksEnabled(): boolean {
68-
return this._sanityChecksEnabled && isDevMode() && !this._isTestEnv();
87+
/** Whether any sanity checks are enabled. */
88+
private _checksAreEnabled(): boolean {
89+
return isDevMode() && !this._isTestEnv();
6990
}
7091

7192
/** Whether the code is running in tests. */
@@ -75,7 +96,10 @@ export class MatCommonModule {
7596
}
7697

7798
private _checkDoctypeIsDefined(): void {
78-
if (this._document && !this._document.doctype) {
99+
const isEnabled = this._checksAreEnabled() &&
100+
(this._sanityChecks === true || (this._sanityChecks as GranularSanityChecks).doctype);
101+
102+
if (isEnabled && this._document && !this._document.doctype) {
79103
console.warn(
80104
'Current document does not have a doctype. This may cause ' +
81105
'some Angular Material components not to behave as expected.'
@@ -86,7 +110,11 @@ export class MatCommonModule {
86110
private _checkThemeIsPresent(): void {
87111
// We need to assert that the `body` is defined, because these checks run very early
88112
// 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') {
113+
const isDisabled = !this._checksAreEnabled() ||
114+
(this._sanityChecks === false || !(this._sanityChecks as GranularSanityChecks).theme);
115+
116+
if (isDisabled || !this._document || !this._document.body ||
117+
typeof getComputedStyle !== 'function') {
90118
return;
91119
}
92120

@@ -113,7 +141,10 @@ export class MatCommonModule {
113141

114142
/** Checks whether the material version matches the cdk version */
115143
private _checkCdkVersionMatch(): void {
116-
if (VERSION.full !== CDK_VERSION.full) {
144+
const isEnabled = this._checksAreEnabled() &&
145+
(this._sanityChecks === true || (this._sanityChecks as GranularSanityChecks).version);
146+
147+
if (isEnabled && VERSION.full !== CDK_VERSION.full) {
117148
console.warn(
118149
'The Angular Material version (' + VERSION.full + ') does not match ' +
119150
'the Angular CDK version (' + CDK_VERSION.full + ').\n' +
@@ -128,7 +159,10 @@ export class MatCommonModule {
128159
return;
129160
}
130161

131-
if (this._areChecksEnabled() && !(this._window as any)['Hammer'] && !this._hammerLoader) {
162+
const isEnabled = this._checksAreEnabled() &&
163+
(this._sanityChecks === true || (this._sanityChecks as GranularSanityChecks).hammer);
164+
165+
if (isEnabled && !(this._window as any)['Hammer'] && !this._hammerLoader) {
132166
console.warn(
133167
'Could not find HammerJS. Certain Angular Material components may not work correctly.');
134168
}

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)