UNPKG

@skyux/packages

Version:

Handles the `ng update` command for SKY UX component libraries.

206 lines 9.3 kB
"use strict"; 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