Skip to content

Commit

Permalink
feat(theming): log a warning if core theme isn't loaded
Browse files Browse the repository at this point in the history
Checks the user's loaded stylesheets and logs a warning if the Material core theme isn't loaded.

Fixes angular#2828.
  • Loading branch information
crisbeto committed Jan 28, 2017
1 parent 3b6cab0 commit f31134e
Show file tree
Hide file tree
Showing 27 changed files with 130 additions and 39 deletions.
10 changes: 8 additions & 2 deletions src/lib/autocomplete/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import {ModuleWithProviders, NgModule} from '@angular/core';
import {MdOptionModule, OverlayModule, OVERLAY_PROVIDERS, CompatibilityModule} from '../core';
import {
MdOptionModule,
OverlayModule,
OVERLAY_PROVIDERS,
CompatibilityModule,
MdThemeCheckModule
} from '../core';
import {MdAutocomplete} from './autocomplete';
import {MdAutocompleteTrigger} from './autocomplete-trigger';
export * from './autocomplete';
export * from './autocomplete-trigger';

@NgModule({
imports: [MdOptionModule, OverlayModule, CompatibilityModule],
imports: [MdOptionModule, OverlayModule, CompatibilityModule, MdThemeCheckModule],
exports: [MdAutocomplete, MdOptionModule, MdAutocompleteTrigger, CompatibilityModule],
declarations: [MdAutocomplete, MdAutocompleteTrigger],
})
Expand Down
3 changes: 2 additions & 1 deletion src/lib/button-toggle/button-toggle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
coerceBooleanProperty,
UNIQUE_SELECTION_DISPATCHER_PROVIDER,
CompatibilityModule,
MdThemeCheckModule,
} from '../core';

