static void es_gumbo_find_by_class_r(GumboNode *node, char **classes, duk_context *ctx, int *idxp, es_gumbo_output_t *ego) { if(node->type != GUMBO_NODE_ELEMENT && node->type != GUMBO_NODE_TEMPLATE) return; const GumboElement *e = &node->v.element; GumboAttribute *a = gumbo_get_attribute(&e->attributes, "class"); if(a != NULL) { char **list = strvec_split(a->value, ' '); for(int i = 0; classes[i] != NULL; i++) { int found = 0; for(int j = 0; list[j] != NULL; j++) { if(!strcmp(list[j], classes[i])) { found = 1; break; } } if(!found) goto notfound; } push_gumbo_node(ctx, node, ego); duk_put_prop_index(ctx, -2, (*idxp)++); notfound: strvec_free(list); } for(int i = 0; i < e->children.length; i++) es_gumbo_find_by_class_r(e->children.data[i], classes, ctx, idxp, ego); }
static prop_t * prop_from_path(const char *path) { char **n = strvec_split(path, '/'); prop_t *p = prop_get_by_name((const char **)n, 1, NULL); strvec_free(n); return p; }
static int es_gumbo_find_by_class(duk_context *ctx) { es_gumbo_node_t *egn = es_get_native_obj(ctx, 0, &es_native_gumbo_node); const char *cls = duk_to_string(ctx, 1); int idx = 0; duk_push_array(ctx); char **classlist = strvec_split(cls, ' '); es_gumbo_find_by_class_r(egn->node, classlist, ctx, &idx, egn->output); strvec_free(classlist); return 1; }