// el-html — Atomic HTML element primitives.
//
// Usage:
// el_div("class=\"card\"", inner_html)
// el_h1("", "Hello world")
// el_img("/logo.png", "Logo", "width=\"120\"")
//
// Children args are raw HTML — pre-escaped by caller.
// Use el_text(s) to safely insert plain text.
// ── Text escaping ─────────────────────────────────────────────────────────────
fn el_escape(s: String) -> String {
let s = str_replace(s, "&", "&")
let s = str_replace(s, "<", "<")
let s = str_replace(s, ">", ">")
let s = str_replace(s, "\"", """)
str_replace(s, "'", "'")
}
fn el_text(s: String) -> String {
el_escape(s)
}
fn el_attr(name: String, value: String) -> String {
" " + name + "=\"" + el_escape(value) + "\""
}
// ── Block elements ────────────────────────────────────────────────────────────
fn el_div(attrs: String, children: String) -> String {
if str_eq(attrs, "") { return "
" + children + "
" }
"" + children + "
"
}
fn el_section(attrs: String, children: String) -> String {
if str_eq(attrs, "") { return "" }
""
}
fn el_article(attrs: String, children: String) -> String {
if str_eq(attrs, "") { return "" + children + "" }
"" + children + ""
}
fn el_header(attrs: String, children: String) -> String {
if str_eq(attrs, "") { return "" }
""
}
fn el_footer(attrs: String, children: String) -> String {
if str_eq(attrs, "") { return "" }
""
}
fn el_main(attrs: String, children: String) -> String {
if str_eq(attrs, "") { return "" + children + "" }
"" + children + ""
}
fn el_nav(attrs: String, children: String) -> String {
if str_eq(attrs, "") { return "" }
""
}
fn el_aside(attrs: String, children: String) -> String {
if str_eq(attrs, "") { return "" }
""
}
fn el_ul(attrs: String, children: String) -> String {
if str_eq(attrs, "") { return "" }
""
}
fn el_ol(attrs: String, children: String) -> String {
if str_eq(attrs, "") { return "" + children + "
" }
"" + children + "
"
}
fn el_li(attrs: String, children: String) -> String {
if str_eq(attrs, "") { return "" + children + "" }
"" + children + ""
}
fn el_p(attrs: String, children: String) -> String {
if str_eq(attrs, "") { return "" + children + "
" }
"" + children + "
"
}
fn el_span(attrs: String, children: String) -> String {
if str_eq(attrs, "") { return "" + children + "" }
"" + children + ""
}
fn el_form(attrs: String, children: String) -> String {
if str_eq(attrs, "") { return "" }
""
}
// ── Headings ──────────────────────────────────────────────────────────────────
fn el_h1(attrs: String, text: String) -> String {
if str_eq(attrs, "") { return "" + el_escape(text) + "
" }
"" + el_escape(text) + "
"
}
fn el_h2(attrs: String, text: String) -> String {
if str_eq(attrs, "") { return "" + el_escape(text) + "
" }
"" + el_escape(text) + "
"
}
fn el_h3(attrs: String, text: String) -> String {
if str_eq(attrs, "") { return "" + el_escape(text) + "
" }
"" + el_escape(text) + "
"
}
fn el_h4(attrs: String, text: String) -> String {
if str_eq(attrs, "") { return "" + el_escape(text) + "
" }
"" + el_escape(text) + "
"
}
// ── Interactive ───────────────────────────────────────────────────────────────
fn el_button(attrs: String, label: String) -> String {
if str_eq(attrs, "") { return "" }
""
}
fn el_a(href: String, attrs: String, children: String) -> String {
let h: String = "href=\"" + el_escape(href) + "\""
if str_eq(attrs, "") { return "" + children + "" }
"" + children + ""
}
fn el_input(type_attr: String, attrs: String) -> String {
if str_eq(attrs, "") { return "" }
""
}
fn el_textarea(attrs: String, value: String) -> String {
if str_eq(attrs, "") { return "" }
""
}
fn el_label(for_id: String, attrs: String, children: String) -> String {
let f: String = "for=\"" + el_escape(for_id) + "\""
if str_eq(attrs, "") { return "" }
""
}
// ── Media ─────────────────────────────────────────────────────────────────────
fn el_img(src: String, alt: String, attrs: String) -> String {
let base: String = "src=\"" + el_escape(src) + "\" alt=\"" + el_escape(alt) + "\""
if str_eq(attrs, "") { return "
" }
"
"
}
fn el_video(attrs: String, children: String) -> String {
if str_eq(attrs, "") { return "" }
""
}
// ── Inline semantic ───────────────────────────────────────────────────────────
fn el_strong(children: String) -> String {
"" + children + ""
}
fn el_em(children: String) -> String {
"" + children + ""
}
fn el_code(children: String) -> String {
"" + children + ""
}
fn el_pre(attrs: String, children: String) -> String {
if str_eq(attrs, "") { return "" + children + "
" }
"" + children + "
"
}
fn el_hr() -> String { "
" }
fn el_br() -> String { "
" }
// ── Document shell ────────────────────────────────────────────────────────────
fn el_html_doc(lang: String, head_html: String, body_html: String) -> String {
""
+ head_html + "" + body_html + ""
}
fn el_meta(name: String, content: String) -> String {
""
}
fn el_meta_charset(charset: String) -> String {
""
}
fn el_link_stylesheet(href: String) -> String {
""
}
fn el_script_src(src: String, defer_load: Bool) -> String {
if defer_load { return "" }
""
}
fn el_script_inline(js: String) -> String {
""
}
fn el_title(text: String) -> String {
"" + el_escape(text) + ""
}
// ── Entry — smoke test ────────────────────────────────────────────────────────
let sample: String = el_div("class=\"card\"", el_h2("", "Hello") + el_p("", "World"))
println("[el-html] sample = " + sample)