/** Acceptable types for a button toggle. */
Expand Down Expand Up @@ -464,7 +465,7 @@ export class MdButtonToggle implements OnInit {


@NgModule({
imports: [FormsModule, CompatibilityModule],
imports: [FormsModule, CompatibilityModule, MdThemeCheckModule],
exports: [
MdButtonToggleGroup,
MdButtonToggleGroupMultiple,
Expand Down
9 changes: 7 additions & 2 deletions src/lib/button/button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ import {
ModuleWithProviders,
} from '@angular/core';
import {CommonModule} from '@angular/common';
import {MdRippleModule, coerceBooleanProperty, CompatibilityModule} from '../core';
import {
MdRippleModule,
coerceBooleanProperty,
CompatibilityModule,
MdThemeCheckModule
} from '../core';


// TODO(jelbourn): Make the `isMouseDown` stuff done with one global listener.
Expand Down Expand Up @@ -164,7 +169,7 @@ export class MdAnchor extends MdButton {


@NgModule({
imports: [CommonModule, MdRippleModule, CompatibilityModule],
imports: [CommonModule, MdRippleModule, CompatibilityModule, MdThemeCheckModule],
exports: [MdButton, MdAnchor, CompatibilityModule],
declarations: [MdButton, MdAnchor],
})
Expand Down
4 changes: 2 additions & 2 deletions src/lib/card/card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
ChangeDetectionStrategy,
Directive
} from '@angular/core';
import {CompatibilityModule} from '../core';
import {CompatibilityModule, MdThemeCheckModule} from '../core';


/**
Expand Down Expand Up @@ -101,7 +101,7 @@ export class MdCardTitleGroup {}


@NgModule({
imports: [CompatibilityModule],
imports: [CompatibilityModule, MdThemeCheckModule],
exports: [
MdCard,
MdCardHeader,
Expand Down
4 changes: 2 additions & 2 deletions src/lib/checkbox/checkbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
import {CommonModule} from '@angular/common';
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from '@angular/forms';
import {coerceBooleanProperty} from '../core/coercion/boolean-property';
import {MdRippleModule, CompatibilityModule} from '../core';
import {MdRippleModule, CompatibilityModule, MdThemeCheckModule} from '../core';


/** Monotonically increasing integer used to auto-generate unique ids for checkbox components. */
Expand Down Expand Up @@ -403,7 +403,7 @@ export class MdCheckbox implements ControlValueAccessor {


@NgModule({
imports: [CommonModule, MdRippleModule, CompatibilityModule],
imports: [CommonModule, MdRippleModule, CompatibilityModule, MdThemeCheckModule],
exports: [MdCheckbox, CompatibilityModule],
declarations: [MdCheckbox],
})
Expand Down
3 changes: 2 additions & 1 deletion src/lib/chips/chip-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
ViewEncapsulation
} from '@angular/core';

import {MdThemeCheckModule} from '../core';
import {MdChip} from './chip';
import {FocusKeyManager} from '../core/a11y/focus-key-manager';
import {coerceBooleanProperty} from '../core/coercion/boolean-property';
Expand Down Expand Up @@ -210,7 +211,7 @@ export class MdChipList implements AfterContentInit {
}

@NgModule({
imports: [],
imports: [MdThemeCheckModule],
exports: [MdChipList, MdChip],
declarations: [MdChipList, MdChip]
})
Expand Down
13 changes: 10 additions & 3 deletions src/lib/core/_core.scss
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,21 @@

// Mixin that renders all of the core styles that depend on the theme.
@mixin md-core-theme($theme) {
@include md-ripple-theme($theme);
@include md-option-theme($theme);
@include md-pseudo-checkbox-theme($theme);
// Marker that is used to determine whether the user has added a theme to their page.
// Note that only the selector is being used, but we add a property, in order to avoid
// it being removed by minifiers.
.md-theme-loaded-marker {
color: #000;
}

// Wrapper element that provides the theme background when the
// user's content isn't inside of a `md-sidenav-container`.
.md-app-background {
$background: map-get($theme, background);
background-color: md-color($background, background);
}

@include md-ripple-theme($theme);
@include md-option-theme($theme);
@include md-pseudo-checkbox-theme($theme);
}
6 changes: 6 additions & 0 deletions src/lib/core/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {PortalModule} from './portal/portal-directives';
import {OverlayModule} from './overlay/overlay-directives';
import {A11yModule} from './a11y/index';
import {MdSelectionModule} from './selection/index';
import {MdThemeCheckModule} from './theming/theme-check';


// RTL
Expand Down Expand Up @@ -86,6 +87,9 @@ export {isFakeMousedownFromScreenReader} from './a11y/fake-mousedown';

export {A11yModule} from './a11y/index';

// Theming check
export {MdThemeCheckModule} from './theming/theme-check';

export {
UniqueSelectionDispatcher,
UniqueSelectionDispatcherListener,
Expand Down Expand Up @@ -137,6 +141,7 @@ export {CompatibilityModule, NoConflictStyleCompatibilityMode} from './compatibi
A11yModule,
MdOptionModule,
MdSelectionModule,
MdThemeCheckModule,
],
exports: [
MdLineModule,
Expand All @@ -148,6 +153,7 @@ export {CompatibilityModule, NoConflictStyleCompatibilityMode} from './compatibi
A11yModule,
MdOptionModule,
MdSelectionModule,
MdThemeCheckModule,
],
})
export class MdCoreModule {
Expand Down
39 changes: 39 additions & 0 deletions src/lib/core/theming/theme-check.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {NgModule, isDevMode} from '@angular/core';

/**
* Module that verifies that the user has loaded the core theming file,
* without which most Material module won't work as expected.
* @docs-private
*/
@NgModule()
export class MdThemeCheckModule {
constructor() {
if (!isDevMode() || typeof document === 'undefined') {
return;
}

for (let i = 0; i < document.styleSheets.length; i++) {
// The try/catch is needed, because some browsers can throw a security
// error when accessing the `cssRules` from another domain.
try {
let rules = (document.styleSheets.item(i) as CSSStyleSheet).cssRules;

if (rules) {
for (let j = 0; j < rules.length; j++) {
let selector = (rules.item(j) as CSSStyleRule).selectorText;

if (selector && selector.includes('.md-theme-loaded-marker')) {
return;
}
}
}
} catch (e) { }
}

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'
);
}
}
2 changes: 2 additions & 0 deletions src/lib/dialog/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
PortalModule,
A11yModule,
CompatibilityModule,
MdThemeCheckModule,
} from '../core';
import {MdDialog} from './dialog';
import {MdDialogContainer} from './dialog-container';
Expand All @@ -21,6 +22,7 @@ import {
PortalModule,
A11yModule,
CompatibilityModule,
MdThemeCheckModule,
],
exports: [
MdDialogContainer,
Expand Down
4 changes: 2 additions & 2 deletions src/lib/grid-list/grid-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {MdGridTile, MdGridTileText} from './grid-tile';
import {TileCoordinator} from './tile-coordinator';
import {TileStyler, FitTileStyler, RatioTileStyler, FixedTileStyler} from './tile-styler';
import {MdGridListColsError} from './grid-list-errors';
import {Dir, MdLineModule, CompatibilityModule} from '../core';
import {Dir, MdLineModule, CompatibilityModule, MdThemeCheckModule} from '../core';
import {
coerceToString,
coerceToNumber,
Expand Down Expand Up @@ -144,7 +144,7 @@ export class MdGridList implements OnInit, AfterContentChecked {


@NgModule({
imports: [MdLineModule, CompatibilityModule],
imports: [MdLineModule, CompatibilityModule, MdThemeCheckModule],
exports: [
MdGridList,
MdGridTile,
Expand Down
4 changes: 2 additions & 2 deletions src/lib/icon/icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from '@angular/core';
import {HttpModule, Http} from '@angular/http';
import {DomSanitizer} from '@angular/platform-browser';
import {MdError, CompatibilityModule} from '../core';
import {MdError, CompatibilityModule, MdThemeCheckModule} from '../core';
import {MdIconRegistry} from './icon-registry';
export {MdIconRegistry} from './icon-registry';

Expand Down Expand Up @@ -260,7 +260,7 @@ export const ICON_REGISTRY_PROVIDER = {
};

@NgModule({
imports: [HttpModule, CompatibilityModule],
imports: [HttpModule, CompatibilityModule, MdThemeCheckModule],
exports: [MdIcon, CompatibilityModule],
declarations: [MdIcon],
providers: [ICON_REGISTRY_PROVIDER],
Expand Down
6 changes: 4 additions & 2 deletions src/lib/input/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {NgModule, ModuleWithProviders} from '@angular/core';
import {MdPlaceholder, MdInputContainer, MdHint, MdInputDirective} from './input-container';
import {MdTextareaAutosize} from './autosize';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {MdThemeCheckModule} from '../core';
import {MdPlaceholder, MdInputContainer, MdHint, MdInputDirective} from './input-container';
import {MdTextareaAutosize} from './autosize';
import {PlatformModule} from '../core/platform/index';


Expand All @@ -23,6 +24,7 @@ export * from './input-container-errors';
CommonModule,
FormsModule,
PlatformModule,
MdThemeCheckModule,
],
exports: [
MdPlaceholder,
Expand Down
11 changes: 9 additions & 2 deletions src/lib/list/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ import {
NgModule,
ModuleWithProviders,
} from '@angular/core';
import {MdLine, MdLineSetter, MdLineModule, CompatibilityModule} from '../core';
import {
MdLine,
MdLineSetter,
MdLineModule,
CompatibilityModule,
MdThemeCheckModule,
} from '../core';


@Directive({
selector: 'md-divider, mat-divider'
Expand Down Expand Up @@ -72,7 +79,7 @@ export class MdListItem implements AfterContentInit {


@NgModule({
imports: [MdLineModule, CompatibilityModule],
imports: [MdLineModule, CompatibilityModule, MdThemeCheckModule],
exports: [
MdList,
MdListItem,
Expand Down
4 changes: 2 additions & 2 deletions src/lib/menu/menu.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {NgModule, ModuleWithProviders} from '@angular/core';
import {CommonModule} from '@angular/common';
import {OverlayModule, CompatibilityModule} from '../core';
import {OverlayModule, CompatibilityModule, MdThemeCheckModule} from '../core';
import {MdMenu} from './menu-directive';
import {MdMenuItem} from './menu-item';
import {MdMenuTrigger} from './menu-trigger';
Expand All @@ -13,7 +13,7 @@ export {MenuPositionX, MenuPositionY} from './menu-positions';


@NgModule({
imports: [OverlayModule, CommonModule, MdRippleModule, CompatibilityModule],
imports: [OverlayModule, CommonModule, MdRippleModule, CompatibilityModule, MdThemeCheckModule],
exports: [MdMenu, MdMenuItem, MdMenuTrigger, CompatibilityModule],
declarations: [MdMenu, MdMenuItem, MdMenuTrigger],
})
Expand Down
2 changes: 2 additions & 0 deletions src/lib/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
A11yModule,
ProjectionModule,
CompatibilityModule,
MdThemeCheckModule,
} from './core/index';

import {MdButtonToggleModule} from './button-toggle/index';
Expand Down Expand Up @@ -61,6 +62,7 @@ const MATERIAL_MODULES = [
MdTabsModule,
MdToolbarModule,
MdTooltipModule,
MdThemeCheckModule,
OverlayModule,
PortalModule,
RtlModule,
Expand Down
4 changes: 2 additions & 2 deletions src/lib/progress-bar/progress-bar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
Input,
} from '@angular/core';
import {CommonModule} from '@angular/common';
import {CompatibilityModule} from '../core/compatibility/compatibility';
import {CompatibilityModule, MdThemeCheckModule} from '../core';

// TODO(josephperrott): Benchpress tests.
// TODO(josephperrott): Add ARIA attributes for progressbar "for".
Expand Down Expand Up @@ -86,7 +86,7 @@ function clamp(v: number, min = 0, max = 100) {


@NgModule({
imports: [CommonModule, CompatibilityModule],
imports: [CommonModule, CompatibilityModule, MdThemeCheckModule],
exports: [MdProgressBar, CompatibilityModule],
declarations: [MdProgressBar],
})
Expand Down
4 changes: 2 additions & 2 deletions src/lib/progress-spinner/progress-spinner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
NgZone,
Renderer
} from '@angular/core';
import {CompatibilityModule} from '../core';
import {CompatibilityModule, MdThemeCheckModule} from '../core';


// TODO(josephperrott): Benchpress tests.
Expand Down Expand Up @@ -362,7 +362,7 @@ function getSvgArc(currentValue: number, rotation: number) {


@NgModule({
imports: [CompatibilityModule],
imports: [CompatibilityModule, MdThemeCheckModule],
exports: [MdProgressSpinner, MdSpinner, CompatibilityModule],
declarations: [MdProgressSpinner, MdSpinner],
})
Expand Down
3 changes: 2 additions & 1 deletion src/lib/radio/radio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
UniqueSelectionDispatcher,
CompatibilityModule,
UNIQUE_SELECTION_DISPATCHER_PROVIDER,
MdThemeCheckModule,
} from '../core';
import {coerceBooleanProperty} from '../core/coercion/boolean-property';
import {VIEWPORT_RULER_PROVIDER} from '../core/overlay/position/viewport-ruler';
Expand Down Expand Up @@ -507,7 +508,7 @@ export class MdRadioButton implements OnInit {


@NgModule({
imports: [CommonModule, MdRippleModule, CompatibilityModule],
imports: [CommonModule, MdRippleModule, CompatibilityModule, MdThemeCheckModule],
exports: [MdRadioGroup, MdRadioButton, CompatibilityModule],
providers: [UNIQUE_SELECTION_DISPATCHER_PROVIDER, VIEWPORT_RULER_PROVIDER],
declarations: [MdRadioGroup, MdRadioButton],
Expand Down
Loading

0 comments on commit f31134e

Please sign in to comment.