From c2a2206dd4d0653f74005b66e803fb45d3c5050e Mon Sep 17 00:00:00 2001 From: crisbeto Date: Sat, 25 Mar 2017 12:36:33 +0100 Subject: [PATCH] feat(theming): log a warning if core theme isn't loaded * Checks the user's loaded stylesheets and logs a warning if the Material core theme isn't loaded. * Fixes a wrong `typeof` check when determining the doctype. Fixes #2828. Note: I originally went with looping through the `document.styleSheets` to check whether the selector is defined, however I had to switch back to `getComputedStyle`, because browsers don't expose the `document.styleSheets`, if the CSS file is being loaded from another domain. This would've caused the warning to be logged if the user loads over a CDN. --- src/lib/core/_core.scss | 5 ++++ src/lib/core/compatibility/compatibility.ts | 33 +++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/lib/core/_core.scss b/src/lib/core/_core.scss index d7ef849bae98..ef9a0523475f 100644 --- a/src/lib/core/_core.scss +++ b/src/lib/core/_core.scss @@ -36,4 +36,9 @@ $background: map-get($theme, background); background-color: mat-color($background, background); } + + // Marker that is used to determine whether the user has added a theme to their page. + .md-theme-loaded-marker { + display: none; + } } diff --git a/src/lib/core/compatibility/compatibility.ts b/src/lib/core/compatibility/compatibility.ts index 7bb8ee9eea1d..d34c442c9c83 100644 --- a/src/lib/core/compatibility/compatibility.ts +++ b/src/lib/core/compatibility/compatibility.ts @@ -9,6 +9,8 @@ import { } from '@angular/core'; import {DOCUMENT} from '@angular/platform-browser'; +/** Flag for whether we've checked that the theme is loaded. */ +let hasCheckedThemePresence = false; export const MATERIAL_COMPATIBILITY_MODE = new OpaqueToken('md-compatibility-mode'); @@ -170,14 +172,41 @@ export class CompatibilityModule { }; } - constructor(@Optional() @Inject(DOCUMENT) document: any) { - if (isDevMode() && typeof document && !document.doctype) { + constructor(@Optional() @Inject(DOCUMENT) private _document: any) { + this._checkDoctype(); + this._checkTheme(); + } + + private _checkDoctype(): void { + if (isDevMode() && this._document && !this._document.doctype) { console.warn( 'Current document does not have a doctype. This may cause ' + 'some Angular Material components not to behave as expected.' ); } } + + private _checkTheme(): void { + if (hasCheckedThemePresence || !this._document || !isDevMode()) { + return; + } + + let testElement = this._document.createElement('div'); + + testElement.classList.add('md-theme-loaded-marker'); + this._document.body.appendChild(testElement); + + if (getComputedStyle(testElement).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://github.com/angular/material2/blob/master/guides/theming.md' + ); + } + + this._document.body.removeChild(testElement); + hasCheckedThemePresence = true; + } }