Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
export function normalizeAttributeValue(
attr: parse5.AST.Default.Attribute,
raw: string,
tag: string
): {
value: string;
escapedExpression: boolean;
} {
const { name, value } = attr;
if (booleanAttributes.has(name)) {
if (value === 'true') {
throw generateCompilerError(ParserDiagnostics.BOOLEAN_ATTRIBUTE_TRUE, {
messageArgs: [tag, name, value],
});
} else if (value === 'false') {
throw generateCompilerError(ParserDiagnostics.BOOLEAN_ATTRIBUTE_FALSE, {
messageArgs: [tag, name, value],
});
}
}
const isQuoted = isQuotedAttribute(raw);
const isEscaped = isEscapedAttribute(raw);
if (!isEscaped && isExpression(value)) {
if (isQuoted) {
// <input value="{myValue}">
// -> ambiguity if the attribute value is a template identifier or a string literal.
messageArgs: [tag, name, value],
});
}
}
const isQuoted = isQuotedAttribute(raw);
const isEscaped = isEscapedAttribute(raw);
if (!isEscaped && isExpression(value)) {
if (isQuoted) {
// <input value="{myValue}">
// -> ambiguity if the attribute value is a template identifier or a string literal.
const unquoted = raw.replace(/"/g, '');
const escaped = raw.replace('"{', '"\\{');
throw generateCompilerError(ParserDiagnostics.AMBIGUOUS_ATTRIBUTE_VALUE, {
messageArgs: [raw, unquoted, escaped],
});
}
// <input value="{myValue}">
// -> Valid identifier.
return { value, escapedExpression: false };
} else if (!isEscaped && isPotentialExpression(value)) {
const isExpressionEscaped = value.startsWith(`\\${EXPRESSION_SYMBOL_START}`);
const isExpressionNextToSelfClosing =
value.startsWith(EXPRESSION_SYMBOL_START) &&
value.endsWith(`${EXPRESSION_SYMBOL_END}/`) &&
!isQuoted;
if (isExpressionNextToSelfClosing) {
// <input value="{myValue}/">
switch (path.extname(filename)) {
case '.html':
transformer = templateTransformer;
break;
case '.css':
transformer = styleTransform;
break;
case '.ts':
case '.js':
transformer = scriptTransformer;
break;
default:
throw generateCompilerError(TransformerErrors.NO_AVAILABLE_TRANSFORMER, {
messageArgs: [filename],
origin: { filename },
});
}
return transformer(src, filename, options);
}
}
if (!testExpression) {
testExpression = bindExpression(element.if!, element).expression;
}
let leftExpression: t.Expression;
const modifier = element.ifModifier!;
if (modifier === 'true') {
leftExpression = testExpression;
} else if (modifier === 'false') {
leftExpression = t.unaryExpression('!', testExpression);
} else if (modifier === 'strict-true') {
leftExpression = t.binaryExpression('===', testExpression, t.booleanLiteral(true));
} else {
throw generateCompilerError(TemplateErrors.UNKNOWN_IF_MODIFIER, {
messageArgs: [modifier],
});
}
return t.conditionalExpression(leftExpression, babelNode, falseValue);
}