Skip to content

Commit 54875a3

Browse files
authoredSep 5, 2024··
fix(material/core): drop sanity checks (#29688)
Removes the sanity checks since they won't execute with standalone by default, they mostly aren't necessary now that we're loading structural styles automatically and they produce some concrete styles that are problematic for the new theming APIs.
1 parent 22b68e0 commit 54875a3

File tree

5 files changed

+29
-151
lines changed

5 files changed

+29
-151
lines changed
 

‎src/material/core/_core-theme.scss

-22
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,6 @@
1515
@use './tokens/m2/mat/full-pseudo-checkbox' as tokens-mat-full-pseudo-checkbox;
1616
@use './tokens/m2/mat/minimal-pseudo-checkbox' as tokens-mat-minimal-pseudo-checkbox;
1717

18-
$_has-inserted-loaded-marker: false;
19-
20-
@mixin _theme-loaded-marker {
21-
@if not $_has-inserted-loaded-marker {
22-
$_has-inserted-loaded-marker: true !global;
23-
24-
// Marker that is used to determine whether the user has added a theme to their page.
25-
// Needs to be generated at the root, because themes may be nested inside classes.
26-
@at-root {
27-
.mat-theme-loaded-marker {
28-
display: none;
29-
}
30-
}
31-
}
32-
}
33-
3418
@mixin base($theme) {
3519
@if inspection.get-theme-version($theme) == 1 {
3620
@include _theme-from-tokens(inspection.get-theme-tokens($theme, base));
@@ -45,9 +29,6 @@ $_has-inserted-loaded-marker: false;
4529
tokens-mat-app.get-unthemable-tokens());
4630
}
4731
}
48-
49-
// The marker is a concrete style no matter which Material version we're targeting.
50-
@include _theme-loaded-marker;
5132
}
5233

5334
@mixin color($theme) {
@@ -129,9 +110,6 @@ $_has-inserted-loaded-marker: false;
129110
}
130111
}
131112
}
132-
133-
// The marker is a concrete style no matter which Material version we're targeting.
134-
@include _theme-loaded-marker;
135113
}
136114

