@skyux/packages
Version:
Handles the `ng update` command for SKY UX component libraries.
206 lines • 9.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.convertPageSummaryToPageHeader = convertPageSummaryToPageHeader;
const schematics_1 = require("@angular-devkit/schematics");
const static_1 = require("@angular-devkit/schematics/src/tree/static");
const utility_1 = require("@schematics/angular/utility");
const eol_1 = require("@schematics/angular/utility/eol");
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");
/**
* The page header component uses a `pageTitle` attribute for its title.
* Extracts the title from the `<sky-page-summary-title>` element and returns it
* as a string.
* If the title is anything more than a simple text node, an error is thrown.
*/
function getPageTitle(pageSummary) {
const heading = (0, template_1.getElementsByTagName)('sky-page-summary-title', pageSummary)[0];
if ((0, template_1.isParentNode)(heading) &&
heading.childNodes.length === 1 &&
heading.childNodes[0].nodeName === '#text') {
return heading.childNodes[0].value.trim();
}
else if (!heading) {
return '';
}
else {
// If the heading contains something other than a single text node,
// throw an error to indicate that the title cannot be converted.
throw new Error(`The '<sky-page-summary-title>' element contains additional markup that is not supported as a 'pageTitle' for the <sky-page-header> component.`);
}
}
/**
* Moves detail elements (subtitle, status, content, key info) from the
* <sky-page-summary> element to a <sky-page-header-details> element.
*/
function moveDetails(pageSummary, recorder, content, offset) {
const detailsContents = [
'sky-page-summary-subtitle',
'sky-page-summary-status',
'sky-page-summary-content',
'sky-page-summary-key-info',
]
.flatMap((tag) => {
const elements = (0, template_1.getElementsByTagName)(tag, pageSummary);
return elements.map((element) => ({
tag,
content: content
.substring(element.sourceCodeLocation.startTag.endOffset, element.sourceCodeLocation.endTag.startOffset)
.trim(),
}));
})
.filter(Boolean);
const indent = ' '.repeat(pageSummary.sourceCodeLocation.endTag.startCol);
const eol = (0, eol_1.getEOL)(content);
if (detailsContents.length > 0) {
recorder.insertLeft(pageSummary.sourceCodeLocation.endTag.startOffset + offset, [
` <sky-page-header-details>`,
detailsContents
.map((detailsContent) => [
`${indent} <div class="${['sky-page-summary-subtitle'].includes(detailsContent.tag) ? 'sky-margin-stacked-sm sky-emphasized' : 'sky-margin-stacked-md'}">`,
`${indent} ${modifyDetailsContent(detailsContent)}`,
`${indent} </div>`,
].join(eol))
.join(eol),
`${indent} </sky-page-header-details>`,
`${indent}`,
].join(eol));
}
}
function modifyDetailsContent(detailsContent) {
if (detailsContent.tag === 'sky-page-summary-key-info') {
// Add class="sky-margin-inline-xxl" and remove layout input from sky-key-info.
const content = detailsContent.content.trim();
const tree = (0, static_1.empty)();
tree.create('template.html', content);
const recorder = tree.beginUpdate('template.html');
const partial = (0, template_1.parseTemplate)(content);
const keyInfoElements = (0, template_1.getElementsByTagName)('sky-key-info', partial);
keyInfoElements.forEach((element) => {
recorder.insertRight(element.sourceCodeLocation.startTag.startOffset +
'<sky-key-info'.length, ` class="sky-margin-inline-xxl"`);
const layoutAttr = element.sourceCodeLocation.attrs?.['layout'] ||
element.sourceCodeLocation.attrs?.['[layout]'];
if (layoutAttr) {
recorder.remove(layoutAttr.startOffset, layoutAttr.endOffset - layoutAttr.startOffset);
}
});
tree.commitUpdate(recorder);
return tree.readText('template.html');
}
return detailsContent.content.trim();
}
/**
* Removes title and detail elements from the page summary, including
* <sky-page-summary-title>, <sky-page-summary-subtitle>, <sky-page-summary-status>,
* <sky-page-summary-content>, and <sky-page-summary-key-info>.
*/
function removeTitleAndDetailElements(pageSummary, recorder, content, offset) {
const tagsToRemove = [
'sky-page-summary-title',
'sky-page-summary-subtitle',
'sky-page-summary-status',
'sky-page-summary-content',
'sky-page-summary-key-info',
];
const eol = (0, eol_1.getEOL)(content);
for (const tag of tagsToRemove) {
const elements = (0, template_1.getElementsByTagName)(tag, pageSummary);
elements.forEach((element) => {
const trailingLineBreak = content.indexOf(eol, offset + element.sourceCodeLocation.endOffset) ===
offset + element.sourceCodeLocation.endOffset;
recorder.remove(offset + element.sourceCodeLocation.startOffset, element.sourceCodeLocation.endOffset -
element.sourceCodeLocation.startOffset +
(trailingLineBreak ? eol.length : 0));
});
}
}
const tags = {
'sky-page-summary': 'sky-page-header',
'sky-page-summary-alert': 'sky-page-header-alerts',
'sky-page-summary-image': 'sky-page-header-avatar',
};
function pageSummaryTagSwap() {
return (position, oldTag, node, content) => {
if (position === 'open') {
if (oldTag === Object.keys(tags)[0]) {
return `<${tags[oldTag]} pageTitle="${getPageTitle(node)}">`;
}
return `<${tags[oldTag]}>`;
}
return `</${tags[oldTag]}>`;
};
}
function convertTemplate(recorder, content, context, offset = 0) {
const fragment = (0, template_1.parseTemplate)(content);
const pageSummaries = (0, template_1.getElementsByTagName)('sky-page-summary', fragment);
for (const pageSummary of pageSummaries) {
removeTitleAndDetailElements(pageSummary, recorder, content, offset);
moveDetails(pageSummary, recorder, content, offset);
(0, template_1.swapTags)(content, recorder, offset, Object.keys(tags), pageSummaryTagSwap(), pageSummary);
}
if (pageSummaries.length > 0) {
(0, log_once_1.logOnce)(context, 'info', `Converted <sky-page-summary> component(s) to <sky-page-header> component(s). Next steps: https://developer.blackbaud.com/skyux/learn/develop/deprecation/page-summary`);
}
}
function convertHtmlFile(tree, filePath, context) {
const content = tree.readText(filePath);
if (content.includes('<sky-page-summary')) {
const recorder = tree.beginUpdate(filePath);
convertTemplate(recorder, content, context);
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, content.slice(template.start, template.end), context, template.start);
}
}
if ((0, ng_ast_1.isImportedFromPackage)(source, 'SkyPageSummaryModule', '@skyux/layout')) {
(0, swap_imported_class_1.swapImportedClass)(recorder, filePath, source, [
{
classNames: {
SkyPageSummaryModule: 'SkyPageModule',
},
moduleName: {
old: '@skyux/layout',
new: '@skyux/pages',
},
},
]);
}
tree.commitUpdate(recorder);
}
function convertPageSummaryToPageHeader(projectPath) {
return (0, schematics_1.chain)([
(tree, context) => {
(0, visit_project_files_1.visitProjectFiles)(tree, projectPath, (filePath) => {
try {
if (filePath.endsWith('.html')) {
convertHtmlFile(tree, filePath, context);
}
else if (filePath.endsWith('.ts')) {
convertTypescriptFile(tree, filePath, context);
}
}
catch (error) {
/* istanbul ignore next */
const msg = error instanceof Error ? error.message : String(error);
throw new Error(`Error converting '${filePath}': ${msg}`);
}
});
},
(0, utility_1.addDependency)('@skyux/pages', `13.7.0`, {
existing: utility_1.ExistingBehavior.Skip,
}),
]);
}
//# sourceMappingURL=convert-page-summary-to-page-header.js.map