Skip to content

Commit

Permalink
fix(material/schematics): Add css token renaming migration
Browse files Browse the repository at this point in the history
(cherry picked from commit e8e02a8)
  • Loading branch information
mmalerba committed May 17, 2024
1 parent 3a81e6a commit ae82909
Show file tree
Hide file tree
Showing 8 changed files with 193 additions and 2 deletions.
30 changes: 30 additions & 0 deletions src/cdk/schematics/ng-update/data/css-tokens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {VersionChanges} from '../../update-tool/version-changes';

export interface CssTokenUpgradeData {
/** The CSS selector to replace. */
replace: string;
/** The new CSS selector. */
replaceWith: string;
/**
* Controls which file types in which this replacement is made. If omitted, it is made in all
* files.
*/
replaceIn?: {
/** Replace this name in stylesheet files. */
stylesheet?: boolean;
/** Replace this name in HTML files. */
html?: boolean;
/** Replace this name in TypeScript strings. */
tsStringLiterals?: boolean;
};
}

export const cssTokens: VersionChanges<CssTokenUpgradeData> = {};
1 change: 1 addition & 0 deletions src/cdk/schematics/ng-update/data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export * from './attribute-selectors';
export * from './class-names';
export * from './constructor-checks';
export * from './css-selectors';
export * from './css-tokens';
export * from './element-selectors';
export * from './input-names';
export * from './method-call-checks';
Expand Down
6 changes: 4 additions & 2 deletions src/cdk/schematics/ng-update/devkit-migration-rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
* found in the LICENSE file at https://angular.io/license
*/

import {workspaces} from '@angular-devkit/core';
import {Rule, SchematicContext, Tree} from '@angular-devkit/schematics';
import {NodePackageInstallTask} from '@angular-devkit/schematics/tasks';
import {workspaces} from '@angular-devkit/core';

import {UpdateProject} from '../update-tool';
import {WorkspacePath} from '../update-tool/file-system';
Expand All @@ -24,14 +24,15 @@ import {ClassInheritanceMigration} from './migrations/class-inheritance';
import {ClassNamesMigration} from './migrations/class-names';
import {ConstructorSignatureMigration} from './migrations/constructor-signature';
import {CssSelectorsMigration} from './migrations/css-selectors';
import {CssTokensMigration} from './migrations/css-tokens';
import {ElementSelectorsMigration} from './migrations/element-selectors';
import {InputNamesMigration} from './migrations/input-names';
import {MethodCallArgumentsMigration} from './migrations/method-call-arguments';
import {MiscTemplateMigration} from './migrations/misc-template';
import {OutputNamesMigration} from './migrations/output-names';
import {PropertyNamesMigration} from './migrations/property-names';
import {UpgradeData} from './upgrade-data';
import {SymbolRemovalMigration} from './migrations/symbol-removal';
import {UpgradeData} from './upgrade-data';

