Skip to content

Commit eae9a65

Browse files
committed
feat: support Angular selectorless syntax
1 parent 192d281 commit eae9a65

File tree

4 files changed

+112
-1
lines changed

4 files changed

+112
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"recommendations": [
3+
"esbenp.prettier-vscode",
4+
"editorconfig.editorconfig",
5+
// "dbaeumer.vscode-eslint",
6+
"streetsidesoftware.code-spell-checker",
7+
],
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"[javascript][typescript][json][jsonc][markdown][yaml]": {
3+
"editor.defaultFormatter": "esbenp.prettier-vscode",
4+
"editor.formatOnSave": true,
5+
},
6+
// "[javascript][typescript]": {
7+
// "editor.codeActionsOnSave": {
8+
// "source.fixAll.eslint": "explicit",
9+
// },
10+
// },
11+
"prettier.requireConfig": true,
12+
}

packages/angular-html-parser/src/index.ts

+7
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ export interface ParseOptions {
4949
* tokenize angular let declaration syntax
5050
*/
5151
tokenizeAngularLetDeclaration?: boolean;
52+
53+
/**
54+
* enable angular selectorless syntax
55+
*/
56+
enableAngularSelectorlessSyntax?: boolean;
5257
}
5358

5459
export function parse(
@@ -62,6 +67,7 @@ export function parse(
6267
getTagContentType,
6368
tokenizeAngularBlocks = false,
6469
tokenizeAngularLetDeclaration = false,
70+
enableAngularSelectorlessSyntax = false,
6571
} = options;
6672
return getParser().parse(
6773
input,
@@ -73,6 +79,7 @@ export function parse(
7379
allowHtmComponentClosingTags,
7480
tokenizeBlocks: tokenizeAngularBlocks,
7581
tokenizeLet: tokenizeAngularLetDeclaration,
82+
selectorlessEnabled: enableAngularSelectorlessSyntax,
7683
},
7784
isTagNameCaseSensitive,
7885
getTagContentType,

packages/angular-html-parser/test/index_spec.ts

+85-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ describe("AST format", () => {
6868
]);
6969
});
7070

71-
it("should have `type` property when tokenizeBlocks is enabled", () => {
71+
it("should support 'tokenizeAngularBlocks'", () => {
7272
const input = `@if (user.isHuman) { <p>Hello human</p> }`;
7373
const ast = parse(input, { tokenizeAngularBlocks: true });
7474
expect(ast.rootNodes).toEqual([
@@ -95,4 +95,88 @@ describe("AST format", () => {
9595
}),
9696
]);
9797
});
98+
99+
it("should support 'tokenizeAngularLetDeclaration'", () => {
100+
const input = `@let foo = 'bar';`;
101+
const ast = parse(input, { tokenizeAngularLetDeclaration: true });
102+
expect(ast.rootNodes).toEqual([
103+
expect.objectContaining({
104+
name: "foo",
105+
type: "letDeclaration",
106+
value: "'bar'",
107+
}),
108+
]);
109+
});
110+
111+
// https://github.com/angular/angular/pull/60724
112+
it("should support 'enableAngularSelectorlessSyntax'", () => {
113+
{
114+
const ast = parse("<div @Dir></div>", {
115+
enableAngularSelectorlessSyntax: true,
116+
});
117+
expect(ast.rootNodes).toEqual([
118+
expect.objectContaining({
119+
name: "div",
120+
type: "element",
121+
directives: [
122+
expect.objectContaining({
123+
name: "Dir",
124+
type: "directive",
125+
}),
126+
],
127+
}),
128+
]);
129+
}
130+
131+
{
132+
const ast = parse("<MyComp>Hello</MyComp>", {
133+
enableAngularSelectorlessSyntax: true,
134+
});
135+
136+
expect(ast.rootNodes).toEqual([
137+
expect.objectContaining({
138+
fullName: "MyComp",
139+
componentName: "MyComp",
140+
type: "component",
141+
}),
142+
]);
143+
}
144+
145+
{
146+
const ast = parse("<MyComp/>", { enableAngularSelectorlessSyntax: true });
147+
expect(ast.rootNodes).toEqual([
148+
expect.objectContaining({
149+
fullName: "MyComp",
150+
componentName: "MyComp",
151+
type: "component",
152+
}),
153+
]);
154+
}
155+
156+
{
157+
const ast = parse("<MyComp:button>Hello</MyComp:button>", {
158+
enableAngularSelectorlessSyntax: true,
159+
});
160+
expect(ast.rootNodes).toEqual([
161+
expect.objectContaining({
162+
fullName: "MyComp:button",
163+
componentName: "MyComp",
164+
type: "component",
165+
}),
166+
]);
167+
}
168+
169+
{
170+
const ast = parse("<MyComp:svg:title>Hello</MyComp:svg:title>", {
171+
enableAngularSelectorlessSyntax: true,
172+
});
173+
expect(ast.rootNodes).toEqual([
174+
expect.objectContaining({
175+
fullName: "MyComp:svg:title",
176+
componentName: "MyComp",
177+
type: "component",
178+
}),
179+
]);
180+
}
181+
});
98182
});

0 commit comments

Comments
 (0)