From 43f5f26084407663316cfa303ba443473da4f373 Mon Sep 17 00:00:00 2001 From: LastLeaf Date: Fri, 27 Sep 2024 15:50:50 +0800 Subject: [PATCH] feat: support dataset on slot node --- .../src/parse/tag.rs | 35 ++++++++++--------- .../src/proc_gen/tag.rs | 14 ++++---- .../src/stringify/tag.rs | 28 +++++++-------- glass-easel/tests/tmpl/structure.test.ts | 29 +++++++++++++++ 4 files changed, 69 insertions(+), 37 deletions(-) diff --git a/glass-easel-template-compiler/src/parse/tag.rs b/glass-easel-template-compiler/src/parse/tag.rs index d8ebcd6..eefed0f 100644 --- a/glass-easel-template-compiler/src/parse/tag.rs +++ b/glass-easel-template-compiler/src/parse/tag.rs @@ -298,7 +298,6 @@ pub enum ElementKind { style: StyleAttribute, change_attributes: Vec, worklet_attributes: Vec, - data: Vec, children: Vec, generics: Vec, extra_attr: Vec, @@ -392,7 +391,6 @@ impl Element { style, change_attributes, worklet_attributes: _, - data, children: _, generics: _, extra_attr: _, @@ -422,9 +420,6 @@ impl Element { for attr in change_attributes { f(&mut attr.value, false); } - for attr in data { - f(&mut attr.value, false); - } common.for_each_value_mut(f); } ElementKind::Pure { @@ -541,7 +536,6 @@ impl Element { style: StyleAttribute::None, change_attributes: vec![], worklet_attributes: vec![], - data: vec![], children: vec![], generics: vec![], extra_attr: vec![], @@ -640,7 +634,7 @@ impl Element { (_, "slot") => AttrPrefixKind::Slot, (ElementKind::Normal { .. }, "class") => AttrPrefixKind::ClassString, (ElementKind::Normal { .. }, "style") => AttrPrefixKind::StyleString, - (ElementKind::Normal { .. }, x) if x.starts_with("data-") => { + (ElementKind::Normal { .. }, x) | (ElementKind::Slot { .. }, x) if x.starts_with("data-") => { AttrPrefixKind::DataHyphen } _ => AttrPrefixKind::Normal, @@ -1346,11 +1340,12 @@ impl Element { } }, AttrPrefixKind::Data(prefix_location) => match &mut element { - ElementKind::Normal { data, .. } => { + ElementKind::Normal { common, .. } | ElementKind::Slot { common, .. } => { if let AttrPrefixParseResult::Value(value, is_value_unspecified) = attr_value { - if data + if common + .data .iter() .find(|attr| attr.name.name_eq(&attr_name)) .is_some() @@ -1360,7 +1355,7 @@ impl Element { attr_name.location, ); } else { - data.push(Attribute { + common.data.push(Attribute { name: attr_name, value, is_model: false, @@ -1370,8 +1365,7 @@ impl Element { } } } - ElementKind::Slot { .. } - | ElementKind::Pure { .. } + ElementKind::Pure { .. } | ElementKind::For { .. } | ElementKind::If { .. } | ElementKind::TemplateRef { .. } @@ -1380,11 +1374,12 @@ impl Element { } }, AttrPrefixKind::DataHyphen => match &mut element { - ElementKind::Normal { data, .. } => { + ElementKind::Normal { common, .. } | ElementKind::Slot { common, .. } => { if let AttrPrefixParseResult::Value(value, is_value_unspecified) = attr_value { - if data + if common + .data .iter() .find(|attr| attr.name.name_eq(&attr_name)) .is_some() @@ -1396,7 +1391,7 @@ impl Element { } else { let prefix_location = attr_name.location.start..attr_name.location.start; - data.push(Attribute { + common.data.push(Attribute { name: attr_name, value, is_model: false, @@ -1406,8 +1401,7 @@ impl Element { } } } - ElementKind::Slot { .. } - | ElementKind::Pure { .. } + ElementKind::Pure { .. } | ElementKind::For { .. } | ElementKind::If { .. } | ElementKind::TemplateRef { .. } @@ -2336,6 +2330,7 @@ pub struct CommonElementAttributes { pub slot: Option<(Range, Value)>, pub slot_value_refs: Vec, pub event_bindings: Vec, + pub data: Vec, pub marks: Vec, } @@ -2365,6 +2360,7 @@ impl CommonElementAttributes { slot, slot_value_refs: _, event_bindings, + data, marks, } = self; if let Some(id) = id { @@ -2376,6 +2372,9 @@ impl CommonElementAttributes { for ev in event_bindings { f(&mut ev.value, false); } + for attr in data { + f(&mut attr.value, false); + } for attr in marks { f(&mut attr.value, false); } @@ -3687,6 +3686,8 @@ mod test { 6..12 ); case!("", r#""#); + case!("", r#""#); + case!("", r#""#); case!("", r#""#); case!("", r#""#); } diff --git a/glass-easel-template-compiler/src/proc_gen/tag.rs b/glass-easel-template-compiler/src/proc_gen/tag.rs index 93d8c5c..00f0236 100644 --- a/glass-easel-template-compiler/src/proc_gen/tag.rs +++ b/glass-easel-template-compiler/src/proc_gen/tag.rs @@ -433,7 +433,6 @@ impl Element { class, style, change_attributes, - data, common, .. } => { @@ -459,7 +458,7 @@ impl Element { for attr in change_attributes { f(&gen_lit_str(&attr.name.name))?; } - for attr in data { + for attr in common.data.iter() { f(&gen_lit_str(&format!("data:{}", &attr.name.name)))?; } for attr in common.marks.iter() { @@ -492,6 +491,9 @@ impl Element { for attr in values { f(&gen_lit_str(&attr.name.name))?; } + for attr in common.data.iter() { + f(&gen_lit_str(&format!("data:{}", &attr.name.name)))?; + } for attr in common.marks.iter() { f(&gen_lit_str(&format!("mark:{}", &attr.name.name)))?; } @@ -517,7 +519,6 @@ impl Element { style, change_attributes, worklet_attributes, - data, children, generics, extra_attr, @@ -607,9 +608,6 @@ impl Element { for attr in attributes.iter() { attr.to_proc_gen_as_normal(w, scopes, bmc)?; } - for attr in data.iter() { - attr.to_proc_gen_with_method(w, "R.d", true, scopes, bmc)?; - } common.to_proc_gen_without_slot(w, scopes, bmc)?; if let SlotKind::Dynamic(p) = &slot_kind { if let Some(( @@ -1197,8 +1195,12 @@ impl CommonElementAttributes { slot: _, slot_value_refs: _, event_bindings, + data, marks, } = self; + for attr in data.iter() { + attr.to_proc_gen_with_method(w, "R.d", true, scopes, bmc)?; + } for mark in marks { mark.to_proc_gen_with_method(w, "M", true, scopes, bmc)?; } diff --git a/glass-easel-template-compiler/src/stringify/tag.rs b/glass-easel-template-compiler/src/stringify/tag.rs index e19e778..ee6a91b 100644 --- a/glass-easel-template-compiler/src/stringify/tag.rs +++ b/glass-easel-template-compiler/src/stringify/tag.rs @@ -222,11 +222,25 @@ impl Stringify for Element { slot: _, slot_value_refs: _, event_bindings, + data, marks, } = common; if let Some((loc, value)) = id.as_ref() { write_named_attr(stringifier, "id", loc, value)?; } + for attr in data.iter() { + let prefix = ( + "data", + attr.prefix_location.as_ref().unwrap_or(&attr.name.location), + ); + write_attr( + stringifier, + Some(prefix), + &attr.name, + &attr.value, + Some(attr.is_value_unspecified), + )?; + } for attr in marks.iter() { let prefix = ( "mark", @@ -367,7 +381,6 @@ impl Stringify for Element { style, change_attributes, worklet_attributes, - data, children: _, generics, extra_attr, @@ -442,19 +455,6 @@ impl Stringify for Element { &attr.value, )?; } - for attr in data.iter() { - let prefix = ( - "data", - attr.prefix_location.as_ref().unwrap_or(&attr.name.location), - ); - write_attr( - stringifier, - Some(prefix), - &attr.name, - &attr.value, - Some(attr.is_value_unspecified), - )?; - } for attr in generics.iter() { write_static_attr( stringifier, diff --git a/glass-easel/tests/tmpl/structure.test.ts b/glass-easel/tests/tmpl/structure.test.ts index 161d07a..f9b2515 100644 --- a/glass-easel/tests/tmpl/structure.test.ts +++ b/glass-easel/tests/tmpl/structure.test.ts @@ -1665,6 +1665,35 @@ const testCases = (testBackend: glassEasel.GeneralBackendContext) => { ops = [] }) + test('binding event on slot', () => { + const ops: any[] = [] + const def = glassEasel + .registerElement({ + template: tmpl(` +
+ +
+ `), + methods: { + ev(ev: any) { + // eslint-disable-next-line no-use-before-define + expect(this).toBe(elem) + ops.push(ev) + }, + }, + }) + .general() + const elem = glassEasel.Component.createWithContext('root', def, testBackend) + glassEasel.Element.pretendAttached(elem) + expect(domHtml(elem)).toBe('
') + matchElementWithDom(elem) + const child = elem.getShadowRoot()!.getElementById('child')! + child.triggerEvent('customEv', null, { bubbles: true }) + const ev = ops.shift() as glassEasel.ShadowedEvent + expect(ev.mark).toStrictEqual({ b: 123 }) + expect(ev.target.dataset).toStrictEqual({ a: 'abc' }) + }) + test('setting properties', () => { const cs = new glassEasel.ComponentSpace() const subComp = cs.defineComponent({