UNPKG

element-vir

Version:

Heroic. Reactive. Declarative. Type safe. Web components without compromise.

103 lines (102 loc) 4.6 kB
import { insertAndRemoveValues } from '../util/array.js'; import { getAlreadyMappedTemplate, setMappedTemplate } from './nested-mapped-templates.js'; export function getTransformedTemplate(templateStringsKey, values, fallbackTransform) { const alreadyTransformedTemplateStrings = getAlreadyMappedTemplate(templateStringsKey, values); const templateTransform = alreadyTransformedTemplateStrings ?? fallbackTransform(); if (!alreadyTransformedTemplateStrings) { const result = setMappedTemplate(templateStringsKey, values, templateTransform); if (!result.result) { throw new Error(`Failed to set template transform: ${result.reason}`); } } const valueTransforms = templateTransform.valuesTransform(values); const transformedValuesArray = insertAndRemoveValues(values, valueTransforms.valueInsertions, valueTransforms.valueIndexDeletions); return { strings: templateTransform.templateStrings, values: transformedValuesArray, }; } export function transformTemplate(inputTemplateStrings, inputValues, transformValue, assertValidString) { const newStrings = []; const newRaws = []; const valueIndexDeletions = []; const valueTransforms = []; inputTemplateStrings.forEach((currentTemplateString, currentTemplateStringIndex) => { const lastNewStringsIndex = newStrings.length - 1; const lastNewString = newStrings[lastNewStringsIndex]; const currentValueIndex = currentTemplateStringIndex - 1; const currentValue = inputValues[currentValueIndex]; if (assertValidString) { assertValidString(currentTemplateString); } let transformOutput = undefined; let extraValues = []; if (typeof lastNewString === 'string') { transformOutput = transformValue(lastNewString, currentTemplateString, currentValue); if (transformOutput) { newStrings[lastNewStringsIndex] = [ lastNewString, transformOutput.replacement, ].join(''); valueIndexDeletions.push(currentValueIndex); const getExtraValuesCallback = transformOutput.getExtraValues; extraValues = getExtraValuesCallback ? getExtraValuesCallback(currentValue) : []; if (extraValues.length && getExtraValuesCallback) { newStrings[lastNewStringsIndex] += ' '; extraValues.forEach((value, index) => { // don't insert the first time, we need n-1 inserts if (index) { newStrings.push(' '); } }); valueTransforms.push((values) => { const latestCurrentValue = values[currentValueIndex]; const insertions = getExtraValuesCallback(latestCurrentValue); return { index: currentValueIndex, values: insertions, }; }); newStrings.push(currentTemplateString); } else { newStrings[lastNewStringsIndex] += currentTemplateString; } } } if (!transformOutput) { newStrings.push(currentTemplateString); } // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const currentRawLitString = inputTemplateStrings.raw[currentTemplateStringIndex]; if (transformOutput) { newRaws[lastNewStringsIndex] = [ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion newRaws[lastNewStringsIndex], transformOutput.replacement, currentRawLitString, ].join(''); if (extraValues.length) { extraValues.forEach(() => { newRaws.push(''); }); } } else { newRaws.push(currentRawLitString); } }); const newTemplateStrings = Object.assign([], newStrings, { raw: newRaws, }); return { templateStrings: newTemplateStrings, valuesTransform(values) { const insertions = valueTransforms.flatMap((transformCallback) => transformCallback(values)); return { valueIndexDeletions, valueInsertions: insertions, }; }, }; }