Skip to content

Commit e8e02a8

Browse files
committed
fix(material/schematics): Add css token renaming migration
1 parent 8563bb8 commit e8e02a8

File tree

8 files changed

+193
-2
lines changed

8 files changed

+193
-2
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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 {VersionChanges} from '../../update-tool/version-changes';
10+
11+
export interface CssTokenUpgradeData {
12+
/** The CSS selector to replace. */
13+
replace: string;
14+
/** The new CSS selector. */
15+
replaceWith: string;
16+
/**
17+
* Controls which file types in which this replacement is made. If omitted, it is made in all
18+
* files.
19+
*/
20+
replaceIn?: {
21+
/** Replace this name in stylesheet files. */
22+
stylesheet?: boolean;
23+
/** Replace this name in HTML files. */
24+
html?: boolean;
25+
/** Replace this name in TypeScript strings. */
26+
tsStringLiterals?: boolean;
27+
};
28+
}
29+
30+
export const cssTokens: VersionChanges<CssTokenUpgradeData> = {};

src/cdk/schematics/ng-update/data/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export * from './attribute-selectors';
1010
export * from './class-names';
1111
export * from './constructor-checks';
1212
export * from './css-selectors';
13+
export * from './css-tokens';
1314
export * from './element-selectors';
1415
export * from './input-names';
1516
export * from './method-call-checks';

src/cdk/schematics/ng-update/devkit-migration-rule.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
import {workspaces} from '@angular-devkit/core';
910
import {Rule, SchematicContext, Tree} from '@angular-devkit/schematics';
1011
import {NodePackageInstallTask} from '@angular-devkit/schematics/tasks';
11-
import {workspaces} from '@angular-devkit/core';
1212

1313
import {UpdateProject} from '../update-tool';
1414
import {WorkspacePath} from '../update-tool/file-system';
@@ -24,14 +24,15 @@ import {ClassInheritanceMigration} from './migrations/class-inheritance';
2424
import {ClassNamesMigration} from './migrations/class-names';
2525
import {ConstructorSignatureMigration} from './migrations/constructor-signature';
2626
import {CssSelectorsMigration} from './migrations/css-selectors';
27+
import {CssTokensMigration} from './migrations/css-tokens';
2728
import {ElementSelectorsMigration} from './migrations/element-selectors';
2829
import {InputNamesMigration} from './migrations/input-names';
2930
import {MethodCallArgumentsMigration} from './migrations/method-call-arguments';
3031
import {MiscTemplateMigration} from './migrations/misc-template';
3132
import {OutputNamesMigration} from './migrations/output-names';
3233
import {PropertyNamesMigration} from './migrations/property-names';
33-
import {UpgradeData} from './upgrade-data';
3434
import {SymbolRemovalMigration} from './migrations/symbol-removal';
35+
import {UpgradeData} from './upgrade-data';
3536

