Skip to content

Commit

Permalink
feat(material/schematics): add template migration to schematic (#24563)
Browse files Browse the repository at this point in the history
* create ComponentMigrator interface to store the
  different types of migrations for each component
* refactor individual migrations to work with ComponentMigrator
* add missing unit test for addAttribute
* create TemplateMigrator to unify the interface
  for template migrations
  • Loading branch information
wagnermaciel authored and mmalerba committed Jul 15, 2022
1 parent 0108de5 commit 6feaaea
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 27 deletions.
5 changes: 2 additions & 3 deletions src/material/schematics/ng-generate/mdc-migration/index.ts
Expand Up @@ -11,9 +11,8 @@ import {Schema} from './schema';
import {DevkitFileSystem, UpdateProject, findStylesheetFiles} from '@angular/cdk/schematics';
import {ThemingStylesMigration} from './rules/theming-styles';
import {TemplateMigration} from './rules/template-migration';
import {MIGRATORS} from './rules';
import {ComponentMigrator, MIGRATORS} from './rules';
import {dirname} from 'path';
import {StyleMigrator} from './rules/style-migrator';

/** Groups of components that must be migrated together. */
const migrationGroups = [
Expand Down Expand Up @@ -62,7 +61,7 @@ export default function (options: Schema): Rule {
console.log('Migrating:', [...componentsToMigrate]);
console.log('Directory:', migrationDir);

const migrators: StyleMigrator[] = [];
const migrators: ComponentMigrator[] = [];
for (let i = 0; i < MIGRATORS.length; i++) {
if (componentsToMigrate.has(MIGRATORS[i].component)) {
migrators.push(MIGRATORS[i]);
Expand Down
70 changes: 57 additions & 13 deletions src/material/schematics/ng-generate/mdc-migration/rules/index.ts
Expand Up @@ -19,18 +19,62 @@ import {SlideToggleStylesMigrator} from './components/slide-toggle/slide-toggle-
import {SliderStylesMigrator} from './components/slider/slider-styles';
import {TableStylesMigrator} from './components/table/table-styles';
import {StyleMigrator} from './style-migrator';
import {TemplateMigrator} from './template-migrator';

export const MIGRATORS: StyleMigrator[] = [
new ButtonStylesMigrator(),
new CardStylesMigrator(),
new CheckboxStylesMigrator(),
new ChipsStylesMigrator(),
new DialogStylesMigrator(),
new PaginatorStylesMigrator(),
new ProgressBarStylesMigrator(),
new ProgressSpinnerStylesMigrator(),
new RadioStylesMigrator(),
new SlideToggleStylesMigrator(),
new SliderStylesMigrator(),
new TableStylesMigrator(),
/** Contains the migrators to migrate a single component. */
export interface ComponentMigrator {
component: string;
styles: StyleMigrator;
template?: TemplateMigrator;
}

export const MIGRATORS: ComponentMigrator[] = [
{
component: 'button',
styles: new ButtonStylesMigrator(),
},
{
component: 'card',
styles: new CardStylesMigrator(),
},
{
component: 'checkbox',
styles: new CheckboxStylesMigrator(),
},
{
component: 'chips',
styles: new ChipsStylesMigrator(),
},
{
component: 'dialog',
styles: new DialogStylesMigrator(),
},
{
component: 'paginator',
styles: new PaginatorStylesMigrator(),
},
{
component: 'progress-bar',
styles: new ProgressBarStylesMigrator(),
},
{
component: 'progress-spinner',
styles: new ProgressSpinnerStylesMigrator(),
},
{
component: 'radio',
styles: new RadioStylesMigrator(),
},
{
component: 'slide-toggle',
styles: new SlideToggleStylesMigrator(),
},
{
component: 'slider',
styles: new SliderStylesMigrator(),
},
{
component: 'table',
styles: new TableStylesMigrator(),
},
];
Expand Up @@ -8,10 +8,10 @@

import {Migration, ResolvedResource} from '@angular/cdk/schematics';
import {SchematicContext} from '@angular-devkit/schematics';
import {StyleMigrator} from './style-migrator';
import {visitElements, parseTemplate} from './tree-traversal';
import {ComponentMigrator} from '.';

export class TemplateMigration extends Migration<StyleMigrator[], SchematicContext> {
export class TemplateMigration extends Migration<ComponentMigrator[], SchematicContext> {
enabled = true;

override visitTemplate(template: ResolvedResource) {
Expand Down
@@ -0,0 +1,39 @@
/**
* @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 * as compiler from '@angular/compiler';

export abstract class TemplateMigrator {
/** The name of the component that this migration handles. */
abstract component: string;

/** The tag name to be updated in the template. */
abstract tagName: string;

/**
* Updates the start tag of the given node in the html template.
*
* @param template The html content to be updated.
* @param node The Element node to be updated.
* @returns The updated template.
*/
updateEndTag(template: string, node: compiler.TmplAstElement): string {
return template;
}

/**
* Updates the end tag of the given node in the html template.
*
* @param template The html content to be updated.
* @param node The Element node to be updated.
* @returns The updated template.
*/
updateStartTag(template: string, node: compiler.TmplAstElement): string {
return template;
}
}
Expand Up @@ -8,11 +8,11 @@

import {Migration, ResolvedResource} from '@angular/cdk/schematics';
import {SchematicContext} from '@angular-devkit/schematics';
import {StyleMigrator} from './style-migrator';
import * as postcss from 'postcss';
import * as scss from 'postcss-scss';
import {ComponentMigrator} from '.';

export class ThemingStylesMigration extends Migration<StyleMigrator[], SchematicContext> {
export class ThemingStylesMigration extends Migration<ComponentMigrator[], SchematicContext> {
enabled = true;
namespace: string;

Expand Down Expand Up @@ -40,13 +40,13 @@ export class ThemingStylesMigration extends Migration<StyleMigrator[], Schematic

atIncludeHandler(atRule: postcss.AtRule) {
const migrator = this.upgradeData.find(m => {
return m.isLegacyMixin(this.namespace, atRule);
return m.styles.isLegacyMixin(this.namespace, atRule);
});
if (migrator) {
migrator.replaceMixin(this.namespace, atRule);
migrator.styles.replaceMixin(this.namespace, atRule);
} else if (atRule.params.includes('all-component-themes') && atRule.parent) {
this.upgradeData.forEach(m => {
m?.addNewMixinsAfterNode(this.namespace, atRule);
m?.styles.addNewMixinsAfterNode(this.namespace, atRule);
});
}
}
Expand All @@ -56,15 +56,15 @@ export class ThemingStylesMigration extends Migration<StyleMigrator[], Schematic
let isDeprecatedSelector;

const migrator = this.upgradeData.find(m => {
isLegacySelector = m.isLegacySelector(rule);
isDeprecatedSelector = m.isDeprecatedSelector(rule);
isLegacySelector = m.styles.isLegacySelector(rule);
isDeprecatedSelector = m.styles.isDeprecatedSelector(rule);
return isLegacySelector || isDeprecatedSelector;
});

if (isLegacySelector) {
migrator?.replaceLegacySelector(rule);
migrator?.styles.replaceLegacySelector(rule);
} else if (isDeprecatedSelector) {
migrator?.addDeprecatedSelectorComment(rule);
migrator?.styles.addDeprecatedSelectorComment(rule);
}
}
}
Expand Down
Expand Up @@ -109,5 +109,14 @@ describe('#visitElements', () => {
'<a attr="val"><b attr="val"></b><c attr="val"></c></a>',
);
});

it('should handle adding multiple attrs to a single element', async () => {
let html = '<a></a>';
visitElements(parseTemplate(html).nodes, undefined, node => {
html = addAttribute(html, node, 'attr1', 'val1');
html = addAttribute(html, node, 'attr2', 'val2');
});
expect(html).toBe('<a attr2="val2" attr1="val1"></a>');
});
});
});

0 comments on commit 6feaaea

Please sign in to comment.