/** List of migrations which run for the CDK update. */
export const cdkMigrations: MigrationCtor<UpgradeData>[] = [
Expand All @@ -40,6 +41,7 @@ export const cdkMigrations: MigrationCtor<UpgradeData>[] = [
ClassNamesMigration,
ConstructorSignatureMigration,
CssSelectorsMigration,
CssTokensMigration,
ElementSelectorsMigration,
InputNamesMigration,
MethodCallArgumentsMigration,
Expand Down
89 changes: 89 additions & 0 deletions src/cdk/schematics/ng-update/migrations/css-tokens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import * as ts from 'typescript';
import {ResolvedResource} from '../../update-tool/component-resource-collector';
import {WorkspacePath} from '../../update-tool/file-system';
import {Migration} from '../../update-tool/migration';
import {CssTokenUpgradeData} from '../data/css-tokens';
import {findAllSubstringIndices} from '../typescript/literal';
import {getVersionUpgradeData, UpgradeData} from '../upgrade-data';

/** Characters that can be part of a valid token name. */
const TOKEN_CHARACTER = /[-_a-z0-9]/i;

/**
* Migration that walks through every string literal, template and stylesheet in
* order to migrate outdated CSS tokens to their new name.
*/
export class CssTokensMigration extends Migration<UpgradeData> {
/** Change data that upgrades to the specified target version. */
data: CssTokenUpgradeData[] = getVersionUpgradeData(this, 'cssTokens');

// Only enable the migration rule if there is upgrade data.
enabled = this.data.length !== 0;

override visitNode(node: ts.Node): void {
if (ts.isStringLiteralLike(node)) {
this._visitStringLiteralLike(node);
}
}

override visitTemplate(template: ResolvedResource): void {
this.data.forEach(data => {
if (data.replaceIn && !data.replaceIn.html) {
return;
}

findAllSubstringIndices(template.content, data.replace)
.map(offset => template.start + offset)
// Filter out matches that are followed by a valid token character, so that we don't match
// partial token names.
.filter(start => !TOKEN_CHARACTER.test(template.content[start + data.replace.length] || ''))
.forEach(start => this._replaceSelector(template.filePath, start, data));
});
}

override visitStylesheet(stylesheet: ResolvedResource): void {
this.data.forEach(data => {
if (data.replaceIn && !data.replaceIn.stylesheet) {
return;
}

findAllSubstringIndices(stylesheet.content, data.replace)
.map(offset => stylesheet.start + offset)
// Filter out matches that are followed by a valid token character, so that we don't match
// partial token names.
.filter(
start => !TOKEN_CHARACTER.test(stylesheet.content[start + data.replace.length] || ''),
)
.forEach(start => this._replaceSelector(stylesheet.filePath, start, data));
});
}

private _visitStringLiteralLike(node: ts.StringLiteralLike) {
if (node.parent && node.parent.kind !== ts.SyntaxKind.CallExpression) {
return;
}

const textContent = node.getText();
const filePath = this.fileSystem.resolve(node.getSourceFile().fileName);

this.data.forEach(data => {
if (data.replaceIn && !data.replaceIn.tsStringLiterals) {
return;
}

findAllSubstringIndices(textContent, data.replace)
.map(offset => node.getStart() + offset)
// Filter out matches that are followed by a valid token character, so that we don't match
// partial token names.
.filter(start => !TOKEN_CHARACTER.test(textContent[start + data.replace.length] || ''))
.forEach(start => this._replaceSelector(filePath, start, data));
});
}

private _replaceSelector(filePath: WorkspacePath, start: number, data: CssTokenUpgradeData) {
this.fileSystem
.edit(filePath)
.remove(start, data.replace.length)
.insertRight(start, data.replaceWith);
}
}
4 changes: 4 additions & 0 deletions src/cdk/schematics/ng-update/upgrade-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import {
PropertyNameUpgradeData,
SymbolRemovalUpgradeData,
symbolRemoval,
cssTokens,
CssTokenUpgradeData,
} from './data';

/** Upgrade data for the Angular CDK. */
Expand All @@ -37,6 +39,7 @@ export const cdkUpgradeData: UpgradeData = {
classNames,
constructorChecks,
cssSelectors,
cssTokens,
elementSelectors,
inputNames,
methodCallChecks,
Expand All @@ -54,6 +57,7 @@ export interface UpgradeData {
classNames: VersionChanges<ClassNameUpgradeData>;
constructorChecks: VersionChanges<ConstructorChecksUpgradeData>;
cssSelectors: VersionChanges<CssSelectorUpgradeData>;
cssTokens: VersionChanges<CssTokenUpgradeData>;
elementSelectors: VersionChanges<ElementSelectorUpgradeData>;
inputNames: VersionChanges<InputNameUpgradeData>;
methodCallChecks: VersionChanges<MethodCallUpgradeData>;
Expand Down
62 changes: 62 additions & 0 deletions src/material/schematics/ng-update/data/css-tokens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {TargetVersion, VersionChanges} from '@angular/cdk/schematics';

export interface MaterialCssTokenData {
/** The CSS selector to replace. */
replace: string;
/** The new CSS selector. */
replaceWith: string;
/**
* Controls which file types in which this replacement is made. If omitted, it is made in all
* files.
*/
replaceIn?: {
/** Replace this name in stylesheet files. */
stylesheet?: boolean;
/** Replace this name in HTML files. */
html?: boolean;
/** Replace this name in TypeScript strings. */
tsStringLiterals?: boolean;
};
}

export const cssTokens: VersionChanges<MaterialCssTokenData> = {
[TargetVersion.V18]: [
{
pr: 'https://github.com/angular/components/pull/29026',
changes: [
{
replace: '--mdc-form-field-label-text-color',
replaceWith: '--mat-checkbox-label-text-color',
},
{
replace: '--mdc-form-field-label-text-font',
replaceWith: '--mat-checkbox-label-text-font',
},
{
replace: '--mdc-form-field-label-text-line-height',
replaceWith: '--mat-checkbox-label-text-line-height',
},
{
replace: '--mdc-form-field-label-text-size',
replaceWith: '--mat-checkbox-label-text-size',
},
{
replace: '--mdc-form-field-label-text-tracking',
replaceWith: '--mat-checkbox-label-text-tracking',
},
{
replace: '--mdc-form-field-label-text-weight',
replaceWith: '--mat-checkbox-label-text-weight',
},
],
},
],
};
1 change: 1 addition & 0 deletions src/material/schematics/ng-update/data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export * from './attribute-selectors';
export * from './class-names';
export * from './constructor-checks';
export * from './css-selectors';
export * from './css-tokens';
export * from './element-selectors';
export * from './input-names';
export * from './method-call-checks';
Expand Down
2 changes: 2 additions & 0 deletions src/material/schematics/ng-update/upgrade-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
classNames,
constructorChecks,
cssSelectors,
cssTokens,
elementSelectors,
inputNames,
methodCallChecks,
Expand All @@ -26,6 +27,7 @@ export const materialUpgradeData: UpgradeData = {
classNames,
constructorChecks,
cssSelectors,
cssTokens,
elementSelectors,
inputNames,
methodCallChecks,
Expand Down

0 comments on commit ae82909

Please sign in to comment.