3637
/** List of migrations which run for the CDK update. */
3738
export const cdkMigrations: MigrationCtor<UpgradeData>[] = [
@@ -40,6 +41,7 @@ export const cdkMigrations: MigrationCtor<UpgradeData>[] = [
4041
ClassNamesMigration,
4142
ConstructorSignatureMigration,
4243
CssSelectorsMigration,
44+
CssTokensMigration,
4345
ElementSelectorsMigration,
4446
InputNamesMigration,
4547
MethodCallArgumentsMigration,
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import * as ts from 'typescript';
2+
import {ResolvedResource} from '../../update-tool/component-resource-collector';
3+
import {WorkspacePath} from '../../update-tool/file-system';
4+
import {Migration} from '../../update-tool/migration';
5+
import {CssTokenUpgradeData} from '../data/css-tokens';
6+
import {findAllSubstringIndices} from '../typescript/literal';
7+
import {getVersionUpgradeData, UpgradeData} from '../upgrade-data';
8+
9+
/** Characters that can be part of a valid token name. */
10+
const TOKEN_CHARACTER = /[-_a-z0-9]/i;
11+
12+
/**
13+
* Migration that walks through every string literal, template and stylesheet in
14+
* order to migrate outdated CSS tokens to their new name.
15+
*/
16+
export class CssTokensMigration extends Migration<UpgradeData> {
17+
/** Change data that upgrades to the specified target version. */
18+
data: CssTokenUpgradeData[] = getVersionUpgradeData(this, 'cssTokens');
19+
20+
// Only enable the migration rule if there is upgrade data.
21+
enabled = this.data.length !== 0;
22+
23+
override visitNode(node: ts.Node): void {
24+
if (ts.isStringLiteralLike(node)) {
25+
this._visitStringLiteralLike(node);
26+
}
27+
}
28+
29+
override visitTemplate(template: ResolvedResource): void {
30+
this.data.forEach(data => {
31+
if (data.replaceIn && !data.replaceIn.html) {
32+
return;
33+
}
34+
35+
findAllSubstringIndices(template.content, data.replace)
36+
.map(offset => template.start + offset)
37+
// Filter out matches that are followed by a valid token character, so that we don't match
38+
// partial token names.
39+
.filter(start => !TOKEN_CHARACTER.test(template.content[start + data.replace.length] || ''))
40+
.forEach(start => this._replaceSelector(template.filePath, start, data));
41+
});
42+
}
43+
44+
override visitStylesheet(stylesheet: ResolvedResource): void {
45+
this.data.forEach(data => {
46+
if (data.replaceIn && !data.replaceIn.stylesheet) {
47+
return;
48+
}
49+
50+
findAllSubstringIndices(stylesheet.content, data.replace)
51+
.map(offset => stylesheet.start + offset)
52+
// Filter out matches that are followed by a valid token character, so that we don't match
53+
// partial token names.
54+
.filter(
55+
start => !TOKEN_CHARACTER.test(stylesheet.content[start + data.replace.length] || ''),
56+
)
57+
.forEach(start => this._replaceSelector(stylesheet.filePath, start, data));
58+
});
59+
}
60+
61+
private _visitStringLiteralLike(node: ts.StringLiteralLike) {
62+
if (node.parent && node.parent.kind !== ts.SyntaxKind.CallExpression) {
63+
return;
64+
}
65+
66+
const textContent = node.getText();
67+
const filePath = this.fileSystem.resolve(node.getSourceFile().fileName);
68+
69+
this.data.forEach(data => {
70+
if (data.replaceIn && !data.replaceIn.tsStringLiterals) {
71+
return;
72+
}
73+
74+
findAllSubstringIndices(textContent, data.replace)
75+
.map(offset => node.getStart() + offset)
76+
// Filter out matches that are followed by a valid token character, so that we don't match
77+
// partial token names.
78+
.filter(start => !TOKEN_CHARACTER.test(textContent[start + data.replace.length] || ''))
79+
.forEach(start => this._replaceSelector(filePath, start, data));
80+
});
81+
}
82+
83+
private _replaceSelector(filePath: WorkspacePath, start: number, data: CssTokenUpgradeData) {
84+
this.fileSystem
85+
.edit(filePath)
86+
.remove(start, data.replace.length)
87+
.insertRight(start, data.replaceWith);
88+
}
89+
}

src/cdk/schematics/ng-update/upgrade-data.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ import {
2929
PropertyNameUpgradeData,
3030
SymbolRemovalUpgradeData,
3131
symbolRemoval,
32+
cssTokens,
33+
CssTokenUpgradeData,
3234
} from './data';
3335

3436
/** Upgrade data for the Angular CDK. */
@@ -37,6 +39,7 @@ export const cdkUpgradeData: UpgradeData = {
3739
classNames,
3840
constructorChecks,
3941
cssSelectors,
42+
cssTokens,
4043
elementSelectors,
4144
inputNames,
4245
methodCallChecks,
@@ -54,6 +57,7 @@ export interface UpgradeData {
5457
classNames: VersionChanges<ClassNameUpgradeData>;
5558
constructorChecks: VersionChanges<ConstructorChecksUpgradeData>;
5659
cssSelectors: VersionChanges<CssSelectorUpgradeData>;
60+
cssTokens: VersionChanges<CssTokenUpgradeData>;
5761
elementSelectors: VersionChanges<ElementSelectorUpgradeData>;
5862
inputNames: VersionChanges<InputNameUpgradeData>;
5963
methodCallChecks: VersionChanges<MethodCallUpgradeData>;
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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 {TargetVersion, VersionChanges} from '@angular/cdk/schematics';
10+
11+
export interface MaterialCssTokenData {
12+
/** The CSS selector to replace. */
13+
replace: string;
14+
/** The new CSS selector. */
15+
replaceWith: string;
16+
/**
17+
* Controls which file types in which this replacement is made. If omitted, it is made in all
18+
* files.
19+
*/
20+
replaceIn?: {
21+
/** Replace this name in stylesheet files. */
22+
stylesheet?: boolean;
23+
/** Replace this name in HTML files. */
24+
html?: boolean;
25+
/** Replace this name in TypeScript strings. */
26+
tsStringLiterals?: boolean;
27+
};
28+
}
29+
30+
export const cssTokens: VersionChanges<MaterialCssTokenData> = {
31+
[TargetVersion.V18]: [
32+
{
33+
pr: 'https://github.com/angular/components/pull/29026',
34+
changes: [
35+
{
36+
replace: '--mdc-form-field-label-text-color',
37+
replaceWith: '--mat-checkbox-label-text-color',
38+
},
39+
{
40+
replace: '--mdc-form-field-label-text-font',
41+
replaceWith: '--mat-checkbox-label-text-font',
42+
},
43+
{
44+
replace: '--mdc-form-field-label-text-line-height',
45+
replaceWith: '--mat-checkbox-label-text-line-height',
46+
},
47+
{
48+
replace: '--mdc-form-field-label-text-size',
49+
replaceWith: '--mat-checkbox-label-text-size',
50+
},
51+
{
52+
replace: '--mdc-form-field-label-text-tracking',
53+
replaceWith: '--mat-checkbox-label-text-tracking',
54+
},
55+
{
56+
replace: '--mdc-form-field-label-text-weight',
57+
replaceWith: '--mat-checkbox-label-text-weight',
58+
},
59+
],
60+
},
61+
],
62+
};

src/material/schematics/ng-update/data/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export * from './attribute-selectors';
1010
export * from './class-names';
1111
export * from './constructor-checks';
1212
export * from './css-selectors';
13+
export * from './css-tokens';
1314
export * from './element-selectors';
1415
export * from './input-names';
1516
export * from './method-call-checks';

src/material/schematics/ng-update/upgrade-data.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
classNames,
1313
constructorChecks,
1414
cssSelectors,
15+
cssTokens,
1516
elementSelectors,
1617
inputNames,
1718
methodCallChecks,
@@ -26,6 +27,7 @@ export const materialUpgradeData: UpgradeData = {
2627
classNames,
2728
constructorChecks,
2829
cssSelectors,
30+
cssTokens,
2931
elementSelectors,
3032
inputNames,
3133
methodCallChecks,

0 commit comments

Comments
 (0)