diff --git a/changelog_unreleased/angular/20044.md b/changelog_unreleased/angular/20044.md index 4364eaf56..5655ba33c 100644 --- a/changelog_unreleased/angular/20044.md +++ b/changelog_unreleased/angular/20044.md @@ -1,4 +1,4 @@ -#### Preserve interpolations inside elements with `ngNonBindable` directive (#20044 by @splincode) +#### Preserve interpolations inside elements with `ngNonBindable` directive (#20044 by @splincode, #20115 by @fisker) ```html diff --git a/src/language-html/embed.js b/src/language-html/embed.js index cd3afc43d..e0ba2fa47 100644 --- a/src/language-html/embed.js +++ b/src/language-html/embed.js @@ -23,7 +23,6 @@ import { isScriptLikeTag, isVueNonHtmlBlock, } from "./utilities/index.js"; -import { isInNgNonBindable } from "./utilities/is-in-ng-non-bindable.js"; import isVueSfcWithTypescriptScript from "./utilities/is-vue-sfc-with-typescript-script.js"; const embeddedAngularControlFlowBlocks = new Set([ @@ -110,10 +109,7 @@ function embed(path, options) { ]; }; } - } else if ( - node.parent.kind === "interpolation" && - !isInNgNonBindable(path, options) - ) { + } else if (node.parent.kind === "interpolation") { return async (textToDoc) => { const textToDocOptions = { __isInHtmlInterpolation: true, // to avoid unexpected `}}` diff --git a/src/language-html/utilities/index.js b/src/language-html/utilities/index.js index a1e289106..530ce6d7f 100644 --- a/src/language-html/utilities/index.js +++ b/src/language-html/utilities/index.js @@ -18,6 +18,7 @@ import { CSS_WHITE_SPACE_TAGS, } from "../constants.evaluate.js"; import isUnknownNamespace from "./is-unknown-namespace.js"; +import { hasOrInNgNonBindable } from "./ng-non-bindable.js"; const htmlTrimLeadingBlankLines = (string) => string.replaceAll(/^[\t\f\r ]*\n/g, ""); @@ -121,7 +122,15 @@ function isScriptLikeTag(node, options) { } function canHaveInterpolation(node, options) { - return node.children && !isScriptLikeTag(node, options); + if (!node.children || isScriptLikeTag(node, options)) { + return false; + } + + if (hasOrInNgNonBindable(node, options)) { + return false; + } + + return true; } function isWhitespaceSensitiveNode(node, options) { diff --git a/src/language-html/utilities/is-in-ng-non-bindable.js b/src/language-html/utilities/is-in-ng-non-bindable.js deleted file mode 100644 index 86698cf3e..000000000 --- a/src/language-html/utilities/is-in-ng-non-bindable.js +++ /dev/null @@ -1,29 +0,0 @@ -import { getOrInsertComputed } from "../../utilities/get-or-insert.js"; - -const angularNonBindableCache = new WeakMap(); -function hasOrInNgNonBindable(node) { - return getOrInsertComputed(angularNonBindableCache, node, (node) => { - if ( - node.kind === "element" && - Object.hasOwn(node.attrMap, "ngNonBindable") - ) { - return true; - } - - if (!node.parent) { - return false; - } - - return hasOrInNgNonBindable(node.parent); - }); -} - -function isInNgNonBindable(path, options) { - if (options.parser !== "angular") { - return false; - } - - return hasOrInNgNonBindable(path.node.parent); -} - -export { isInNgNonBindable }; diff --git a/src/language-html/utilities/ng-non-bindable.js b/src/language-html/utilities/ng-non-bindable.js new file mode 100644 index 000000000..46caebc48 --- /dev/null +++ b/src/language-html/utilities/ng-non-bindable.js @@ -0,0 +1,20 @@ +import { getOrInsertComputed } from "../../utilities/get-or-insert.js"; + +const isElementWithNgNonBindable = (node) => + node?.kind === "element" && Object.hasOwn(node.attrMap, "ngNonBindable"); + +const angularNonBindableCache = new WeakMap(); +const hasOrInNgNonBindableInternal = (node) => + Boolean(node) && + getOrInsertComputed( + angularNonBindableCache, + node, + (node) => + isElementWithNgNonBindable(node) || + hasOrInNgNonBindableInternal(node.parent), + ); + +const hasOrInNgNonBindable = (node, options) => + options.parser === "angular" && hasOrInNgNonBindableInternal(node); + +export { hasOrInNgNonBindable }; diff --git a/tests/format/angular/ng-non-bindable/__snapshots__/format.test.js.snap b/tests/format/angular/ng-non-bindable/__snapshots__/format.test.js.snap index b92b175cb..5c5d2b8a9 100644 --- a/tests/format/angular/ng-non-bindable/__snapshots__/format.test.js.snap +++ b/tests/format/angular/ng-non-bindable/__snapshots__/format.test.js.snap @@ -78,24 +78,38 @@ parsers: ["angular"]
{{foo +bar}}
+ {{ foo + bar }}
+[[ foo + bar ]]+ =====================================output===================================== -{{foo +bar}} +{{foo +bar}}
{{foo +bar}}
+ {{ foo + bar }}
+[[ foo + bar ]]+ ================================================================================ `; diff --git a/tests/format/angular/ng-non-bindable/embedded-language-formatting/__snapshots__/format.test.js.snap b/tests/format/angular/ng-non-bindable/embedded-language-formatting/__snapshots__/format.test.js.snap index 6d85c6267..dcbf18c37 100644 --- a/tests/format/angular/ng-non-bindable/embedded-language-formatting/__snapshots__/format.test.js.snap +++ b/tests/format/angular/ng-non-bindable/embedded-language-formatting/__snapshots__/format.test.js.snap @@ -7,9 +7,15 @@ parsers: ["angular"] printWidth: 80 (default) | =====================================input====================================== {{foo +bar}} +
{{foo +bar}}
+{{foo
+.bar(
+)}}
=====================================output=====================================
-{{foo +bar}}
+{{foo +bar}}
+{{foo +bar}}
+{{foo .bar( )}}
================================================================================
`;
diff --git a/tests/format/angular/ng-non-bindable/embedded-language-formatting/ng-non-bindable.html b/tests/format/angular/ng-non-bindable/embedded-language-formatting/ng-non-bindable.html
index afeebe5f4..25e6e7df8 100644
--- a/tests/format/angular/ng-non-bindable/embedded-language-formatting/ng-non-bindable.html
+++ b/tests/format/angular/ng-non-bindable/embedded-language-formatting/ng-non-bindable.html
@@ -1 +1,5 @@
{{foo +bar}}
+{{foo +bar}}
+{{foo
+.bar(
+)}}
diff --git a/tests/format/angular/ng-non-bindable/interpolation.html b/tests/format/angular/ng-non-bindable/interpolation.html
index 5f7abb049..376f042f7 100644
--- a/tests/format/angular/ng-non-bindable/interpolation.html
+++ b/tests/format/angular/ng-non-bindable/interpolation.html
@@ -14,3 +14,10 @@
{{foo +bar}}
+
+ {{ foo + bar }}
+[[ foo + bar ]]