diff --git a/package.json b/package.json index 150fe0179..939958aab 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "acorn": "8.15.0", "acorn-jsx": "5.3.2", "angular-estree-parser": "13.0.4", - "angular-html-parser": "8.1.0", + "angular-html-parser": "9.3.0", "camelcase": "8.0.0", "ci-info": "4.3.1", "cjk-regex": "3.4.0", diff --git a/src/language-html/clean.js b/src/language-html/clean.js index 07942672a..580fa67d7 100644 --- a/src/language-html/clean.js +++ b/src/language-html/clean.js @@ -96,6 +96,15 @@ function clean(original, cloned, parent) { if (original.type === "angularLetDeclarationInitializer") { delete cloned.value; } + + // We always print void tags as self closing + if ( + original.type === "element" && + original.isVoid && + !original.isSelfClosing + ) { + cloned.isSelfClosing = true; + } } clean.ignoredProperties = ignoredProperties; diff --git a/src/language-html/parser-html.js b/src/language-html/parser-html.js index 6ae0b21de..33a820810 100644 --- a/src/language-html/parser-html.js +++ b/src/language-html/parser-html.js @@ -22,7 +22,7 @@ import isUnknownNamespace from "./utils/is-unknown-namespace.js"; /** * @import {ParseOptions as AngularHtmlParserParseOptions} from "angular-html-parser" - * @import {Node as AstNode, Attribute, Element} from "angular-html-parser/lib/compiler/src/ml_parser/ast.js" + * @import {Node as AstNode, Attribute, Element, Comment, Text} from "angular-html-parser/lib/compiler/src/ml_parser/ast.js" * @import {ParseTreeResult} from "angular-html-parser/lib/compiler/src/ml_parser/parser.js" */ @@ -199,9 +199,10 @@ function ngHtmlParser(input, parseOptions, options) { */ const restoreNameAndValue = (node) => { switch (node.type) { - case "element": - restoreName(node); - for (const attr of node.attrs) { + case "element": { + const element = /** @type {Element} */ (node); + restoreName(element); + for (const attr of element.attrs) { restoreName(attr); if (!attr.valueSpan) { attr.value = null; @@ -213,14 +214,19 @@ function ngHtmlParser(input, parseOptions, options) { } } break; - case "comment": - node.value = node.sourceSpan + } + case "comment": { + const comment = /** @type {Comment} */ (node); + comment.value = comment.sourceSpan .toString() .slice("".length); break; - case "text": - node.value = node.sourceSpan.toString(); + } + case "text": { + const text = /** @type {Text} */ (node); + text.value = text.sourceSpan.toString(); break; + } // No default } }; @@ -274,17 +280,18 @@ function ngHtmlParser(input, parseOptions, options) { */ const addTagDefinition = (node) => { if (node.type === "element") { + const element = /** @type {Element} */ (node); const tagDefinition = getHtmlTagDefinition( - isTagNameCaseSensitive ? node.name : node.name.toLowerCase(), + isTagNameCaseSensitive ? element.name : element.name.toLowerCase(), ); if ( - !node.namespace || - node.namespace === tagDefinition.implicitNamespacePrefix || - isUnknownNamespace(node) + !element.namespace || + element.namespace === tagDefinition.implicitNamespacePrefix || + isUnknownNamespace(element) ) { - node.tagDefinition = tagDefinition; + element.tagDefinition = tagDefinition; } else { - node.tagDefinition = getHtmlTagDefinition(""); // the default one + element.tagDefinition = getHtmlTagDefinition(""); // the default one } } }; @@ -371,7 +378,6 @@ function parse( location.column, ), ); - // @ts-expect-error -- not a real AstNode rawAst.children.unshift({ ...frontMatter, sourceSpan: new ParseSourceSpan(start, end), diff --git a/tests/format/angular/control-flow/__snapshots__/format.test.js.snap b/tests/format/angular/control-flow/__snapshots__/format.test.js.snap index 380b36d43..8e14f252c 100644 --- a/tests/format/angular/control-flow/__snapshots__/format.test.js.snap +++ b/tests/format/angular/control-flow/__snapshots__/format.test.js.snap @@ -592,23 +592,6 @@ printWidth: 80 ================================================================================ `; -exports[`unknown-block.html format 1`] = ` -====================================options===================================== -parsers: ["angular"] -printWidth: 80 - | printWidth -=====================================input====================================== -@unknown (foo) { -} @unknown (foo) { -} - -=====================================output===================================== -@unknown (foo) {} -@unknown (foo) {} - -================================================================================ -`; - exports[`with-comment.html format 1`] = ` ====================================options===================================== parsers: ["angular"] diff --git a/tests/format/angular/control-flow/small-print-width/__snapshots__/format.test.js.snap b/tests/format/angular/control-flow/small-print-width/__snapshots__/format.test.js.snap index 8f69725e1..18beb6def 100644 --- a/tests/format/angular/control-flow/small-print-width/__snapshots__/format.test.js.snap +++ b/tests/format/angular/control-flow/small-print-width/__snapshots__/format.test.js.snap @@ -6,12 +6,12 @@ parsers: ["angular"] printWidth: 20 | printWidth =====================================input====================================== -@unknown (long expression;long expression;long expression;long expression;long expression;long expression;long expression;long expression;) { +@for (long expression;long expression;long expression;long expression;long expression;long expression;long expression;long expression;) { } =====================================output===================================== -@unknown ( +@for ( long expression; long expression; long expression; diff --git a/tests/format/angular/control-flow/small-print-width/test.html b/tests/format/angular/control-flow/small-print-width/test.html index dffe53b37..278a24218 100644 --- a/tests/format/angular/control-flow/small-print-width/test.html +++ b/tests/format/angular/control-flow/small-print-width/test.html @@ -1,3 +1,3 @@ -@unknown (long expression;long expression;long expression;long expression;long expression;long expression;long expression;long expression;) { +@for (long expression;long expression;long expression;long expression;long expression;long expression;long expression;long expression;) { } diff --git a/tests/format/angular/let-declaration/__snapshots__/format.test.js.snap b/tests/format/angular/let-declaration/__snapshots__/format.test.js.snap index 95dfac17f..35bdd0cf2 100644 --- a/tests/format/angular/let-declaration/__snapshots__/format.test.js.snap +++ b/tests/format/angular/let-declaration/__snapshots__/format.test.js.snap @@ -185,7 +185,11 @@ parsers: ["angular"] printWidth: 80 | printWidth =====================================input====================================== - + @let foo = 123 + 456; @@ -216,7 +220,7 @@ foo = 123; 789 ; -@block {@let foo = 123 + 456;} +@defer {@let foo = 123 + 456;} @let foo = 'a; b'; @let foo = "';'"; @@ -236,7 +240,11 @@ foo = 123; @let foo = fn({a: 1, b: [otherFn([{c: ";"}], 321, {d: [',']})]}); =====================================output===================================== - + @let foo = 123 + 456; @@ -255,7 +263,7 @@ foo = 123; @let foo = 123 + 456 + 789; -@block { +@defer { @let foo = 123 + 456; } diff --git a/tests/format/angular/let-declaration/valid-from-tokenizer-test.html b/tests/format/angular/let-declaration/valid-from-tokenizer-test.html index ab7211158..d0963f5b4 100644 --- a/tests/format/angular/let-declaration/valid-from-tokenizer-test.html +++ b/tests/format/angular/let-declaration/valid-from-tokenizer-test.html @@ -1,4 +1,8 @@ - + @let foo = 123 + 456; @@ -29,7 +33,7 @@ foo = 123; 789 ; -@block {@let foo = 123 + 456;} +@defer {@let foo = 123 + 456;} @let foo = 'a; b'; @let foo = "';'"; diff --git a/tests/format/misc/errors/angular/__snapshots__/format.test.js.snap b/tests/format/misc/errors/angular/__snapshots__/format.test.js.snap new file mode 100644 index 000000000..2e2dbffe0 --- /dev/null +++ b/tests/format/misc/errors/angular/__snapshots__/format.test.js.snap @@ -0,0 +1,10 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`unkown-block.html [angular] format 1`] = ` +"Unexpected character "EOF" (Do you have an unescaped "{" in your template? Use "{{ '{' }}") to escape it.) (4:1) + 2 | } @unknown (foo) { + 3 | } +> 4 | + | ^ +Cause: Unexpected character "EOF" (Do you have an unescaped "{" in your template? Use "{{ '{' }}") to escape it.)" +`; diff --git a/tests/format/misc/errors/angular/format.test.js b/tests/format/misc/errors/angular/format.test.js new file mode 100644 index 000000000..8cbc48b1a --- /dev/null +++ b/tests/format/misc/errors/angular/format.test.js @@ -0,0 +1 @@ +runFormatTest(import.meta, ["angular"]); diff --git a/tests/format/angular/control-flow/unknown-block.html b/tests/format/misc/errors/angular/unkown-block.html similarity index 100% rename from tests/format/angular/control-flow/unknown-block.html rename to tests/format/misc/errors/angular/unkown-block.html diff --git a/tests/format/misc/errors/vue/__snapshots__/format.test.js.snap b/tests/format/misc/errors/vue/__snapshots__/format.test.js.snap index 10dc76a37..5a1b398ca 100644 --- a/tests/format/misc/errors/vue/__snapshots__/format.test.js.snap +++ b/tests/format/misc/errors/vue/__snapshots__/format.test.js.snap @@ -5,7 +5,8 @@ exports[`unclosed_tag.vue [vue] format 1`] = ` > 1 |