Skip to content

Commit

Permalink
fix(compatibility): throw better error when wrong prefix is used (#3871)
Browse files Browse the repository at this point in the history
Throws a slightly better error when the wrong prefix is used. The error now includes the node name of the offending element, which should make it easier to pinpoint the issue.
  • Loading branch information
crisbeto authored and jelbourn committed Apr 11, 2017
1 parent a65d2f4 commit 2d50044
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 9 deletions.
18 changes: 13 additions & 5 deletions src/lib/core/compatibility/compatibility.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import {MdCheckboxModule} from '../../checkbox/index';
import {
NoConflictStyleCompatibilityMode,
MAT_ELEMENTS_SELECTOR,
MD_ELEMENTS_SELECTOR
MD_ELEMENTS_SELECTOR,
MdCompatibilityInvalidPrefixError,
} from './compatibility';
import {wrappedErrorMessage} from '../testing/wrapped-error-message';


describe('Style compatibility', () => {
Expand All @@ -32,9 +34,11 @@ describe('Style compatibility', () => {
}));

it('should throw an error when trying to use the "mat-" prefix', () => {
const expectedError = new MdCompatibilityInvalidPrefixError('mat', 'mat-checkbox');

expect(() => {
TestBed.createComponent(ComponentWithMatCheckbox);
}).toThrowError(/The "mat-" prefix cannot be used out of ng-material v1 compatibility mode/);
}).toThrowError(wrappedErrorMessage(expectedError));
});
});

Expand All @@ -53,9 +57,11 @@ describe('Style compatibility', () => {
});

it('should throw an error when trying to use the "md-" prefix', () => {
const expectedError = new MdCompatibilityInvalidPrefixError('md', 'md-checkbox');

expect(() => {
TestBed.createComponent(ComponentWithMdCheckbox);
}).toThrowError(/The "md-" prefix cannot be used in ng-material v1 compatibility mode/);
}).toThrowError(wrappedErrorMessage(expectedError));
});
});

Expand All @@ -69,9 +75,11 @@ describe('Style compatibility', () => {
}));

it('should throw an error when using the "md-" prefix', () => {
expect(() => {
const expectedError = new MdCompatibilityInvalidPrefixError('md', 'md-checkbox');

expect(() => {
TestBed.createComponent(ComponentWithMdCheckbox);
}).toThrowError(/The "md-" prefix cannot be used in ng-material v1 compatibility mode/);
}).toThrowError(wrappedErrorMessage(expectedError));
});

it('should not throw an error when using the "mat-" prefix', () => {
Expand Down
29 changes: 25 additions & 4 deletions src/lib/core/compatibility/compatibility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,29 @@ import {
Inject,
Optional,
isDevMode,
ElementRef,
} from '@angular/core';
import {DOCUMENT} from '@angular/platform-browser';
import {MdError} from '../errors/error';

/** Whether we've done the global sanity checks (e.g. a theme is loaded, there is a doctype). */
let hasDoneGlobalChecks = false;

export const MATERIAL_COMPATIBILITY_MODE = new OpaqueToken('md-compatibility-mode');

/**
* Exception thrown if the consumer has used an invalid Material prefix on a component.
* @docs-private
*/
export class MdCompatibilityInvalidPrefixError extends MdError {
constructor(prefix: string, nodeName: string) {
super(
`The "${prefix}-" prefix cannot be used in ng-material v1 compatibility mode. ` +
`It was used on an "${nodeName.toLowerCase()}" element.`
);
}
}

/** Selector that matches all elements that may have style collisions with AngularJS Material. */
export const MAT_ELEMENTS_SELECTOR = `
[mat-button],
Expand Down Expand Up @@ -137,19 +152,25 @@ export const MD_ELEMENTS_SELECTOR = `
/** Directive that enforces that the `mat-` prefix cannot be used. */
@Directive({selector: MAT_ELEMENTS_SELECTOR})
export class MatPrefixRejector {
constructor(@Optional() @Inject(MATERIAL_COMPATIBILITY_MODE) isCompatibilityMode: boolean) {
constructor(
@Optional() @Inject(MATERIAL_COMPATIBILITY_MODE) isCompatibilityMode: boolean,
elementRef: ElementRef) {

if (!isCompatibilityMode) {
throw Error('The "mat-" prefix cannot be used out of ng-material v1 compatibility mode.');
throw new MdCompatibilityInvalidPrefixError('mat', elementRef.nativeElement.nodeName);
}
}
}

/** Directive that enforces that the `md-` prefix cannot be used. */
@Directive({selector: MD_ELEMENTS_SELECTOR})
export class MdPrefixRejector {
constructor(@Optional() @Inject(MATERIAL_COMPATIBILITY_MODE) isCompatibilityMode: boolean) {
constructor(
@Optional() @Inject(MATERIAL_COMPATIBILITY_MODE) isCompatibilityMode: boolean,
elementRef: ElementRef) {

if (isCompatibilityMode) {
throw Error('The "md-" prefix cannot be used in ng-material v1 compatibility mode.');
throw new MdCompatibilityInvalidPrefixError('md', elementRef.nativeElement.nodeName);
}
}
}
Expand Down

0 comments on commit 2d50044

Please sign in to comment.