@@ -5,6 +5,7 @@ export class OpeningElementVisitor {}
5
5
``` typescript
6
6
< OpeningElementVisitor / > +
7
7
function Visit(e : NodePath <JSXOpeningElement >, generator : IGenerator ) {
8
+ < HandleSlotProps / > ;
8
9
< HandleAttributes / > ;
9
10
10
11
//
@@ -19,27 +20,90 @@ export class OpeningElementVisitor {}
19
20
```
20
21
21
22
``` typescript
22
- const TargetTable = { DoubleClick: " dblclick" , InnerHTML: " innerHTML" , contentEditable: " contenteditable" };
23
+ const TargetTable = { DoubleClick: " dblclick" , InnerHTML: " innerHTML" , contentEditable: " contenteditable" , Ref: " this " };
23
24
```
24
25
25
26
``` typescript
26
27
const NamespaceList = [" on" , " bind" ];
27
28
```
28
29
30
+ ``` typescript
31
+ const DirectiveSet = new Set ([" transition" , " in" , " out" , " localTransition" , " animate" , " use" ]);
32
+ ```
33
+
29
34
``` typescript
30
35
function HandleAttributes(e : NodePath <JSXOpeningElement >) {
36
+ < PreprocessAttributes / > ;
31
37
e .node .attributes .forEach (attr => {
32
38
if (attr .type === " JSXAttribute" && attr .name .type === " JSXIdentifier" ) {
33
39
const name = attr .name .name ;
34
- NamespaceList .forEach (namespace => {
35
- if (TargetTable [name ]) {
36
- attr .name = jsxIdentifier (TargetTable [name ]);
37
- } else if (name .startsWith (namespace )) {
38
- const raw_target = name .substr (namespace .length );
39
- const target = TargetTable [raw_target ] || raw_target .toLowerCase ();
40
- attr .name = jsxNamespacedName (jsxIdentifier (namespace ), jsxIdentifier (target ));
41
- }
42
- });
40
+ if (DirectiveSet .has (name )) {
41
+ < HandleDirective / > ;
42
+ } else {
43
+ < HandleNamespace / > ;
44
+ }
45
+ }
46
+ });
47
+ }
48
+ ```
49
+
50
+ ``` typescript
51
+ function PreprocessAttributes(e : NodePath <JSXOpeningElement >) {
52
+ e .node .attributes = e .node .attributes .reduce ((container , attr ) => {
53
+ if (attr .type === " JSXAttribute" && attr .name .type === " JSXIdentifier" && (attr .name .name === " on" || attr .name .name === " props" )) {
54
+ const value = attr .value as JSXExpressionContainer ;
55
+ const config = value .expression as CallExpression ;
56
+ const [event_config] = config .arguments as [ObjectExpression ];
57
+ const properties = event_config .properties as Array <ObjectProperty >;
58
+ properties .forEach (each => {
59
+ //
60
+ const prop: string = (each .key as Identifier ).name ;
61
+ const prop_value: string = ToString (each .value );
62
+
63
+ //
64
+ const prefix = attr .name .name === " on" ? " on" : " " ;
65
+ const name = jsxIdentifier (` ${prefix }${prop } ` );
66
+ const value = stringLiteral (` {${prop_value }} ` );
67
+ container .push (jsxAttribute (name , value ));
68
+ });
69
+ } else {
70
+ container .push (attr );
71
+ }
72
+ return container ;
73
+ }, []);
74
+ }
75
+ ```
76
+
77
+ ``` typescript
78
+ const VerticalBar = " $VERTICAL_BAR$" ;
79
+ ```
80
+
81
+ ``` typescript
82
+ function HandleDirective(attr : JSXAttribute ) {
83
+ const value = attr .value as JSXExpressionContainer ;
84
+ const config = value .expression as CallExpression ;
85
+
86
+ // use compact to avoid \n in params after ToString
87
+ const args = config .arguments .map (arg => ToString (arg , { compact: true }));
88
+ const [transition_function, transition_params] = args ;
89
+
90
+ // use VerticalBar and replace it with | latter because | is invalid in JSX
91
+ let namespace = name === " localTransition" ? ` transition ` : name ;
92
+ let function_name = name === " localTransition" ? ` ${transition_function }${VerticalBar }local ` : transition_function ;
93
+ attr .name = jsxNamespacedName (jsxIdentifier (namespace ), jsxIdentifier (function_name ));
94
+ attr .value = transition_params ? stringLiteral (` {${transition_params }} ` ) : null ;
95
+ }
96
+ ```
97
+
98
+ ``` typescript
99
+ function HandleNamespace(attr : JSXAttribute , name : string ) {
100
+ NamespaceList .forEach (namespace => {
101
+ if (TargetTable [name ]) {
102
+ attr .name = jsxIdentifier (TargetTable [name ]);
103
+ } else if (name .startsWith (namespace )) {
104
+ const raw_target = name .substr (namespace .length );
105
+ const target = TargetTable [raw_target ] || raw_target .toLowerCase ();
106
+ attr .name = jsxNamespacedName (jsxIdentifier (namespace ), jsxIdentifier (target ));
43
107
}
44
108
});
45
109
}
@@ -48,6 +112,9 @@ function HandleAttributes(e: NodePath<JSXOpeningElement>) {
48
112
``` typescript
49
113
function HandleOpeningElement(tag_name : string ) {
50
114
" use match" ;
115
+ (tag_name : " debug" ) => {
116
+ < HandleDebug / > ;
117
+ };
51
118
(tag_name : " if" ) => {
52
119
< HandleIf / > ;
53
120
};
@@ -67,8 +134,19 @@ function HandleOpeningElement(tag_name: string) {
67
134
```
68
135
69
136
``` typescript
70
- function HandleDefault(e : NodePath <JSXOpeningElement >, Append : (value : string ) => void ) {
71
- Append (ToString (e .node ));
137
+ function HandleDefault(e : NodePath <JSXOpeningElement >, Append : (value : string ) => void ) {
138
+ //
139
+ let element = ToString (e .node );
140
+
141
+ // handle |
142
+ element = element .replace (VerticalBar , " |" );
143
+ Append (element );
144
+ }
145
+ ```
146
+
147
+ ``` typescript
148
+ function HandleDebug(Append : (value : string ) => void ) {
149
+ Append (` {@debug ` );
72
150
}
73
151
```
74
152
@@ -90,6 +168,25 @@ function HandleElse(e: NodePath<JSXOpeningElement>, Append: (value: string) => v
90
168
}
91
169
```
92
170
171
+ ``` typescript
172
+ function HandleSlotProps(e : NodePath <JSXOpeningElement >) {
173
+ const slot_props = FindChildJSXExpressionContainer (e )
174
+ ?.get (" expression" )
175
+ ?.get (" params" )
176
+ .find (each => each .isObjectPattern ()) as NodePath <ObjectPattern >;
177
+ if (slot_props ) {
178
+ const properties = slot_props .node .properties as Array <ObjectProperty >;
179
+ properties .forEach (each => {
180
+ const prop: string = (each .key as Identifier ).name ;
181
+ const alias: string = ToString (each .value );
182
+ const name = jsxNamespacedName (jsxIdentifier (" let" ), jsxIdentifier (prop ));
183
+ const value = jsxExpressionContainer (identifier (alias ));
184
+ e .node .attributes .push (jsxAttribute (name , value ));
185
+ });
186
+ }
187
+ }
188
+ ```
189
+
93
190
``` typescript
94
191
function HandleEach(e : NodePath <JSXOpeningElement >, Append : (value : string ) => void ) {
95
192
const raw_from = FindAttribute (" from" , e )?.node ;
@@ -114,7 +211,7 @@ function HandleEach(e: NodePath<JSXOpeningElement>, Append: (value: string) => v
114
211
115
212
// if we specify value, key only, key info is stored in index
116
213
const item_part = ` #each ${data } as ${value || " __invalid value__" } ` ;
117
- const index_part = index ? (index .is_key ? ` (${index .key_name })} ` : ` , ${index } ` ) : " " ;
214
+ const index_part = index ? (index .is_key ? ` (${index .key_name }) ` : ` , ${index } ` ) : " " ;
118
215
const key_part = key ? ` (${key .key_name }) ` : " " ;
119
216
const each = ` {${item_part }${index_part }${key_part }} ` ;
120
217
Append (each );
0 commit comments