137115
@mixin _theme-from-tokens($tokens, $options...) {

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

+20-108
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,32 @@
88

99
import {HighContrastModeDetector} from '@angular/cdk/a11y';
1010
import {BidiModule} from '@angular/cdk/bidi';
11-
import {inject, Inject, InjectionToken, NgModule, Optional} from '@angular/core';
12-
import {VERSION as CDK_VERSION} from '@angular/cdk';
13-
import {DOCUMENT} from '@angular/common';
14-
import {Platform, _isTestEnvironment} from '@angular/cdk/platform';
15-
import {VERSION} from '../version';
11+
import {inject, InjectionToken, NgModule} from '@angular/core';
12+
import {_isTestEnvironment} from '@angular/cdk/platform';
1613

17-
/** @docs-private */
18-
export function MATERIAL_SANITY_CHECKS_FACTORY(): SanityChecks {
19-
return true;
20-
}
21-
22-
/** Injection token that configures whether the Material sanity checks are enabled. */
14+
/**
15+
* Injection token that configures whether the Material sanity checks are enabled.
16+
* @deprecated No longer used and will be removed.
17+
* @breaking-change 21.0.0
18+
*/
2319
export const MATERIAL_SANITY_CHECKS = new InjectionToken<SanityChecks>('mat-sanity-checks', {
2420
providedIn: 'root',
25-
factory: MATERIAL_SANITY_CHECKS_FACTORY,
21+
factory: () => true,
2622
});
2723

2824
/**
2925
* Possible sanity checks that can be enabled. If set to
3026
* true/false, all checks will be enabled/disabled.
27+
* @deprecated No longer used and will be removed.
28+
* @breaking-change 21.0.0
3129
*/
3230
export type SanityChecks = boolean | GranularSanityChecks;
3331

34-
/** Object that can be used to configure the sanity checks granularly. */
32+
/**
33+
* Object that can be used to configure the sanity checks granularly.
34+
* @deprecated No longer used and will be removed.
35+
* @breaking-change 21.0.0
36+
*/
3537
export interface GranularSanityChecks {
3638
doctype: boolean;
3739
theme: boolean;
@@ -43,109 +45,19 @@ export interface GranularSanityChecks {
4345
* components. This includes Bidi, etc.
4446
*
4547
* This module should be imported to each top-level component module (e.g., MatTabsModule).
48+
* @deprecated No longer used and will be removed.
49+
* @breaking-change 21.0.0
4650
*/
4751
@NgModule({
4852
imports: [BidiModule],
4953
exports: [BidiModule],
5054
})
5155
export class MatCommonModule {
52-
/** Whether we've done the global sanity checks (e.g. a theme is loaded, there is a doctype). */
53-
private _hasDoneGlobalChecks = false;
56+
constructor(...args: any[]);
5457

55-
constructor(
56-
highContrastModeDetector: HighContrastModeDetector,
57-
@Optional() @Inject(MATERIAL_SANITY_CHECKS) private _sanityChecks: SanityChecks,
58-
@Inject(DOCUMENT) private _document: Document,
59-
) {
58+
constructor() {
6059
// While A11yModule also does this, we repeat it here to avoid importing A11yModule
6160
// in MatCommonModule.
62-
highContrastModeDetector._applyBodyHighContrastModeCssClasses();
63-
64-
if (!this._hasDoneGlobalChecks) {
65-
this._hasDoneGlobalChecks = true;
66-
67-
if (typeof ngDevMode === 'undefined' || ngDevMode) {
68-
// Inject in here so the reference to `Platform` can be removed in production mode.
69-
const platform = inject(Platform, {optional: true});
70-
71-
if (this._checkIsEnabled('doctype')) {
72-
_checkDoctypeIsDefined(this._document);
73-
}
74-
75-
if (this._checkIsEnabled('theme')) {
76-
_checkThemeIsPresent(this._document, !!platform?.isBrowser);
77-
}
78-
79-
if (this._checkIsEnabled('version')) {
80-
_checkCdkVersionMatch();
81-
}
82-
}
83-
}
84-
}
85-
86-
/** Gets whether a specific sanity check is enabled. */
87-
private _checkIsEnabled(name: keyof GranularSanityChecks): boolean {
88-
if (_isTestEnvironment()) {
89-
return false;
90-
}
91-
92-
if (typeof this._sanityChecks === 'boolean') {
93-
return this._sanityChecks;
94-
}
95-
96-
return !!this._sanityChecks[name];
97-
}
98-
}
99-
100-
/** Checks that the page has a doctype. */
101-
function _checkDoctypeIsDefined(doc: Document): void {
102-
if (!doc.doctype) {
103-
console.warn(
104-
'Current document does not have a doctype. This may cause ' +
105-
'some Angular Material components not to behave as expected.',
106-
);
107-
}
108-
}
109-
110-
/** Checks that a theme has been included. */
111-
function _checkThemeIsPresent(doc: Document, isBrowser: boolean): void {
112-
// We need to assert that the `body` is defined, because these checks run very early
113-
// and the `body` won't be defined if the consumer put their scripts in the `head`.
114-
if (!doc.body || !isBrowser) {
115-
return;
116-
}
117-
118-
const testElement = doc.createElement('div');
119-
testElement.classList.add('mat-theme-loaded-marker');
120-
doc.body.appendChild(testElement);
121-
122-
const computedStyle = getComputedStyle(testElement);
123-
124-
// In some situations the computed style of the test element can be null. For example in
125-
// Firefox, the computed style is null if an application is running inside of a hidden iframe.
126-
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=548397
127-
if (computedStyle && computedStyle.display !== 'none') {
128-
console.warn(
129-
'Could not find Angular Material core theme. Most Material ' +
130-
'components may not work as expected. For more info refer ' +
131-
'to the theming guide: https://material.angular.io/guide/theming',
132-
);
133-
}
134-
135-
testElement.remove();
136-
}
137-
138-
/** Checks whether the Material version matches the CDK version. */
139-
function _checkCdkVersionMatch(): void {
140-
if (VERSION.full !== CDK_VERSION.full) {
141-
console.warn(
142-
'The Angular Material version (' +
143-
VERSION.full +
144-
') does not match ' +
145-
'the Angular CDK version (' +
146-
CDK_VERSION.full +
147-
').\n' +
148-
'Please ensure the versions of these two packages exactly match.',
149-
);
61+
inject(HighContrastModeDetector)._applyBodyHighContrastModeCssClasses();
15062
}
15163
}

‎src/material/core/theming/tests/m3-theme.spec.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,14 @@ describe('M3 theme', () => {
5656
root.walkRules(rule => {
5757
selectors.add(rule.selector);
5858
});
59-
expect(Array.from(selectors)).toEqual(['html', '.mat-theme-loaded-marker']);
59+
expect(Array.from(selectors)).toEqual(['html']);
6060
});
6161

6262
it('should only emit CSS variables', () => {
6363
const root = parse(transpile(`html { @include mat.all-component-themes($theme); }`));
6464
const nonVarProps: string[] = [];
6565
root.walkDecls(decl => {
66-
if (
67-
!decl.prop.startsWith('--') &&
68-
// Skip the theme loaded marker since it can't be a variable.
69-
(decl.parent as Rule).selector !== '.mat-theme-loaded-marker'
70-
) {
66+
if (!decl.prop.startsWith('--')) {
7167
nonVarProps.push(decl.prop);
7268
}
7369
});

‎src/material/core/theming/tests/theming-inspection-api.spec.ts

+1-8
Original file line numberDiff line numberDiff line change
@@ -460,14 +460,7 @@ describe('theming inspection api', () => {
460460
div {
461461
@include mat.all-component-themes($theme);
462462
}`);
463-
expect(css).toBe(
464-
[
465-
// The marker is always included.
466-
`.mat-theme-loaded-marker {`,
467-
` display: none;`,
468-
`}`,
469-
].join('\n'),
470-
);
463+
expect(css.trim()).toBe('');
471464
});
472465
});
473466
});

‎tools/public_api_guard/material/core.md

+6-7
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { EventEmitter } from '@angular/core';
1212
import { FocusableOption } from '@angular/cdk/a11y';
1313
import { FocusOrigin } from '@angular/cdk/a11y';
1414
import { FormGroupDirective } from '@angular/forms';
15-
import { HighContrastModeDetector } from '@angular/cdk/a11y';
1615
import * as i0 from '@angular/core';
1716
import * as i1 from '@angular/cdk/bidi';
1817
import { InjectionToken } from '@angular/core';
@@ -119,7 +118,7 @@ export class _ErrorStateTracker {
119118
// @public
120119
export function _getOptionScrollPosition(optionOffset: number, optionHeight: number, currentScrollPosition: number, panelHeight: number): number;
121120

122-
// @public
121+
// @public @deprecated
123122
export interface GranularSanityChecks {
124123
// (undocumented)
125124
doctype: boolean;
@@ -150,11 +149,11 @@ export const MAT_OPTION_PARENT_COMPONENT: InjectionToken<MatOptionParentComponen
150149
// @public
151150
export const MAT_RIPPLE_GLOBAL_OPTIONS: InjectionToken<RippleGlobalOptions>;
152151

153-
// @public
152+
// @public @deprecated
154153
export class MatCommonModule {
155-
constructor(highContrastModeDetector: HighContrastModeDetector, _sanityChecks: SanityChecks, _document: Document);
154+
constructor(...args: any[]);
156155
// (undocumented)
157-
static ɵfac: i0.ɵɵFactoryDeclaration<MatCommonModule, [null, { optional: true; }, null]>;
156+
static ɵfac: i0.ɵɵFactoryDeclaration<MatCommonModule, never>;
158157
// (undocumented)
159158
static ɵinj: i0.ɵɵInjectorDeclaration<MatCommonModule>;
160159
// (undocumented)
@@ -175,7 +174,7 @@ export type MatDateFormats = {
175174
};
176175
};
177176

178-
// @public
177+
// @public @deprecated
179178
export const MATERIAL_SANITY_CHECKS: InjectionToken<SanityChecks>;
180179

181180
// @public
@@ -527,7 +526,7 @@ export interface RippleTarget {
527526
rippleDisabled: boolean;
528527
}
529528

530-
// @public
529+
// @public @deprecated
531530
export type SanityChecks = boolean | GranularSanityChecks;
532531

533532
// @public

0 commit comments

Comments
 (0)
Please sign in to comment.