97 lines
3.8 KiB
Text
97 lines
3.8 KiB
Text
# build.ludic - a template and the model, made into this frame's nodes. <if>/<else> and
|
|
# <each in= as= index=> are the template's own; a tag its file linked to a component is that one,
|
|
# given its attributes as props (over the defaults its own tag gives: <component name="Card"
|
|
# sub="">), its on-* as what `emit` runs, and its content as <slot/>.
|
|
function bd_kids(ui_st: mut UiState, kids: []UiTpl, e0: UiEnv, key: string, out: []UiNode) -> void {
|
|
var last_if = true
|
|
var e = e0
|
|
for i in 0 .. len(kids) {
|
|
let k = kids[i]
|
|
ui_st.ui_at = k.where
|
|
let ck = mm_join(ui_st, key, "/", mm_int(ui_st, i))
|
|
if k.tag == "state" or k.tag == "style" { continue }
|
|
if k.tag == "let" {
|
|
e = bd_let(ui_st, k, e)
|
|
continue
|
|
}
|
|
if k.tag == "fragment" or k.tag == "#text" or (k.tag == "template" and tpl_attr(k, "slot") == null) { bd_group(ui_st, k, e, ck, out) } else if k.tag == "provide" { bd_provide(ui_st, k, e, ck, out) } else if k.tag == "template" { continue } else if k.tag == "if" {
|
|
last_if = bd_test(ui_st, k, e)
|
|
if last_if { bd_kids(ui_st, k.kids, e, ck, out) }
|
|
} else if k.tag == "else" {
|
|
if not last_if { bd_kids(ui_st, k.kids, e, ck, out) }
|
|
last_if = true
|
|
} else if k.tag == "each" { bd_each(ui_st, k, e, ck, out) } else if k.tag == "slot" { bd_slot(ui_st, k, e, ck, out) } else if not bd_comp(ui_st, k, e, ck, out) { ui_kept(out, bd_elem(ui_st, k, e, ck)) }
|
|
}
|
|
}
|
|
function bd_test(ui_st: mut UiState, k: UiTpl, e: UiEnv) -> bool {
|
|
let t = tpl_attr(k, "test")
|
|
if t == null {
|
|
ui_err(ui_st, "<if> needs a test=\"{...}\"")
|
|
return false
|
|
}
|
|
return ui_eval_bool(ui_st, t, e)
|
|
}
|
|
function bd_name(k: UiTpl, attr: string, dflt: string) -> string {
|
|
let x = tpl_attr(k, attr)
|
|
if x == null or x.op != X_LIT { return dflt }
|
|
return Value.as_str(x.v)
|
|
}
|
|
function bd_each(ui_st: mut UiState, k: UiTpl, e: UiEnv, key: string, out: []UiNode) -> void {
|
|
let src = tpl_attr(k, "in")
|
|
if src == null {
|
|
ui_err(ui_st, "<each> needs an in=\"{...}\"")
|
|
return
|
|
}
|
|
let list = ui_eval(ui_st, src, e)
|
|
let as_name = bd_name(k, "as", "item")
|
|
let at_name = bd_name(k, "index", "index")
|
|
let by = tpl_attr(k, "key")
|
|
for j in 0 .. Value.count(list) {
|
|
let le = env_new(ui_st, e)
|
|
env_bind(le, as_name, Value.at(list, j))
|
|
env_bind(le, at_name, mm_ival(ui_st, j))
|
|
var id = mm_int(ui_st, j)
|
|
if by != null { id = ui_eval_text(ui_st, by, le) }
|
|
bd_kids(ui_st, k.kids, le, mm_join(ui_st, key, "#", id), out)
|
|
}
|
|
}
|
|
# <slot/> is what the component's user put inside it; <slot name="x"/> their <template slot="x">
|
|
function bd_slot(ui_st: mut UiState, k: UiTpl, e: UiEnv, key: string, out: []UiNode) -> void {
|
|
var at = e
|
|
while at != null and at.slot == null { at = at.parent }
|
|
if at == null { return }
|
|
let name = bd_name(k, "name", "")
|
|
if name == "" {
|
|
bd_kids(ui_st, at.slot.kids, at.slot_env, key, out)
|
|
return
|
|
}
|
|
for i in 0 .. len(at.slot.kids) {
|
|
let t = at.slot.kids[i]
|
|
if t.tag == "template" and bd_name(t, "slot", "") == name { bd_group(ui_st, t, at.slot_env, key, out) }
|
|
}
|
|
}
|
|
function bd_comp(ui_st: mut UiState, k: UiTpl, e: UiEnv, key: string, out: []UiNode) -> bool {
|
|
if k.cls != null {
|
|
bd_class(ui_st, k, e, key, out)
|
|
return true
|
|
}
|
|
if k.comp == null { return false }
|
|
let c = k.comp
|
|
let ce = env_new(ui_st, null)
|
|
ce.model = e.model
|
|
ce.ctx = e.ctx
|
|
for i in 0 .. len(c.keys) {
|
|
if c.keys[i] != "name" and c.keys[i] != "export" { env_bind(ce, c.keys[i], ui_eval(ui_st, c.vals[i], ce)) }
|
|
}
|
|
for i in 0 .. len(k.keys) { env_bind(ce, k.keys[i], ui_eval(ui_st, k.vals[i], e)) }
|
|
ce.on_names = k.on_keys
|
|
ce.on_acts = k.on_acts
|
|
for i in 0 .. len(k.on_keys) { ui_kept(ce.on_envs, e) }
|
|
ce.slot = k
|
|
ce.slot_env = e
|
|
ce.ctx = e.ctx
|
|
ce.state = st_for(ui_st, key, c, ce)
|
|
lc_note(ui_st, key, k.on_keys, k.on_acts, e)
|
|
bd_kids(ui_st, c.kids, ce, key, out)
|
|
return true
|
|
}
|