CssParser::CssParser() { css_error code; css_stylesheet_params params; params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1; params.level = CSS_LEVEL_21; params.charset = "UTF-8"; params.url = "foo"; params.title = "foo"; params.allow_quirks = false; params.inline_style = false; params.resolve = resolve_url; params.resolve_pw = NULL; params.import = NULL; params.import_pw = NULL; params.color = NULL; params.color_pw = NULL; params.font = NULL; params.font_pw = NULL; /* create a stylesheet */ code = css_stylesheet_create(¶ms, &sheet); if (code != CSS_OK) die("css_stylesheet_create", code); }
/** * Register an import with a stylesheet * * \param c CSS object that requested the import * \param import Cache handle of import, or NULL for blank * \return CSS_OK on success, appropriate error otherwise */ css_error nscss_register_import(struct content_css_data *c, const hlcache_handle *import) { css_stylesheet *sheet; css_error error; if (import != NULL) { nscss_content *s = (nscss_content *) hlcache_handle_get_content(import); sheet = s->data.sheet; } else { /* Create a blank sheet if needed. */ if (blank_import == NULL) { css_stylesheet_params params; params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1; params.level = CSS_LEVEL_DEFAULT; params.charset = NULL; params.url = ""; params.title = NULL; params.allow_quirks = false; params.inline_style = false; params.resolve = nscss_resolve_url; params.resolve_pw = NULL; params.import = NULL; params.import_pw = NULL; params.color = gui_system_colour; params.color_pw = NULL; params.font = NULL; params.font_pw = NULL; error = css_stylesheet_create(¶ms, ns_realloc, NULL, &blank_import); if (error != CSS_OK) { return error; } error = css_stylesheet_data_done(blank_import); if (error != CSS_OK) { css_stylesheet_destroy(blank_import); return error; } } sheet = blank_import; } error = css_stylesheet_register_import(c->sheet, sheet); if (error != CSS_OK) { return error; } return error; }
/** * Create an inline style * * \param data Source data * \param len Length of data in bytes * \param charset Charset of data, or NULL if unknown * \param url Base URL of document containing data * \param allow_quirks True to permit CSS parsing quirks * \return Pointer to stylesheet, or NULL on failure. */ css_stylesheet *nscss_create_inline_style(const uint8_t *data, size_t len, const char *charset, const char *url, bool allow_quirks) { css_stylesheet_params params; css_stylesheet *sheet; css_error error; params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1; params.level = CSS_LEVEL_DEFAULT; params.charset = charset; params.url = url; params.title = NULL; params.allow_quirks = allow_quirks; params.inline_style = true; params.resolve = nscss_resolve_url; params.resolve_pw = NULL; params.import = NULL; params.import_pw = NULL; params.color = ns_system_colour; params.color_pw = NULL; params.font = NULL; params.font_pw = NULL; error = css_stylesheet_create(¶ms, &sheet); if (error != CSS_OK) { NSLOG(netsurf, INFO, "Failed creating sheet: %d", error); return NULL; } error = css_stylesheet_append_data(sheet, data, len); if (error != CSS_OK && error != CSS_NEEDDATA) { NSLOG(netsurf, INFO, "failed appending data: %d", error); css_stylesheet_destroy(sheet); return NULL; } error = css_stylesheet_data_done(sheet); if (error != CSS_OK) { NSLOG(netsurf, INFO, "failed completing parse: %d", error); css_stylesheet_destroy(sheet); return NULL; } return sheet; }
/** * Create a struct content_css_data, creating a stylesheet object * * \param c Struct to populate * \param url URL of stylesheet * \param charset Stylesheet charset * \param quirks Stylesheet quirks mode * \param done Callback to call when content has completed * \param pw Client data for \a done * \return NSERROR_OK on success, NSERROR_NOMEM on memory exhaustion */ static nserror nscss_create_css_data(struct content_css_data *c, const char *url, const char *charset, bool quirks, nscss_done_callback done, void *pw) { css_error error; css_stylesheet_params params; c->pw = pw; c->done = done; c->next_to_register = (uint32_t) -1; c->import_count = 0; c->imports = NULL; if (charset != NULL) c->charset = strdup(charset); else c->charset = NULL; params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1; params.level = CSS_LEVEL_DEFAULT; params.charset = charset; params.url = url; params.title = NULL; params.allow_quirks = quirks; params.inline_style = false; params.resolve = nscss_resolve_url; params.resolve_pw = NULL; params.import = nscss_handle_import; params.import_pw = c; params.color = gui_system_colour; params.color_pw = NULL; params.font = NULL; params.font_pw = NULL; error = css_stylesheet_create(¶ms, ns_realloc, NULL, &c->sheet); if (error != CSS_OK) { return NSERROR_NOMEM; } return NSERROR_OK; }
void css__parse_sheet(line_ctx *ctx, const char *data, size_t len) { css_stylesheet_params params; const char *p; const char *end = data + len; css_origin origin = CSS_ORIGIN_AUTHOR; uint64_t media = CSS_MEDIA_ALL; css_stylesheet *sheet; sheet_ctx *temp; /* <origin> <media_list>? */ /* Find end of origin */ for (p = data; p < end; p++) { if (isspace(*p)) break; } if (p - data == 6 && strncasecmp(data, "author", 6) == 0) origin = CSS_ORIGIN_AUTHOR; else if (p - data == 4 && strncasecmp(data, "user", 4) == 0) origin = CSS_ORIGIN_USER; else if (p - data == 2 && strncasecmp(data, "ua", 2) == 0) origin = CSS_ORIGIN_UA; else assert(0 && "Unknown stylesheet origin"); /* Skip any whitespace */ while (p < end && isspace(*p)) p++; if (p < end) { size_t ignored = end - p; css__parse_media_list(&p, &ignored, &media); } params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1; params.level = CSS_LEVEL_21; params.charset = "UTF-8"; params.url = "foo"; params.title = "foo"; params.allow_quirks = false; params.inline_style = false; params.resolve = resolve_url; params.resolve_pw = NULL; params.import = NULL; params.import_pw = NULL; params.color = NULL; params.color_pw = NULL; params.font = NULL; params.font_pw = NULL; /** \todo How are we going to handle @import? */ assert(css_stylesheet_create(¶ms, &sheet) == CSS_OK); /* Extend array of sheets and append new sheet to it */ temp = realloc(ctx->sheets, (ctx->n_sheets + 1) * sizeof(sheet_ctx)); assert(temp != NULL); ctx->sheets = temp; ctx->sheets[ctx->n_sheets].sheet = sheet; ctx->sheets[ctx->n_sheets].origin = origin; ctx->sheets[ctx->n_sheets].media = media; ctx->n_sheets++; }
int main(int argc, char **argv) { css_stylesheet_params params; css_stylesheet *sheet; FILE *fp; size_t len, origlen; #define CHUNK_SIZE (4096) uint8_t buf[CHUNK_SIZE]; css_error error; int count; if (argc != 2) { printf("Usage: %s <filename>\n", argv[0]); return 1; } params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1; params.level = CSS_LEVEL_21; params.charset = "UTF-8"; params.url = argv[1]; params.title = NULL; params.allow_quirks = false; params.inline_style = false; params.resolve = resolve_url; params.resolve_pw = NULL; params.import = NULL; params.import_pw = NULL; params.color = NULL; params.color_pw = NULL; params.font = NULL; params.font_pw = NULL; for (count = 0; count < ITERATIONS; count++) { assert(css_stylesheet_create(¶ms, myrealloc, NULL, &sheet) == CSS_OK); fp = fopen(argv[1], "rb"); if (fp == NULL) { printf("Failed opening %s\n", argv[1]); return 1; } fseek(fp, 0, SEEK_END); origlen = len = ftell(fp); fseek(fp, 0, SEEK_SET); while (len >= CHUNK_SIZE) { size_t read = fread(buf, 1, CHUNK_SIZE, fp); assert(read == CHUNK_SIZE); error = css_stylesheet_append_data(sheet, buf, CHUNK_SIZE); assert(error == CSS_OK || error == CSS_NEEDDATA); len -= CHUNK_SIZE; } if (len > 0) { size_t read = fread(buf, 1, len, fp); assert(read == len); error = css_stylesheet_append_data(sheet, buf, len); assert(error == CSS_OK || error == CSS_NEEDDATA); len = 0; } fclose(fp); error = css_stylesheet_data_done(sheet); assert(error == CSS_OK || error == CSS_IMPORTS_PENDING); while (error == CSS_IMPORTS_PENDING) { lwc_string *url; uint64_t media; error = css_stylesheet_next_pending_import(sheet, &url, &media); assert(error == CSS_OK || error == CSS_INVALID); if (error == CSS_OK) { css_stylesheet *import; char *buf = alloca(lwc_string_length(url) + 1); memcpy(buf, lwc_string_data(url), lwc_string_length(url)); buf[lwc_string_length(url)] = '\0'; params.url = buf; assert(css_stylesheet_create(¶ms, myrealloc, NULL, &import) == CSS_OK); assert(css_stylesheet_data_done(import) == CSS_OK); assert(css_stylesheet_register_import(sheet, import) == CSS_OK); css_stylesheet_destroy(import); error = CSS_IMPORTS_PENDING; } } #if DUMP_CSS { #ifndef max #define max(a,b) ((a) > (b) ? (a) : (b)) #endif char *out; size_t outsize = max(16384, origlen * 8); size_t outlen = outsize; size_t written; out = malloc(outsize); assert(out != NULL); dump_sheet(sheet, out, &outlen); written = fwrite(out, 1, outsize - outlen, stdout); assert(written == outsize - outlen); free(out); } #endif css_stylesheet_destroy(sheet); } printf("PASS\n"); return 0; }