From c227fb7cc9e30d6a4330cdad34b0b2a53b014d93 Mon Sep 17 00:00:00 2001 From: David Vazgenovich Shakaryan Date: Mon, 9 May 2022 18:02:30 -0700 Subject: web: add support for child DOM elements and text nodes --- web/web_dom.c | 54 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 10 deletions(-) (limited to 'web/web_dom.c') diff --git a/web/web_dom.c b/web/web_dom.c index eadca7f..cff0459 100644 --- a/web/web_dom.c +++ b/web/web_dom.c @@ -7,41 +7,60 @@ #include +static struct dom_elem *dom_node_init(char *type, int size_attrs) +{ + struct dom_elem *e = calloc(1, sizeof(*e)); + e->type = type; // string literal, not freed + + e->size_attrs = size_attrs; + e->attr_names = malloc(size_attrs * sizeof(*(e->attr_names))); + e->attr_vals = malloc(size_attrs * sizeof(*(e->attr_vals))); + + return e; +} + struct dom_elem *dom_elem_init(char *ns, char *name, int size_attrs) { - struct dom_elem *e = malloc(sizeof(*e)); + struct dom_elem *e = dom_node_init("element", size_attrs); e->ns = ns ? strdup(ns) : NULL; e->name = strdup(name); - e->content = NULL; - e->n_attrs = 0; - e->size_attrs = size_attrs; - e->attr_names = malloc(size_attrs * sizeof(*(e->attr_names))); - e->attr_vals = malloc(size_attrs * sizeof(*(e->attr_vals))); + return e; +} + +struct dom_elem *dom_text_init(char *content) +{ + struct dom_elem *e = dom_node_init("text", 0); + e->content = strdup(content); return e; } void dom_elem_free(struct dom_elem *e) { - for(int i = 0; i < e->n_attrs; ++i) { + for (int i = 0; i < e->n_attrs; ++i) { free(e->attr_names[i]); free(e->attr_vals[i]); } + for (int i = 0; i < e->n_children; ++i) { + dom_elem_free(e->children[i]); + } + free(e->ns); free(e->name); free(e->content); free(e->attr_names); free(e->attr_vals); + free(e->children); free(e); } void dom_elem_add_attr(struct dom_elem *e, char *name, char *val) { if (e->n_attrs == e->size_attrs) { - e->size_attrs *= 2; + e->size_attrs += e->size_attrs ? e->size_attrs : 1; e->attr_names = realloc(e->attr_names, e->size_attrs * sizeof(*(e->attr_names))); e->attr_vals = realloc(e->attr_vals, @@ -59,16 +78,31 @@ void dom_elem_add_attrd(struct dom_elem *e, char *name, double val) dom_elem_add_attr(e, name, str); } +void dom_elem_add_child(struct dom_elem *e, struct dom_elem *child) +{ + if (e->n_children == e->size_children) { + e->size_children += e->size_children ? e->size_children : 1; + e->children = realloc(e->children, + e->size_children * sizeof(*(e->children))); + } + + e->children[e->n_children++] = child; +} + inline void dom_append_elemv(char *sel, int elemc, struct dom_elem **elemv) { - EM_ASM({elemAppendElemv($0, $1, $2, $3, $4, $5, $6, $7, $8)}, + EM_ASM({elemAppendElemv($0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, + $11)}, sel, elemc, elemv, + offsetof(struct dom_elem, type), offsetof(struct dom_elem, ns), offsetof(struct dom_elem, name), offsetof(struct dom_elem, content), offsetof(struct dom_elem, n_attrs), offsetof(struct dom_elem, attr_names), - offsetof(struct dom_elem, attr_vals)); + offsetof(struct dom_elem, attr_vals), + offsetof(struct dom_elem, n_children), + offsetof(struct dom_elem, children)); } inline char *dom_get_content(char *sel) -- cgit v1.2.3-70-g09d2