igniteui-angular-sovn
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
107 lines (89 loc) • 3.97 kB
text/typescript
import {
Rule,
SchematicContext,
Tree
} from '@angular-devkit/schematics';
import { Element } from '@angular/compiler';
import { nativeImport } from '../common/import-helper.js';
import { Options } from '../../schematics/interfaces/options';
import { BoundPropertyObject, InputPropertyType, UpdateChanges } from '../common/UpdateChanges';
import { FileChange, findElementNodes, getAttribute, getSourceOffset, parseFile, hasAttribute } from '../common/util';
const version = '15.1.0';
export default (options: Options): Rule => async (host: Tree, context: SchematicContext) => {
context.logger.info(`Applying migration for Ignite UI for Angular to version ${version}`);
const { HtmlParser } = await nativeImport('@angular/compiler') as typeof import('@angular/compiler');
const update = new UpdateChanges(__dirname, host, context);
const cardsToMigrate = new Set<any>();
const CARD_ACTIONS = ['igx-card-actions'];
const prop = ['igxButton'];
const changes = new Map<string, FileChange[]>();
const applyChanges = () => {
for (const [path, change] of changes.entries()) {
let buffer = host.read(path).toString();
change.sort((c, c1) => c.position - c1.position)
.reverse()
.forEach(c => buffer = c.apply(buffer));
host.overwrite(path, buffer);
}
};
const addChange = (path: string, change: FileChange) => {
if (changes.has(path)) {
changes.get(path).push(change);
} else {
changes.set(path, [change]);
}
};
const getChildren = (parent: Element, buttons: any[], icons: any[]) => {
const cardButtons = parent.children.filter(btn => (btn as Element).attrs !== undefined && hasAttribute(btn as Element, prop));
const cardIcons = parent.children.filter(btn => (btn as Element).name === 'igx-icon');
buttons.push(...cardButtons);
icons.push(...cardIcons);
}
for (const path of update.templateFiles) {
cardsToMigrate.clear();
const cardActions = findElementNodes(parseFile(new HtmlParser(), host, path), CARD_ACTIONS);
cardActions.forEach(card => {
const card_action_elem = card as Element;
const buttons: any[] = [];
const icons: any[] = [];
getChildren(card_action_elem, buttons, icons);
icons.map(node => getSourceOffset(node as Element))
.forEach(offset => {
const { startTag, file, node } = offset;
const end = getAttribute(node, 'igxEnd')[0];
if (!end) {
addChange(file.url, new FileChange(startTag.end - 1, ' igxEnd'));
}
})
buttons.map(node => getSourceOffset(node as Element))
.forEach(offset => {
const { startTag, file, node } = offset;
const { value } = getAttribute(node, prop)[0];
const start = getAttribute(node, 'igxStart')[0];
const end = getAttribute(node, 'igxEnd')[0];
if (!start && value !== 'icon') {
addChange(file.url, new FileChange(startTag.end - 1, ' igxStart'));
}
if (!end && value === 'icon') {
addChange(file.url, new FileChange(startTag.end - 1, ' igxEnd'));
}
});
});
}
update.shouldInvokeLS = options['shouldInvokeLS'];
update.addValueTransform('roundShape_is_deprecated', (args: BoundPropertyObject): void => {
args.bindingType = InputPropertyType.STRING;
switch (args.value) {
case 'true':
args.value = 'circle';
break;
case 'false':
args.value = 'square';
break;
default:
args.value += ` ? 'circle' : 'square' `;
}
});
applyChanges();
update.applyChanges();
};