fix(compiler): do not remove whitespace wrapping i18n expansions (#31962)
Similar to interpolation, we do not want to completely remove whitespace nodes that are siblings of an expansion. For example, the following template ```html <div> <strong>items left<strong> {count, plural, =1 {item} other {items}} </div> ``` was being collapsed to ```html <div><strong>items left<strong>{count, plural, =1 {item} other {items}}</div> ``` which results in the text looking like ``` items left4 ``` instead it should be collapsed to ```html <div><strong>items left<strong> {count, plural, =1 {item} other {items}}</div> ``` which results in the text looking like ``` items left 4 ``` --- **Analysis of the code and manual testing has shown that this does not cause the generated ids to change, so there is no breaking change here.** PR Close #31962
This commit is contained in:

committed by
Kara Erickson

parent
fd6ed1713d
commit
0ddf0c4895
@ -60,18 +60,20 @@ export class WhitespaceVisitor implements html.Visitor {
|
||||
}
|
||||
|
||||
return new html.Element(
|
||||
element.name, element.attrs, html.visitAll(this, element.children), element.sourceSpan,
|
||||
element.startSourceSpan, element.endSourceSpan, element.i18n);
|
||||
element.name, element.attrs, visitAllWithSiblings(this, element.children),
|
||||
element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n);
|
||||
}
|
||||
|
||||
visitAttribute(attribute: html.Attribute, context: any): any {
|
||||
return attribute.name !== PRESERVE_WS_ATTR_NAME ? attribute : null;
|
||||
}
|
||||
|
||||
visitText(text: html.Text, context: any): any {
|
||||
visitText(text: html.Text, context: SiblingVisitorContext|null): any {
|
||||
const isNotBlank = text.value.match(NO_WS_REGEXP);
|
||||
const hasExpansionSibling = context &&
|
||||
(context.prev instanceof html.Expansion || context.next instanceof html.Expansion);
|
||||
|
||||
if (isNotBlank) {
|
||||
if (isNotBlank || hasExpansionSibling) {
|
||||
return new html.Text(
|
||||
replaceNgsp(text.value).replace(WS_REPLACE_REGEXP, ' '), text.sourceSpan, text.i18n);
|
||||
}
|
||||
@ -91,3 +93,21 @@ export function removeWhitespaces(htmlAstWithErrors: ParseTreeResult): ParseTree
|
||||
html.visitAll(new WhitespaceVisitor(), htmlAstWithErrors.rootNodes),
|
||||
htmlAstWithErrors.errors);
|
||||
}
|
||||
|
||||
interface SiblingVisitorContext {
|
||||
prev: html.Node|undefined;
|
||||
next: html.Node|undefined;
|
||||
}
|
||||
|
||||
function visitAllWithSiblings(visitor: WhitespaceVisitor, nodes: html.Node[]): any[] {
|
||||
const result: any[] = [];
|
||||
|
||||
nodes.forEach((ast, i) => {
|
||||
const context: SiblingVisitorContext = {prev: nodes[i - 1], next: nodes[i + 1]};
|
||||
const astResult = ast.visit(visitor, context);
|
||||
if (astResult) {
|
||||
result.push(astResult);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
Reference in New Issue
Block a user