void destroy_tree(node *root) { node *n, *p; uint32_t i; for (n = root->children; n != NULL; n = p) { p = n->next; destroy_tree(n); } css_select_results_destroy(root->sr); for (i = 0; i < root->n_attrs; ++i) { lwc_string_unref(root->attrs[i].name); lwc_string_unref(root->attrs[i].value); } free(root->attrs); if (root->classes != NULL) { for (i = 0; i < root->n_classes; ++i) { lwc_string_unref(root->classes[i]); } free(root->classes); } if (root->libcss_node_data != NULL) { css_libcss_node_data_handler(&select_handler, CSS_NODE_DELETED, NULL, root, NULL, root->libcss_node_data); } lwc_string_unref(root->name); free(root); }
void run_test(line_ctx *ctx, const char *exp, size_t explen) { css_select_ctx *select; css_select_results *results; uint32_t i; char *buf; size_t buflen; static int testnum; UNUSED(exp); buf = malloc(8192); if (buf == NULL) { assert(0 && "No memory for result data"); } buflen = 8192; assert(css_select_ctx_create(&select) == CSS_OK); for (i = 0; i < ctx->n_sheets; i++) { assert(css_select_ctx_append_sheet(select, ctx->sheets[i].sheet, ctx->sheets[i].origin, ctx->sheets[i].media) == CSS_OK); } testnum++; assert(css_select_style(select, ctx->target, ctx->media, NULL, &select_handler, ctx, &results) == CSS_OK); assert(results->styles[ctx->pseudo_element] != NULL); dump_computed_style(results->styles[ctx->pseudo_element], buf, &buflen); if (8192 - buflen != explen || memcmp(buf, exp, explen) != 0) { printf("Expected (%u):\n%.*s\n", (int) explen, (int) explen, exp); printf("Result (%u):\n%.*s\n", (int) (8192 - buflen), (int) (8192 - buflen), buf); assert(0 && "Result doesn't match expected"); } /* Clean up */ css_select_results_destroy(results); css_select_ctx_destroy(select); destroy_tree(ctx->tree); for (i = 0; i < ctx->n_sheets; i++) { css_stylesheet_destroy(ctx->sheets[i].sheet); } ctx->tree = NULL; ctx->current = NULL; ctx->depth = 0; ctx->n_sheets = 0; free(ctx->sheets); ctx->sheets = NULL; ctx->target = NULL; free(buf); printf("Test %d: PASS\n", testnum); }
/** * Get style selection results for an element * * \param ctx CSS selection context * \param n Element to select for * \param media Permitted media types * \param inline_style Inline style associated with element, or NULL * \return Pointer to selection results (containing computed styles), * or NULL on failure */ css_select_results *nscss_get_style(nscss_select_ctx *ctx, dom_node *n, uint64_t media, const css_stylesheet *inline_style) { css_computed_style *composed; css_select_results *styles; int pseudo_element; css_error error; /* Select style for node */ error = css_select_style(ctx->ctx, n, media, inline_style, &selection_handler, ctx, &styles); if (error != CSS_OK || styles == NULL) { /* Failed selecting partial style -- bail out */ return NULL; } /* If there's a parent style, compose with partial to obtain * complete computed style for element */ if (ctx->parent_style != NULL) { /* Complete the computed style, by composing with the parent * element's style */ error = css_computed_style_compose(ctx->parent_style, styles->styles[CSS_PSEUDO_ELEMENT_NONE], nscss_compute_font_size, ctx, &composed); if (error != CSS_OK) { css_select_results_destroy(styles); return NULL; } /* Replace select_results style with composed style */ css_computed_style_destroy( styles->styles[CSS_PSEUDO_ELEMENT_NONE]); styles->styles[CSS_PSEUDO_ELEMENT_NONE] = composed; } for (pseudo_element = CSS_PSEUDO_ELEMENT_NONE + 1; pseudo_element < CSS_PSEUDO_ELEMENT_COUNT; pseudo_element++) { if (pseudo_element == CSS_PSEUDO_ELEMENT_FIRST_LETTER || pseudo_element == CSS_PSEUDO_ELEMENT_FIRST_LINE) /* TODO: Handle first-line and first-letter pseudo * element computed style completion */ continue; if (styles->styles[pseudo_element] == NULL) /* There were no rules concerning this pseudo element */ continue; /* Complete the pseudo element's computed style, by composing * with the base element's style */ error = css_computed_style_compose( styles->styles[CSS_PSEUDO_ELEMENT_NONE], styles->styles[pseudo_element], nscss_compute_font_size, ctx, &composed); if (error != CSS_OK) { /* TODO: perhaps this shouldn't be quite so * catastrophic? */ css_select_results_destroy(styles); return NULL; } /* Replace select_results style with composed style */ css_computed_style_destroy(styles->styles[pseudo_element]); styles->styles[pseudo_element] = composed; } return styles; }