From a501e508284b4d3b47c4e923e8932008ed3075eb Mon Sep 17 00:00:00 2001 From: chyizheng Date: Wed, 31 Jan 2024 14:46:15 +0800 Subject: [PATCH] fix: support listener binding on slot --- glass-easel-template-compiler/src/parser.rs | 8 ++- glass-easel-template-compiler/src/tree.rs | 54 +++++++++------------ glass-easel/tests/tmpl/event.test.ts | 50 +++++++++++++++---- 3 files changed, 71 insertions(+), 41 deletions(-) diff --git a/glass-easel-template-compiler/src/parser.rs b/glass-easel-template-compiler/src/parser.rs index 9afa5d24..81047e29 100644 --- a/glass-easel-template-compiler/src/parser.rs +++ b/glass-easel-template-compiler/src/parser.rs @@ -725,7 +725,13 @@ impl<'a> TmplParseTask<'a> { for attr in old_attrs.into_iter() { if attr.is_property("name") { name = attr.value; - } else if attr.is_any_property() { + } else if match attr.kind { + TmplAttrKind::PropertyOrExternalClass { .. } + | TmplAttrKind::Data { .. } + | TmplAttrKind::Mark { .. } + | TmplAttrKind::Event { .. } => true, + _ => false, + } { if let Some(arr) = &mut props { arr.push(attr); } else { diff --git a/glass-easel-template-compiler/src/tree.rs b/glass-easel-template-compiler/src/tree.rs index 44699cfc..60124b77 100644 --- a/glass-easel-template-compiler/src/tree.rs +++ b/glass-easel-template-compiler/src/tree.rs @@ -1233,10 +1233,23 @@ impl TmplElement { } TmplVirtualType::Slot { name, props } => { let slot_kind = SlotKind::new(&self.slot, w, scopes)?; - let slot_value_init = if let Some(props) = props { - let var_slot_value_init = w.gen_private_ident(); - w.expr_stmt(|w| { - write!(w, "var {}=", var_slot_value_init)?; + let name = StaticStrOrProcGen::new(name, w, scopes)?; + w.expr_stmt(|w| { + write!(w, "S(")?; + match name { + StaticStrOrProcGen::Static(s) => { + write!(w, "{}", gen_lit_str(s))?; + } + StaticStrOrProcGen::Dynamic(p) => { + write!(w, r#"C||K||"#)?; + p.lvalue_state_expr(w, scopes)?; + write!(w, r#"?Y("#)?; + p.value_expr(w)?; + write!(w, "):undefined")?; + } + } + if let Some(props) = props { + write!(w, r#","#)?; w.function_args("N", |w| { for prop in props { match &prop.kind { @@ -1267,6 +1280,11 @@ impl TmplElement { } } } + TmplAttrKind::Event { .. } + | TmplAttrKind::Data { .. } + | TmplAttrKind::Mark { .. } => { + prop.to_proc_gen(w, scopes, bmc)?; + } _ => { // TODO warn unused attr } @@ -1274,34 +1292,10 @@ impl TmplElement { } Ok(()) })?; - Ok(()) - })?; - format!("{}", var_slot_value_init) - } else { - String::new() - }; - let name = StaticStrOrProcGen::new(name, w, scopes)?; - w.expr_stmt(|w| { - write!(w, "S(")?; - match name { - StaticStrOrProcGen::Static(s) => { - write!(w, "{}", gen_lit_str(s))?; - }, - StaticStrOrProcGen::Dynamic(p) => { - write!(w, r#"C||K||"#)?; - p.lvalue_state_expr(w, scopes)?; - write!(w, r#"?Y("#)?; - p.value_expr(w)?; - write!(w, "):undefined")?; - }, - } - if slot_value_init.len() > 0 { - write!(w, r#",{}"#, slot_value_init)?; + } else if (!slot_kind.is_none()) { + write!(w, r#",undefined"#)?; } if !slot_kind.is_none() { - if slot_value_init.len() == 0 { - write!(w, r#",undefined"#)?; - } slot_kind.write_as_extra_argument(w)?; } write!(w, ")")?; diff --git a/glass-easel/tests/tmpl/event.test.ts b/glass-easel/tests/tmpl/event.test.ts index 92aae4d8..17bd5417 100644 --- a/glass-easel/tests/tmpl/event.test.ts +++ b/glass-easel/tests/tmpl/event.test.ts @@ -124,42 +124,66 @@ const testCases = (testBackend: glassEasel.GeneralBackendContext) => { const single = glassEasel.registerElement({ template: tmpl(` -
-
+
+ +
+
+ +
`), methods: { on0: () => ops.push('s0'), on1: () => ops.push('s1'), + on2: () => ops.push('s2'), + on3: () => ops.push('s3'), on0c: () => ops.push('s0c'), on1c: () => ops.push('s1c'), + on2c: () => ops.push('s2c'), + on3c: () => ops.push('s3c'), }, }) const multi = glassEasel.registerElement({ options: { multipleSlots: true }, template: tmpl(` -
-
+
+ +
+
+ +
`), methods: { on0: () => ops.push('m0'), on1: () => ops.push('m1'), + on2: () => ops.push('m2'), + on3: () => ops.push('m3'), on0c: () => ops.push('m0c'), on1c: () => ops.push('m1c'), + on2c: () => ops.push('m2c'), + on3c: () => ops.push('m3c'), }, }) const dynamic = glassEasel.registerElement({ options: { dynamicSlots: true }, template: tmpl(` -
-
+
+ +
+
+ +
`), methods: { on0: () => ops.push('d0'), on1: () => ops.push('d1'), + on2: () => ops.push('d2'), + on3: () => ops.push('d3'), on0c: () => ops.push('d0c'), on1c: () => ops.push('d1c'), + on2c: () => ops.push('d2c'), + on3c: () => ops.push('d3c'), }, }) @@ -220,21 +244,27 @@ const testCases = (testBackend: glassEasel.GeneralBackendContext) => { expect(ops).toEqual([ 'p0c', 's0c', + 's1c', 'p3c', 'p3', + 's1', 's0', 'p0', 'p1c', - 'm1c', + 'm2c', + 'm3c', 'p4c', 'p4', - 'm1', + 'm3', + 'm2', 'p1', 'p2c', - 'd1c', + 'd2c', + 'd3c', 'p5c', 'p5', - 'd1', + 'd3', + 'd2', 'p2', ]) })