From 81018cd4384f5de5129501051a1bc4c7e6740ec5 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Wed, 4 Sep 2024 11:46:39 +0200 Subject: [PATCH] fix(material/core): drop sanity checks 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. --- src/material/core/_core-theme.scss | 22 --- .../core/common-behaviors/common-module.ts | 128 +++--------------- .../core/theming/tests/m3-theme.spec.ts | 8 +- .../tests/theming-inspection-api.spec.ts | 9 +- tools/public_api_guard/material/core.md | 13 +- 5 files changed, 29 insertions(+), 151 deletions(-) diff --git a/src/material/core/_core-theme.scss b/src/material/core/_core-theme.scss index 66f75dde4e22..a9ade883cc70 100644 --- a/src/material/core/_core-theme.scss +++ b/src/material/core/_core-theme.scss @@ -15,22 +15,6 @@ @use './tokens/m2/mat/full-pseudo-checkbox' as tokens-mat-full-pseudo-checkbox; @use './tokens/m2/mat/minimal-pseudo-checkbox' as tokens-mat-minimal-pseudo-checkbox; -$_has-inserted-loaded-marker: false; - -@mixin _theme-loaded-marker { - @if not $_has-inserted-loaded-marker { - $_has-inserted-loaded-marker: true !global; - - // Marker that is used to determine whether the user has added a theme to their page. - // Needs to be generated at the root, because themes may be nested inside classes. - @at-root { - .mat-theme-loaded-marker { - display: none; - } - } - } -} - @mixin base($theme) { @if inspection.get-theme-version($theme) == 1 { @include _theme-from-tokens(inspection.get-theme-tokens($theme, base)); @@ -45,9 +29,6 @@ $_has-inserted-loaded-marker: false; tokens-mat-app.get-unthemable-tokens()); } } - - // The marker is a concrete style no matter which Material version we're targeting. - @include _theme-loaded-marker; } @mixin color($theme) { @@ -129,9 +110,6 @@ $_has-inserted-loaded-marker: false; } } } - - // The marker is a concrete style no matter which Material version we're targeting. - @include _theme-loaded-marker; } @mixin _theme-from-tokens($tokens, $options...) { diff --git a/src/material/core/common-behaviors/common-module.ts b/src/material/core/common-behaviors/common-module.ts index 4039b57b8ace..9bc5f25e041a 100644 --- a/src/material/core/common-behaviors/common-module.ts +++ b/src/material/core/common-behaviors/common-module.ts @@ -8,30 +8,32 @@ import {HighContrastModeDetector} from '@angular/cdk/a11y'; import {BidiModule} from '@angular/cdk/bidi'; -import {inject, Inject, InjectionToken, NgModule, Optional} from '@angular/core'; -import {VERSION as CDK_VERSION} from '@angular/cdk'; -import {DOCUMENT} from '@angular/common'; -import {Platform, _isTestEnvironment} from '@angular/cdk/platform'; -import {VERSION} from '../version'; +import {inject, InjectionToken, NgModule} from '@angular/core'; +import {_isTestEnvironment} from '@angular/cdk/platform'; -/** @docs-private */ -export function MATERIAL_SANITY_CHECKS_FACTORY(): SanityChecks { - return true; -} - -/** Injection token that configures whether the Material sanity checks are enabled. */ +/** + * Injection token that configures whether the Material sanity checks are enabled. + * @deprecated No longer used and will be removed. + * @breaking-change 21.0.0 + */ export const MATERIAL_SANITY_CHECKS = new InjectionToken('mat-sanity-checks', { providedIn: 'root', - factory: MATERIAL_SANITY_CHECKS_FACTORY, + factory: () => true, }); /** * Possible sanity checks that can be enabled. If set to * true/false, all checks will be enabled/disabled. + * @deprecated No longer used and will be removed. + * @breaking-change 21.0.0 */ export type SanityChecks = boolean | GranularSanityChecks; -/** Object that can be used to configure the sanity checks granularly. */ +/** + * Object that can be used to configure the sanity checks granularly. + * @deprecated No longer used and will be removed. + * @breaking-change 21.0.0 + */ export interface GranularSanityChecks { doctype: boolean; theme: boolean; @@ -43,109 +45,19 @@ export interface GranularSanityChecks { * components. This includes Bidi, etc. * * This module should be imported to each top-level component module (e.g., MatTabsModule). + * @deprecated No longer used and will be removed. + * @breaking-change 21.0.0 */ @NgModule({ imports: [BidiModule], exports: [BidiModule], }) export class MatCommonModule { - /** Whether we've done the global sanity checks (e.g. a theme is loaded, there is a doctype). */ - private _hasDoneGlobalChecks = false; + constructor(...args: any[]); - constructor( - highContrastModeDetector: HighContrastModeDetector, - @Optional() @Inject(MATERIAL_SANITY_CHECKS) private _sanityChecks: SanityChecks, - @Inject(DOCUMENT) private _document: Document, - ) { + constructor() { // While A11yModule also does this, we repeat it here to avoid importing A11yModule // in MatCommonModule. - highContrastModeDetector._applyBodyHighContrastModeCssClasses(); - - if (!this._hasDoneGlobalChecks) { - this._hasDoneGlobalChecks = true; - - if (typeof ngDevMode === 'undefined' || ngDevMode) { - // Inject in here so the reference to `Platform` can be removed in production mode. - const platform = inject(Platform, {optional: true}); - - if (this._checkIsEnabled('doctype')) { - _checkDoctypeIsDefined(this._document); - } - - if (this._checkIsEnabled('theme')) { - _checkThemeIsPresent(this._document, !!platform?.isBrowser); - } - - if (this._checkIsEnabled('version')) { - _checkCdkVersionMatch(); - } - } - } - } - - /** Gets whether a specific sanity check is enabled. */ - private _checkIsEnabled(name: keyof GranularSanityChecks): boolean { - if (_isTestEnvironment()) { - return false; - } - - if (typeof this._sanityChecks === 'boolean') { - return this._sanityChecks; - } - - return !!this._sanityChecks[name]; - } -} - -/** Checks that the page has a doctype. */ -function _checkDoctypeIsDefined(doc: Document): void { - if (!doc.doctype) { - console.warn( - 'Current document does not have a doctype. This may cause ' + - 'some Angular Material components not to behave as expected.', - ); - } -} - -/** Checks that a theme has been included. */ -function _checkThemeIsPresent(doc: Document, isBrowser: boolean): void { - // We need to assert that the `body` is defined, because these checks run very early - // and the `body` won't be defined if the consumer put their scripts in the `head`. - if (!doc.body || !isBrowser) { - return; - } - - const testElement = doc.createElement('div'); - testElement.classList.add('mat-theme-loaded-marker'); - doc.body.appendChild(testElement); - - const computedStyle = getComputedStyle(testElement); - - // In some situations the computed style of the test element can be null. For example in - // Firefox, the computed style is null if an application is running inside of a hidden iframe. - // See: https://bugzilla.mozilla.org/show_bug.cgi?id=548397 - if (computedStyle && computedStyle.display !== 'none') { - console.warn( - 'Could not find Angular Material core theme. Most Material ' + - 'components may not work as expected. For more info refer ' + - 'to the theming guide: https://material.angular.io/guide/theming', - ); - } - - testElement.remove(); -} - -/** Checks whether the Material version matches the CDK version. */ -function _checkCdkVersionMatch(): void { - if (VERSION.full !== CDK_VERSION.full) { - console.warn( - 'The Angular Material version (' + - VERSION.full + - ') does not match ' + - 'the Angular CDK version (' + - CDK_VERSION.full + - ').\n' + - 'Please ensure the versions of these two packages exactly match.', - ); + inject(HighContrastModeDetector)._applyBodyHighContrastModeCssClasses(); } } diff --git a/src/material/core/theming/tests/m3-theme.spec.ts b/src/material/core/theming/tests/m3-theme.spec.ts index 0516495fc7fc..52c867f80525 100644 --- a/src/material/core/theming/tests/m3-theme.spec.ts +++ b/src/material/core/theming/tests/m3-theme.spec.ts @@ -56,18 +56,14 @@ describe('M3 theme', () => { root.walkRules(rule => { selectors.add(rule.selector); }); - expect(Array.from(selectors)).toEqual(['html', '.mat-theme-loaded-marker']); + expect(Array.from(selectors)).toEqual(['html']); }); it('should only emit CSS variables', () => { const root = parse(transpile(`html { @include mat.all-component-themes($theme); }`)); const nonVarProps: string[] = []; root.walkDecls(decl => { - if ( - !decl.prop.startsWith('--') && - // Skip the theme loaded marker since it can't be a variable. - (decl.parent as Rule).selector !== '.mat-theme-loaded-marker' - ) { + if (!decl.prop.startsWith('--')) { nonVarProps.push(decl.prop); } }); diff --git a/src/material/core/theming/tests/theming-inspection-api.spec.ts b/src/material/core/theming/tests/theming-inspection-api.spec.ts index 34e91550bd4e..6d3f9b74f5aa 100644 --- a/src/material/core/theming/tests/theming-inspection-api.spec.ts +++ b/src/material/core/theming/tests/theming-inspection-api.spec.ts @@ -460,14 +460,7 @@ describe('theming inspection api', () => { div { @include mat.all-component-themes($theme); }`); - expect(css).toBe( - [ - // The marker is always included. - `.mat-theme-loaded-marker {`, - ` display: none;`, - `}`, - ].join('\n'), - ); + expect(css.trim()).toBe(''); }); }); }); diff --git a/tools/public_api_guard/material/core.md b/tools/public_api_guard/material/core.md index d08ba3f87de6..5c38679b0099 100644 --- a/tools/public_api_guard/material/core.md +++ b/tools/public_api_guard/material/core.md @@ -12,7 +12,6 @@ import { EventEmitter } from '@angular/core'; import { FocusableOption } from '@angular/cdk/a11y'; import { FocusOrigin } from '@angular/cdk/a11y'; import { FormGroupDirective } from '@angular/forms'; -import { HighContrastModeDetector } from '@angular/cdk/a11y'; import * as i0 from '@angular/core'; import * as i1 from '@angular/cdk/bidi'; import { InjectionToken } from '@angular/core'; @@ -119,7 +118,7 @@ export class _ErrorStateTracker { // @public export function _getOptionScrollPosition(optionOffset: number, optionHeight: number, currentScrollPosition: number, panelHeight: number): number; -// @public +// @public @deprecated export interface GranularSanityChecks { // (undocumented) doctype: boolean; @@ -150,11 +149,11 @@ export const MAT_OPTION_PARENT_COMPONENT: InjectionToken; -// @public +// @public @deprecated export class MatCommonModule { - constructor(highContrastModeDetector: HighContrastModeDetector, _sanityChecks: SanityChecks, _document: Document); + constructor(...args: any[]); // (undocumented) - static ɵfac: i0.ɵɵFactoryDeclaration; + static ɵfac: i0.ɵɵFactoryDeclaration; // (undocumented) static ɵinj: i0.ɵɵInjectorDeclaration; // (undocumented) @@ -175,7 +174,7 @@ export type MatDateFormats = { }; }; -// @public +// @public @deprecated export const MATERIAL_SANITY_CHECKS: InjectionToken; // @public @@ -527,7 +526,7 @@ export interface RippleTarget { rippleDisabled: boolean; } -// @public +// @public @deprecated export type SanityChecks = boolean | GranularSanityChecks; // @public