Skip to content

Commit 6a88806

Browse files
committed
feat: angular attribute syntax
1 parent e43e730 commit 6a88806

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

crates/biome_html_parser/src/parser.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ impl From<&HtmlFileSource> for HtmlParseOptions {
186186
HtmlVariant::Svelte => {
187187
options = options.with_single_text_expression().with_svelte();
188188
}
189+
HtmlVariant::Angular => {
190+
options = options.with_single_text_expression();
191+
}
189192
}
190193

191194
options

crates/biome_html_syntax/src/file_source.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ pub enum HtmlVariant {
3131
Vue,
3232
/// Use this variant to parse a Svelte file
3333
Svelte,
34+
/// Use this variant to parse an Angular file
35+
Angular,
3436
}
3537

3638
impl Default for HtmlVariant {
@@ -103,6 +105,12 @@ impl HtmlFileSource {
103105
}
104106
}
105107

108+
pub fn angular() -> Self {
109+
Self {
110+
variant: HtmlVariant::Angular,
111+
}
112+
}
113+
106114
/// Try to return the HTML file source corresponding to this file name from well-known files
107115
pub fn try_from_well_known(path: &Utf8Path) -> Result<Self, FileSourceError> {
108116
let Some(extension) = path.extension() else {
@@ -120,6 +128,7 @@ impl HtmlFileSource {
120128
"astro" => Ok(Self::astro()),
121129
"vue" => Ok(Self::vue()),
122130
"svelte" => Ok(Self::svelte()),
131+
"component.html" => Ok(Self::angular()),
123132
_ => Err(FileSourceError::UnknownExtension),
124133
}
125134
}
@@ -139,6 +148,7 @@ impl HtmlFileSource {
139148
"astro" => Ok(Self::astro()),
140149
"vuejs" | "vue" => Ok(Self::vue()),
141150
"svelte" => Ok(Self::svelte()),
151+
"angular" => Ok(Self::angular()),
142152
_ => Err(FileSourceError::UnknownLanguageId),
143153
}
144154
}

xtask/codegen/html.ungram

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ AnyHtmlAttribute =
186186
| HtmlAttributeSingleTextExpression
187187
| SvelteAttachAttribute
188188
| HtmlSpreadAttribute
189+
| AnyAngularAttribute
189190
| AnySvelteDirective
190191
| AnyVueDirective
191192
| AnyAstroDirective
@@ -757,3 +758,57 @@ AstroDirectiveValue =
757758
colon_token: ':'
758759
name: HtmlAttributeName
759760
initializer: HtmlAttributeInitializerClause?
761+
762+
// ==================================
763+
// Angular
764+
// ==================================
765+
766+
// reference: https://angular.dev/guide/templates
767+
768+
AnyAngularAttribute =
769+
AngularEventBinding
770+
| AngularPropertyBinding
771+
| AngularTwoWayBinding
772+
| AngularStructuralDirective
773+
| AngularTemplateRefVariable
774+
775+
// <button (click)="onClick()">
776+
// ^^^^^^^^^^^^^^^^^^
777+
AngularEventBinding =
778+
'('
779+
name: AngularBindingName
780+
')'
781+
initializer: HtmlAttributeInitializerClause?
782+
783+
// <input [value]="val">
784+
// ^^^^^^^^^^^^^^
785+
AngularPropertyBinding =
786+
'['
787+
name: AngularBindingName
788+
']'
789+
initializer: HtmlAttributeInitializerClause?
790+
791+
// <input [(ngModel)]="value">
792+
// ^^^^^^^^^^^^^^^^^^^
793+
AngularTwoWayBinding =
794+
'['
795+
'('
796+
name: AngularBindingName
797+
')'
798+
']'
799+
initializer: HtmlAttributeInitializerClause?
800+
801+
// <div *ngIf="cond">
802+
// ^^^^^^^^^^^^^
803+
AngularStructuralDirective =
804+
'*'
805+
name: AngularBindingName
806+
initializer: HtmlAttributeInitializerClause?
807+
808+
// <ng-template #tmpl>
809+
// ^^^^^
810+
AngularTemplateRefVariable =
811+
'#'
812+
name: AngularBindingName
813+
814+
AngularBindingName = value: 'html_literal'

0 commit comments

Comments
 (0)