@taiga-ui/cdk
Version:
Base library for creating Angular components and applications using Taiga UI principles regarding of actual visual appearance
193 lines • 8.68 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.migrateAccordionItem = migrateAccordionItem;
const elements_1 = require("../../../../utils/templates/elements");
const template_resource_1 = require("../../../../utils/templates/template-resource");
const templates_1 = require("../../../utils/templates");
function migrateAccordionItem({ resource, recorder, fileSystem, }) {
const template = (0, template_resource_1.getTemplateFromTemplateResource)(resource, fileSystem);
const templateOffset = (0, template_resource_1.getTemplateOffset)(resource);
const items = (0, elements_1.findElementsByTagName)(template, 'tui-accordion-item').filter((element) => !(0, templates_1.hasAncestor)(element, 'tui-accordion-item'));
const replacements = items
.map((element) => buildReplacement(template, element, {
isStandalone: !(0, templates_1.hasAncestor)(element, 'tui-accordion'),
}))
.filter((x) => Boolean(x))
.sort((a, b) => b.startOffset - a.startOffset);
replacements.forEach(({ startOffset, endOffset, replacement }) => {
recorder.remove(templateOffset + startOffset, endOffset - startOffset);
recorder.insertRight(templateOffset + startOffset, replacement);
});
}
function buildReplacement(template, element, options) {
var _a, _b, _c, _d;
const loc = element.sourceCodeLocation;
const startTag = loc === null || loc === void 0 ? void 0 : loc.startTag;
const endTag = loc === null || loc === void 0 ? void 0 : loc.endTag;
if (!startTag || !endTag) {
return null;
}
// cspell:disable
const contentElements = (0, elements_1.findElementsByFn)([element], (el) => (0, elements_1.hasElementAttribute)(el, 'tuiaccordionitemcontent'));
const contentElement = contentElements[contentElements.length - 1];
if (!((_a = contentElement === null || contentElement === void 0 ? void 0 : contentElement.sourceCodeLocation) === null || _a === void 0 ? void 0 : _a.startTag)) {
return null;
}
const contentStart = contentElement.sourceCodeLocation.startTag.startOffset;
const contentEnd = (_b = contentElement.sourceCodeLocation.endTag) === null || _b === void 0 ? void 0 : _b.endOffset;
const headerRaw = template.slice(startTag.endOffset, contentStart);
const header = normalizePlainText(normalizeBlock(headerRaw));
const contentRaw = contentEnd === undefined
? ''
: template.slice(contentElement.sourceCodeLocation.startTag.endOffset, (_d = (_c = contentElement.sourceCodeLocation.endTag) === null || _c === void 0 ? void 0 : _c.startOffset) !== null && _d !== void 0 ? _d : contentEnd);
const contentBlock = normalizeBlock(transformAccordionItems(contentRaw));
const content = normalizePlainText(contentBlock);
const forceBlock = contentBlock.includes('\n');
const { indent, startOffset } = getLineIndent(template, startTag.startOffset);
const buttonAttr = getButtonAttr(element);
const isLazy = options.isStandalone && contentElement.tagName === 'ng-template';
const lineIndent = options.isStandalone ? `${indent} ` : indent;
const ATTRS_TO_REMOVE = [
'borders',
'disableHover',
'showArrow',
'async',
'rounded',
'tuiaccordionitemcontent',
];
const attributes = element.attrs
.filter((attr) => !isOpenAttr(attr.name) &&
!ATTRS_TO_REMOVE.includes(attr.name.toLowerCase()))
.map((attr) => `${attr.name}${attr.value ? `="${attr.value}"` : ''}`);
const classAttr = attributes.find((attr) => attr.startsWith('class'));
if (classAttr) {
attributes.splice(attributes.indexOf(classAttr), 1);
}
const otherAttrs = attributes.length ? ` ${attributes.join(' ')}` : '';
const classAttrStr = classAttr ? ` ${classAttr}` : '';
const button = buildButton(header, `${buttonAttr}${otherAttrs}`, lineIndent);
const expand = buildExpand(content, isLazy, lineIndent, forceBlock, classAttrStr);
const replacement = options.isStandalone
? [`${indent}<tui-accordion>`, button, expand, `${indent}</tui-accordion>`].join('\n')
: [button, expand].join('\n');
return {
startOffset,
endOffset: endTag.endOffset,
replacement,
};
}
function getButtonAttr(element) {
const openAttr = element.attrs.find((attr) => isOpenAttr(attr.name));
if (!openAttr) {
return 'tuiAccordion';
}
if (openAttr.name === 'open') {
return openAttr.value ? `tuiAccordion="${openAttr.value}"` : 'tuiAccordion';
}
if (openAttr.name === '[open]') {
return openAttr.value ? `[tuiAccordion]="${openAttr.value}"` : '[tuiAccordion]';
}
if (openAttr.name === '[(open)]') {
return openAttr.value
? `[(tuiAccordion)]="${openAttr.value}"`
: '[(tuiAccordion)]';
}
return 'tuiAccordion';
}
function isOpenAttr(name) {
return name === 'open' || name === '[open]' || name === '[(open)]';
}
function transformAccordionItems(html) {
const items = (0, elements_1.findElementsByTagName)(html, 'tui-accordion-item').filter((element) => !(0, templates_1.hasAncestor)(element, 'tui-accordion-item'));
if (!items.length) {
return html;
}
const replacements = items
.map((element) => buildReplacement(html, element, {
isStandalone: !(0, templates_1.hasAncestor)(element, 'tui-accordion'),
}))
.filter((x) => Boolean(x))
.sort((a, b) => b.startOffset - a.startOffset);
let next = html;
replacements.forEach(({ startOffset, endOffset, replacement }) => {
next = `${next.slice(0, startOffset)}${replacement}${next.slice(endOffset)}`;
});
return next;
}
function getLineIndent(template, offset) {
const lastLineBreak = template.lastIndexOf('\n', offset);
if (lastLineBreak === -1) {
return { indent: '', startOffset: offset };
}
const lineStart = lastLineBreak + 1;
const indentation = template.slice(lineStart, offset);
return indentation.trim()
? { indent: '', startOffset: offset }
: { indent: indentation, startOffset: lineStart };
}
function normalizeBlock(value) {
var _a, _b;
const lines = value.split('\n');
while (lines.length && ((_a = lines[0]) === null || _a === void 0 ? void 0 : _a.trim()) === '') {
lines.shift();
}
while (lines.length && ((_b = lines[lines.length - 1]) === null || _b === void 0 ? void 0 : _b.trim()) === '') {
lines.pop();
}
let minIndent = Infinity;
lines.forEach((line) => {
var _a, _b;
if (line.trim()) {
const indent = (_b = (_a = /^\s*/.exec(line)) === null || _a === void 0 ? void 0 : _a[0].length) !== null && _b !== void 0 ? _b : 0;
minIndent = Math.min(minIndent, indent);
}
});
if (!Number.isFinite(minIndent)) {
minIndent = 0;
}
return lines.map((line) => line.slice(minIndent)).join('\n');
}
function normalizePlainText(value) {
const trimmed = value.trim();
const hasMarkup = /<[^>]+>/.test(trimmed) || /\{\{|\}\}/.test(trimmed);
return hasMarkup ? value : trimmed.replaceAll(/\s+/g, ' ');
}
function buildButton(content, attr, indent) {
return content.includes('\n')
? [
`${indent}<button ${attr}>`,
...indentLines(content, `${indent} `),
`${indent}</button>`,
].join('\n')
: `${indent}<button ${attr}>${content}</button>`;
}
function buildExpand(content, isLazy, indent, forceBlock, classAttr = '') {
if (!content.includes('\n') && !isLazy && !forceBlock) {
return `${indent}<tui-expand${classAttr}>${content}</tui-expand>`;
}
if (!content.includes('\n') && isLazy && !forceBlock) {
return [
`${indent}<tui-expand${classAttr}>`,
`${indent} <ng-container *tuiItem>${content}</ng-container>`,
`${indent}</tui-expand>`,
].join('\n');
}
const contentLines = indentLines(content, `${indent} `);
return isLazy
? [
`${indent}<tui-expand${classAttr}>`,
`${indent} <ng-container *tuiItem>`,
...indentLines(content, `${indent} `),
`${indent} </ng-container>`,
`${indent}</tui-expand>`,
].join('\n')
: [
`${indent}<tui-expand${classAttr}>`,
...contentLines,
`${indent}</tui-expand>`,
].join('\n');
}
function indentLines(value, indent) {
return value.split('\n').map((line) => (line ? `${indent}${line}` : line));
}
//# sourceMappingURL=migrate-accordion.js.map