Fix interpolation boundaries in text (#20117)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: fisker Cheung <lionkay@gmail.com>
This commit is contained in:
authored and GitHub committed 2026-10-03 02:04:49 +08:00
1 parent eea6146027
commit 78f49dac02
9 files changed
+122 -9

No files matched your search

+17
View File
@@ -0,0 +1,17 @@
#### Preserve double-brace placeholders inside string literals (#20117 by @splincode)
<!-- prettier-ignore -->
```html
<!-- Input -->
{{ "{{num_of_selected_files}} / {{num_of_total_files}} files selected" | translate: {num_of_selected_files: 20, num_of_total_files: 30} }}
<!-- Prettier stable -->
{{ "{{num_of_selected_files}} / {{ num_of_total_files }} files selected" |
translate: {num_of_selected_files: 20, num_of_total_files: 30} }}
<!-- Prettier main -->
{{
"{{num_of_selected_files}} / {{num_of_total_files}} files selected"
| translate: { num_of_selected_files: 20, num_of_total_files: 30 }
}}
```
+19
View File
@@ -0,0 +1,19 @@
#### Preserve double-brace placeholders inside string literals (#20117 by @splincode)
<!-- prettier-ignore -->
```html
<!-- Input -->
<template>
<div>{{"{{first}} / {{second}} files selected"}}</div>
</template>
<!-- Prettier stable -->
<template>
<div>{{"{{first}} / {{ second }} files selected"}}</div>
</template>
<!-- Prettier main -->
<template>
<div>{{ "{{first}} / {{second}} files selected" }}</div>
</template>
```
+1 -1
View File
@@ -61,7 +61,7 @@
"acorn": "8.18.0",
"acorn-jsx": "5.3.2",
"angular-estree-parser": "15.5.0",
"angular-html-parser": "10.12.0",
"angular-html-parser": "10.13.0",
"camelcase": "9.0.0",
"ci-info": "4.4.0",
"cjk-regex": "3.5.0",
+34 -3
View File
@@ -1,4 +1,4 @@
import { ParseSourceSpan } from "angular-html-parser";
import { ParseSourceSpan, TokenType } from "angular-html-parser";
import htmlWhitespace from "../utilities/html-whitespace.js";
import isNonEmptyArray from "../utilities/is-non-empty-array.js";
import {
@@ -273,7 +273,6 @@ function extractInterpolation(ast, options) {
return;
}
const interpolationRegex = /\{\{(.+?)\}\}/s;
ast.walk((node) => {
if (!canHaveInterpolation(node, options)) {
return;
@@ -286,7 +285,8 @@ function extractInterpolation(ast, options) {
let startSourceSpan = child.sourceSpan.start;
let endSourceSpan;
const components = child.value.split(interpolationRegex);
const components = splitInterpolation(child);
for (
let i = 0;
i < components.length;
@@ -331,6 +331,37 @@ function extractInterpolation(ast, options) {
});
}
function splitInterpolation(node) {
const interpolationTokens = node.tokens?.filter(
(token) =>
token.type === TokenType.INTERPOLATION && token.parts.length === 3,
);
if (!interpolationTokens?.some((token) => token.parts[1].includes("}}"))) {
return node.value.split(/\{\{(.+?)\}\}/s);
}
const components = [];
const { content } = node.sourceSpan.start.file;
let startOffset = node.sourceSpan.start.offset;
for (const { parts, sourceSpan } of interpolationTokens) {
components.push(
content.slice(startOffset, sourceSpan.start.offset),
content.slice(
sourceSpan.start.offset + parts[0].length,
sourceSpan.end.offset - parts[2].length,
),
);
startOffset = sourceSpan.end.offset;
}
components.push(content.slice(startOffset, node.sourceSpan.end.offset));
return components;
}
/**
* - add `hasLeadingSpaces` field
* - add `hasTrailingSpaces` field
@@ -0,0 +1,2 @@
{{}}
{{ "{{num_of_selected_files}} / {{num_of_total_files}} files selected" | translate: {num_of_selected_files: 20, num_of_total_files: 30} }}
@@ -16,6 +16,24 @@ parsers: ["angular"]
================================================================================
`;
exports[`18939.html format 1`] = `
====================================options=====================================
parsers: ["angular"]
printWidth: 80 (default) |
=====================================input======================================
{{}}
{{ "{{num_of_selected_files}} / {{num_of_total_files}} files selected" | translate: {num_of_selected_files: 20, num_of_total_files: 30} }}
=====================================output=====================================
{{}}
{{
"{{num_of_selected_files}} / {{num_of_total_files}} files selected"
| translate: { num_of_selected_files: 20, num_of_total_files: 30 }
}}
================================================================================
`;
exports[`block.html format 1`] = `
====================================options=====================================
parsers: ["angular"]
@@ -75,6 +75,27 @@ parsers: ["vue"]
================================================================================
`;
exports[`double-brace-string.vue format 1`] = `
====================================options=====================================
parsers: ["vue"]
printWidth: 80 (default) |
=====================================input======================================
<template>
<div>{{"{{first}} / {{second}} files selected"}}</div>
<div>{{'{{first}} / {{second}} files selected'}}</div>
<div>Before {{ "}}" }} between {{value}} after {{ "{{third}}" }}</div>
</template>
=====================================output=====================================
<template>
<div>{{ "{{first}} / {{second}} files selected" }}</div>
<div>{{ "{{first}} / {{second}} files selected" }}</div>
<div>Before {{ "}}" }} between {{ value }} after {{ "{{third}}" }}</div>
</template>
================================================================================
`;
exports[`ng-non-bindable.vue format 1`] = `
====================================options=====================================
parsers: ["vue"]
@@ -0,0 +1,5 @@
<template>
<div>{{"{{first}} / {{second}} files selected"}}</div>
<div>{{'{{first}} / {{second}} files selected'}}</div>
<div>Before {{ "}}" }} between {{value}} after {{ "{{third}}" }}</div>
</template>
+5 -5
View File
@@ -3372,10 +3372,10 @@ __metadata:
languageName: node
linkType: hard
"angular-html-parser@npm:10.12.0":
version: 10.12.0
resolution: "angular-html-parser@npm:10.12.0"
checksum: 10/d71e0faa33c3ad91d07a71f4c5878eb047bb42f506fef3b66d15c5dd94a59eba12599de186adf4518ebe28a2f58b669394943281b91aebefed35987d8e29cbbe
"angular-html-parser@npm:10.13.0":
version: 10.13.0
resolution: "angular-html-parser@npm:10.13.0"
checksum: 10/e2d37993e888469d061145f2880f523a74b0bbfd772438cd3b17b435b5be7f648ce83d2e83714a8322f755f5b2275fae8ff31b9c9ec37faf6a840d9ea8ce6d86
languageName: node
linkType: hard
@@ -8288,7 +8288,7 @@ __metadata:
acorn: "npm:8.18.0"
acorn-jsx: "npm:5.3.2"
angular-estree-parser: "npm:15.5.0"
angular-html-parser: "npm:10.12.0"
angular-html-parser: "npm:10.13.0"
browserslist: "npm:4.29.0"
browserslist-to-esbuild: "npm:2.1.1"
buffer: "npm:6.0.3"