UNPKG

wuchale

Version:

Protobuf-like i18n from normal code

162 lines 6.02 kB
// Shared logic between adapters for handling nested / mixed elements within elements / fragments import { IndexTracker, NestText } from "../adapters.js"; import { nonWhitespaceText } from "./index.js"; export class MixedVisitor { constructor(props) { Object.assign(this, props); } separatelyVisitChildren = (props) => { let hasTextChild = false; let hasNonTextChild = false; let heurTxt = ''; let hasCommentDirectives = false; for (const child of props.children) { if (this.isText(child)) { const text = this.getTextContent(child); const txt = text.trim(); if (!txt) { continue; } hasTextChild = true; heurTxt += text + ' '; } else if (this.isComment(child)) { if (this.getCommentData(child).trim().startsWith('@wc-')) { hasCommentDirectives = true; } } else { hasNonTextChild = true; heurTxt += `# `; } } heurTxt = heurTxt.trimEnd(); const passHeuristic = this.checkHeuristic(heurTxt); let hasCompoundText = hasTextChild && hasNonTextChild; const visitAsOne = passHeuristic && !hasCommentDirectives; if (props.inCompoundText || hasCompoundText && visitAsOne) { return [false, hasTextChild, hasCompoundText, []]; } const txts = []; // can't be extracted as one; visitSv each separately for (const child of props.children) { txts.push(...this.visitFunc(child, props.inCompoundText)); } return [true, false, false, txts]; }; visit = (props) => { if (props.children.length === 0) { return []; } const [visitedSeparately, hasTextChild, hasCompoundText, separateTxts] = this.separatelyVisitChildren(props); if (visitedSeparately) { return separateTxts; } let txt = ''; let iArg = 0; let iTag = 0; const lastChildEnd = this.getRange(props.children.slice(-1)[0]).end; const childrenNestedRanges = []; let hasTextDescendants = false; const txts = []; for (const child of props.children) { if (this.isComment(child)) { continue; } const chRange = this.getRange(child); if (this.isText(child)) { const [startWh, trimmed, endWh] = nonWhitespaceText(this.getTextContent(child)); const nTxt = new NestText(trimmed, 'markup', props.commentDirectives.context); if (startWh && !txt.endsWith(' ')) { txt += ' '; } if (!trimmed) { // whitespace continue; } txt += nTxt.text; if (endWh) { txt += ' '; } this.mstr.remove(chRange.start, chRange.end); continue; } if (this.isExpression(child)) { txts.push(...this.visitExpressionTag(child)); if (!hasCompoundText) { continue; } txt += `{${iArg}}`; let moveStart = chRange.start; if (iArg > 0) { this.mstr.update(chRange.start, chRange.start + 1, ', '); } else { moveStart++; this.mstr.remove(chRange.start, chRange.start + 1); } this.mstr.move(moveStart, chRange.end - 1, lastChildEnd); this.mstr.remove(chRange.end - 1, chRange.end); iArg++; continue; } // elements, components and other things as well const canHaveChildren = this.canHaveChildren(child); const childTxts = this.visitFunc(child, canHaveChildren); let nestedNeedsCtx = false; let chTxt = ''; for (const txt of childTxts) { if (canHaveChildren && txt.scope === 'markup') { chTxt += txt.text[0]; hasTextDescendants = true; nestedNeedsCtx = true; } else { // attributes, blocks txts.push(txt); } } childrenNestedRanges.push([chRange.start, chRange.end, nestedNeedsCtx]); if (canHaveChildren && chTxt) { chTxt = `<${iTag}>${chTxt}</${iTag}>`; } else { // childless elements and everything else chTxt = `<${iTag}/>`; } iTag++; txt += chTxt; } txt = txt.trim(); if (!txt) { return txts; } const nTxt = new NestText(txt, 'markup', props.commentDirectives.context); if (hasTextChild || hasTextDescendants) { txts.push(nTxt); } else { return txts; } if (childrenNestedRanges.length) { this.wrapNested(nTxt, iArg > 0, childrenNestedRanges, lastChildEnd); } else if (hasTextChild) { // no need for component use let begin = '{'; let end = ')}'; if (props.inCompoundText) { begin += `${this.vars.rtTransCtx}(${this.vars.nestCtx}`; } else { begin += `${this.vars.rtTrans}(${this.index.get(nTxt.toKey())}`; } if (iArg > 0) { begin += ', ['; end = ']' + end; } this.mstr.appendLeft(lastChildEnd, begin); this.mstr.appendRight(lastChildEnd, end); } return txts; }; } //# sourceMappingURL=mixed-visitor.js.map