@skyux/packages
Version:
Handles the `ng update` command for SKY UX component libraries.
121 lines • 6.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.convertDefinitionListToDescriptionList = convertDefinitionListToDescriptionList;
const eol_1 = require("@schematics/angular/utility/eol");
const parse5_1 = require("parse5");
const log_once_1 = require("../../utility/log-once");
const template_1 = require("../../utility/template");
const ng_ast_1 = require("../../utility/typescript/ng-ast");
const swap_imported_class_1 = require("../../utility/typescript/swap-imported-class");
const visit_project_files_1 = require("../../utility/visit-project-files");
/**
* Description list does not use a heading element.
* Create a new `<h3>` element with the heading text.
*/
function moveHeading(definitionList, recorder, offset, eol) {
const heading = (0, template_1.getElementsByTagName)('sky-definition-list-heading', definitionList)[0];
if ((0, template_1.isParentNode)(heading)) {
const headingText = (0, parse5_1.serialize)(heading);
const indent = ' '.repeat(definitionList.sourceCodeLocation.startTag.startCol - 1);
recorder.insertLeft(offset + definitionList.sourceCodeLocation.startTag.startOffset, `<h3 class="sky-margin-stacked-sm">${headingText}</h3>${eol}${indent}`);
recorder.remove(offset + heading.sourceCodeLocation.startOffset, heading.sourceCodeLocation.endOffset -
heading.sourceCodeLocation.startOffset);
}
}
const regexpEscape = (str) => str.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
const tags = {
'sky-definition-list': 'sky-description-list',
'sky-definition-list-content': 'sky-description-list-content',
'sky-definition-list-label': 'sky-description-list-term',
'sky-definition-list-value': 'sky-description-list-description',
};
function definitionListTagSwap(context) {
return (position, oldTag, node, content) => {
if (position === 'open') {
const attributesString = content.substring(node.sourceCodeLocation.startOffset + oldTag.length + 1, node.sourceCodeLocation.startTag.endOffset);
if (oldTag === 'sky-definition-list') {
let value = `<${tags[oldTag]} mode="horizontal"`;
// Copy over any other attributes that are not in the new tag.
for (const attr of node.attrs) {
// eslint-disable-next-line @cspell/spellchecker
if (['labelwidth', '[labelwidth]'].includes(attr.name)) {
context.logger.warn(`The "labelWidth" attribute is not supported on the <${tags[oldTag]}> component. Please review the code to ensure it still works as expected.`);
}
else if (attr.name === 'defaultValue'.toLowerCase()) {
value += ` defaultDescription="${attr.value}"`;
}
else if (attr.name === '[defaultValue]'.toLowerCase()) {
value += ` [defaultDescription]="${attr.value}"`;
}
else if (!['defaultvalue', '[defaultvalue]', 'mode'].includes(attr.name)) {
const attributeText = new RegExp(`(?<=\\s)${regexpEscape(attr.name)}(="[^"]*")?`, 'di')
.exec(attributesString)
?.shift();
if (attributeText) {
value += ` ${attributeText}`;
}
}
}
value += '>';
return value;
}
return `<${tags[oldTag]}${attributesString}`;
}
return `</${tags[oldTag]}>`;
};
}
function convertTemplate(recorder, context, content, offset = 0) {
const eol = (0, eol_1.getEOL)(content);
const fragment = (0, template_1.parseTemplate)(content);
const definitionLists = (0, template_1.getElementsByTagName)('sky-definition-list', fragment);
for (const definitionList of definitionLists) {
moveHeading(definitionList, recorder, offset, eol);
(0, template_1.swapTags)(content, recorder, offset, Object.keys(tags), definitionListTagSwap(context), definitionList);
}
if (definitionLists.length > 0) {
(0, log_once_1.logOnce)(context, 'info', `Converted ${definitionLists.length} <sky-definition-list> component(s) to <sky-description-list> component(s). Next steps: https://developer.blackbaud.com/skyux/learn/develop/deprecation/definition-list`);
}
}
function convertHtmlFile(tree, filePath, context) {
const content = tree.readText(filePath);
if (content.includes('<sky-definition-list')) {
const recorder = tree.beginUpdate(filePath);
convertTemplate(recorder, context, content);
tree.commitUpdate(recorder);
}
}
function convertTypescriptFile(tree, filePath, context) {
const source = (0, ng_ast_1.parseSourceFile)(tree, filePath);
const templates = (0, ng_ast_1.getInlineTemplates)(source);
const recorder = tree.beginUpdate(filePath);
if (templates.length > 0) {
const content = tree.readText(filePath);
for (const template of templates) {
convertTemplate(recorder, context, content.slice(template.start, template.end), template.start);
}
}
if ((0, ng_ast_1.isImportedFromPackage)(source, 'SkyDefinitionListModule', '@skyux/layout')) {
(0, swap_imported_class_1.swapImportedClass)(recorder, filePath, source, [
{
classNames: {
SkyDefinitionListModule: 'SkyDescriptionListModule',
},
moduleName: '@skyux/layout',
},
]);
}
tree.commitUpdate(recorder);
}
function convertDefinitionListToDescriptionList(projectPath) {
return (tree, context) => {
(0, visit_project_files_1.visitProjectFiles)(tree, projectPath, (filePath) => {
if (filePath.endsWith('.html')) {
convertHtmlFile(tree, filePath, context);
}
else if (filePath.endsWith('.ts')) {
convertTypescriptFile(tree, filePath, context);
}
});
};
}
//# sourceMappingURL=convert-definition-list-to-description-list.js.map