Skip to content

Commit 2d50044

Browse files
crisbetojelbourn
authored andcommitted
fix(compatibility): throw better error when wrong prefix is used (#3871)
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.
1 parent a65d2f4 commit 2d50044

File tree

2 files changed

+38
-9
lines changed

2 files changed

+38
-9
lines changed

src/lib/core/compatibility/compatibility.spec.ts

+13-5
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import {MdCheckboxModule} from '../../checkbox/index';
44
import {
55
NoConflictStyleCompatibilityMode,
66
MAT_ELEMENTS_SELECTOR,
7-
MD_ELEMENTS_SELECTOR
7+
MD_ELEMENTS_SELECTOR,
8+
MdCompatibilityInvalidPrefixError,
89
} from './compatibility';
10+
import {wrappedErrorMessage} from '../testing/wrapped-error-message';
911

1012

1113
describe('Style compatibility', () => {
@@ -32,9 +34,11 @@ describe('Style compatibility', () => {
3234
}));
3335

3436
it('should throw an error when trying to use the "mat-" prefix', () => {
37+
const expectedError = new MdCompatibilityInvalidPrefixError('mat', 'mat-checkbox');
38+
3539
expect(() => {
3640
TestBed.createComponent(ComponentWithMatCheckbox);
37-
}).toThrowError(/The "mat-" prefix cannot be used out of ng-material v1 compatibility mode/);
41+
}).toThrowError(wrappedErrorMessage(expectedError));
3842
});
3943
});
4044

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

5559
it('should throw an error when trying to use the "md-" prefix', () => {
60+
const expectedError = new MdCompatibilityInvalidPrefixError('md', 'md-checkbox');
61+
5662
expect(() => {
5763
TestBed.createComponent(ComponentWithMdCheckbox);
58-
}).toThrowError(/The "md-" prefix cannot be used in ng-material v1 compatibility mode/);
64+
}).toThrowError(wrappedErrorMessage(expectedError));
5965
});
6066
});
6167

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

7177
it('should throw an error when using the "md-" prefix', () => {
72-
expect(() => {
78+
const expectedError = new MdCompatibilityInvalidPrefixError('md', 'md-checkbox');
79+
80+
expect(() => {
7381
TestBed.createComponent(ComponentWithMdCheckbox);
74-
}).toThrowError(/The "md-" prefix cannot be used in ng-material v1 compatibility mode/);
82+
}).toThrowError(wrappedErrorMessage(expectedError));
7583
});
7684

7785
it('should not throw an error when using the "mat-" prefix', () => {

src/lib/core/compatibility/compatibility.ts

+25-4
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,29 @@ import {
66
Inject,
77
Optional,
88
isDevMode,
9+
ElementRef,
910
} from '@angular/core';
1011
import {DOCUMENT} from '@angular/platform-browser';
12+
import {MdError} from '../errors/error';
1113

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

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

19+
/**
20+
* Exception thrown if the consumer has used an invalid Material prefix on a component.
21+
* @docs-private
22+
*/
23+
export class MdCompatibilityInvalidPrefixError extends MdError {
24+
constructor(prefix: string, nodeName: string) {
25+
super(
26+
`The "${prefix}-" prefix cannot be used in ng-material v1 compatibility mode. ` +
27+
`It was used on an "${nodeName.toLowerCase()}" element.`
28+
);
29+
}
30+
}
31+
1732
/** Selector that matches all elements that may have style collisions with AngularJS Material. */
1833
export const MAT_ELEMENTS_SELECTOR = `
1934
[mat-button],
@@ -137,19 +152,25 @@ export const MD_ELEMENTS_SELECTOR = `
137152
/** Directive that enforces that the `mat-` prefix cannot be used. */
138153
@Directive({selector: MAT_ELEMENTS_SELECTOR})
139154
export class MatPrefixRejector {
140-
constructor(@Optional() @Inject(MATERIAL_COMPATIBILITY_MODE) isCompatibilityMode: boolean) {
155+
constructor(
156+
@Optional() @Inject(MATERIAL_COMPATIBILITY_MODE) isCompatibilityMode: boolean,
157+
elementRef: ElementRef) {
158+
141159
if (!isCompatibilityMode) {
142-
throw Error('The "mat-" prefix cannot be used out of ng-material v1 compatibility mode.');
160+
throw new MdCompatibilityInvalidPrefixError('mat', elementRef.nativeElement.nodeName);
143161
}
144162
}
145163
}
146164

147165
/** Directive that enforces that the `md-` prefix cannot be used. */
148166
@Directive({selector: MD_ELEMENTS_SELECTOR})
149167
export class MdPrefixRejector {
150-
constructor(@Optional() @Inject(MATERIAL_COMPATIBILITY_MODE) isCompatibilityMode: boolean) {
168+
constructor(
169+
@Optional() @Inject(MATERIAL_COMPATIBILITY_MODE) isCompatibilityMode: boolean,
170+
elementRef: ElementRef) {
171+
151172
if (isCompatibilityMode) {
152-
throw Error('The "md-" prefix cannot be used in ng-material v1 compatibility mode.');
173+
throw new MdCompatibilityInvalidPrefixError('md', elementRef.nativeElement.nodeName);
153174
}
154175
}
155176
}

0 commit comments

Comments
 (0)