static void run_test_select_tree(css_select_ctx *select, node *node, line_ctx *ctx, char *buf, size_t *buflen) { css_select_results *sr; struct node *n = NULL; assert(css_select_style(select, node, ctx->media, NULL, &select_handler, ctx, &sr) == CSS_OK); if (node->parent != NULL) { assert(css_computed_style_compose( node->parent->sr->styles[ctx->pseudo_element], sr->styles[ctx->pseudo_element], compute_font_size, NULL, sr->styles[ctx->pseudo_element]) == CSS_OK); } node->sr = sr; if (node == ctx->target) { dump_computed_style(sr->styles[ctx->pseudo_element], buf, buflen); } for (n = node->children; n != NULL; n = n->next) { run_test_select_tree(select, n, ctx, buf, buflen); } }
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; }