Skip to content

Commit 36d8412

Browse files
devversionjelbourn
authored andcommitted
refactor(schematics): css name rules interfere with element selectors (#12805)
* Currently the `cssName` rules interfere with the element selector rules. This is not desired because it causes unexpected behavior because both rules try to update specific code parts. * Renames the `cssNames` data to `cssSelectors` because technically this rule should **only** update CSS selectors inside of string literals, stylesheets and also partly templates (inline styles). * Fixes that TypeScript sometimes doesn't report syntax failures (credits to @jelbourn)
1 parent 4c2a9f2 commit 36d8412

File tree

10 files changed

+144
-144
lines changed

10 files changed

+144
-144
lines changed

src/lib/schematics/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"compilerOptions": {
3-
"lib": ["es2017", "dom"],
3+
"lib": ["es2017"],
44
"module": "commonjs",
55
"moduleResolution": "node",
66
"outDir": "../../../dist/schematics",

src/lib/schematics/update/material/data/css-names.ts

Lines changed: 0 additions & 106 deletions
This file was deleted.
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {transformChanges} from '../transform-change-data';
10+
11+
export interface MaterialCssSelectorData {
12+
/** The CSS selector to replace. */
13+
replace: string;
14+
/** The new CSS selector. */
15+
replaceWith: string;
16+
/** Whitelist where this replacement is made. If omitted it is made in all files. */
17+
whitelist?: {
18+
/** Replace this name in stylesheet files. */
19+
stylesheet?: boolean,
20+
/** Replace this name in HTML files. */
21+
html?: boolean,
22+
/** Replace this name in TypeScript strings. */
23+
strings?: boolean
24+
};
25+
}
26+
27+
export const cssSelectors = transformChanges<MaterialCssSelectorData>([
28+
{
29+
pr: 'https://github.com/angular/material2/pull/10296',
30+
changes: [
31+
{
32+
replace: '.mat-form-field-placeholder',
33+
replaceWith: '.mat-form-field-label'
34+
},
35+
{
36+
replace: '.mat-input-container',
37+
replaceWith: '.mat-form-field'
38+
},
39+
{
40+
replace: '.mat-input-flex',
41+
replaceWith: '.mat-form-field-flex'
42+
},
43+
{
44+
replace: '.mat-input-hint-spacer',
45+
replaceWith: '.mat-form-field-hint-spacer'
46+
},
47+
{
48+
replace: '.mat-input-hint-wrapper',
49+
replaceWith: '.mat-form-field-hint-wrapper'
50+
},
51+
{
52+
replace: '.mat-input-infix',
53+
replaceWith: '.mat-form-field-infix'
54+
},
55+
{
56+
replace: '.mat-input-invalid',
57+
replaceWith: '.mat-form-field-invalid'
58+
},
59+
{
60+
replace: '.mat-input-placeholder',
61+
replaceWith: '.mat-form-field-label'
62+
},
63+
{
64+
replace: '.mat-input-placeholder-wrapper',
65+
replaceWith: '.mat-form-field-label-wrapper'
66+
},
67+
{
68+
replace: '.mat-input-prefix',
69+
replaceWith: '.mat-form-field-prefix'
70+
},
71+
{
72+
replace: '.mat-input-ripple',
73+
replaceWith: '.mat-form-field-ripple'
74+
},
75+
{
76+
replace: '.mat-input-subscript-wrapper',
77+
replaceWith: '.mat-form-field-subscript-wrapper'
78+
},
79+
{
80+
replace: '.mat-input-suffix',
81+
replaceWith: '.mat-form-field-suffix'
82+
},
83+
{
84+
replace: '.mat-input-underline',
85+
replaceWith: '.mat-form-field-underline'
86+
},
87+
{
88+
replace: '.mat-input-wrapper',
89+
replaceWith: '.mat-form-field-wrapper'
90+
}
91+
]
92+
},
93+
94+
// TODO(devversion): this shouldn't be here because it's not a CSS selector. Move into misc rule.
95+
{
96+
pr: 'https://github.com/angular/material2/pull/10430',
97+
changes: [
98+
{
99+
replace: '$mat-font-family',
100+
replaceWith: "Roboto, 'Helvetica Neue', sans-serif",
101+
whitelist: {
102+
stylesheet: true
103+
}
104+
}
105+
]
106+
}
107+
]);

src/lib/schematics/update/rules/css-names/cssNamesStringLiteralRule.ts renamed to src/lib/schematics/update/rules/css-selectors/cssSelectorsStringLiteralRule.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
import {green, red} from 'chalk';
1010
import {Replacement, RuleFailure, Rules, RuleWalker} from 'tslint';
1111
import * as ts from 'typescript';
12-
import {cssNames, MaterialCssNameData} from '../../material/data/css-names';
12+
import {cssSelectors, MaterialCssSelectorData} from '../../material/data/css-selectors';
1313
import {findAllSubstringIndices} from '../../typescript/literal';
1414

1515
/**
1616
* Rule that walks through every string literal that is wrapped inside of a call expression.
17-
* All string literals which include an outdated CSS class name will be migrated.
17+
* All string literals which include an outdated CSS selector will be migrated.
1818
*/
1919
export class Rule extends Rules.AbstractRule {
2020
apply(sourceFile: ts.SourceFile): RuleFailure[] {
@@ -31,22 +31,22 @@ export class Walker extends RuleWalker {
3131

3232
const textContent = node.getFullText();
3333

34-
cssNames.forEach(name => {
35-
if (name.whitelist && !name.whitelist.strings) {
34+
cssSelectors.forEach(data => {
35+
if (data.whitelist && !data.whitelist.strings) {
3636
return;
3737
}
3838

39-
findAllSubstringIndices(textContent, name.replace)
39+
findAllSubstringIndices(textContent, data.replace)
4040
.map(offset => node.getStart() + offset)
41-
.map(start => new Replacement(start, name.replace.length, name.replaceWith))
42-
.forEach(replacement => this._addFailureWithReplacement(node, replacement, name));
41+
.map(start => new Replacement(start, data.replace.length, data.replaceWith))
42+
.forEach(replacement => this._addFailureWithReplacement(node, replacement, data));
4343
});
4444
}
4545

46-
/** Adds a css name failure with the given replacement at the specified node. */
46+
/** Adds a css selector failure with the given replacement at the specified node. */
4747
private _addFailureWithReplacement(node: ts.Node, replacement: Replacement,
48-
name: MaterialCssNameData) {
49-
this.addFailureAtNode(node, `Found deprecated CSS class "${red(name.replace)}" which has ` +
50-
`been renamed to "${green(name.replaceWith)}"`, replacement);
48+
data: MaterialCssSelectorData) {
49+
this.addFailureAtNode(node, `Found deprecated CSS selector "${red(data.replace)}" which has ` +
50+
`been renamed to "${green(data.replaceWith)}"`, replacement);
5151
}
5252
}

src/lib/schematics/update/rules/css-names/cssNamesStylesheetRule.ts renamed to src/lib/schematics/update/rules/css-selectors/cssSelectorsStylesheetRule.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {green, red} from 'chalk';
1010
import {sync as globSync} from 'glob';
1111
import {IOptions, Replacement, RuleFailure, Rules} from 'tslint';
1212
import * as ts from 'typescript';
13-
import {cssNames} from '../../material/data/css-names';
13+
import {cssSelectors} from '../../material/data/css-selectors';
1414
import {ExternalResource} from '../../tslint/component-file';
1515
import {ComponentWalker} from '../../tslint/component-walker';
1616
import {
@@ -21,7 +21,7 @@ import {findAllSubstringIndices} from '../../typescript/literal';
2121

2222
/**
2323
* Rule that walks through every inline or external CSs stylesheet and updates outdated
24-
* CSS classes.
24+
* CSS selectors.
2525
*/
2626
export class Rule extends Rules.AbstractRule {
2727
apply(sourceFile: ts.SourceFile): RuleFailure[] {
@@ -54,23 +54,23 @@ export class Walker extends ComponentWalker {
5454
}
5555

5656
/**
57-
* Searches for outdated CSs classes in the specified content and creates replacements
57+
* Searches for outdated CSS selectors in the specified content and creates replacements
5858
* with the according messages that can be added to a rule failure.
5959
*/
6060
private _createReplacementsForContent(node: ts.Node, stylesheetContent: string) {
6161
const replacements: {failureMessage: string, replacement: Replacement}[] = [];
6262

63-
cssNames.forEach(name => {
64-
if (name.whitelist && !name.whitelist.stylesheet) {
63+
cssSelectors.forEach(data => {
64+
if (data.whitelist && !data.whitelist.stylesheet) {
6565
return;
6666
}
6767

68-
const failureMessage = `Found deprecated CSS class "${red(name.replace)}" ` +
69-
`which has been renamed to "${green(name.replaceWith)}"`;
68+
const failureMessage = `Found deprecated CSS selector "${red(data.replace)}" ` +
69+
`which has been renamed to "${green(data.replaceWith)}"`;
7070

71-
findAllSubstringIndices(stylesheetContent, name.replace)
71+
findAllSubstringIndices(stylesheetContent, data.replace)
7272
.map(offset => node.getStart() + offset)
73-
.map(start => new Replacement(start, name.replace.length, name.replaceWith))
73+
.map(start => new Replacement(start, data.replace.length, data.replaceWith))
7474
.forEach(replacement => replacements.push({replacement, failureMessage}));
7575
});
7676

src/lib/schematics/update/rules/css-names/cssNamesTemplateRule.ts renamed to src/lib/schematics/update/rules/css-selectors/cssSelectorsTemplateRule.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import {green, red} from 'chalk';
1010
import {Replacement, RuleFailure, Rules} from 'tslint';
1111
import * as ts from 'typescript';
12-
import {cssNames} from '../../material/data/css-names';
12+
import {cssSelectors} from '../../material/data/css-selectors';
1313
import {ExternalResource} from '../../tslint/component-file';
1414
import {ComponentWalker} from '../../tslint/component-walker';
1515
import {
@@ -20,7 +20,7 @@ import {findAllSubstringIndices} from '../../typescript/literal';
2020

2121
/**
2222
* Rule that walks through every inline or external HTML template and updates outdated
23-
* CSS classes.
23+
* CSS selectors.
2424
*/
2525
export class Rule extends Rules.AbstractRule {
2626
apply(sourceFile: ts.SourceFile): RuleFailure[] {
@@ -43,23 +43,23 @@ export class Walker extends ComponentWalker {
4343
}
4444

4545
/**
46-
* Searches for outdated css names in the specified content and creates replacements
46+
* Searches for outdated css selectors in the specified content and creates replacements
4747
* with the according messages that can be added to a rule failure.
4848
*/
4949
private _createReplacementsForContent(node: ts.Node, templateContent: string) {
5050
const replacements: {failureMessage: string, replacement: Replacement}[] = [];
5151

52-
cssNames.forEach(name => {
53-
if (name.whitelist && !name.whitelist.html) {
52+
cssSelectors.forEach(data => {
53+
if (data.whitelist && !data.whitelist.html) {
5454
return;
5555
}
5656

57-
const failureMessage = `Found deprecated CSS class "${red(name.replace)}"` +
58-
` which has been renamed to "${green(name.replaceWith)}"`;
57+
const failureMessage = `Found deprecated CSS selector "${red(data.replace)}"` +
58+
` which has been renamed to "${green(data.replaceWith)}"`;
5959

60-
findAllSubstringIndices(templateContent, name.replace)
60+
findAllSubstringIndices(templateContent, data.replace)
6161
.map(offset => node.getStart() + offset)
62-
.map(start => new Replacement(start, name.replace.length, name.replaceWith))
62+
.map(start => new Replacement(start, data.replace.length, data.replaceWith))
6363
.forEach(replacement => replacements.push({replacement, failureMessage}));
6464
});
6565

src/lib/schematics/update/rules/element-selectors/elementSelectorsStringLiteralRule.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export class Walker extends RuleWalker {
3535
findAllSubstringIndices(textContent, selector.replace)
3636
.map(offset => node.getStart() + offset)
3737
.map(start => new Replacement(start, selector.replace.length, selector.replaceWith))
38-
.forEach(replacement => this._addFailureWithReplacement(node, replacement, name));
38+
.forEach(replacement => this._addFailureWithReplacement(node, replacement, selector));
3939
});
4040
}
4141

src/lib/schematics/update/test-cases/v5/css-names_expected_output.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ const e = By.css('.mat-form-field-hint-spacer');
1010
@Component({
1111
template: `
1212
<ng-content select=".mat-form-field-suffix"></ng-content>
13-
<div [panelClass]="mat-form-field-underline">Content</div>
1413
1514
<style>
1615
.mat-form-field-suffix {

src/lib/schematics/update/test-cases/v5/css-names_input.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ const e = By.css('.mat-input-hint-spacer');
1010
@Component({
1111
template: `
1212
<ng-content select=".mat-input-suffix"></ng-content>
13-
<div [panelClass]="mat-input-underline">Content</div>
1413
1514
<style>
1615
.mat-input-suffix {

0 commit comments

Comments
 (0)