summaryrefslogtreecommitdiff
path: root/web/web_dom.c
diff options
context:
space:
mode:
Diffstat (limited to 'web/web_dom.c')
-rw-r--r--web/web_dom.c54
1 files changed, 44 insertions, 10 deletions
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 <emscripten/emscripten.h>
+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)