diff --git a/packages/angular-html-parser/.vscode/extensions.json b/packages/angular-html-parser/.vscode/extensions.json new file mode 100644 index 0000000000000..77e870d1b231a --- /dev/null +++ b/packages/angular-html-parser/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "esbenp.prettier-vscode", + "editorconfig.editorconfig", + // "dbaeumer.vscode-eslint", + "streetsidesoftware.code-spell-checker" + ] +} diff --git a/packages/angular-html-parser/.vscode/settings.json b/packages/angular-html-parser/.vscode/settings.json new file mode 100644 index 0000000000000..707104dc663e6 --- /dev/null +++ b/packages/angular-html-parser/.vscode/settings.json @@ -0,0 +1,12 @@ +{ + "[javascript][typescript][json][jsonc][markdown][yaml]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + }, + // "[javascript][typescript]": { + // "editor.codeActionsOnSave": { + // "source.fixAll.eslint": "explicit", + // }, + // }, + "prettier.requireConfig": true +} diff --git a/packages/angular-html-parser/src/index.ts b/packages/angular-html-parser/src/index.ts index ceef960444598..815fbd599d34f 100644 --- a/packages/angular-html-parser/src/index.ts +++ b/packages/angular-html-parser/src/index.ts @@ -49,6 +49,11 @@ export interface ParseOptions { * tokenize angular let declaration syntax */ tokenizeAngularLetDeclaration?: boolean; + + /** + * enable angular selectorless syntax + */ + enableAngularSelectorlessSyntax?: boolean; } export function parse( @@ -62,6 +67,7 @@ export function parse( getTagContentType, tokenizeAngularBlocks = false, tokenizeAngularLetDeclaration = false, + enableAngularSelectorlessSyntax = false, } = options; return getParser().parse( input, @@ -73,6 +79,7 @@ export function parse( allowHtmComponentClosingTags, tokenizeBlocks: tokenizeAngularBlocks, tokenizeLet: tokenizeAngularLetDeclaration, + selectorlessEnabled: enableAngularSelectorlessSyntax, }, isTagNameCaseSensitive, getTagContentType, diff --git a/packages/angular-html-parser/test/index_spec.ts b/packages/angular-html-parser/test/index_spec.ts index e6088bfb79893..81e87afcb6628 100644 --- a/packages/angular-html-parser/test/index_spec.ts +++ b/packages/angular-html-parser/test/index_spec.ts @@ -68,7 +68,7 @@ describe("AST format", () => { ]); }); - it("should have `type` property when tokenizeBlocks is enabled", () => { + it("should support 'tokenizeAngularBlocks'", () => { const input = `@if (user.isHuman) {

Hello human

}`; const ast = parse(input, { tokenizeAngularBlocks: true }); expect(ast.rootNodes).toEqual([ @@ -95,4 +95,88 @@ describe("AST format", () => { }), ]); }); + + it("should support 'tokenizeAngularLetDeclaration'", () => { + const input = `@let foo = 'bar';`; + const ast = parse(input, { tokenizeAngularLetDeclaration: true }); + expect(ast.rootNodes).toEqual([ + expect.objectContaining({ + name: "foo", + type: "letDeclaration", + value: "'bar'", + }), + ]); + }); + + // https://github.com/angular/angular/pull/60724 + it("should support 'enableAngularSelectorlessSyntax'", () => { + { + const ast = parse("
", { + enableAngularSelectorlessSyntax: true, + }); + expect(ast.rootNodes).toEqual([ + expect.objectContaining({ + name: "div", + type: "element", + directives: [ + expect.objectContaining({ + name: "Dir", + type: "directive", + }), + ], + }), + ]); + } + + { + const ast = parse("Hello", { + enableAngularSelectorlessSyntax: true, + }); + + expect(ast.rootNodes).toEqual([ + expect.objectContaining({ + fullName: "MyComp", + componentName: "MyComp", + type: "component", + }), + ]); + } + + { + const ast = parse("", { enableAngularSelectorlessSyntax: true }); + expect(ast.rootNodes).toEqual([ + expect.objectContaining({ + fullName: "MyComp", + componentName: "MyComp", + type: "component", + }), + ]); + } + + { + const ast = parse("Hello", { + enableAngularSelectorlessSyntax: true, + }); + expect(ast.rootNodes).toEqual([ + expect.objectContaining({ + fullName: "MyComp:button", + componentName: "MyComp", + type: "component", + }), + ]); + } + + { + const ast = parse("Hello", { + enableAngularSelectorlessSyntax: true, + }); + expect(ast.rootNodes).toEqual([ + expect.objectContaining({ + fullName: "MyComp:svg:title", + componentName: "MyComp", + type: "component", + }), + ]); + } + }); });