diff options
author | Vincent Sanders <vince@kyllikki.org> | 2016-05-26 11:18:41 +0100 |
---|---|---|
committer | Vincent Sanders <vince@kyllikki.org> | 2016-05-26 11:18:41 +0100 |
commit | 6722943b81c0dba84ed187b2d117cc92972117ed (patch) | |
tree | 5de3de53a92696c9a4b9edcfd54e7f608ad2fb04 /css | |
parent | c25eb6b7e7a08d7e2aaf33994c2c24053cf47b82 (diff) | |
download | netsurf-6722943b81c0dba84ed187b2d117cc92972117ed.tar.gz netsurf-6722943b81c0dba84ed187b2d117cc92972117ed.tar.bz2 |
move the CSS content handler
Diffstat (limited to 'css')
-rw-r--r-- | css/Makefile | 5 | ||||
-rw-r--r-- | css/css.c | 847 | ||||
-rw-r--r-- | css/css.h | 44 | ||||
-rw-r--r-- | css/dump.c | 1806 | ||||
-rw-r--r-- | css/dump.h | 26 | ||||
-rw-r--r-- | css/hints.c | 1611 | ||||
-rw-r--r-- | css/hints.h | 49 | ||||
-rw-r--r-- | css/internal.c | 73 | ||||
-rw-r--r-- | css/internal.h | 27 | ||||
-rw-r--r-- | css/select.c | 1854 | ||||
-rw-r--r-- | css/select.h | 57 | ||||
-rw-r--r-- | css/utils.c | 142 | ||||
-rw-r--r-- | css/utils.h | 70 |
13 files changed, 0 insertions, 6611 deletions
diff --git a/css/Makefile b/css/Makefile deleted file mode 100644 index 127dbaa32..000000000 --- a/css/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# CSS sources - -S_CSS := css.c dump.c internal.c hints.c select.c utils.c - -S_CSS := $(addprefix css/,$(S_CSS)) diff --git a/css/css.c b/css/css.c deleted file mode 100644 index 66dc6d4ba..000000000 --- a/css/css.c +++ /dev/null @@ -1,847 +0,0 @@ -/* - * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <assert.h> -#include <libwapcaplet/libwapcaplet.h> -#include <dom/dom.h> - -#include "content/content_protected.h" -#include "content/fetch.h" -#include "content/hlcache.h" -#include "desktop/system_colour.h" -#include "utils/corestrings.h" -#include "utils/utils.h" -#include "utils/http.h" -#include "utils/log.h" -#include "utils/messages.h" - -#include "css/css.h" -#include "css/hints.h" -#include "css/internal.h" - -/* Define to trace import fetches */ -#undef NSCSS_IMPORT_TRACE - -struct content_css_data; - -/** - * Type of callback called when a CSS object has finished - * - * \param css CSS object that has completed - * \param pw Client-specific data - */ -typedef void (*nscss_done_callback)(struct content_css_data *css, void *pw); - -/** - * CSS content data - */ -struct content_css_data -{ - css_stylesheet *sheet; /**< Stylesheet object */ - char *charset; /**< Character set of stylesheet */ - struct nscss_import *imports; /**< Array of imported sheets */ - uint32_t import_count; /**< Number of sheets imported */ - uint32_t next_to_register; /**< Index of next import to register */ - nscss_done_callback done; /**< Completion callback */ - void *pw; /**< Client data */ -}; - -/** - * CSS content data - */ -typedef struct nscss_content -{ - struct content base; /**< Underlying content object */ - - struct content_css_data data; /**< CSS data */ -} nscss_content; - -/** - * Context for import fetches - */ -typedef struct { - struct content_css_data *css; /**< Object containing import */ - uint32_t index; /**< Index into parent sheet's - * imports array */ -} nscss_import_ctx; - -static bool nscss_process_data(struct content *c, const char *data, - unsigned int size); -static bool nscss_convert(struct content *c); -static void nscss_destroy(struct content *c); -static nserror nscss_clone(const struct content *old, struct content **newc); -static bool nscss_matches_quirks(const struct content *c, bool quirks); -static content_type nscss_content_type(void); - -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); -static css_error nscss_process_css_data(struct content_css_data *c, const char *data, - unsigned int size); -static css_error nscss_convert_css_data(struct content_css_data *c); -static void nscss_destroy_css_data(struct content_css_data *c); - -static void nscss_content_done(struct content_css_data *css, void *pw); -static css_error nscss_handle_import(void *pw, css_stylesheet *parent, - lwc_string *url, uint64_t media); -static nserror nscss_import(hlcache_handle *handle, - const hlcache_event *event, void *pw); -static css_error nscss_import_complete(nscss_import_ctx *ctx); - -static css_error nscss_register_imports(struct content_css_data *c); -static css_error nscss_register_import(struct content_css_data *c, - const hlcache_handle *import); - - -static css_stylesheet *blank_import; - - -/** - * Initialise a CSS content - * - * \param handler content handler - * \param imime_type mime-type - * \param params Content-Type parameters - * \param llcache handle to content - * \param fallback_charset The character set to fallback to. - * \param quirks allow quirks - * \param c Content to initialise - * \return NSERROR_OK or error cod eon faliure - */ -static nserror -nscss_create(const content_handler *handler, - lwc_string *imime_type, - const http_parameter *params, - llcache_handle *llcache, - const char *fallback_charset, - bool quirks, - struct content **c) -{ - nscss_content *result; - const char *charset = NULL; - const char *xnsbase = NULL; - lwc_string *charset_value = NULL; - union content_msg_data msg_data; - nserror error; - - result = calloc(1, sizeof(nscss_content)); - if (result == NULL) - return NSERROR_NOMEM; - - error = content__init(&result->base, handler, imime_type, - params, llcache, fallback_charset, quirks); - if (error != NSERROR_OK) { - free(result); - return error; - } - - /* Find charset specified on HTTP layer, if any */ - error = http_parameter_list_find_item(params, corestring_lwc_charset, - &charset_value); - if (error != NSERROR_OK || lwc_string_length(charset_value) == 0) { - /* No charset specified, use fallback, if any */ - /** \todo libcss will take this as gospel, which is wrong */ - charset = fallback_charset; - } else { - charset = lwc_string_data(charset_value); - } - - /* Compute base URL for stylesheet */ - xnsbase = llcache_handle_get_header(llcache, "X-NS-Base"); - if (xnsbase == NULL) { - xnsbase = nsurl_access(content_get_url(&result->base)); - } - - error = nscss_create_css_data(&result->data, - xnsbase, charset, result->base.quirks, - nscss_content_done, result); - if (error != NSERROR_OK) { - msg_data.error = messages_get("NoMemory"); - content_broadcast(&result->base, CONTENT_MSG_ERROR, msg_data); - if (charset_value != NULL) - lwc_string_unref(charset_value); - free(result); - return error; - } - - if (charset_value != NULL) - lwc_string_unref(charset_value); - - *c = (struct content *) result; - - return NSERROR_OK; -} - -/** - * 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 = ns_system_colour; - params.color_pw = NULL; - params.font = NULL; - params.font_pw = NULL; - - error = css_stylesheet_create(¶ms, &c->sheet); - if (error != CSS_OK) { - return NSERROR_NOMEM; - } - - return NSERROR_OK; -} - -/** - * Process CSS source data - * - * \param c Content structure - * \param data Data to process - * \param size Number of bytes to process - * \return true on success, false on failure - */ -bool nscss_process_data(struct content *c, const char *data, unsigned int size) -{ - nscss_content *css = (nscss_content *) c; - union content_msg_data msg_data; - css_error error; - - error = nscss_process_css_data(&css->data, data, size); - if (error != CSS_OK && error != CSS_NEEDDATA) { - msg_data.error = "?"; - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - } - - return (error == CSS_OK || error == CSS_NEEDDATA); -} - -/** - * Process CSS data - * - * \param c CSS content object - * \param data Data to process - * \param size Number of bytes to process - * \return CSS_OK on success, appropriate error otherwise - */ -static css_error nscss_process_css_data(struct content_css_data *c, - const char *data, unsigned int size) -{ - return css_stylesheet_append_data(c->sheet, - (const uint8_t *) data, size); -} - -/** - * Convert a CSS content ready for use - * - * \param c Content to convert - * \return true on success, false on failure - */ -bool nscss_convert(struct content *c) -{ - nscss_content *css = (nscss_content *) c; - union content_msg_data msg_data; - css_error error; - - error = nscss_convert_css_data(&css->data); - if (error != CSS_OK) { - msg_data.error = "?"; - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - return false; - } - - return true; -} - -/** - * Convert CSS data ready for use - * - * \param c CSS data to convert - * \return CSS error - */ -static css_error nscss_convert_css_data(struct content_css_data *c) -{ - css_error error; - - error = css_stylesheet_data_done(c->sheet); - - /* Process pending imports */ - if (error == CSS_IMPORTS_PENDING) { - /* We must not have registered any imports yet */ - assert(c->next_to_register == (uint32_t) -1); - - /* Start registering, until we find one that - * hasn't finished fetching */ - c->next_to_register = 0; - error = nscss_register_imports(c); - } else if (error == CSS_OK) { - /* No imports, and no errors, so complete conversion */ - c->done(c, c->pw); - } else { - const char *url; - - if (css_stylesheet_get_url(c->sheet, &url) == CSS_OK) { - LOG("Failed converting %p %s (%d)", c, url, error); - } else { - LOG("Failed converting %p (%d)", c, error); - } - } - - return error; -} - -/** - * Clean up a CSS content - * - * \param c Content to clean up - */ -void nscss_destroy(struct content *c) -{ - nscss_content *css = (nscss_content *) c; - - nscss_destroy_css_data(&css->data); -} - -/** - * Clean up CSS data - * - * \param c CSS data to clean up - */ -static void nscss_destroy_css_data(struct content_css_data *c) -{ - uint32_t i; - - for (i = 0; i < c->import_count; i++) { - if (c->imports[i].c != NULL) { - hlcache_handle_release(c->imports[i].c); - } - c->imports[i].c = NULL; - } - - free(c->imports); - - if (c->sheet != NULL) { - css_stylesheet_destroy(c->sheet); - c->sheet = NULL; - } - - free(c->charset); -} - -nserror nscss_clone(const struct content *old, struct content **newc) -{ - const nscss_content *old_css = (const nscss_content *) old; - nscss_content *new_css; - const char *data; - unsigned long size; - nserror error; - - new_css = calloc(1, sizeof(nscss_content)); - if (new_css == NULL) - return NSERROR_NOMEM; - - /* Clone content */ - error = content__clone(old, &new_css->base); - if (error != NSERROR_OK) { - content_destroy(&new_css->base); - return error; - } - - /* Simply replay create/process/convert */ - error = nscss_create_css_data(&new_css->data, - nsurl_access(content_get_url(&new_css->base)), - old_css->data.charset, - new_css->base.quirks, - nscss_content_done, new_css); - if (error != NSERROR_OK) { - content_destroy(&new_css->base); - return error; - } - - data = content__get_source_data(&new_css->base, &size); - if (size > 0) { - if (nscss_process_data(&new_css->base, data, size) == false) { - content_destroy(&new_css->base); - return NSERROR_CLONE_FAILED; - } - } - - if (old->status == CONTENT_STATUS_READY || - old->status == CONTENT_STATUS_DONE) { - if (nscss_convert(&new_css->base) == false) { - content_destroy(&new_css->base); - return NSERROR_CLONE_FAILED; - } - } - - *newc = (struct content *) new_css; - - return NSERROR_OK; -} - -bool nscss_matches_quirks(const struct content *c, bool quirks) -{ - return c->quirks == quirks; -} - -/** - * Retrieve the stylesheet object associated with a CSS content - * - * \param h Stylesheet content - * \return Pointer to stylesheet object - */ -css_stylesheet *nscss_get_stylesheet(struct hlcache_handle *h) -{ - nscss_content *c = (nscss_content *) hlcache_handle_get_content(h); - - assert(c != NULL); - - return c->data.sheet; -} - -/** - * Retrieve imported stylesheets - * - * \param h Stylesheet containing imports - * \param n Pointer to location to receive number of imports - * \return Pointer to array of imported stylesheets - */ -struct nscss_import *nscss_get_imports(hlcache_handle *h, uint32_t *n) -{ - nscss_content *c = (nscss_content *) hlcache_handle_get_content(h); - - assert(c != NULL); - assert(n != NULL); - - *n = c->data.import_count; - - return c->data.imports; -} - -/** - * Compute the type of a content - * - * \return CONTENT_CSS - */ -content_type nscss_content_type(void) -{ - return CONTENT_CSS; -} - -/***************************************************************************** - * Object completion * - *****************************************************************************/ - -/** - * Handle notification that a CSS object is done - * - * \param css CSS object - * \param pw Private data - */ -void nscss_content_done(struct content_css_data *css, void *pw) -{ - union content_msg_data msg_data; - struct content *c = pw; - uint32_t i; - size_t size; - css_error error; - - /* Retrieve the size of this sheet */ - error = css_stylesheet_size(css->sheet, &size); - if (error != CSS_OK) { - msg_data.error = "?"; - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - content_set_error(c); - return; - } - c->size += size; - - /* Add on the size of the imported sheets */ - for (i = 0; i < css->import_count; i++) { - if (css->imports[i].c != NULL) { - struct content *import = hlcache_handle_get_content( - css->imports[i].c); - - if (import != NULL) { - c->size += import->size; - } - } - } - - /* Finally, catch the content's users up with reality */ - content_set_ready(c); - content_set_done(c); -} - -/***************************************************************************** - * Import handling * - *****************************************************************************/ - -/** - * Handle notification of the need for an imported stylesheet - * - * \param pw CSS object requesting the import - * \param parent Stylesheet requesting the import - * \param url URL of the imported sheet - * \param media Applicable media for the imported sheet - * \return CSS_OK on success, appropriate error otherwise - */ -css_error nscss_handle_import(void *pw, css_stylesheet *parent, - lwc_string *url, uint64_t media) -{ - content_type accept = CONTENT_CSS; - struct content_css_data *c = pw; - nscss_import_ctx *ctx; - hlcache_child_context child; - struct nscss_import *imports; - const char *referer; - css_error error; - nserror nerror; - - nsurl *ns_url; - nsurl *ns_ref; - - assert(parent == c->sheet); - - error = css_stylesheet_get_url(c->sheet, &referer); - if (error != CSS_OK) { - return error; - } - - ctx = malloc(sizeof(*ctx)); - if (ctx == NULL) - return CSS_NOMEM; - - ctx->css = c; - ctx->index = c->import_count; - - /* Increase space in table */ - imports = realloc(c->imports, (c->import_count + 1) * - sizeof(struct nscss_import)); - if (imports == NULL) { - free(ctx); - return CSS_NOMEM; - } - c->imports = imports; - - /** \todo fallback charset */ - child.charset = NULL; - error = css_stylesheet_quirks_allowed(c->sheet, &child.quirks); - if (error != CSS_OK) { - free(ctx); - return error; - } - - /* Create content */ - c->imports[c->import_count].media = media; - - /** \todo Why aren't we getting a relative url part, to join? */ - nerror = nsurl_create(lwc_string_data(url), &ns_url); - if (nerror != NSERROR_OK) { - free(ctx); - return CSS_NOMEM; - } - - /** \todo Constructing nsurl for referer here is silly, avoid */ - nerror = nsurl_create(referer, &ns_ref); - if (nerror != NSERROR_OK) { - nsurl_unref(ns_url); - free(ctx); - return CSS_NOMEM; - } - - /* Avoid importing ourself */ - if (nsurl_compare(ns_url, ns_ref, NSURL_COMPLETE)) { - c->imports[c->import_count].c = NULL; - /* No longer require context as we're not fetching anything */ - free(ctx); - ctx = NULL; - } else { - nerror = hlcache_handle_retrieve(ns_url, - 0, ns_ref, NULL, nscss_import, ctx, - &child, accept, - &c->imports[c->import_count].c); - if (nerror != NSERROR_OK) { - free(ctx); - return CSS_NOMEM; - } - } - - nsurl_unref(ns_url); - nsurl_unref(ns_ref); - -#ifdef NSCSS_IMPORT_TRACE - LOG("Import %d '%s' -> (handle: %p ctx: %p)", c->import_count, lwc_string_data(url), c->imports[c->import_count].c, ctx); -#endif - - c->import_count++; - - return CSS_OK; -} - -/** - * Handler for imported stylesheet events - * - * \param handle Handle for stylesheet - * \param event Event object - * \param pw Callback context - * \return NSERROR_OK on success, appropriate error otherwise - */ -nserror nscss_import(hlcache_handle *handle, - const hlcache_event *event, void *pw) -{ - nscss_import_ctx *ctx = pw; - css_error error = CSS_OK; - -#ifdef NSCSS_IMPORT_TRACE - LOG("Event %d for %p (%p)", event->type, handle, ctx); -#endif - - assert(ctx->css->imports[ctx->index].c == handle); - - switch (event->type) { - case CONTENT_MSG_DONE: - error = nscss_import_complete(ctx); - break; - - case CONTENT_MSG_ERROR: - hlcache_handle_release(handle); - ctx->css->imports[ctx->index].c = NULL; - - error = nscss_import_complete(ctx); - /* Already released handle */ - break; - - default: - break; - } - - /* Preserve out-of-memory. Anything else is OK */ - return error == CSS_NOMEM ? NSERROR_NOMEM : NSERROR_OK; -} - -/** - * Handle an imported stylesheet completing - * - * \param ctx Import context - * \return CSS_OK on success, appropriate error otherwise - */ -css_error nscss_import_complete(nscss_import_ctx *ctx) -{ - css_error error = CSS_OK; - - /* If this import is the next to be registered, do so */ - if (ctx->css->next_to_register == ctx->index) - error = nscss_register_imports(ctx->css); - -#ifdef NSCSS_IMPORT_TRACE - LOG("Destroying import context %p for %d", ctx, ctx->index); -#endif - - /* No longer need import context */ - free(ctx); - - return error; -} - -/***************************************************************************** - * Import registration * - *****************************************************************************/ - -/** - * Register imports with a stylesheet - * - * \param c CSS object containing the imports - * \return CSS_OK on success, appropriate error otherwise - */ -css_error nscss_register_imports(struct content_css_data *c) -{ - uint32_t index; - css_error error; - - assert(c->next_to_register != (uint32_t) -1); - assert(c->next_to_register < c->import_count); - - /* Register imported sheets */ - for (index = c->next_to_register; index < c->import_count; index++) { - /* Stop registering if we encounter one whose fetch hasn't - * completed yet. We'll resume at this point when it has - * completed. - */ - if (c->imports[index].c != NULL && - content_get_status(c->imports[index].c) != - CONTENT_STATUS_DONE) { - break; - } - - error = nscss_register_import(c, c->imports[index].c); - if (error != CSS_OK) - return error; - } - - /* Record identity of the next import to register */ - c->next_to_register = (uint32_t) index; - - if (c->next_to_register == c->import_count) { - /* No more imports: notify parent that we're DONE */ - c->done(c, c->pw); - } - - return CSS_OK; -} - - -/** - * 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 = ns_system_colour; - params.color_pw = NULL; - params.font = NULL; - params.font_pw = NULL; - - error = css_stylesheet_create(¶ms, &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; -} - -/** - * Clean up after the CSS content handler - */ -static void nscss_fini(void) -{ - if (blank_import != NULL) { - css_stylesheet_destroy(blank_import); - blank_import = NULL; - } - css_hint_fini(); -} - -static const content_handler css_content_handler = { - .fini = nscss_fini, - .create = nscss_create, - .process_data = nscss_process_data, - .data_complete = nscss_convert, - .destroy = nscss_destroy, - .clone = nscss_clone, - .matches_quirks = nscss_matches_quirks, - .type = nscss_content_type, - .no_share = false, -}; - -/** - * Initialise the CSS content handler - */ -nserror nscss_init(void) -{ - nserror error; - - error = content_factory_register_handler("text/css", - &css_content_handler); - if (error != NSERROR_OK) - goto error; - - error = css_hint_init(); - if (error != NSERROR_OK) - goto error; - - return NSERROR_OK; - -error: - nscss_fini(); - - return error; -} diff --git a/css/css.h b/css/css.h deleted file mode 100644 index be8d4bcd8..000000000 --- a/css/css.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef netsurf_css_css_h_ -#define netsurf_css_css_h_ - -#include <stdint.h> - -#include <libcss/libcss.h> - -#include "utils/errors.h" - -struct hlcache_handle; - -/** - * Imported stylesheet record - */ -struct nscss_import { - struct hlcache_handle *c; /**< Content containing sheet */ - uint64_t media; /**< Media types that sheet applies to */ -}; - -nserror nscss_init(void); - -css_stylesheet *nscss_get_stylesheet(struct hlcache_handle *h); -struct nscss_import *nscss_get_imports(struct hlcache_handle *h, uint32_t *n); - -#endif - diff --git a/css/dump.c b/css/dump.c deleted file mode 100644 index d3ebc9481..000000000 --- a/css/dump.c +++ /dev/null @@ -1,1806 +0,0 @@ -/* - * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <stdio.h> - -#include "css/dump.h" - -static void dump_css_fixed(FILE *stream, css_fixed f); -static void dump_css_number(FILE *stream, css_fixed val); -static void dump_css_unit(FILE *stream, css_fixed val, css_unit unit); - -/** - * Dump a computed style \a style to the give file handle \a stream. - * - * \param stream Stream to write to - * \param style Computed style to dump - */ -void nscss_dump_computed_style(FILE *stream, const css_computed_style *style) -{ - uint8_t val; - css_color color = 0; - lwc_string *url = NULL; - css_fixed len1 = 0, len2 = 0; - css_unit unit1 = CSS_UNIT_PX, unit2 = CSS_UNIT_PX; - css_computed_clip_rect rect = { 0, 0, 0, 0, CSS_UNIT_PX, CSS_UNIT_PX, - CSS_UNIT_PX, CSS_UNIT_PX, true, true, - true, true }; - const css_computed_content_item *content = NULL; - const css_computed_counter *counter = NULL; - lwc_string **string_list = NULL; - int32_t zindex = 0; - - fprintf(stream, "{ "); - - /* background-attachment */ - val = css_computed_background_attachment(style); - switch (val) { - case CSS_BACKGROUND_ATTACHMENT_FIXED: - fprintf(stream, "background-attachment: fixed "); - break; - case CSS_BACKGROUND_ATTACHMENT_SCROLL: - fprintf(stream, "background-attachment: scroll "); - break; - default: - break; - } - - /* background-color */ - val = css_computed_background_color(style, &color); - switch (val) { - case CSS_BACKGROUND_COLOR_COLOR: - fprintf(stream, "background-color: #%08x ", color); - break; - default: - break; - } - - /* background-image */ - val = css_computed_background_image(style, &url); - if (val == CSS_BACKGROUND_IMAGE_IMAGE && url != NULL) { - fprintf(stream, "background-image: url('%.*s') ", - (int) lwc_string_length(url), - lwc_string_data(url)); - } else if (val == CSS_BACKGROUND_IMAGE_NONE) { - fprintf(stream, "background-image: none "); - } - - /* background-position */ - val = css_computed_background_position(style, &len1, &unit1, - &len2, &unit2); - if (val == CSS_BACKGROUND_POSITION_SET) { - fprintf(stream, "background-position: "); - dump_css_unit(stream, len1, unit1); - fprintf(stream, " "); - dump_css_unit(stream, len2, unit2); - fprintf(stream, " "); - } - - /* background-repeat */ - val = css_computed_background_repeat(style); - switch (val) { - case CSS_BACKGROUND_REPEAT_REPEAT_X: - fprintf(stream, "background-repeat: repeat-x "); - break; - case CSS_BACKGROUND_REPEAT_REPEAT_Y: - fprintf(stream, "background-repeat: repeat-y "); - break; - case CSS_BACKGROUND_REPEAT_REPEAT: - fprintf(stream, "background-repeat: repeat "); - break; - case CSS_BACKGROUND_REPEAT_NO_REPEAT: - fprintf(stream, "background-repeat: no-repeat "); - break; - default: - break; - } - - /* border-collapse */ - val = css_computed_border_collapse(style); - switch (val) { - case CSS_BORDER_COLLAPSE_SEPARATE: - fprintf(stream, "border-collapse: separate "); - break; - case CSS_BORDER_COLLAPSE_COLLAPSE: - fprintf(stream, "border-collapse: collapse "); - break; - default: - - break; - } - - /* border-spacing */ - val = css_computed_border_spacing(style, &len1, &unit1, &len2, &unit2); - if (val == CSS_BORDER_SPACING_SET) { - fprintf(stream, "border-spacing: "); - dump_css_unit(stream, len1, unit1); - fprintf(stream, " "); - dump_css_unit(stream, len2, unit2); - fprintf(stream, " "); - } - - /* border-top-color */ - val = css_computed_border_top_color(style, &color); - switch (val) { - case CSS_BORDER_COLOR_COLOR: - fprintf(stream, "border-top-color: #%08x ", color); - break; - default: - break; - } - - /* border-right-color */ - val = css_computed_border_right_color(style, &color); - switch (val) { - case CSS_BORDER_COLOR_COLOR: - fprintf(stream, "border-right-color: #%08x ", color); - break; - default: - break; - } - - /* border-bottom-color */ - val = css_computed_border_bottom_color(style, &color); - switch (val) { - case CSS_BORDER_COLOR_COLOR: - fprintf(stream, "border-bottom-color: #%08x ", color); - break; - default: - break; - } - - /* border-left-color */ - val = css_computed_border_left_color(style, &color); - switch (val) { - case CSS_BORDER_COLOR_COLOR: - fprintf(stream, "border-left-color: #%08x ", color); - break; - default: - break; - } - - /* border-top-style */ - val = css_computed_border_top_style(style); - switch (val) { - case CSS_BORDER_STYLE_NONE: - fprintf(stream, "border-top-style: none "); - break; - case CSS_BORDER_STYLE_HIDDEN: - fprintf(stream, "border-top-style: hidden "); - break; - case CSS_BORDER_STYLE_DOTTED: - fprintf(stream, "border-top-style: dotted "); - break; - case CSS_BORDER_STYLE_DASHED: - fprintf(stream, "border-top-style: dashed "); - break; - case CSS_BORDER_STYLE_SOLID: - fprintf(stream, "border-top-style: solid "); - break; - case CSS_BORDER_STYLE_DOUBLE: - fprintf(stream, "border-top-style: double "); - break; - case CSS_BORDER_STYLE_GROOVE: - fprintf(stream, "border-top-style: groove "); - break; - case CSS_BORDER_STYLE_RIDGE: - fprintf(stream, "border-top-style: ridge "); - break; - case CSS_BORDER_STYLE_INSET: - fprintf(stream, "border-top-style: inset "); - break; - case CSS_BORDER_STYLE_OUTSET: - fprintf(stream, "border-top-style: outset "); - break; - default: - break; - } - - /* border-right-style */ - val = css_computed_border_right_style(style); - switch (val) { - case CSS_BORDER_STYLE_NONE: - fprintf(stream, "border-right-style: none "); - break; - case CSS_BORDER_STYLE_HIDDEN: - fprintf(stream, "border-right-style: hidden "); - break; - case CSS_BORDER_STYLE_DOTTED: - fprintf(stream, "border-right-style: dotted "); - break; - case CSS_BORDER_STYLE_DASHED: - fprintf(stream, "border-right-style: dashed "); - break; - case CSS_BORDER_STYLE_SOLID: - fprintf(stream, "border-right-style: solid "); - break; - case CSS_BORDER_STYLE_DOUBLE: - fprintf(stream, "border-right-style: double "); - break; - case CSS_BORDER_STYLE_GROOVE: - fprintf(stream, "border-right-style: groove "); - break; - case CSS_BORDER_STYLE_RIDGE: - fprintf(stream, "border-right-style: ridge "); - break; - case CSS_BORDER_STYLE_INSET: - fprintf(stream, "border-right-style: inset "); - break; - case CSS_BORDER_STYLE_OUTSET: - fprintf(stream, "border-right-style: outset "); - break; - default: - break; - } - - /* border-bottom-style */ - val = css_computed_border_bottom_style(style); - switch (val) { - case CSS_BORDER_STYLE_NONE: - fprintf(stream, "border-bottom-style: none "); - break; - case CSS_BORDER_STYLE_HIDDEN: - fprintf(stream, "border-bottom-style: hidden "); - break; - case CSS_BORDER_STYLE_DOTTED: - fprintf(stream, "border-bottom-style: dotted "); - break; - case CSS_BORDER_STYLE_DASHED: - fprintf(stream, "border-bottom-style: dashed "); - break; - case CSS_BORDER_STYLE_SOLID: - fprintf(stream, "border-bottom-style: solid "); - break; - case CSS_BORDER_STYLE_DOUBLE: - fprintf(stream, "border-bottom-style: double "); - break; - case CSS_BORDER_STYLE_GROOVE: - fprintf(stream, "border-bottom-style: groove "); - break; - case CSS_BORDER_STYLE_RIDGE: - fprintf(stream, "border-bottom-style: ridge "); - break; - case CSS_BORDER_STYLE_INSET: - fprintf(stream, "border-bottom-style: inset "); - break; - case CSS_BORDER_STYLE_OUTSET: - fprintf(stream, "border-bottom-style: outset "); - break; - default: - break; - } - - /* border-left-style */ - val = css_computed_border_left_style(style); - switch (val) { - case CSS_BORDER_STYLE_NONE: - fprintf(stream, "border-left-style: none "); - break; - case CSS_BORDER_STYLE_HIDDEN: - fprintf(stream, "border-left-style: hidden "); - break; - case CSS_BORDER_STYLE_DOTTED: - fprintf(stream, "border-left-style: dotted "); - break; - case CSS_BORDER_STYLE_DASHED: - fprintf(stream, "border-left-style: dashed "); - break; - case CSS_BORDER_STYLE_SOLID: - fprintf(stream, "border-left-style: solid "); - break; - case CSS_BORDER_STYLE_DOUBLE: - fprintf(stream, "border-left-style: double "); - break; - case CSS_BORDER_STYLE_GROOVE: - fprintf(stream, "border-left-style: groove "); - break; - case CSS_BORDER_STYLE_RIDGE: - fprintf(stream, "border-left-style: ridge "); - break; - case CSS_BORDER_STYLE_INSET: - fprintf(stream, "border-left-style: inset "); - break; - case CSS_BORDER_STYLE_OUTSET: - fprintf(stream, "border-left-style: outset "); - break; - default: - break; - } - - /* border-top-width */ - val = css_computed_border_top_width(style, &len1, &unit1); - switch (val) { - case CSS_BORDER_WIDTH_THIN: - fprintf(stream, "border-top-width: thin "); - break; - case CSS_BORDER_WIDTH_MEDIUM: - fprintf(stream, "border-top-width: medium "); - break; - case CSS_BORDER_WIDTH_THICK: - fprintf(stream, "border-top-width: thick "); - break; - case CSS_BORDER_WIDTH_WIDTH: - fprintf(stream, "border-top-width: "); - dump_css_unit(stream, len1, unit1); - fprintf(stream, " "); - break; - default: - break; - } - - /* border-right-width */ - val = css_computed_border_right_width(style, &len1, &unit1); - switch (val) { - case CSS_BORDER_WIDTH_THIN: - fprintf(stream, "border-right-width: thin "); - break; - case CSS_BORDER_WIDTH_MEDIUM: - fprintf(stream, "border-right-width: medium "); - break; - case CSS_BORDER_WIDTH_THICK: - fprintf(stream, "border-right-width: thick "); - break; - case CSS_BORDER_WIDTH_WIDTH: - fprintf(stream, "border-right-width: "); - dump_css_unit(stream, len1, unit1); - fprintf(stream, " "); - break; - default: - break; - } - - /* border-bottom-width */ - val = css_computed_border_bottom_width(style, &len1, &unit1); - switch (val) { - case CSS_BORDER_WIDTH_THIN: - fprintf(stream, "border-bottom-width: thin "); - break; - case CSS_BORDER_WIDTH_MEDIUM: - fprintf(stream, "border-bottom-width: medium "); - break; - case CSS_BORDER_WIDTH_THICK: - fprintf(stream, "border-bottom-width: thick "); - break; - case CSS_BORDER_WIDTH_WIDTH: - fprintf(stream, "border-bottom-width: "); - dump_css_unit(stream, len1, unit1); - fprintf(stream, " "); - break; - default: - break; - } - - /* border-left-width */ - val = css_computed_border_left_width(style, &len1, &unit1); - switch (val) { - case CSS_BORDER_WIDTH_THIN: - fprintf(stream, "border-left-width: thin "); - break; - case CSS_BORDER_WIDTH_MEDIUM: - fprintf(stream, "border-left-width: medium "); - break; - case CSS_BORDER_WIDTH_THICK: - fprintf(stream, "border-left-width: thick "); - break; - case CSS_BORDER_WIDTH_WIDTH: - fprintf(stream, "border-left-width: "); - dump_css_unit(stream, len1, unit1); - fprintf(stream, " "); - break; - default: - break; - } - - /* bottom */ - val = css_computed_bottom(style, &len1, &unit1); - switch (val) { - case CSS_BOTTOM_AUTO: - fprintf(stream, "bottom: auto "); - break; - case CSS_BOTTOM_SET: - fprintf(stream, "bottom: "); - dump_css_unit(stream, len1, unit1); - fprintf(stream, " "); - break; - default: - break; - } - - /* caption-side */ - val = css_computed_caption_side(style); - switch (val) { - case CSS_CAPTION_SIDE_TOP: - fprintf(stream, "caption_side: top "); - break; - case CSS_CAPTION_SIDE_BOTTOM: - fprintf(stream, "caption_side: bottom "); - break; - default: - break; - } - - /* clear */ - val = css_computed_clear(style); - switch (val) { - case CSS_CLEAR_NONE: - fprintf(stream, "clear: none "); - break; - case CSS_CLEAR_LEFT: - fprintf(stream, "clear: left "); - break; - case CSS_CLEAR_RIGHT: - fprintf(stream, "clear: right "); - break; - case CSS_CLEAR_BOTH: - fprintf(stream, "clear: both "); - break; - default: - break; - } - - /* clip */ - val = css_computed_clip(style, &rect); - switch (val) { - case CSS_CLIP_AUTO: - fprintf(stream, "clip: auto "); - break; - case CSS_CLIP_RECT: - fprintf(stream, "clip: rect( "); - - if (rect.top_auto) - fprintf(stream, "auto"); - else - dump_css_unit(stream, rect.top, rect.tunit); - fprintf(stream, ", "); - - if (rect.right_auto) - fprintf(stream, "auto"); - else - dump_css_unit(stream, rect.right, rect.runit); - fprintf(stream, ", "); - - if (rect.bottom_auto) - fprintf(stream, "auto"); - else - dump_css_unit(stream, rect.bottom, rect.bunit); - fprintf(stream, ", "); - - if (rect.left_auto) - fprintf(stream, "auto"); - else - dump_css_unit(stream, rect.left, rect.lunit); - fprintf(stream, ") "); - break; - default: - break; - } - - /* color */ - val = css_computed_color(style, &color); - if (val == CSS_COLOR_COLOR) { - fprintf(stream, "color: #%08x ", color); - } - - /* content */ - val = css_computed_content(style, &content); - switch (val) { - case CSS_CONTENT_NONE: - fprintf(stream, "content: none "); - break; - case CSS_CONTENT_NORMAL: - fprintf(stream, "content: normal "); - break; - case CSS_CONTENT_SET: - fprintf(stream, "content:"); - - while (content->type != CSS_COMPUTED_CONTENT_NONE) { - fprintf(stream, " "); - - switch (content->type) { - case CSS_COMPUTED_CONTENT_STRING: - fprintf(stream, "\"%.*s\"", - (int) lwc_string_length( - content->data.string), - lwc_string_data( - content->data.string)); - break; - case CSS_COMPUTED_CONTENT_URI: - fprintf(stream, "uri(\"%.*s\")", - (int) lwc_string_length( - content->data.uri), - lwc_string_data( - content->data.uri)); - break; - case CSS_COMPUTED_CONTENT_COUNTER: - fprintf(stream, "counter(%.*s)", - (int) lwc_string_length( - content->data.counter.name), - lwc_string_data( - content->data.counter.name)); - break; - case CSS_COMPUTED_CONTENT_COUNTERS: - fprintf(stream, "counters(%.*s, \"%.*s\")", - (int) lwc_string_length( - content->data.counters.name), - lwc_string_data( - content->data.counters.name), - (int) lwc_string_length( - content->data.counters.sep), - lwc_string_data( - content->data.counters.sep)); - break; - case CSS_COMPUTED_CONTENT_ATTR: - fprintf(stream, "attr(%.*s)", - (int) lwc_string_length( - content->data.attr), - lwc_string_data( - content->data.attr)); - break; - case CSS_COMPUTED_CONTENT_OPEN_QUOTE: - fprintf(stream, "open-quote"); - break; - case CSS_COMPUTED_CONTENT_CLOSE_QUOTE: - fprintf(stream, "close-quote"); - break; - case CSS_COMPUTED_CONTENT_NO_OPEN_QUOTE: - fprintf(stream, "no-open-quote"); - break; - case CSS_COMPUTED_CONTENT_NO_CLOSE_QUOTE: - fprintf(stream, "no-close-quote"); - break; - } - - content++; - } - - fprintf(stream, " "); - break; - default: - break; - } - - /* counter-increment */ - val = css_computed_counter_increment(style, &counter); - if ((val == CSS_COUNTER_INCREMENT_NONE) || (counter == NULL)) { - fprintf(stream, "counter-increment: none "); - } else { - fprintf(stream, "counter-increment:"); - - while (counter->name != NULL) { - fprintf(stream, " %.*s ", - (int) lwc_string_length(counter->name), - lwc_string_data(counter->name)); - - dump_css_fixed(stream, counter->value); - - counter++; - } - - fprintf(stream, " "); - } - - /* counter-reset */ - val = css_computed_counter_reset(style, &counter); - if ((val == CSS_COUNTER_RESET_NONE) || (counter == NULL)) { - fprintf(stream, "counter-reset: none "); - } else { - fprintf(stream, "counter-reset:"); - - while (counter->name != NULL) { - fprintf(stream, " %.*s ", - (int) lwc_string_length(counter->name), - lwc_string_data(counter->name)); - - dump_css_fixed(stream, counter->value); - - counter++; - } - - fprintf(stream, " "); - } - - /* cursor */ - val = css_computed_cursor(style, &string_list); - fprintf(stream, "cursor:"); - - if (string_list != NULL) { - while (*string_list != NULL) { - fprintf(stream, " url\"%.*s\")", - (int) lwc_string_length(*string_list), - lwc_string_data(*string_list)); - - string_list++; - } - } - switch (val) { - case CSS_CURSOR_AUTO: - fprintf(stream, " auto "); - break; - case CSS_CURSOR_CROSSHAIR: - fprintf(stream, " crosshair "); - break; - case CSS_CURSOR_DEFAULT: - fprintf(stream, " default "); - break; - case CSS_CURSOR_POINTER: - fprintf(stream, " pointer "); - break; - case CSS_CURSOR_MOVE: - fprintf(stream, " move "); - break; - case CSS_CURSOR_E_RESIZE: - fprintf(stream, " e-resize "); - break; - case CSS_CURSOR_NE_RESIZE: - fprintf(stream, " ne-resize "); - break; - case CSS_CURSOR_NW_RESIZE: - fprintf(stream, " nw-resize "); - break; - case CSS_CURSOR_N_RESIZE: - fprintf(stream, " n-resize "); - break; - case CSS_CURSOR_SE_RESIZE: - fprintf(stream, " se-resize "); - break; - case CSS_CURSOR_SW_RESIZE: - fprintf(stream, " sw-resize "); - break; - case CSS_CURSOR_S_RESIZE: - fprintf(stream, " s-resize "); - break; - case CSS_CURSOR_W_RESIZE: - fprintf(stream, " w-resize "); - break; - case CSS_CURSOR_TEXT: - fprintf(stream, " text "); - break; - case CSS_CURSOR_WAIT: - fprintf(stream, " wait "); - break; - case CSS_CURSOR_HELP: - fprintf(stream, " help "); - break; - case CSS_CURSOR_PROGRESS: - fprintf(stream, " progress "); - break; - default: - break; - } - - /* direction */ - val = css_computed_direction(style); - switch (val) { - case CSS_DIRECTION_LTR: - fprintf(stream, "direction: ltr "); - break; - case CSS_DIRECTION_RTL: - fprintf(stream, "direction: rtl "); - break; - default: - break; - } - - /* display */ - val = css_computed_display_static(style); - switch (val) { - case CSS_DISPLAY_INLINE: - fprintf(stream, "display: inline "); - break; - case CSS_DISPLAY_BLOCK: - fprintf(stream, "display: block "); - break; - case CSS_DISPLAY_LIST_ITEM: - fprintf(stream, "display: list-item "); - break; - case CSS_DISPLAY_RUN_IN: - fprintf(stream, "display: run-in "); - break; - case CSS_DISPLAY_INLINE_BLOCK: - fprintf(stream, "display: inline-block "); - break; - case CSS_DISPLAY_TABLE: - fprintf(stream, "display: table "); - break; - case CSS_DISPLAY_INLINE_TABLE: - fprintf(stream, "display: inline-table "); - break; - case CSS_DISPLAY_TABLE_ROW_GROUP: - fprintf(stream, "display: table-row-group "); - break; - case CSS_DISPLAY_TABLE_HEADER_GROUP: - fprintf(stream, "display: table-header-group "); - break; - case CSS_DISPLAY_TABLE_FOOTER_GROUP: - fprintf(stream, "display: table-footer-group "); - break; - case CSS_DISPLAY_TABLE_ROW: - fprintf(stream, "display: table-row "); - break; - case CSS_DISPLAY_TABLE_COLUMN_GROUP: - fprintf(stream, "display: table-column-group "); - break; - case CSS_DISPLAY_TABLE_COLUMN: - fprintf(stream, "display: table-column "); - break; - case CSS_DISPLAY_TABLE_CELL: - fprintf(stream, "display: table-cell "); - break; - case CSS_DISPLAY_TABLE_CAPTION: - fprintf(stream, "display: table-caption "); - break; - case CSS_DISPLAY_NONE: - fprintf(stream, "display: none "); - break; - default: - break; - } - - /* empty-cells */ - val = css_computed_empty_cells(style); - switch (val) { - case CSS_EMPTY_CELLS_SHOW: - fprintf(stream, "empty-cells: show "); - break; - case CSS_EMPTY_CELLS_HIDE: - fprintf(stream, "empty-cells: hide "); - break; - default: - break; - } - - /* float */ - val = css_computed_float(style); - switch (val) { - case CSS_FLOAT_LEFT: - fprintf(stream, "float: left "); - break; - case CSS_FLOAT_RIGHT: - fprintf(stream, "float: right "); - break; - case CSS_FLOAT_NONE: - fprintf(stream, "float: none "); - break; - default: - break; - } - - /* font-family */ - val = css_computed_font_family(style, &string_list); - if (val != CSS_FONT_FAMILY_INHERIT) { - fprintf(stream, "font-family:"); - - if (string_list != NULL) { - while (*string_list != NULL) { - fprintf(stream, " \"%.*s\"", - (int) lwc_string_length(*string_list), - lwc_string_data(*string_list)); - - string_list++; - } - } - switch (val) { - case CSS_FONT_FAMILY_SERIF: - fprintf(stream, " serif "); - break; - case CSS_FONT_FAMILY_SANS_SERIF: - fprintf(stream, " sans-serif "); - break; - case CSS_FONT_FAMILY_CURSIVE: - fprintf(stream, " cursive "); - break; - case CSS_FONT_FAMILY_FANTASY: - fprintf(stream, " fantasy "); - break; - case CSS_FONT_FAMILY_MONOSPACE: - fprintf(stream, " monospace "); - break; - } - } - - /* font-size */ - val = css_computed_font_size(style, &len1, &unit1); - switch (val) { - case CSS_FONT_SIZE_XX_SMALL: - fprintf(stream, "font-size: xx-small "); - break; - case CSS_FONT_SIZE_X_SMALL: - fprintf(stream, "font-size: x-small "); - break; - case CSS_FONT_SIZE_SMALL: - fprintf(stream, "font-size: small "); - break; - case CSS_FONT_SIZE_MEDIUM: - fprintf(stream, "font-size: medium "); - break; - case CSS_FONT_SIZE_LARGE: - fprintf(stream, "font-size: large "); - break; - case CSS_FONT_SIZE_X_LARGE: - fprintf(stream, "font-size: x-large "); - break; - case CSS_FONT_SIZE_XX_LARGE: - fprintf(stream, "font-size: xx-large "); - break; - case CSS_FONT_SIZE_LARGER: - fprintf(stream, "font-size: larger "); - break; - case CSS_FONT_SIZE_SMALLER: - fprintf(stream, "font-size: smaller "); - break; - case CSS_FONT_SIZE_DIMENSION: - fprintf(stream, "font-size: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* font-style */ - val = css_computed_font_style(style); - switch (val) { - case CSS_FONT_STYLE_NORMAL: - fprintf(stream, "font-style: normal "); - break; - case CSS_FONT_STYLE_ITALIC: - fprintf(stream, "font-style: italic "); - break; - case CSS_FONT_STYLE_OBLIQUE: - fprintf(stream, "font-style: oblique "); - break; - default: - break; - } - - /* font-variant */ - val = css_computed_font_variant(style); - switch (val) { - case CSS_FONT_VARIANT_NORMAL: - fprintf(stream, "font-variant: normal "); - break; - case CSS_FONT_VARIANT_SMALL_CAPS: - fprintf(stream, "font-variant: small-caps "); - break; - default: - break; - } - - /* font-weight */ - val = css_computed_font_weight(style); - switch (val) { - case CSS_FONT_WEIGHT_NORMAL: - fprintf(stream, "font-weight: normal "); - break; - case CSS_FONT_WEIGHT_BOLD: - fprintf(stream, "font-weight: bold "); - break; - case CSS_FONT_WEIGHT_BOLDER: - fprintf(stream, "font-weight: bolder "); - break; - case CSS_FONT_WEIGHT_LIGHTER: - fprintf(stream, "font-weight: lighter "); - break; - case CSS_FONT_WEIGHT_100: - fprintf(stream, "font-weight: 100 "); - break; - case CSS_FONT_WEIGHT_200: - fprintf(stream, "font-weight: 200 "); - break; - case CSS_FONT_WEIGHT_300: - fprintf(stream, "font-weight: 300 "); - break; - case CSS_FONT_WEIGHT_400: - fprintf(stream, "font-weight: 400 "); - break; - case CSS_FONT_WEIGHT_500: - fprintf(stream, "font-weight: 500 "); - break; - case CSS_FONT_WEIGHT_600: - fprintf(stream, "font-weight: 600 "); - break; - case CSS_FONT_WEIGHT_700: - fprintf(stream, "font-weight: 700 "); - break; - case CSS_FONT_WEIGHT_800: - fprintf(stream, "font-weight: 800 "); - break; - case CSS_FONT_WEIGHT_900: - fprintf(stream, "font-weight: 900 "); - break; - default: - break; - } - - /* height */ - val = css_computed_height(style, &len1, &unit1); - switch (val) { - case CSS_HEIGHT_AUTO: - fprintf(stream, "height: auto "); - break; - case CSS_HEIGHT_SET: - fprintf(stream, "height: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* left */ - val = css_computed_left(style, &len1, &unit1); - switch (val) { - case CSS_LEFT_AUTO: - fprintf(stream, "left: auto "); - break; - case CSS_LEFT_SET: - fprintf(stream, "left: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* letter-spacing */ - val = css_computed_letter_spacing(style, &len1, &unit1); - switch (val) { - case CSS_LETTER_SPACING_NORMAL: - fprintf(stream, "letter-spacing: normal "); - break; - case CSS_LETTER_SPACING_SET: - fprintf(stream, "letter-spacing: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* line-height */ - val = css_computed_line_height(style, &len1, &unit1); - switch (val) { - case CSS_LINE_HEIGHT_NORMAL: - fprintf(stream, "line-height: normal "); - break; - case CSS_LINE_HEIGHT_NUMBER: - fprintf(stream, "line-height: "); - - dump_css_fixed(stream, len1); - - fprintf(stream, " "); - break; - case CSS_LINE_HEIGHT_DIMENSION: - fprintf(stream, "line-height: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* list-style-image */ - val = css_computed_list_style_image(style, &url); - if (url != NULL) { - fprintf(stream, "list-style-image: url('%.*s') ", - (int) lwc_string_length(url), - lwc_string_data(url)); - } else if (val == CSS_LIST_STYLE_IMAGE_NONE) { - fprintf(stream, "list-style-image: none "); - } - - /* list-style-position */ - val = css_computed_list_style_position(style); - switch (val) { - case CSS_LIST_STYLE_POSITION_INSIDE: - fprintf(stream, "list-style-position: inside "); - break; - case CSS_LIST_STYLE_POSITION_OUTSIDE: - fprintf(stream, "list-style-position: outside "); - break; - default: - break; - } - - /* list-style-type */ - val = css_computed_list_style_type(style); - switch (val) { - case CSS_LIST_STYLE_TYPE_DISC: - fprintf(stream, "list-style-type: disc "); - break; - case CSS_LIST_STYLE_TYPE_CIRCLE: - fprintf(stream, "list-style-type: circle "); - break; - case CSS_LIST_STYLE_TYPE_SQUARE: - fprintf(stream, "list-style-type: square "); - break; - case CSS_LIST_STYLE_TYPE_DECIMAL: - fprintf(stream, "list-style-type: decimal "); - break; - case CSS_LIST_STYLE_TYPE_DECIMAL_LEADING_ZERO: - fprintf(stream, "list-style-type: decimal-leading-zero "); - break; - case CSS_LIST_STYLE_TYPE_LOWER_ROMAN: - fprintf(stream, "list-style-type: lower-roman "); - break; - case CSS_LIST_STYLE_TYPE_UPPER_ROMAN: - fprintf(stream, "list-style-type: upper-roman "); - break; - case CSS_LIST_STYLE_TYPE_LOWER_GREEK: - fprintf(stream, "list-style-type: lower-greek "); - break; - case CSS_LIST_STYLE_TYPE_LOWER_LATIN: - fprintf(stream, "list-style-type: lower-latin "); - break; - case CSS_LIST_STYLE_TYPE_UPPER_LATIN: - fprintf(stream, "list-style-type: upper-latin "); - break; - case CSS_LIST_STYLE_TYPE_ARMENIAN: - fprintf(stream, "list-style-type: armenian "); - break; - case CSS_LIST_STYLE_TYPE_GEORGIAN: - fprintf(stream, "list-style-type: georgian "); - break; - case CSS_LIST_STYLE_TYPE_LOWER_ALPHA: - fprintf(stream, "list-style-type: lower-alpha "); - break; - case CSS_LIST_STYLE_TYPE_UPPER_ALPHA: - fprintf(stream, "list-style-type: upper-alpha "); - break; - case CSS_LIST_STYLE_TYPE_NONE: - fprintf(stream, "list-style-type: none "); - break; - default: - break; - } - - /* margin-top */ - val = css_computed_margin_top(style, &len1, &unit1); - switch (val) { - case CSS_MARGIN_AUTO: - fprintf(stream, "margin-top: auto "); - break; - case CSS_MARGIN_SET: - fprintf(stream, "margin-top: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* margin-right */ - val = css_computed_margin_right(style, &len1, &unit1); - switch (val) { - case CSS_MARGIN_AUTO: - fprintf(stream, "margin-right: auto "); - break; - case CSS_MARGIN_SET: - fprintf(stream, "margin-right: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* margin-bottom */ - val = css_computed_margin_bottom(style, &len1, &unit1); - switch (val) { - case CSS_MARGIN_AUTO: - fprintf(stream, "margin-bottom: auto "); - break; - case CSS_MARGIN_SET: - fprintf(stream, "margin-bottom: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* margin-left */ - val = css_computed_margin_left(style, &len1, &unit1); - switch (val) { - case CSS_MARGIN_AUTO: - fprintf(stream, "margin-left: auto "); - break; - case CSS_MARGIN_SET: - fprintf(stream, "margin-left: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* max-height */ - val = css_computed_max_height(style, &len1, &unit1); - switch (val) { - case CSS_MAX_HEIGHT_NONE: - fprintf(stream, "max-height: none "); - break; - case CSS_MAX_HEIGHT_SET: - fprintf(stream, "max-height: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* max-width */ - val = css_computed_max_width(style, &len1, &unit1); - switch (val) { - case CSS_MAX_WIDTH_NONE: - fprintf(stream, "max-width: none "); - break; - case CSS_MAX_WIDTH_SET: - fprintf(stream, "max-width: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* min-height */ - val = css_computed_min_height(style, &len1, &unit1); - switch (val) { - case CSS_MIN_HEIGHT_SET: - fprintf(stream, "min-height: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* min-width */ - val = css_computed_min_width(style, &len1, &unit1); - switch (val) { - case CSS_MIN_WIDTH_SET: - fprintf(stream, "min-width: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* opacity */ - val = css_computed_opacity(style, &len1); - switch (val) { - case CSS_OPACITY_SET: - fprintf(stream, "opacity: "); - - dump_css_fixed(stream, len1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* outline-color */ - val = css_computed_outline_color(style, &color); - switch (val) { - case CSS_OUTLINE_COLOR_INVERT: - fprintf(stream, "outline-color: invert "); - break; - case CSS_OUTLINE_COLOR_COLOR: - fprintf(stream, "outline-color: #%08x ", color); - break; - default: - break; - } - - /* outline-style */ - val = css_computed_outline_style(style); - switch (val) { - case CSS_OUTLINE_STYLE_NONE: - fprintf(stream, "outline-style: none "); - break; - case CSS_OUTLINE_STYLE_DOTTED: - fprintf(stream, "outline-style: dotted "); - break; - case CSS_OUTLINE_STYLE_DASHED: - fprintf(stream, "outline-style: dashed "); - break; - case CSS_OUTLINE_STYLE_SOLID: - fprintf(stream, "outline-style: solid "); - break; - case CSS_OUTLINE_STYLE_DOUBLE: - fprintf(stream, "outline-style: double "); - break; - case CSS_OUTLINE_STYLE_GROOVE: - fprintf(stream, "outline-style: groove "); - break; - case CSS_OUTLINE_STYLE_RIDGE: - fprintf(stream, "outline-style: ridge "); - break; - case CSS_OUTLINE_STYLE_INSET: - fprintf(stream, "outline-style: inset "); - break; - case CSS_OUTLINE_STYLE_OUTSET: - fprintf(stream, "outline-style: outset "); - break; - default: - break; - } - - /* outline-width */ - val = css_computed_outline_width(style, &len1, &unit1); - switch (val) { - case CSS_OUTLINE_WIDTH_THIN: - fprintf(stream, "outline-width: thin "); - break; - case CSS_OUTLINE_WIDTH_MEDIUM: - fprintf(stream, "outline-width: medium "); - break; - case CSS_OUTLINE_WIDTH_THICK: - fprintf(stream, "outline-width: thick "); - break; - case CSS_OUTLINE_WIDTH_WIDTH: - fprintf(stream, "outline-width: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* overflow */ - val = css_computed_overflow_x(style); - switch (val) { - case CSS_OVERFLOW_VISIBLE: - fprintf(stream, "overflow-x: visible "); - break; - case CSS_OVERFLOW_HIDDEN: - fprintf(stream, "overflow-x: hidden "); - break; - case CSS_OVERFLOW_SCROLL: - fprintf(stream, "overflow-x: scroll "); - break; - case CSS_OVERFLOW_AUTO: - fprintf(stream, "overflow-x auto "); - break; - default: - break; - } - - /* overflow */ - val = css_computed_overflow_y(style); - switch (val) { - case CSS_OVERFLOW_VISIBLE: - fprintf(stream, "overflow-y: visible "); - break; - case CSS_OVERFLOW_HIDDEN: - fprintf(stream, "overflow-y: hidden "); - break; - case CSS_OVERFLOW_SCROLL: - fprintf(stream, "overflow-y: scroll "); - break; - case CSS_OVERFLOW_AUTO: - fprintf(stream, "overflow-y: auto "); - break; - default: - break; - } - - /* padding-top */ - val = css_computed_padding_top(style, &len1, &unit1); - switch (val) { - case CSS_PADDING_SET: - fprintf(stream, "padding-top: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* padding-right */ - val = css_computed_padding_right(style, &len1, &unit1); - switch (val) { - case CSS_PADDING_SET: - fprintf(stream, "padding-right: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* padding-bottom */ - val = css_computed_padding_bottom(style, &len1, &unit1); - switch (val) { - case CSS_PADDING_SET: - fprintf(stream, "padding-bottom: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* padding-left */ - val = css_computed_padding_left(style, &len1, &unit1); - switch (val) { - case CSS_PADDING_SET: - fprintf(stream, "padding-left: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* position */ - val = css_computed_position(style); - switch (val) { - case CSS_POSITION_STATIC: - fprintf(stream, "position: static "); - break; - case CSS_POSITION_RELATIVE: - fprintf(stream, "position: relative "); - break; - case CSS_POSITION_ABSOLUTE: - fprintf(stream, "position: absolute "); - break; - case CSS_POSITION_FIXED: - fprintf(stream, "position: fixed "); - break; - default: - break; - } - - /* quotes */ - val = css_computed_quotes(style, &string_list); - if (val == CSS_QUOTES_STRING && string_list != NULL) { - fprintf(stream, "quotes:"); - - while (*string_list != NULL) { - fprintf(stream, " \"%.*s\"", - (int) lwc_string_length(*string_list), - lwc_string_data(*string_list)); - - string_list++; - } - - fprintf(stream, " "); - } else { - switch (val) { - case CSS_QUOTES_NONE: - fprintf(stream, "quotes: none "); - break; - default: - break; - } - } - - /* right */ - val = css_computed_right(style, &len1, &unit1); - switch (val) { - case CSS_RIGHT_AUTO: - fprintf(stream, "right: auto "); - break; - case CSS_RIGHT_SET: - fprintf(stream, "right: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* table-layout */ - val = css_computed_table_layout(style); - switch (val) { - case CSS_TABLE_LAYOUT_AUTO: - fprintf(stream, "table-layout: auto "); - break; - case CSS_TABLE_LAYOUT_FIXED: - fprintf(stream, "table-layout: fixed "); - break; - default: - break; - } - - /* text-align */ - val = css_computed_text_align(style); - switch (val) { - case CSS_TEXT_ALIGN_LEFT: - fprintf(stream, "text-align: left "); - break; - case CSS_TEXT_ALIGN_RIGHT: - fprintf(stream, "text-align: right "); - break; - case CSS_TEXT_ALIGN_CENTER: - fprintf(stream, "text-align: center "); - break; - case CSS_TEXT_ALIGN_JUSTIFY: - fprintf(stream, "text-align: justify "); - break; - case CSS_TEXT_ALIGN_DEFAULT: - fprintf(stream, "text-align: default "); - break; - case CSS_TEXT_ALIGN_LIBCSS_LEFT: - fprintf(stream, "text-align: -libcss-left "); - break; - case CSS_TEXT_ALIGN_LIBCSS_CENTER: - fprintf(stream, "text-align: -libcss-center "); - break; - case CSS_TEXT_ALIGN_LIBCSS_RIGHT: - fprintf(stream, "text-align: -libcss-right "); - break; - default: - break; - } - - /* text-decoration */ - val = css_computed_text_decoration(style); - if (val == CSS_TEXT_DECORATION_NONE) { - fprintf(stream, "text-decoration: none "); - } else { - fprintf(stream, "text-decoration:"); - - if (val & CSS_TEXT_DECORATION_BLINK) { - fprintf(stream, " blink"); - } - if (val & CSS_TEXT_DECORATION_LINE_THROUGH) { - fprintf(stream, " line-through"); - } - if (val & CSS_TEXT_DECORATION_OVERLINE) { - fprintf(stream, " overline"); - } - if (val & CSS_TEXT_DECORATION_UNDERLINE) { - fprintf(stream, " underline"); - } - - fprintf(stream, " "); - } - - /* text-indent */ - val = css_computed_text_indent(style, &len1, &unit1); - switch (val) { - case CSS_TEXT_INDENT_SET: - fprintf(stream, "text-indent: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* text-transform */ - val = css_computed_text_transform(style); - switch (val) { - case CSS_TEXT_TRANSFORM_CAPITALIZE: - fprintf(stream, "text-transform: capitalize "); - break; - case CSS_TEXT_TRANSFORM_UPPERCASE: - fprintf(stream, "text-transform: uppercase "); - break; - case CSS_TEXT_TRANSFORM_LOWERCASE: - fprintf(stream, "text-transform: lowercase "); - break; - case CSS_TEXT_TRANSFORM_NONE: - fprintf(stream, "text-transform: none "); - break; - default: - break; - } - - /* top */ - val = css_computed_top(style, &len1, &unit1); - switch (val) { - case CSS_TOP_AUTO: - fprintf(stream, "top: auto "); - break; - case CSS_TOP_SET: - fprintf(stream, "top: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* unicode-bidi */ - val = css_computed_unicode_bidi(style); - switch (val) { - case CSS_UNICODE_BIDI_NORMAL: - fprintf(stream, "unicode-bidi: normal "); - break; - case CSS_UNICODE_BIDI_EMBED: - fprintf(stream, "unicode-bidi: embed "); - break; - case CSS_UNICODE_BIDI_BIDI_OVERRIDE: - fprintf(stream, "unicode-bidi: bidi-override "); - break; - default: - break; - } - - /* vertical-align */ - val = css_computed_vertical_align(style, &len1, &unit1); - switch (val) { - case CSS_VERTICAL_ALIGN_BASELINE: - fprintf(stream, "vertical-align: baseline "); - break; - case CSS_VERTICAL_ALIGN_SUB: - fprintf(stream, "vertical-align: sub "); - break; - case CSS_VERTICAL_ALIGN_SUPER: - fprintf(stream, "vertical-align: super "); - break; - case CSS_VERTICAL_ALIGN_TOP: - fprintf(stream, "vertical-align: top "); - break; - case CSS_VERTICAL_ALIGN_TEXT_TOP: - fprintf(stream, "vertical-align: text-top "); - break; - case CSS_VERTICAL_ALIGN_MIDDLE: - fprintf(stream, "vertical-align: middle "); - break; - case CSS_VERTICAL_ALIGN_BOTTOM: - fprintf(stream, "vertical-align: bottom "); - break; - case CSS_VERTICAL_ALIGN_TEXT_BOTTOM: - fprintf(stream, "vertical-align: text-bottom "); - break; - case CSS_VERTICAL_ALIGN_SET: - fprintf(stream, "vertical-align: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* visibility */ - val = css_computed_visibility(style); - switch (val) { - case CSS_VISIBILITY_VISIBLE: - fprintf(stream, "visibility: visible "); - break; - case CSS_VISIBILITY_HIDDEN: - fprintf(stream, "visibility: hidden "); - break; - case CSS_VISIBILITY_COLLAPSE: - fprintf(stream, "visibility: collapse "); - break; - default: - break; - } - - /* white-space */ - val = css_computed_white_space(style); - switch (val) { - case CSS_WHITE_SPACE_NORMAL: - fprintf(stream, "white-space: normal "); - break; - case CSS_WHITE_SPACE_PRE: - fprintf(stream, "white-space: pre "); - break; - case CSS_WHITE_SPACE_NOWRAP: - fprintf(stream, "white-space: nowrap "); - break; - case CSS_WHITE_SPACE_PRE_WRAP: - fprintf(stream, "white-space: pre-wrap "); - break; - case CSS_WHITE_SPACE_PRE_LINE: - fprintf(stream, "white-space: pre-line "); - break; - default: - break; - } - - /* width */ - val = css_computed_width(style, &len1, &unit1); - switch (val) { - case CSS_WIDTH_AUTO: - fprintf(stream, "width: auto "); - break; - case CSS_WIDTH_SET: - fprintf(stream, "width: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* word-spacing */ - val = css_computed_word_spacing(style, &len1, &unit1); - switch (val) { - case CSS_WORD_SPACING_NORMAL: - fprintf(stream, "word-spacing: normal "); - break; - case CSS_WORD_SPACING_SET: - fprintf(stream, "word-spacing: "); - - dump_css_unit(stream, len1, unit1); - - fprintf(stream, " "); - break; - default: - break; - } - - /* z-index */ - val = css_computed_z_index(style, &zindex); - switch (val) { - case CSS_Z_INDEX_AUTO: - fprintf(stream, "z-index: auto "); - break; - case CSS_Z_INDEX_SET: - fprintf(stream, "z-index: %d ", zindex); - break; - default: - break; - } - - fprintf(stream, "}"); -} - -/****************************************************************************** - * Helper functions for nscss_dump_computed_style * - ******************************************************************************/ - -/** - * Dump a fixed point value to the stream in a textual form. - * - * \param stream Stream to write to - * \param f Value to write - */ -void dump_css_fixed(FILE *stream, css_fixed f) -{ -#define NSCSS_ABS(x) (uint32_t)((x) < 0 ? -(x) : (x)) - uint32_t uintpart = FIXTOINT(NSCSS_ABS(f)); - /* + 500 to ensure round to nearest (division will truncate) */ - uint32_t fracpart = ((NSCSS_ABS(f) & 0x3ff) * 1000 + 500) / (1 << 10); -#undef NSCSS_ABS - - fprintf(stream, "%s%d.%03d", f < 0 ? "-" : "", uintpart, fracpart); -} - -/** - * Dump a numeric value to the stream in a textual form. - * - * \param stream Stream to write to - * \param val Value to write - */ -void dump_css_number(FILE *stream, css_fixed val) -{ - if (INTTOFIX(FIXTOINT(val)) == val) - fprintf(stream, "%d", FIXTOINT(val)); - else - dump_css_fixed(stream, val); -} - -/** - * Dump a dimension to the stream in a textual form. - * - * \param stream Stream to write to - * \param val Value to write - * \param unit Unit to write - */ -void dump_css_unit(FILE *stream, css_fixed val, css_unit unit) -{ - dump_css_number(stream, val); - - switch (unit) { - case CSS_UNIT_PX: - fprintf(stream, "px"); - break; - case CSS_UNIT_EX: - fprintf(stream, "ex"); - break; - case CSS_UNIT_EM: - fprintf(stream, "em"); - break; - case CSS_UNIT_IN: - fprintf(stream, "in"); - break; - case CSS_UNIT_CM: - fprintf(stream, "cm"); - break; - case CSS_UNIT_MM: - fprintf(stream, "mm"); - break; - case CSS_UNIT_PT: - fprintf(stream, "pt"); - break; - case CSS_UNIT_PC: - fprintf(stream, "pc"); - break; - case CSS_UNIT_PCT: - fprintf(stream, "%%"); - break; - case CSS_UNIT_DEG: - fprintf(stream, "deg"); - break; - case CSS_UNIT_GRAD: - fprintf(stream, "grad"); - break; - case CSS_UNIT_RAD: - fprintf(stream, "rad"); - break; - case CSS_UNIT_MS: - fprintf(stream, "ms"); - break; - case CSS_UNIT_S: - fprintf(stream, "s"); - break; - case CSS_UNIT_HZ: - fprintf(stream, "Hz"); - break; - case CSS_UNIT_KHZ: - fprintf(stream, "kHz"); - break; - } -} - diff --git a/css/dump.h b/css/dump.h deleted file mode 100644 index 25d283e9e..000000000 --- a/css/dump.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef NETSURF_CSS_DUMP_H_ -#define NETSURF_CSS_DUMP_H_ - -#include "css/css.h" - -void nscss_dump_computed_style(FILE *stream, const css_computed_style *style); - -#endif diff --git a/css/hints.c b/css/hints.c deleted file mode 100644 index 356153983..000000000 --- a/css/hints.c +++ /dev/null @@ -1,1611 +0,0 @@ -/* - * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <string.h> -#include <strings.h> - -#include "utils/nsoption.h" -#include "utils/corestrings.h" -#include "utils/log.h" -#include "utils/nsurl.h" -#include "utils/utils.h" - -#include "css/hints.h" -#include "css/select.h" - -#define LOG_STATS -#undef LOG_STATS - -/****************************************************************************** - * Utility functions * - ******************************************************************************/ - -/** - * Determine if a given character is whitespace - * - * \param c Character to consider - * \return true if character is whitespace, false otherwise - */ -static bool isWhitespace(char c) -{ - return c == ' ' || c == '\t' || c == '\f' || c == '\r' || c == '\n'; -} - -/** - * Determine if a given character is a valid hex digit - * - * \param c Character to consider - * \return true if character is a valid hex digit, false otherwise - */ -static bool isHex(char c) -{ - return ('0' <= c && c <= '9') || - ('A' <= (c & ~0x20) && (c & ~0x20) <= 'F'); -} - -/** - * Convert a character representing a hex digit to the corresponding hex value - * - * \param c Character to convert - * \return Hex value represented by character - * - * \note This function assumes an ASCII-compatible character set - */ -static uint8_t charToHex(char c) -{ - /* 0-9 */ - c -= '0'; - - /* A-F */ - if (c > 9) - c -= 'A' - '9' - 1; - - /* a-f */ - if (c > 15) - c -= 'a' - 'A'; - - return c; -} - - -/****************************************************************************** - * Common parsing functions * - ******************************************************************************/ - -/** - * Parse a number string - * - * \param data Data to parse (NUL-terminated) - * \param maybe_negative Negative numbers permitted - * \param real Floating point numbers permitted - * \param value Pointer to location to receive numeric value - * \param consumed Pointer to location to receive number of input - * bytes consumed - * \return true on success, false on invalid input - */ -static bool parse_number(const char *data, bool maybe_negative, bool real, - css_fixed *value, size_t *consumed) -{ - size_t len; - const uint8_t *ptr; - int32_t intpart = 0; - int32_t fracpart = 0; - int32_t pwr = 1; - int sign = 1; - - *consumed = 0; - - len = strlen(data); - ptr = (const uint8_t *) data; - - if (len == 0) - return false; - - /* Skip leading whitespace */ - while (len > 0 && isWhitespace(ptr[0])) { - len--; - ptr++; - } - - if (len == 0) - return false; - - /* Extract sign, if any */ - if (ptr[0] == '+') { - len--; - ptr++; - } else if (ptr[0] == '-' && maybe_negative) { - sign = -1; - len--; - ptr++; - } - - if (len == 0) - return false; - - /* Must have a digit [0,9] */ - if ('0' > ptr[0] || ptr[0] > '9') - return false; - - /* Now extract intpart, assuming base 10 */ - while (len > 0) { - /* Stop on first non-digit */ - if (ptr[0] < '0' || '9' < ptr[0]) - break; - - /* Prevent overflow of 'intpart'; proper clamping below */ - if (intpart < (1 << 22)) { - intpart *= 10; - intpart += ptr[0] - '0'; - } - ptr++; - len--; - } - - /* And fracpart, again, assuming base 10 */ - if (real && len > 1 && ptr[0] == '.' && - ('0' <= ptr[1] && ptr[1] <= '9')) { - ptr++; - len--; - - while (len > 0) { - if (ptr[0] < '0' || '9' < ptr[0]) - break; - - if (pwr < 1000000) { - pwr *= 10; - fracpart *= 10; - fracpart += ptr[0] - '0'; - } - ptr++; - len--; - } - - fracpart = ((1 << 10) * fracpart + pwr/2) / pwr; - if (fracpart >= (1 << 10)) { - intpart++; - fracpart &= (1 << 10) - 1; - } - } - - if (sign > 0) { - /* If the result is larger than we can represent, - * then clamp to the maximum value we can store. */ - if (intpart >= (1 << 21)) { - intpart = (1 << 21) - 1; - fracpart = (1 << 10) - 1; - } - } else { - /* If the negated result is smaller than we can represent - * then clamp to the minimum value we can store. */ - if (intpart >= (1 << 21)) { - intpart = -(1 << 21); - fracpart = 0; - } else { - intpart = -intpart; - if (fracpart) { - fracpart = (1 << 10) - fracpart; - intpart--; - } - } - } - - *value = (intpart << 10) | fracpart; - - *consumed = ptr - (const uint8_t *) data; - - return true; -} - -/** - * Parse a dimension string - * - * \param data Data to parse (NUL-terminated) - * \param strict Whether to enforce strict parsing rules - * \param length Pointer to location to receive dimension's length - * \param unit Pointer to location to receive dimension's unit - * \return true on success, false on invalid input - */ -static bool parse_dimension(const char *data, bool strict, css_fixed *length, - css_unit *unit) -{ - size_t len; - size_t read; - css_fixed value; - - len = strlen(data); - - if (parse_number(data, false, true, &value, &read) == false) - return false; - - if (strict && value < INTTOFIX(1)) - return false; - - *length = value; - - if (len > read && data[read] == '%') - *unit = CSS_UNIT_PCT; - else - *unit = CSS_UNIT_PX; - - return true; -} - -/** - * Mapping of colour name to CSS color - */ -struct colour_map { - const char *name; - css_color color; -}; - -/** - * Name comparator for named colour matching - * - * \param a Name to match - * \param b Colour map entry to consider - * \return 0 on match, - * < 0 if a < b, - * > 0 if b > a. - */ -static int cmp_colour_name(const void *a, const void *b) -{ - const char *aa = a; - const struct colour_map *bb = b; - - return strcasecmp(aa, bb->name); -} - -/** - * Parse a named colour - * - * \param name Name to parse - * \param result Pointer to location to receive css_color - * \return true on success, false on invalid input - */ -static bool parse_named_colour(const char *name, css_color *result) -{ - static const struct colour_map named_colours[] = { - { "aliceblue", 0xfff0f8ff }, - { "antiquewhite", 0xfffaebd7 }, - { "aqua", 0xff00ffff }, - { "aquamarine", 0xff7fffd4 }, - { "azure", 0xfff0ffff }, - { "beige", 0xfff5f5dc }, - { "bisque", 0xffffe4c4 }, - { "black", 0xff000000 }, - { "blanchedalmond", 0xffffebcd }, - { "blue", 0xff0000ff }, - { "blueviolet", 0xff8a2be2 }, - { "brown", 0xffa52a2a }, - { "burlywood", 0xffdeb887 }, - { "cadetblue", 0xff5f9ea0 }, - { "chartreuse", 0xff7fff00 }, - { "chocolate", 0xffd2691e }, - { "coral", 0xffff7f50 }, - { "cornflowerblue", 0xff6495ed }, - { "cornsilk", 0xfffff8dc }, - { "crimson", 0xffdc143c }, - { "cyan", 0xff00ffff }, - { "darkblue", 0xff00008b }, - { "darkcyan", 0xff008b8b }, - { "darkgoldenrod", 0xffb8860b }, - { "darkgray", 0xffa9a9a9 }, - { "darkgreen", 0xff006400 }, - { "darkgrey", 0xffa9a9a9 }, - { "darkkhaki", 0xffbdb76b }, - { "darkmagenta", 0xff8b008b }, - { "darkolivegreen", 0xff556b2f }, - { "darkorange", 0xffff8c00 }, - { "darkorchid", 0xff9932cc }, - { "darkred", 0xff8b0000 }, - { "darksalmon", 0xffe9967a }, - { "darkseagreen", 0xff8fbc8f }, - { "darkslateblue", 0xff483d8b }, - { "darkslategray", 0xff2f4f4f }, - { "darkslategrey", 0xff2f4f4f }, - { "darkturquoise", 0xff00ced1 }, - { "darkviolet", 0xff9400d3 }, - { "deeppink", 0xffff1493 }, - { "deepskyblue", 0xff00bfff }, - { "dimgray", 0xff696969 }, - { "dimgrey", 0xff696969 }, - { "dodgerblue", 0xff1e90ff }, - { "feldspar", 0xffd19275 }, - { "firebrick", 0xffb22222 }, - { "floralwhite", 0xfffffaf0 }, - { "forestgreen", 0xff228b22 }, - { "fuchsia", 0xffff00ff }, - { "gainsboro", 0xffdcdcdc }, - { "ghostwhite", 0xfff8f8ff }, - { "gold", 0xffffd700 }, - { "goldenrod", 0xffdaa520 }, - { "gray", 0xff808080 }, - { "green", 0xff008000 }, - { "greenyellow", 0xffadff2f }, - { "grey", 0xff808080 }, - { "honeydew", 0xfff0fff0 }, - { "hotpink", 0xffff69b4 }, - { "indianred", 0xffcd5c5c }, - { "indigo", 0xff4b0082 }, - { "ivory", 0xfffffff0 }, - { "khaki", 0xfff0e68c }, - { "lavender", 0xffe6e6fa }, - { "lavenderblush", 0xfffff0f5 }, - { "lawngreen", 0xff7cfc00 }, - { "lemonchiffon", 0xfffffacd }, - { "lightblue", 0xffadd8e6 }, - { "lightcoral", 0xfff08080 }, - { "lightcyan", 0xffe0ffff }, - { "lightgoldenrodyellow", 0xfffafad2 }, - { "lightgray", 0xffd3d3d3 }, - { "lightgreen", 0xff90ee90 }, - { "lightgrey", 0xffd3d3d3 }, - { "lightpink", 0xffffb6c1 }, - { "lightsalmon", 0xffffa07a }, - { "lightseagreen", 0xff20b2aa }, - { "lightskyblue", 0xff87cefa }, - { "lightslateblue", 0xff8470ff }, - { "lightslategray", 0xff778899 }, - { "lightslategrey", 0xff778899 }, - { "lightsteelblue", 0xffb0c4de }, - { "lightyellow", 0xffffffe0 }, - { "lime", 0xff00ff00 }, - { "limegreen", 0xff32cd32 }, - { "linen", 0xfffaf0e6 }, - { "magenta", 0xffff00ff }, - { "maroon", 0xff800000 }, - { "mediumaquamarine", 0xff66cdaa }, - { "mediumblue", 0xff0000cd }, - { "mediumorchid", 0xffba55d3 }, - { "mediumpurple", 0xff9370db }, - { "mediumseagreen", 0xff3cb371 }, - { "mediumslateblue", 0xff7b68ee }, - { "mediumspringgreen", 0xff00fa9a }, - { "mediumturquoise", 0xff48d1cc }, - { "mediumvioletred", 0xffc71585 }, - { "midnightblue", 0xff191970 }, - { "mintcream", 0xfff5fffa }, - { "mistyrose", 0xffffe4e1 }, - { "moccasin", 0xffffe4b5 }, - { "navajowhite", 0xffffdead }, - { "navy", 0xff000080 }, - { "oldlace", 0xfffdf5e6 }, - { "olive", 0xff808000 }, - { "olivedrab", 0xff6b8e23 }, - { "orange", 0xffffa500 }, - { "orangered", 0xffff4500 }, - { "orchid", 0xffda70d6 }, - { "palegoldenrod", 0xffeee8aa }, - { "palegreen", 0xff98fb98 }, - { "paleturquoise", 0xffafeeee }, - { "palevioletred", 0xffdb7093 }, - { "papayawhip", 0xffffefd5 }, - { "peachpuff", 0xffffdab9 }, - { "peru", 0xffcd853f }, - { "pink", 0xffffc0cb }, - { "plum", 0xffdda0dd }, - { "powderblue", 0xffb0e0e6 }, - { "purple", 0xff800080 }, - { "red", 0xffff0000 }, - { "rosybrown", 0xffbc8f8f }, - { "royalblue", 0xff4169e1 }, - { "saddlebrown", 0xff8b4513 }, - { "salmon", 0xfffa8072 }, - { "sandybrown", 0xfff4a460 }, - { "seagreen", 0xff2e8b57 }, - { "seashell", 0xfffff5ee }, - { "sienna", 0xffa0522d }, - { "silver", 0xffc0c0c0 }, - { "skyblue", 0xff87ceeb }, - { "slateblue", 0xff6a5acd }, - { "slategray", 0xff708090 }, - { "slategrey", 0xff708090 }, - { "snow", 0xfffffafa }, - { "springgreen", 0xff00ff7f }, - { "steelblue", 0xff4682b4 }, - { "tan", 0xffd2b48c }, - { "teal", 0xff008080 }, - { "thistle", 0xffd8bfd8 }, - { "tomato", 0xffff6347 }, - { "turquoise", 0xff40e0d0 }, - { "violet", 0xffee82ee }, - { "violetred", 0xffd02090 }, - { "wheat", 0xfff5deb3 }, - { "white", 0xffffffff }, - { "whitesmoke", 0xfff5f5f5 }, - { "yellow", 0xffffff00 }, - { "yellowgreen", 0xff9acd32 } - }; - const struct colour_map *entry; - - entry = bsearch(name, named_colours, - sizeof(named_colours) / sizeof(named_colours[0]), - sizeof(named_colours[0]), - cmp_colour_name); - - if (entry != NULL) - *result = entry->color; - - return entry != NULL; -} - -/** - * Parser for colours specified in attribute values. - * - * \param data Data to parse (NUL-terminated) - * \param result Pointer to location to receive resulting css_color - * \return true on success, false on invalid input - */ -bool nscss_parse_colour(const char *data, css_color *result) -{ - size_t len = strlen(data); - uint8_t r, g, b; - - /* 2 */ - if (len == 0) - return false; - - /* 3 */ - if (len == SLEN("transparent") && strcasecmp(data, "transparent") == 0) - return false; - - /* 4 */ - if (parse_named_colour(data, result)) - return true; - - /** \todo Implement HTML5's utterly insane legacy colour parsing */ - - if (data[0] == '#') { - data++; - len--; - } - - if (len == 3 && isHex(data[0]) && isHex(data[1]) && isHex(data[2])) { - r = charToHex(data[0]); - g = charToHex(data[1]); - b = charToHex(data[2]); - - r |= (r << 4); - g |= (g << 4); - b |= (b << 4); - - *result = (0xff << 24) | (r << 16) | (g << 8) | b; - - return true; - } else if (len == 6 && isHex(data[0]) && isHex(data[1]) && - isHex(data[2]) && isHex(data[3]) && isHex(data[4]) && - isHex(data[5])) { - r = (charToHex(data[0]) << 4) | charToHex(data[1]); - g = (charToHex(data[2]) << 4) | charToHex(data[3]); - b = (charToHex(data[4]) << 4) | charToHex(data[5]); - - *result = (0xff << 24) | (r << 16) | (g << 8) | b; - - return true; - } - - return false; -} - -/** - * Parse a font \@size attribute - * - * \param size Data to parse (NUL-terminated) - * \param val Pointer to location to receive enum value - * \param len Pointer to location to receive length - * \param unit Pointer to location to receive unit - * \return True on success, false on failure - */ -static bool parse_font_size(const char *size, uint8_t *val, - css_fixed *len, css_unit *unit) -{ - static const uint8_t size_map[] = { - CSS_FONT_SIZE_XX_SMALL, - CSS_FONT_SIZE_SMALL, - CSS_FONT_SIZE_MEDIUM, - CSS_FONT_SIZE_LARGE, - CSS_FONT_SIZE_X_LARGE, - CSS_FONT_SIZE_XX_LARGE, - CSS_FONT_SIZE_DIMENSION /* xxx-large (see below) */ - }; - - const char *p = size; - char mode; - int value = 0; - - /* Skip whitespace */ - while (*p != '\0' && isWhitespace(*p)) - p++; - - mode = *p; - - /* Skip +/- */ - if (mode == '+' || mode == '-') - p++; - - /* Need at least one digit */ - if (*p < '0' || *p > '9') { - return false; - } - - /* Consume digits, computing value */ - while ('0' <= *p && *p <= '9') { - value = value * 10 + (*p - '0'); - p++; - } - - /* Resolve relative sizes */ - if (mode == '+') - value += 3; - else if (mode == '-') - value = 3 - value; - - /* Clamp to range [1,7] */ - if (value < 1) - value = 1; - else if (value > 7) - value = 7; - - if (value == 7) { - /* Manufacture xxx-large */ - *len = FDIV(FMUL(INTTOFIX(3), INTTOFIX(nsoption_int(font_size))), - F_10); - } else { - /* Len is irrelevant */ - *len = 0; - } - - *unit = CSS_UNIT_PT; - *val = size_map[value - 1]; - - return true; -} - - -/****************************************************************************** - * Hint context management * - ******************************************************************************/ - -#define MAX_HINTS_PER_ELEMENT 32 - -struct css_hint_ctx { - struct css_hint *hints; - uint32_t len; -}; - -struct css_hint_ctx hint_ctx; - -nserror css_hint_init(void) -{ - hint_ctx.hints = malloc(sizeof(struct css_hint) * - MAX_HINTS_PER_ELEMENT); - if (hint_ctx.hints == NULL) { - return NSERROR_NOMEM; - } - - return NSERROR_OK; -} - -void css_hint_fini(void) -{ - hint_ctx.len = 0; - free(hint_ctx.hints); -} - -static void css_hint_clean(void) -{ - hint_ctx.len = 0; -} - -static inline struct css_hint * css_hint_advance(struct css_hint *hint) -{ - hint_ctx.len++; - assert(hint_ctx.len < MAX_HINTS_PER_ELEMENT); - - return ++hint; -} - -static void css_hint_get_hints(struct css_hint **hints, uint32_t *nhints) -{ - *hints = hint_ctx.hints; - *nhints = hint_ctx.len; -} - - -/****************************************************************************** - * Presentational hint handlers * - ******************************************************************************/ - -static void css_hint_table_cell_border_padding( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - css_qname qs; - dom_string *attr = NULL; - dom_node *tablenode = NULL; - dom_exception exc; - - qs.ns = NULL; - qs.name = lwc_string_ref(corestring_lwc_table); - if (named_ancestor_node(ctx, node, &qs, - (void *)&tablenode) != CSS_OK) { - /* Didn't find, or had error */ - lwc_string_unref(qs.name); - return; - } - lwc_string_unref(qs.name); - - if (tablenode == NULL) { - return; - } - /* No need to unref tablenode, named_ancestor_node does not - * return a reffed node to the CSS - */ - - exc = dom_element_get_attribute(tablenode, - corestring_dom_border, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - uint32_t hint_prop; - css_hint_length hint_length; - - if (parse_dimension( - dom_string_data(attr), false, - &hint_length.value, - &hint_length.unit) && - INTTOFIX(0) != hint_length.value) { - - for (hint_prop = CSS_PROP_BORDER_TOP_STYLE; - hint_prop <= CSS_PROP_BORDER_LEFT_STYLE; - hint_prop++) { - hint->prop = hint_prop; - hint->status = CSS_BORDER_STYLE_INSET; - hint = css_hint_advance(hint); - } - - for (hint_prop = CSS_PROP_BORDER_TOP_WIDTH; - hint_prop <= CSS_PROP_BORDER_LEFT_WIDTH; - hint_prop++) { - hint->prop = hint_prop; - hint->data.length.value = INTTOFIX(1); - hint->data.length.unit = CSS_UNIT_PX; - hint->status = CSS_BORDER_WIDTH_WIDTH; - hint = css_hint_advance(hint); - } - } - dom_string_unref(attr); - } - - exc = dom_element_get_attribute(tablenode, - corestring_dom_bordercolor, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - uint32_t hint_prop; - css_color hint_color; - - if (nscss_parse_colour( - (const char *)dom_string_data(attr), - &hint_color)) { - - for (hint_prop = CSS_PROP_BORDER_TOP_COLOR; - hint_prop <= CSS_PROP_BORDER_LEFT_COLOR; - hint_prop++) { - hint->prop = hint_prop; - hint->data.color = hint_color; - hint->status = CSS_BORDER_COLOR_COLOR; - hint = css_hint_advance(hint); - } - } - dom_string_unref(attr); - } - - exc = dom_element_get_attribute(tablenode, - corestring_dom_cellpadding, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - uint32_t hint_prop; - css_hint_length hint_length; - - if (parse_dimension( - dom_string_data(attr), false, - &hint_length.value, - &hint_length.unit)) { - - for (hint_prop = CSS_PROP_PADDING_TOP; - hint_prop <= CSS_PROP_PADDING_LEFT; - hint_prop++) { - hint->prop = hint_prop; - hint->data.length.value = hint_length.value; - hint->data.length.unit = hint_length.unit; - hint->status = CSS_PADDING_SET; - hint = css_hint_advance(hint); - } - } - dom_string_unref(attr); - } -} - -static void css_hint_vertical_align_table_cells( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *attr = NULL; - dom_exception err; - - err = dom_element_get_attribute(node, - corestring_dom_valign, &attr); - - if (err == DOM_NO_ERR && attr != NULL) { - if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_top)) { - hint->prop = CSS_PROP_VERTICAL_ALIGN; - hint->status = CSS_VERTICAL_ALIGN_TOP; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_middle)) { - hint->prop = CSS_PROP_VERTICAL_ALIGN; - hint->status = CSS_VERTICAL_ALIGN_MIDDLE; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_bottom)) { - hint->prop = CSS_PROP_VERTICAL_ALIGN; - hint->status = CSS_VERTICAL_ALIGN_BOTTOM; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_baseline)) { - hint->prop = CSS_PROP_VERTICAL_ALIGN; - hint->status = CSS_VERTICAL_ALIGN_BASELINE; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } -} - -static void css_hint_vertical_align_replaced( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *attr = NULL; - dom_exception err; - - err = dom_element_get_attribute(node, - corestring_dom_valign, &attr); - - if (err == DOM_NO_ERR && attr != NULL) { - if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_top)) { - hint->prop = CSS_PROP_VERTICAL_ALIGN; - hint->status = CSS_VERTICAL_ALIGN_TOP; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_bottom) || - dom_string_caseless_lwc_isequal(attr, - corestring_lwc_baseline)) { - hint->prop = CSS_PROP_VERTICAL_ALIGN; - hint->status = CSS_VERTICAL_ALIGN_BASELINE; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_texttop)) { - hint->prop = CSS_PROP_VERTICAL_ALIGN; - hint->status = CSS_VERTICAL_ALIGN_TEXT_TOP; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_absmiddle) || - dom_string_caseless_lwc_isequal(attr, - corestring_lwc_abscenter)) { - hint->prop = CSS_PROP_VERTICAL_ALIGN; - hint->status = CSS_VERTICAL_ALIGN_MIDDLE; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } -} - -static void css_hint_text_align_normal( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *align = NULL; - dom_exception err; - - err = dom_element_get_attribute(node, - corestring_dom_align, &align); - if (err == DOM_NO_ERR && align != NULL) { - if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_left)) { - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_LEFT; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_center)) { - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_CENTER; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_right)) { - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_RIGHT; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_justify)) { - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_JUSTIFY; - hint = css_hint_advance(hint); - } - dom_string_unref(align); - } -} - -static void css_hint_text_align_center( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_LIBCSS_CENTER; - hint = css_hint_advance(hint); -} - -static void css_hint_margin_left_right_align_center( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *attr; - dom_exception exc; - - exc = dom_element_get_attribute(node, - corestring_dom_align, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_center) || - dom_string_caseless_lwc_isequal(attr, - corestring_lwc_abscenter) || - dom_string_caseless_lwc_isequal(attr, - corestring_lwc_middle) || - dom_string_caseless_lwc_isequal(attr, - corestring_lwc_absmiddle)) { - hint->prop = CSS_PROP_MARGIN_LEFT; - hint->status = CSS_MARGIN_AUTO; - hint = css_hint_advance(hint); - - hint->prop = CSS_PROP_MARGIN_RIGHT; - hint->status = CSS_MARGIN_AUTO; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } -} - -static void css_hint_text_align_special( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *align = NULL; - dom_exception err; - - err = dom_element_get_attribute(node, - corestring_dom_align, &align); - - if (err == DOM_NO_ERR && align != NULL) { - if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_center)) { - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_LIBCSS_CENTER; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_left)) { - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_LIBCSS_LEFT; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_right)) { - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_LIBCSS_RIGHT; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_justify)) { - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_JUSTIFY; - hint = css_hint_advance(hint); - } - dom_string_unref(align); - } -} - -static void css_hint_text_align_table_special( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_INHERIT_IF_NON_MAGIC; - hint = css_hint_advance(hint); -} - -static void css_hint_margin_hspace_vspace( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *attr = NULL; - dom_exception exc; - - exc = dom_element_get_attribute(node, - corestring_dom_vspace, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - css_hint_length hint_length; - if (parse_dimension( - dom_string_data(attr), false, - &hint_length.value, - &hint_length.unit)) { - hint->prop = CSS_PROP_MARGIN_TOP; - hint->data.length.value = hint_length.value; - hint->data.length.unit = hint_length.unit; - hint->status = CSS_MARGIN_SET; - hint = css_hint_advance(hint); - - hint->prop = CSS_PROP_MARGIN_BOTTOM; - hint->data.length.value = hint_length.value; - hint->data.length.unit = hint_length.unit; - hint->status = CSS_MARGIN_SET; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } - - exc = dom_element_get_attribute(node, - corestring_dom_hspace, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - css_hint_length hint_length; - if (parse_dimension( - dom_string_data(attr), false, - &hint_length.value, - &hint_length.unit)) { - hint->prop = CSS_PROP_MARGIN_LEFT; - hint->data.length.value = hint_length.value; - hint->data.length.unit = hint_length.unit; - hint->status = CSS_MARGIN_SET; - hint = css_hint_advance(hint); - - hint->prop = CSS_PROP_MARGIN_RIGHT; - hint->data.length.value = hint_length.value; - hint->data.length.unit = hint_length.unit; - hint->status = CSS_MARGIN_SET; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } -} - -static void css_hint_margin_left_right_hr( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *attr; - dom_exception exc; - - exc = dom_element_get_attribute(node, - corestring_dom_align, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_left)) { - hint->prop = CSS_PROP_MARGIN_LEFT; - hint->data.length.value = 0; - hint->data.length.unit = CSS_UNIT_PX; - hint->status = CSS_MARGIN_SET; - hint = css_hint_advance(hint); - - hint->prop = CSS_PROP_MARGIN_RIGHT; - hint->status = CSS_MARGIN_AUTO; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_center)) { - hint->prop = CSS_PROP_MARGIN_LEFT; - hint->status = CSS_MARGIN_AUTO; - hint = css_hint_advance(hint); - - hint->prop = CSS_PROP_MARGIN_RIGHT; - hint->status = CSS_MARGIN_AUTO; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_right)) { - hint->prop = CSS_PROP_MARGIN_LEFT; - hint->status = CSS_MARGIN_AUTO; - hint = css_hint_advance(hint); - - hint->prop = CSS_PROP_MARGIN_RIGHT; - hint->data.length.value = 0; - hint->data.length.unit = CSS_UNIT_PX; - hint->status = CSS_MARGIN_SET; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } -} - -static void css_hint_table_spacing_border( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_exception exc; - dom_string *attr = NULL; - - exc = dom_element_get_attribute(node, corestring_dom_border, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - uint32_t hint_prop; - css_hint_length hint_length; - - for (hint_prop = CSS_PROP_BORDER_TOP_STYLE; - hint_prop <= CSS_PROP_BORDER_LEFT_STYLE; - hint_prop++) { - hint->prop = hint_prop; - hint->status = CSS_BORDER_STYLE_OUTSET; - hint = css_hint_advance(hint); - } - - if (parse_dimension( - dom_string_data(attr), false, - &hint_length.value, - &hint_length.unit)) { - - for (hint_prop = CSS_PROP_BORDER_TOP_WIDTH; - hint_prop <= CSS_PROP_BORDER_LEFT_WIDTH; - hint_prop++) { - hint->prop = hint_prop; - hint->data.length.value = hint_length.value; - hint->data.length.unit = hint_length.unit; - hint->status = CSS_BORDER_WIDTH_WIDTH; - hint = css_hint_advance(hint); - } - } - dom_string_unref(attr); - } - - exc = dom_element_get_attribute(node, - corestring_dom_bordercolor, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - uint32_t hint_prop; - css_color hint_color; - - if (nscss_parse_colour( - (const char *)dom_string_data(attr), - &hint_color)) { - - for (hint_prop = CSS_PROP_BORDER_TOP_COLOR; - hint_prop <= CSS_PROP_BORDER_LEFT_COLOR; - hint_prop++) { - hint->prop = hint_prop; - hint->data.color = hint_color; - hint->status = CSS_BORDER_COLOR_COLOR; - hint = css_hint_advance(hint); - } - } - dom_string_unref(attr); - } - - exc = dom_element_get_attribute(node, - corestring_dom_cellspacing, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - if (parse_dimension( - (const char *)dom_string_data(attr), false, - &hint->data.position.h.value, - &hint->data.position.h.unit)) { - hint->prop = CSS_PROP_BORDER_SPACING; - hint->data.position.v = hint->data.position.h; - hint->status = CSS_BORDER_SPACING_SET; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } -} - -static void css_hint_height( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *attr = NULL; - dom_exception err; - - err = dom_element_get_attribute(node, - corestring_dom_height, &attr); - - if (err == DOM_NO_ERR && attr != NULL) { - if (parse_dimension( - (const char *)dom_string_data(attr), false, - &hint->data.length.value, - &hint->data.length.unit)) { - hint->prop = CSS_PROP_HEIGHT; - hint->status = CSS_HEIGHT_SET; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } -} - -static void css_hint_width( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *attr = NULL; - dom_exception err; - - err = dom_element_get_attribute(node, - corestring_dom_width, &attr); - - if (err == DOM_NO_ERR && attr != NULL) { - if (parse_dimension( - (const char *)dom_string_data(attr), false, - &hint->data.length.value, - &hint->data.length.unit)) { - hint->prop = CSS_PROP_WIDTH; - hint->status = CSS_WIDTH_SET; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } -} - -static void css_hint_height_width_textarea( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *attr = NULL; - dom_exception err; - - err = dom_element_get_attribute(node, - corestring_dom_rows, &attr); - - if (err == DOM_NO_ERR && attr != NULL) { - if (parse_dimension( - (const char *)dom_string_data(attr), false, - &hint->data.length.value, - &hint->data.length.unit)) { - hint->prop = CSS_PROP_HEIGHT; - hint->data.length.unit = CSS_UNIT_EM; - hint->status = CSS_HEIGHT_SET; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } - - err = dom_element_get_attribute(node, - corestring_dom_cols, &attr); - - if (err == DOM_NO_ERR && attr != NULL) { - if (parse_dimension( - (const char *)dom_string_data(attr), false, - &hint->data.length.value, - &hint->data.length.unit)) { - hint->prop = CSS_PROP_WIDTH; - hint->data.length.unit = CSS_UNIT_EX; - hint->status = CSS_WIDTH_SET; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } -} - -static void css_hint_width_input( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &(hint_ctx.hints[hint_ctx.len]); - dom_string *attr = NULL; - dom_exception err; - - err = dom_element_get_attribute(node, - corestring_dom_size, &attr); - - if (err == DOM_NO_ERR && attr != NULL) { - if (parse_dimension( - (const char *)dom_string_data(attr), false, - &hint->data.length.value, - &hint->data.length.unit)) { - dom_string *attr2 = NULL; - - err = dom_element_get_attribute(node, - corestring_dom_type, &attr2); - if (err == DOM_NO_ERR) { - - hint->prop = CSS_PROP_WIDTH; - hint->status = CSS_WIDTH_SET; - - if (attr2 == NULL || - dom_string_caseless_lwc_isequal( - attr2, - corestring_lwc_text) || - dom_string_caseless_lwc_isequal( - attr2, - corestring_lwc_search) || - dom_string_caseless_lwc_isequal( - attr2, - corestring_lwc_password) || - dom_string_caseless_lwc_isequal( - attr2, - corestring_lwc_file)) { - hint->data.length.unit = CSS_UNIT_EX; - } - if (attr2 != NULL) { - dom_string_unref(attr2); - } - hint = css_hint_advance(hint); - } - } - dom_string_unref(attr); - } -} - -static void css_hint_anchor_color( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - css_error error; - dom_exception err; - dom_string *color; - dom_node *bodynode = NULL; - - /* find body node */ - css_qname qs; - bool is_visited; - - qs.ns = NULL; - qs.name = lwc_string_ref(corestring_lwc_body); - if (named_ancestor_node(ctx, node, &qs, - (void *)&bodynode) != CSS_OK) { - /* Didn't find, or had error */ - lwc_string_unref(qs.name); - return ; - } - lwc_string_unref(qs.name); - - if (bodynode == NULL) { - return; - } - - error = node_is_visited(ctx, node, &is_visited); - if (error != CSS_OK) - return; - - if (is_visited) { - err = dom_element_get_attribute(bodynode, - corestring_dom_vlink, &color); - } else { - err = dom_element_get_attribute(bodynode, - corestring_dom_link, &color); - } - - if (err == DOM_NO_ERR && color != NULL) { - if (nscss_parse_colour( - (const char *)dom_string_data(color), - &hint->data.color)) { - hint->prop = CSS_PROP_COLOR; - hint->status = CSS_COLOR_COLOR; - hint = css_hint_advance(hint); - } - dom_string_unref(color); - } -} - -static void css_hint_body_color( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_exception err; - dom_string *color; - - err = dom_element_get_attribute(node, corestring_dom_text, &color); - - if (err == DOM_NO_ERR && color != NULL) { - if (nscss_parse_colour( - (const char *)dom_string_data(color), - &hint->data.color)) { - hint->prop = CSS_PROP_COLOR; - hint->status = CSS_COLOR_COLOR; - hint = css_hint_advance(hint); - } - dom_string_unref(color); - } -} - -static void css_hint_color( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_exception err; - dom_string *color; - - err = dom_element_get_attribute(node, corestring_dom_color, &color); - - if (err == DOM_NO_ERR && color != NULL) { - if (nscss_parse_colour( - (const char *)dom_string_data(color), - &hint->data.color)) { - hint->prop = CSS_PROP_COLOR; - hint->status = CSS_COLOR_COLOR; - hint = css_hint_advance(hint); - } - dom_string_unref(color); - } -} - -static void css_hint_font_size( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_exception err; - dom_string *size; - - err = dom_element_get_attribute(node, corestring_dom_size, &size); - if (err == DOM_NO_ERR && size != NULL) { - if (parse_font_size( - (const char *)dom_string_data(size), - &hint->status, - &hint->data.length.value, - &hint->data.length.unit)) { - hint->prop = CSS_PROP_FONT_SIZE; - hint = css_hint_advance(hint); - } - dom_string_unref(size); - } -} - -static void css_hint_float( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_exception err; - dom_string *align; - - err = dom_element_get_attribute(node, corestring_dom_align, &align); - if (err == DOM_NO_ERR && align != NULL) { - if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_left)) { - hint->prop = CSS_PROP_FLOAT; - hint->status = CSS_FLOAT_LEFT; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_right)) { - hint->prop = CSS_PROP_FLOAT; - hint->status = CSS_FLOAT_RIGHT; - hint = css_hint_advance(hint); - } - dom_string_unref(align); - } -} - -static void css_hint_caption_side( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_exception err; - dom_string *align = NULL; - - err = dom_element_get_attribute(node, corestring_dom_align, &align); - if (err == DOM_NO_ERR && align != NULL) { - if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_bottom)) { - hint->prop = CSS_PROP_CAPTION_SIDE; - hint->status = CSS_CAPTION_SIDE_BOTTOM; - hint = css_hint_advance(hint); - } - dom_string_unref(align); - } -} - -static void css_hint_bg_color( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_exception err; - dom_string *bgcolor; - - err = dom_element_get_attribute(node, - corestring_dom_bgcolor, &bgcolor); - if (err == DOM_NO_ERR && bgcolor != NULL) { - if (nscss_parse_colour( - (const char *)dom_string_data(bgcolor), - &hint->data.color)) { - hint->prop = CSS_PROP_BACKGROUND_COLOR; - hint->status = CSS_BACKGROUND_COLOR_COLOR; - hint = css_hint_advance(hint); - } - dom_string_unref(bgcolor); - } -} - -static void css_hint_bg_image( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &(hint_ctx.hints[hint_ctx.len]); - dom_exception err; - dom_string *attr; - - err = dom_element_get_attribute(node, - corestring_dom_background, &attr); - if (err == DOM_NO_ERR && attr != NULL) { - nsurl *url; - nserror error = nsurl_join(ctx->base_url, - (const char *)dom_string_data(attr), &url); - dom_string_unref(attr); - - if (error == NSERROR_OK) { - lwc_string *iurl; - lwc_error lerror = lwc_intern_string(nsurl_access(url), - nsurl_length(url), &iurl); - nsurl_unref(url); - - if (lerror == lwc_error_ok) { - hint->prop = CSS_PROP_BACKGROUND_IMAGE; - hint->data.string = iurl; - hint->status = CSS_BACKGROUND_IMAGE_IMAGE; - hint = css_hint_advance(hint); - } - } - } -} - - -/* Exported function, documeted in css/hints.h */ -css_error node_presentational_hint(void *pw, void *node, - uint32_t *nhints, css_hint **hints) -{ - dom_exception exc; - dom_html_element_type tag_type; - - css_hint_clean(); - - exc = dom_html_element_get_tag_type(node, &tag_type); - if (exc != DOM_NO_ERR) { - tag_type = DOM_HTML_ELEMENT_TYPE__UNKNOWN; - } - - switch (tag_type) { - case DOM_HTML_ELEMENT_TYPE_TH: - case DOM_HTML_ELEMENT_TYPE_TD: - css_hint_width(pw, node); - css_hint_table_cell_border_padding(pw, node); - /* fallthrough */ - case DOM_HTML_ELEMENT_TYPE_TR: - css_hint_height(pw, node); - /* fallthrough */ - case DOM_HTML_ELEMENT_TYPE_THEAD: - case DOM_HTML_ELEMENT_TYPE_TBODY: - case DOM_HTML_ELEMENT_TYPE_TFOOT: - css_hint_text_align_special(pw, node); - /* fallthrough */ - case DOM_HTML_ELEMENT_TYPE_COL: - css_hint_vertical_align_table_cells(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_APPLET: - case DOM_HTML_ELEMENT_TYPE_IMG: - css_hint_margin_hspace_vspace(pw, node); - /* fallthrough */ - case DOM_HTML_ELEMENT_TYPE_EMBED: - case DOM_HTML_ELEMENT_TYPE_IFRAME: - case DOM_HTML_ELEMENT_TYPE_OBJECT: - css_hint_height(pw, node); - css_hint_width(pw, node); - css_hint_vertical_align_replaced(pw, node); - css_hint_float(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_P: - case DOM_HTML_ELEMENT_TYPE_H1: - case DOM_HTML_ELEMENT_TYPE_H2: - case DOM_HTML_ELEMENT_TYPE_H3: - case DOM_HTML_ELEMENT_TYPE_H4: - case DOM_HTML_ELEMENT_TYPE_H5: - case DOM_HTML_ELEMENT_TYPE_H6: - css_hint_text_align_normal(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_CENTER: - css_hint_text_align_center(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_CAPTION: - css_hint_caption_side(pw, node); - /* fallthrough */ - case DOM_HTML_ELEMENT_TYPE_DIV: - css_hint_text_align_special(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_TABLE: - css_hint_text_align_table_special(pw, node); - css_hint_table_spacing_border(pw, node); - css_hint_float(pw, node); - css_hint_margin_left_right_align_center(pw, node); - css_hint_width(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_HR: - css_hint_margin_left_right_hr(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_TEXTAREA: - css_hint_height_width_textarea(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_INPUT: - css_hint_width_input(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_A: - css_hint_anchor_color(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_FONT: - css_hint_font_size(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_BODY: - css_hint_body_color(pw, node); - break; - default: - break; - } - - if (tag_type != DOM_HTML_ELEMENT_TYPE__UNKNOWN) { - css_hint_color(pw, node); - css_hint_bg_color(pw, node); - css_hint_bg_image(pw, node); - } - -#ifdef LOG_STATS - LOG("Properties with hints: %i", hint_ctx.len); -#endif - - css_hint_get_hints(hints, nhints); - - return CSS_OK; -} - diff --git a/css/hints.h b/css/hints.h deleted file mode 100644 index fda1bec7e..000000000 --- a/css/hints.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef NETSURF_CSS_HINTS_H_ -#define NETSURF_CSS_HINTS_H_ - -#include <stdint.h> - -#include "css/css.h" - -nserror css_hint_init(void); -void css_hint_fini(void); - - -/** - * Callback to retrieve presentational hints for a node - * - * \param[in] pw HTML document - * \param[in] node DOM node - * \param[out] nhints number of hints retrived - * \param[out] hints retrived hints - * \return CSS_OK on success, - * CSS_PROPERTY_NOT_SET if there is no hint for the requested property, - * CSS_NOMEM on memory exhaustion. - */ -css_error node_presentational_hint( - void *pw, - void *node, - uint32_t *nhints, - css_hint **hints); - -bool nscss_parse_colour(const char *data, css_color *result); - -#endif diff --git a/css/internal.c b/css/internal.c deleted file mode 100644 index 46c529b03..000000000 --- a/css/internal.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <string.h> - -#include "css/internal.h" - -#include "utils/nsurl.h" - -/** - * URL resolution callback for libcss - * - * \param pw Resolution context - * \param base Base URI - * \param rel Relative URL - * \param abs Pointer to location to receive resolved URL - * \return CSS_OK on success, - * CSS_NOMEM on memory exhaustion, - * CSS_INVALID if resolution failed. - */ -css_error nscss_resolve_url(void *pw, const char *base, - lwc_string *rel, lwc_string **abs) -{ - lwc_error lerror; - nserror error; - nsurl *nsbase; - nsurl *nsabs; - - /* Create nsurl from base */ - /* TODO: avoid this */ - error = nsurl_create(base, &nsbase); - if (error != NSERROR_OK) { - return error == NSERROR_NOMEM ? CSS_NOMEM : CSS_INVALID; - } - - /* Resolve URI */ - error = nsurl_join(nsbase, lwc_string_data(rel), &nsabs); - if (error != NSERROR_OK) { - nsurl_unref(nsbase); - return error == NSERROR_NOMEM ? CSS_NOMEM : CSS_INVALID; - } - - nsurl_unref(nsbase); - - /* Intern it */ - lerror = lwc_intern_string(nsurl_access(nsabs), - nsurl_length(nsabs), abs); - if (lerror != lwc_error_ok) { - *abs = NULL; - nsurl_unref(nsabs); - return lerror == lwc_error_oom ? CSS_NOMEM : CSS_INVALID; - } - - nsurl_unref(nsabs); - - return CSS_OK; -} - diff --git a/css/internal.h b/css/internal.h deleted file mode 100644 index 0344d6b32..000000000 --- a/css/internal.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef NETSURF_CSS_INTERNAL_H_ -#define NETSURF_CSS_INTERNAL_H_ - -#include "css/css.h" - -css_error nscss_resolve_url(void *pw, const char *base, - lwc_string *rel, lwc_string **abs); - -#endif diff --git a/css/select.c b/css/select.c deleted file mode 100644 index a929cf10a..000000000 --- a/css/select.c +++ /dev/null @@ -1,1854 +0,0 @@ -/* - * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <assert.h> -#include <string.h> -#include <strings.h> - -#include "content/urldb.h" -#include "desktop/system_colour.h" -#include "utils/nsoption.h" -#include "utils/corestrings.h" -#include "utils/log.h" - -#include "css/internal.h" -#include "css/hints.h" -#include "css/select.h" - -static css_error node_name(void *pw, void *node, css_qname *qname); -static css_error node_classes(void *pw, void *node, - lwc_string ***classes, uint32_t *n_classes); -static css_error node_id(void *pw, void *node, lwc_string **id); -static css_error named_parent_node(void *pw, void *node, - const css_qname *qname, void **parent); -static css_error named_sibling_node(void *pw, void *node, - const css_qname *qname, void **sibling); -static css_error named_generic_sibling_node(void *pw, void *node, - const css_qname *qname, void **sibling); -static css_error parent_node(void *pw, void *node, void **parent); -static css_error sibling_node(void *pw, void *node, void **sibling); -static css_error node_has_name(void *pw, void *node, - const css_qname *qname, bool *match); -static css_error node_has_class(void *pw, void *node, - lwc_string *name, bool *match); -static css_error node_has_id(void *pw, void *node, - lwc_string *name, bool *match); -static css_error node_has_attribute(void *pw, void *node, - const css_qname *qname, bool *match); -static css_error node_has_attribute_equal(void *pw, void *node, - const css_qname *qname, lwc_string *value, - bool *match); -static css_error node_has_attribute_dashmatch(void *pw, void *node, - const css_qname *qname, lwc_string *value, - bool *match); -static css_error node_has_attribute_includes(void *pw, void *node, - const css_qname *qname, lwc_string *value, - bool *match); -static css_error node_has_attribute_prefix(void *pw, void *node, - const css_qname *qname, lwc_string *value, - bool *match); -static css_error node_has_attribute_suffix(void *pw, void *node, - const css_qname *qname, lwc_string *value, - bool *match); -static css_error node_has_attribute_substring(void *pw, void *node, - const css_qname *qname, lwc_string *value, - bool *match); -static css_error node_is_root(void *pw, void *node, bool *match); -static css_error node_count_siblings(void *pw, void *node, - bool same_name, bool after, int32_t *count); -static css_error node_is_empty(void *pw, void *node, bool *match); -static css_error node_is_link(void *pw, void *node, bool *match); -static css_error node_is_hover(void *pw, void *node, bool *match); -static css_error node_is_active(void *pw, void *node, bool *match); -static css_error node_is_focus(void *pw, void *node, bool *match); -static css_error node_is_enabled(void *pw, void *node, bool *match); -static css_error node_is_disabled(void *pw, void *node, bool *match); -static css_error node_is_checked(void *pw, void *node, bool *match); -static css_error node_is_target(void *pw, void *node, bool *match); -static css_error node_is_lang(void *pw, void *node, - lwc_string *lang, bool *match); -static css_error ua_default_for_property(void *pw, uint32_t property, - css_hint *hint); -static css_error set_libcss_node_data(void *pw, void *node, - void *libcss_node_data); -static css_error get_libcss_node_data(void *pw, void *node, - void **libcss_node_data); - -static css_error nscss_compute_font_size(void *pw, const css_hint *parent, - css_hint *size); - - -/** - * Selection callback table for libcss - */ -static css_select_handler selection_handler = { - CSS_SELECT_HANDLER_VERSION_1, - - node_name, - node_classes, - node_id, - named_ancestor_node, - named_parent_node, - named_sibling_node, - named_generic_sibling_node, - parent_node, - sibling_node, - node_has_name, - node_has_class, - node_has_id, - node_has_attribute, - node_has_attribute_equal, - node_has_attribute_dashmatch, - node_has_attribute_includes, - node_has_attribute_prefix, - node_has_attribute_suffix, - node_has_attribute_substring, - node_is_root, - node_count_siblings, - node_is_empty, - node_is_link, - node_is_visited, - node_is_hover, - node_is_active, - node_is_focus, - node_is_enabled, - node_is_disabled, - node_is_checked, - node_is_target, - node_is_lang, - node_presentational_hint, - ua_default_for_property, - nscss_compute_font_size, - set_libcss_node_data, - get_libcss_node_data -}; - -/** - * 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) { - LOG("Failed creating sheet: %d", error); - return NULL; - } - - error = css_stylesheet_append_data(sheet, data, len); - if (error != CSS_OK && error != CSS_NEEDDATA) { - LOG("failed appending data: %d", error); - css_stylesheet_destroy(sheet); - return NULL; - } - - error = css_stylesheet_data_done(sheet); - if (error != CSS_OK) { - LOG("failed completing parse: %d", error); - css_stylesheet_destroy(sheet); - return NULL; - } - - return sheet; -} - -/* Handler for libcss_node_data, stored as libdom node user data */ -static void nscss_dom_user_data_handler(dom_node_operation operation, - dom_string *key, void *data, struct dom_node *src, - struct dom_node *dst) -{ - css_error error; - - if (dom_string_isequal(corestring_dom___ns_key_libcss_node_data, - key) == false || data == NULL) { - return; - } - - switch (operation) { - case DOM_NODE_CLONED: - error = css_libcss_node_data_handler(&selection_handler, - CSS_NODE_CLONED, - NULL, src, dst, data); - if (error != CSS_OK) - LOG("Failed to clone libcss_node_data."); - break; - - case DOM_NODE_RENAMED: - error = css_libcss_node_data_handler(&selection_handler, - CSS_NODE_MODIFIED, - NULL, src, NULL, data); - if (error != CSS_OK) - LOG("Failed to update libcss_node_data."); - break; - - case DOM_NODE_IMPORTED: - case DOM_NODE_ADOPTED: - case DOM_NODE_DELETED: - error = css_libcss_node_data_handler(&selection_handler, - CSS_NODE_DELETED, - NULL, src, NULL, data); - if (error != CSS_OK) - LOG("Failed to delete libcss_node_data."); - break; - - default: - LOG("User data operation not handled."); - assert(0); - } -} - -/** - * 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_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, NULL, - styles->styles[CSS_PSEUDO_ELEMENT_NONE]); - if (error != CSS_OK) { - css_select_results_destroy(styles); - return NULL; - } - } - - 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, NULL, - styles->styles[pseudo_element]); - if (error != CSS_OK) { - /* TODO: perhaps this shouldn't be quite so - * catastrophic? */ - css_select_results_destroy(styles); - return NULL; - } - } - - return styles; -} - -/** - * Get an initial style - * - * \param ctx CSS selection context - * \return Pointer to partial computed style, or NULL on failure - */ -static css_computed_style *nscss_get_initial_style(nscss_select_ctx *ctx) -{ - css_computed_style *style; - css_error error; - - error = css_computed_style_create(&style); - if (error != CSS_OK) - return NULL; - - error = css_computed_style_initialise(style, &selection_handler, ctx); - if (error != CSS_OK) { - css_computed_style_destroy(style); - return NULL; - } - - return style; -} - -/** - * Get a blank style - * - * \param ctx CSS selection context - * \param parent Parent style to cascade inherited properties from - * \return Pointer to blank style, or NULL on failure - */ -css_computed_style *nscss_get_blank_style(nscss_select_ctx *ctx, - const css_computed_style *parent) -{ - css_computed_style *partial; - css_error error; - - partial = nscss_get_initial_style(ctx); - if (partial == NULL) - return NULL; - - error = css_computed_style_compose(parent, partial, - nscss_compute_font_size, NULL, partial); - if (error != CSS_OK) { - css_computed_style_destroy(partial); - return NULL; - } - - return partial; -} - -/** - * Font size computation callback for libcss - * - * \param pw Computation context - * \param parent Parent font size (absolute) - * \param size Font size to compute - * \return CSS_OK on success - * - * \post \a size will be an absolute font size - */ -css_error nscss_compute_font_size(void *pw, const css_hint *parent, - css_hint *size) -{ - /** - * Table of font-size keyword scale factors - * - * These are multiplied by the configured default font size - * to produce an absolute size for the relevant keyword - */ - static const css_fixed factors[] = { - FLTTOFIX(0.5625), /* xx-small */ - FLTTOFIX(0.6250), /* x-small */ - FLTTOFIX(0.8125), /* small */ - FLTTOFIX(1.0000), /* medium */ - FLTTOFIX(1.1250), /* large */ - FLTTOFIX(1.5000), /* x-large */ - FLTTOFIX(2.0000) /* xx-large */ - }; - css_hint_length parent_size; - - /* Grab parent size, defaulting to medium if none */ - if (parent == NULL) { - parent_size.value = FDIV(FMUL(factors[CSS_FONT_SIZE_MEDIUM - 1], - INTTOFIX(nsoption_int(font_size))), - INTTOFIX(10)); - parent_size.unit = CSS_UNIT_PT; - } else { - assert(parent->status == CSS_FONT_SIZE_DIMENSION); - assert(parent->data.length.unit != CSS_UNIT_EM); - assert(parent->data.length.unit != CSS_UNIT_EX); - assert(parent->data.length.unit != CSS_UNIT_PCT); - - parent_size = parent->data.length; - } - - assert(size->status != CSS_FONT_SIZE_INHERIT); - - if (size->status < CSS_FONT_SIZE_LARGER) { - /* Keyword -- simple */ - size->data.length.value = FDIV(FMUL(factors[size->status - 1], - INTTOFIX(nsoption_int(font_size))), F_10); - size->data.length.unit = CSS_UNIT_PT; - } else if (size->status == CSS_FONT_SIZE_LARGER) { - /** \todo Step within table, if appropriate */ - size->data.length.value = - FMUL(parent_size.value, FLTTOFIX(1.2)); - size->data.length.unit = parent_size.unit; - } else if (size->status == CSS_FONT_SIZE_SMALLER) { - /** \todo Step within table, if appropriate */ - size->data.length.value = - FDIV(parent_size.value, FLTTOFIX(1.2)); - size->data.length.unit = parent_size.unit; - } else if (size->data.length.unit == CSS_UNIT_EM || - size->data.length.unit == CSS_UNIT_EX) { - size->data.length.value = - FMUL(size->data.length.value, parent_size.value); - - if (size->data.length.unit == CSS_UNIT_EX) { - /* 1ex = 0.6em in NetSurf */ - size->data.length.value = FMUL(size->data.length.value, - FLTTOFIX(0.6)); - } - - size->data.length.unit = parent_size.unit; - } else if (size->data.length.unit == CSS_UNIT_PCT) { - size->data.length.value = FDIV(FMUL(size->data.length.value, - parent_size.value), INTTOFIX(100)); - size->data.length.unit = parent_size.unit; - } - - size->status = CSS_FONT_SIZE_DIMENSION; - - return CSS_OK; -} - -/****************************************************************************** - * Style selection callbacks * - ******************************************************************************/ - -/** - * Callback to retrieve a node's name. - * - * \param pw HTML document - * \param node DOM node - * \param qname Pointer to location to receive node name - * \return CSS_OK on success, - * CSS_NOMEM on memory exhaustion. - */ -css_error node_name(void *pw, void *node, css_qname *qname) -{ - dom_node *n = node; - dom_string *name; - dom_exception err; - - err = dom_node_get_node_name(n, &name); - if (err != DOM_NO_ERR) - return CSS_NOMEM; - - qname->ns = NULL; - - err = dom_string_intern(name, &qname->name); - if (err != DOM_NO_ERR) { - dom_string_unref(name); - return CSS_NOMEM; - } - - dom_string_unref(name); - - return CSS_OK; -} - -/** - * Callback to retrieve a node's classes. - * - * \param pw HTML document - * \param node DOM node - * \param classes Pointer to location to receive class name array - * \param n_classes Pointer to location to receive length of class name array - * \return CSS_OK on success, - * CSS_NOMEM on memory exhaustion. - * - * \note The returned array will be destroyed by libcss. Therefore, it must - * be allocated using the same allocator as used by libcss during style - * selection. - */ -css_error node_classes(void *pw, void *node, - lwc_string ***classes, uint32_t *n_classes) -{ - dom_node *n = node; - dom_exception err; - - *classes = NULL; - *n_classes = 0; - - err = dom_element_get_classes(n, classes, n_classes); - if (err != DOM_NO_ERR) - return CSS_NOMEM; - - return CSS_OK; -} - -/** - * Callback to retrieve a node's ID. - * - * \param pw HTML document - * \param node DOM node - * \param id Pointer to location to receive id value - * \return CSS_OK on success, - * CSS_NOMEM on memory exhaustion. - */ -css_error node_id(void *pw, void *node, lwc_string **id) -{ - dom_node *n = node; - dom_string *attr; - dom_exception err; - - *id = NULL; - - /** \todo Assumes an HTML DOM */ - err = dom_html_element_get_id(n, &attr); - if (err != DOM_NO_ERR) - return CSS_NOMEM; - - if (attr != NULL) { - err = dom_string_intern(attr, id); - if (err != DOM_NO_ERR) { - dom_string_unref(attr); - return CSS_NOMEM; - } - dom_string_unref(attr); - } - - return CSS_OK; -} - -/** - * Callback to find a named ancestor node. - * - * \param pw HTML document - * \param node DOM node - * \param qname Node name to search for - * \param ancestor Pointer to location to receive ancestor - * \return CSS_OK. - * - * \post \a ancestor will contain the result, or NULL if there is no match - */ -css_error named_ancestor_node(void *pw, void *node, - const css_qname *qname, void **ancestor) -{ - dom_element_named_ancestor_node(node, qname->name, - (struct dom_element **)ancestor); - - return CSS_OK; -} - -/** - * Callback to find a named parent node - * - * \param pw HTML document - * \param node DOM node - * \param qname Node name to search for - * \param parent Pointer to location to receive parent - * \return CSS_OK. - * - * \post \a parent will contain the result, or NULL if there is no match - */ -css_error named_parent_node(void *pw, void *node, - const css_qname *qname, void **parent) -{ - dom_element_named_parent_node(node, qname->name, - (struct dom_element **)parent); - - return CSS_OK; -} - -/** - * Callback to find a named sibling node. - * - * \param pw HTML document - * \param node DOM node - * \param qname Node name to search for - * \param sibling Pointer to location to receive sibling - * \return CSS_OK. - * - * \post \a sibling will contain the result, or NULL if there is no match - */ -css_error named_sibling_node(void *pw, void *node, - const css_qname *qname, void **sibling) -{ - dom_node *n = node; - dom_node *prev; - dom_exception err; - - *sibling = NULL; - - /* Find sibling element */ - err = dom_node_get_previous_sibling(n, &n); - if (err != DOM_NO_ERR) - return CSS_OK; - - while (n != NULL) { - dom_node_type type; - - err = dom_node_get_node_type(n, &type); - if (err != DOM_NO_ERR) { - dom_node_unref(n); - return CSS_OK; - } - - if (type == DOM_ELEMENT_NODE) - break; - - err = dom_node_get_previous_sibling(n, &prev); - if (err != DOM_NO_ERR) { - dom_node_unref(n); - return CSS_OK; - } - - dom_node_unref(n); - n = prev; - } - - if (n != NULL) { - dom_string *name; - - err = dom_node_get_node_name(n, &name); - if (err != DOM_NO_ERR) { - dom_node_unref(n); - return CSS_OK; - } - - dom_node_unref(n); - - if (dom_string_caseless_lwc_isequal(name, qname->name)) { - *sibling = n; - } - - dom_string_unref(name); - } - - return CSS_OK; -} - -/** - * Callback to find a named generic sibling node. - * - * \param pw HTML document - * \param node DOM node - * \param qname Node name to search for - * \param sibling Pointer to location to receive ancestor - * \return CSS_OK. - * - * \post \a sibling will contain the result, or NULL if there is no match - */ -css_error named_generic_sibling_node(void *pw, void *node, - const css_qname *qname, void **sibling) -{ - dom_node *n = node; - dom_node *prev; - dom_exception err; - - *sibling = NULL; - - err = dom_node_get_previous_sibling(n, &n); - if (err != DOM_NO_ERR) - return CSS_OK; - - while (n != NULL) { - dom_node_type type; - dom_string *name; - - err = dom_node_get_node_type(n, &type); - if (err != DOM_NO_ERR) { - dom_node_unref(n); - return CSS_OK; - } - - if (type == DOM_ELEMENT_NODE) { - err = dom_node_get_node_name(n, &name); - if (err != DOM_NO_ERR) { - dom_node_unref(n); - return CSS_OK; - } - - if (dom_string_caseless_lwc_isequal(name, - qname->name)) { - dom_string_unref(name); - dom_node_unref(n); - *sibling = n; - break; - } - dom_string_unref(name); - } - - err = dom_node_get_previous_sibling(n, &prev); - if (err != DOM_NO_ERR) { - dom_node_unref(n); - return CSS_OK; - } - - dom_node_unref(n); - n = prev; - } - - return CSS_OK; -} - -/** - * Callback to retrieve the parent of a node. - * - * \param pw HTML document - * \param node DOM node - * \param parent Pointer to location to receive parent - * \return CSS_OK. - * - * \post \a parent will contain the result, or NULL if there is no match - */ -css_error parent_node(void *pw, void *node, void **parent) -{ - dom_element_parent_node(node, (struct dom_element **)parent); - - return CSS_OK; -} - -/** - * Callback to retrieve the preceding sibling of a node. - * - * \param pw HTML document - * \param node DOM node - * \param sibling Pointer to location to receive sibling - * \return CSS_OK. - * - * \post \a sibling will contain the result, or NULL if there is no match - */ -css_error sibling_node(void *pw, void *node, void **sibling) -{ - dom_node *n = node; - dom_node *prev; - dom_exception err; - - *sibling = NULL; - - /* Find sibling element */ - err = dom_node_get_previous_sibling(n, &n); - if (err != DOM_NO_ERR) - return CSS_OK; - - while (n != NULL) { - dom_node_type type; - - err = dom_node_get_node_type(n, &type); - if (err != DOM_NO_ERR) { - dom_node_unref(n); - return CSS_OK; - } - - if (type == DOM_ELEMENT_NODE) - break; - - err = dom_node_get_previous_sibling(n, &prev); - if (err != DOM_NO_ERR) { - dom_node_unref(n); - return CSS_OK; - } - - dom_node_unref(n); - n = prev; - } - - if (n != NULL) { - /** \todo Sort out reference counting */ - dom_node_unref(n); - - *sibling = n; - } - - return CSS_OK; -} - -/** - * Callback to determine if a node has the given name. - * - * \param pw HTML document - * \param node DOM node - * \param qname Name to match - * \param match Pointer to location to receive result - * \return CSS_OK. - * - * \post \a match will contain true if the node matches and false otherwise. - */ -css_error node_has_name(void *pw, void *node, - const css_qname *qname, bool *match) -{ - nscss_select_ctx *ctx = pw; - dom_node *n = node; - - if (lwc_string_isequal(qname->name, ctx->universal, match) == - lwc_error_ok && *match == false) { - dom_string *name; - dom_exception err; - - err = dom_node_get_node_name(n, &name); - if (err != DOM_NO_ERR) - return CSS_OK; - - /* Element names are case insensitive in HTML */ - *match = dom_string_caseless_lwc_isequal(name, qname->name); - - dom_string_unref(name); - } - - return CSS_OK; -} - -/** - * Callback to determine if a node has the given class. - * - * \param pw HTML document - * \param node DOM node - * \param name Name to match - * \param match Pointer to location to receive result - * \return CSS_OK. - * - * \post \a match will contain true if the node matches and false otherwise. - */ -css_error node_has_class(void *pw, void *node, - lwc_string *name, bool *match) -{ - dom_node *n = node; - dom_exception err; - - /** \todo: Ensure that libdom performs case-insensitive - * matching in quirks mode */ - err = dom_element_has_class(n, name, match); - - assert(err == DOM_NO_ERR); - - return CSS_OK; -} - -/** - * Callback to determine if a node has the given id. - * - * \param pw HTML document - * \param node DOM node - * \param name Name to match - * \param match Pointer to location to receive result - * \return CSS_OK. - * - * \post \a match will contain true if the node matches and false otherwise. - */ -css_error node_has_id(void *pw, void *node, - lwc_string *name, bool *match) -{ - dom_node *n = node; - dom_string *attr; - dom_exception err; - - *match = false; - - /** \todo Assumes an HTML DOM */ - err = dom_html_element_get_id(n, &attr); - if (err != DOM_NO_ERR) - return CSS_OK; - - if (attr != NULL) { - *match = dom_string_lwc_isequal(attr, name); - - dom_string_unref(attr); - } - - return CSS_OK; -} - -/** - * Callback to determine if a node has an attribute with the given name. - * - * \param pw HTML document - * \param node DOM node - * \param qname Name to match - * \param match Pointer to location to receive result - * \return CSS_OK on success, - * CSS_NOMEM on memory exhaustion. - * - * \post \a match will contain true if the node matches and false otherwise. - */ -css_error node_has_attribute(void *pw, void *node, - const css_qname *qname, bool *match) -{ - dom_node *n = node; - dom_string *name; - dom_exception err; - - err = dom_string_create_interned( - (const uint8_t *) lwc_string_data(qname->name), - lwc_string_length(qname->name), &name); - if (err != DOM_NO_ERR) - return CSS_NOMEM; - - err = dom_element_has_attribute(n, name, match); - if (err != DOM_NO_ERR) { - dom_string_unref(name); - return CSS_OK; - } - - dom_string_unref(name); - - return CSS_OK; -} - -/** - * Callback to determine if a node has an attribute with given name and value. - * - * \param pw HTML document - * \param node DOM node - * \param qname Name to match - * \param value Value to match - * \param match Pointer to location to receive result - * \return CSS_OK on success, - * CSS_NOMEM on memory exhaustion. - * - * \post \a match will contain true if the node matches and false otherwise. - */ -css_error node_has_attribute_equal(void *pw, void *node, - const css_qname *qname, lwc_string *value, - bool *match) -{ - dom_node *n = node; - dom_string *name; - dom_string *atr_val; - dom_exception err; - - size_t vlen = lwc_string_length(value); - - if (vlen == 0) { - *match = false; - return CSS_OK; - } - - err = dom_string_create_interned( - (const uint8_t *) lwc_string_data(qname->name), - lwc_string_length(qname->name), &name); - if (err != DOM_NO_ERR) - return CSS_NOMEM; - - err = dom_element_get_attribute(n, name, &atr_val); - if ((err != DOM_NO_ERR) || (atr_val == NULL)) { - dom_string_unref(name); - *match = false; - return CSS_OK; - } - - dom_string_unref(name); - - *match = dom_string_caseless_lwc_isequal(atr_val, value); - - dom_string_unref(atr_val); - - return CSS_OK; -} - -/** - * Callback to determine if a node has an attribute with the given name whose - * value dashmatches that given. - * - * \param pw HTML document - * \param node DOM node - * \param qname Name to match - * \param value Value to match - * \param match Pointer to location to receive result - * \return CSS_OK on success, - * CSS_NOMEM on memory exhaustion. - * - * \post \a match will contain true if the node matches and false otherwise. - */ -css_error node_has_attribute_dashmatch(void *pw, void *node, - const css_qname *qname, lwc_string *value, - bool *match) -{ - dom_node *n = node; - dom_string *name; - dom_string *atr_val; - dom_exception err; - - size_t vlen = lwc_string_length(value); - - if (vlen == 0) { - *match = false; - return CSS_OK; - } - - err = dom_string_create_interned( - (const uint8_t *) lwc_string_data(qname->name), - lwc_string_length(qname->name), &name); - if (err != DOM_NO_ERR) - return CSS_NOMEM; - - err = dom_element_get_attribute(n, name, &atr_val); - if ((err != DOM_NO_ERR) || (atr_val == NULL)) { - dom_string_unref(name); - *match = false; - return CSS_OK; - } - - dom_string_unref(name); - - /* check for exact match */ - *match = dom_string_caseless_lwc_isequal(atr_val, value); - - /* check for dashmatch */ - if (*match == false) { - const char *vdata = lwc_string_data(value); - const char *data = (const char *) dom_string_data(atr_val); - size_t len = dom_string_byte_length(atr_val); - - if (len > vlen && data[vlen] == '-' && - strncasecmp(data, vdata, vlen) == 0) { - *match = true; - } - } - - dom_string_unref(atr_val); - - return CSS_OK; -} - -/** - * Callback to determine if a node has an attribute with the given name whose - * value includes that given. - * - * \param pw HTML document - * \param node DOM node - * \param qname Name to match - * \param value Value to match - * \param match Pointer to location to receive result - * \return CSS_OK on success, - * CSS_NOMEM on memory exhaustion. - * - * \post \a match will contain true if the node matches and false otherwise. - */ -css_error node_has_attribute_includes(void *pw, void *node, - const css_qname *qname, lwc_string *value, - bool *match) -{ - dom_node *n = node; - dom_string *name; - dom_string *atr_val; - dom_exception err; - size_t vlen = lwc_string_length(value); - const char *p; - const char *start; - const char *end; - - *match = false; - - if (vlen == 0) { - return CSS_OK; - } - - err = dom_string_create_interned( - (const uint8_t *) lwc_string_data(qname->name), - lwc_string_length(qname->name), &name); - if (err != DOM_NO_ERR) - return CSS_NOMEM; - - err = dom_element_get_attribute(n, name, &atr_val); - if ((err != DOM_NO_ERR) || (atr_val == NULL)) { - dom_string_unref(name); - *match = false; - return CSS_OK; - } - - dom_string_unref(name); - - /* check for match */ - start = (const char *) dom_string_data(atr_val); - end = start + dom_string_byte_length(atr_val); - - for (p = start; p <= end; p++) { - if (*p == ' ' || *p == '\0') { - if ((size_t) (p - start) == vlen && - strncasecmp(start, - lwc_string_data(value), - vlen) == 0) { - *match = true; - break; - } - - start = p + 1; - } - } - - dom_string_unref(atr_val); - - return CSS_OK; -} - -/** - * Callback to determine if a node has an attribute with the given name whose - * value has the prefix given. - * - * \param pw HTML document - * \param node DOM node - * \param qname Name to match - * \param value Value to match - * \param match Pointer to location to receive result - * \return CSS_OK on success, - * CSS_NOMEM on memory exhaustion. - * - * \post \a match will contain true if the node matches and false otherwise. - */ -css_error node_has_attribute_prefix(void *pw, void *node, - const css_qname *qname, lwc_string *value, - bool *match) -{ - dom_node *n = node; - dom_string *name; - dom_string *atr_val; - dom_exception err; - - size_t vlen = lwc_string_length(value); - - if (vlen == 0) { - *match = false; - return CSS_OK; - } - - err = dom_string_create_interned( - (const uint8_t *) lwc_string_data(qname->name), - lwc_string_length(qname->name), &name); - if (err != DOM_NO_ERR) - return CSS_NOMEM; - - err = dom_element_get_attribute(n, name, &atr_val); - if ((err != DOM_NO_ERR) || (atr_val == NULL)) { - dom_string_unref(name); - *match = false; - return CSS_OK; - } - - dom_string_unref(name); - - /* check for exact match */ - *match = dom_string_caseless_lwc_isequal(atr_val, value); - - /* check for prefix match */ - if (*match == false) { - const char *data = (const char *) dom_string_data(atr_val); - size_t len = dom_string_byte_length(atr_val); - - if ((len >= vlen) && - (strncasecmp(data, lwc_string_data(value), vlen) == 0)) { - *match = true; - } - } - - dom_string_unref(atr_val); - - return CSS_OK; -} - -/** - * Callback to determine if a node has an attribute with the given name whose - * value has the suffix given. - * - * \param pw HTML document - * \param node DOM node - * \param qname Name to match - * \param value Value to match - * \param match Pointer to location to receive result - * \return CSS_OK on success, - * CSS_NOMEM on memory exhaustion. - * - * \post \a match will contain true if the node matches and false otherwise. - */ -css_error node_has_attribute_suffix(void *pw, void *node, - const css_qname *qname, lwc_string *value, - bool *match) -{ - dom_node *n = node; - dom_string *name; - dom_string *atr_val; - dom_exception err; - - size_t vlen = lwc_string_length(value); - - if (vlen == 0) { - *match = false; - return CSS_OK; - } - - err = dom_string_create_interned( - (const uint8_t *) lwc_string_data(qname->name), - lwc_string_length(qname->name), &name); - if (err != DOM_NO_ERR) - return CSS_NOMEM; - - err = dom_element_get_attribute(n, name, &atr_val); - if ((err != DOM_NO_ERR) || (atr_val == NULL)) { - dom_string_unref(name); - *match = false; - return CSS_OK; - } - - dom_string_unref(name); - - /* check for exact match */ - *match = dom_string_caseless_lwc_isequal(atr_val, value); - - /* check for prefix match */ - if (*match == false) { - const char *data = (const char *) dom_string_data(atr_val); - size_t len = dom_string_byte_length(atr_val); - - const char *start = (char *) data + len - vlen; - - if ((len >= vlen) && - (strncasecmp(start, lwc_string_data(value), vlen) == 0)) { - *match = true; - } - - - } - - dom_string_unref(atr_val); - - return CSS_OK; -} - -/** - * Callback to determine if a node has an attribute with the given name whose - * value contains the substring given. - * - * \param pw HTML document - * \param node DOM node - * \param qname Name to match - * \param value Value to match - * \param match Pointer to location to receive result - * \return CSS_OK on success, - * CSS_NOMEM on memory exhaustion. - * - * \post \a match will contain true if the node matches and false otherwise. - */ -css_error node_has_attribute_substring(void *pw, void *node, - const css_qname *qname, lwc_string *value, - bool *match) -{ - dom_node *n = node; - dom_string *name; - dom_string *atr_val; - dom_exception err; - - size_t vlen = lwc_string_length(value); - - if (vlen == 0) { - *match = false; - return CSS_OK; - } - - err = dom_string_create_interned( - (const uint8_t *) lwc_string_data(qname->name), - lwc_string_length(qname->name), &name); - if (err != DOM_NO_ERR) - return CSS_NOMEM; - - err = dom_element_get_attribute(n, name, &atr_val); - if ((err != DOM_NO_ERR) || (atr_val == NULL)) { - dom_string_unref(name); - *match = false; - return CSS_OK; - } - - dom_string_unref(name); - - /* check for exact match */ - *match = dom_string_caseless_lwc_isequal(atr_val, value); - - /* check for prefix match */ - if (*match == false) { - const char *vdata = lwc_string_data(value); - const char *start = (const char *) dom_string_data(atr_val); - size_t len = dom_string_byte_length(atr_val); - const char *last_start = start + len - vlen; - - if (len >= vlen) { - while (start <= last_start) { - if (strncasecmp(start, vdata, - vlen) == 0) { - *match = true; - break; - } - - start++; - } - } - } - - dom_string_unref(atr_val); - - return CSS_OK; -} - -/** - * Callback to determine if a node is the root node of the document. - * - * \param pw HTML document - * \param node DOM node - * \param match Pointer to location to receive result - * \return CSS_OK. - * - * \post \a match will contain true if the node matches and false otherwise. - */ -css_error node_is_root(void *pw, void *node, bool *match) -{ - dom_node *n = node; - dom_node *parent; - dom_node_type type; - dom_exception err; - - err = dom_node_get_parent_node(n, &parent); - if (err != DOM_NO_ERR) { - return CSS_NOMEM; - } - - if (parent != NULL) { - err = dom_node_get_node_type(parent, &type); - - dom_node_unref(parent); - - if (err != DOM_NO_ERR) - return CSS_NOMEM; - - if (type != DOM_DOCUMENT_NODE) { - *match = false; - return CSS_OK; - } - } - - *match = true; - - return CSS_OK; -} - -static int -node_count_siblings_check(dom_node *node, - bool check_name, - dom_string *name) -{ - dom_node_type type; - int ret = 0; - dom_exception exc; - - if (node == NULL) - return 0; - - exc = dom_node_get_node_type(node, &type); - if ((exc != DOM_NO_ERR) || (type != DOM_ELEMENT_NODE)) { - return 0; - } - - if (check_name) { - dom_string *node_name = NULL; - exc = dom_node_get_node_name(node, &node_name); - - if ((exc == DOM_NO_ERR) && (node_name != NULL)) { - - if (dom_string_caseless_isequal(name, - node_name)) { - ret = 1; - } - dom_string_unref(node_name); - } - } else { - ret = 1; - } - - return ret; -} - -/** - * Callback to count a node's siblings. - * - * \param pw HTML document - * \param n DOM node - * \param same_name Only count siblings with the same name, or all - * \param after Count anteceding instead of preceding siblings - * \param count Pointer to location to receive result - * \return CSS_OK. - * - * \post \a count will contain the number of siblings - */ -css_error node_count_siblings(void *pw, void *n, bool same_name, - bool after, int32_t *count) -{ - int32_t cnt = 0; - dom_exception exc; - dom_string *node_name = NULL; - - if (same_name) { - dom_node *node = n; - exc = dom_node_get_node_name(node, &node_name); - if ((exc != DOM_NO_ERR) || (node_name == NULL)) { - return CSS_NOMEM; - } - } - - if (after) { - dom_node *node = dom_node_ref(n); - dom_node *next; - - do { - exc = dom_node_get_next_sibling(node, &next); - if ((exc != DOM_NO_ERR)) - break; - - dom_node_unref(node); - node = next; - - cnt += node_count_siblings_check(node, same_name, node_name); - } while (node != NULL); - } else { - dom_node *node = dom_node_ref(n); - dom_node *next; - - do { - exc = dom_node_get_previous_sibling(node, &next); - if ((exc != DOM_NO_ERR)) - break; - - dom_node_unref(node); - node = next; - - cnt += node_count_siblings_check(node, same_name, node_name); - - } while (node != NULL); - } - - if (node_name != NULL) { - dom_string_unref(node_name); - } - - *count = cnt; - return CSS_OK; -} - -/** - * Callback to determine if a node is empty. - * - * \param pw HTML document - * \param node DOM node - * \param match Pointer to location to receive result - * \return CSS_OK. - * - * \post \a match will contain true if the node is empty and false otherwise. - */ -css_error node_is_empty(void *pw, void *node, bool *match) -{ - dom_node *n = node, *next; - dom_exception err; - - *match = true; - - err = dom_node_get_first_child(n, &n); - if (err != DOM_NO_ERR) { - return CSS_BADPARM; - } - - while (n != NULL) { - dom_node_type ntype; - err = dom_node_get_node_type(n, &ntype); - if (err != DOM_NO_ERR) { - dom_node_unref(n); - return CSS_BADPARM; - } - - if (ntype == DOM_ELEMENT_NODE || - ntype == DOM_TEXT_NODE) { - *match = false; - dom_node_unref(n); - break; - } - - err = dom_node_get_next_sibling(n, &next); - if (err != DOM_NO_ERR) { - dom_node_unref(n); - return CSS_BADPARM; - } - dom_node_unref(n); - n = next; - } - - return CSS_OK; -} - -/** - * Callback to determine if a node is a linking element. - * - * \param pw HTML document - * \param n DOM node - * \param match Pointer to location to receive result - * \return CSS_OK. - * - * \post \a match will contain true if the node matches and false otherwise. - */ -css_error node_is_link(void *pw, void *n, bool *match) -{ - dom_node *node = n; - dom_exception exc; - dom_string *node_name = NULL; - - exc = dom_node_get_node_name(node, &node_name); - if ((exc != DOM_NO_ERR) || (node_name == NULL)) { - return CSS_NOMEM; - } - - if (dom_string_caseless_lwc_isequal(node_name, corestring_lwc_a)) { - bool has_href; - exc = dom_element_has_attribute(node, corestring_dom_href, - &has_href); - if ((exc == DOM_NO_ERR) && (has_href)) { - *match = true; - } else { - *match = false; - } - } else { - *match = false; - } - dom_string_unref(node_name); - - return CSS_OK; -} - -/** - * Callback to determine if a node is a linking element whose target has been - * visited. - * - * \param pw HTML document - * \param node DOM node - * \param match Pointer to location to receive result - * \return CSS_OK. - * - * \post \a match will contain true if the node matches and false otherwise. - */ -css_error node_is_visited(void *pw, void *node, bool *match) -{ - nscss_select_ctx *ctx = pw; - nsurl *url; - nserror error; - const struct url_data *data; - - dom_exception exc; - dom_node *n = node; - dom_string *s = NULL; - - *match = false; - - exc = dom_node_get_node_name(n, &s); - if ((exc != DOM_NO_ERR) || (s == NULL)) { - return CSS_NOMEM; - } - - if (!dom_string_caseless_lwc_isequal(s, corestring_lwc_a)) { - /* Can't be visited; not ancher element */ - dom_string_unref(s); - return CSS_OK; - } - - /* Finished with node name string */ - dom_string_unref(s); - s = NULL; - - exc = dom_element_get_attribute(n, corestring_dom_href, &s); - if ((exc != DOM_NO_ERR) || (s == NULL)) { - /* Can't be visited; not got a URL */ - return CSS_OK; - } - - /* Make href absolute */ - /* TODO: this duplicates what we do for box->href - * should we put the absolute URL on the dom node? */ - error = nsurl_join(ctx->base_url, dom_string_data(s), &url); - - /* Finished with href string */ - dom_string_unref(s); - - if (error != NSERROR_OK) { - /* Couldn't make nsurl object */ - return CSS_NOMEM; - } - - data = urldb_get_url_data(url); - - /* Visited if in the db and has - * non-zero visit count */ - if (data != NULL && data->visits > 0) - *match = true; - - nsurl_unref(url); - - return CSS_OK; -} - -/** - * Callback to determine if a node is currently being hovered over. - * - * \param pw HTML document - * \param node DOM node - * \param match Pointer to location to receive result - * \return CSS_OK. - * - * \post \a match will contain true if the node matches and false otherwise. - */ -css_error node_is_hover(void *pw, void *node, bool *match) -{ - /** \todo Support hovering */ - - *match = false; - - return CSS_OK; -} - -/** - * Callback to determine if a node is currently activated. - * - * \param pw HTML document - * \param node DOM node - * \param match Pointer to location to receive result - * \return CSS_OK. - * - * \post \a match will contain true if the node matches and false otherwise. - */ -css_error node_is_active(void *pw, void *node, bool *match) -{ - /** \todo Support active nodes */ - - *match = false; - - return CSS_OK; -} - -/** - * Callback to determine if a node has the input focus. - * - * \param pw HTML document - * \param node DOM node - * \param match Pointer to location to receive result - * \return CSS_OK. - * - * \post \a match will contain true if the node matches and false otherwise. - */ -css_error node_is_focus(void *pw, void *node, bool *match) -{ - /** \todo Support focussed nodes */ - - *match = false; - - return CSS_OK; -} - -/** - * Callback to determine if a node is enabled. - * - * \param pw HTML document - * \param node DOM node - * \param match Pointer to location to receive result - * \return CSS_OK. - * - * \post \a match with contain true if the node is enabled and false otherwise. - */ -css_error node_is_enabled(void *pw, void *node, bool *match) -{ - /** \todo Support enabled nodes */ - - *match = false; - - return CSS_OK; -} - -/** - * Callback to determine if a node is disabled. - * - * \param pw HTML document - * \param node DOM node - * \param match Pointer to location to receive result - * \return CSS_OK. - * - * \post \a match with contain true if the node is disabled and false otherwise. - */ -css_error node_is_disabled(void *pw, void *node, bool *match) -{ - /** \todo Support disabled nodes */ - - *match = false; - - return CSS_OK; -} - -/** - * Callback to determine if a node is checked. - * - * \param pw HTML document - * \param node DOM node - * \param match Pointer to location to receive result - * \return CSS_OK. - * - * \post \a match with contain true if the node is checked and false otherwise. - */ -css_error node_is_checked(void *pw, void *node, bool *match) -{ - /** \todo Support checked nodes */ - - *match = false; - - return CSS_OK; -} - -/** - * Callback to determine if a node is the target of the document URL. - * - * \param pw HTML document - * \param node DOM node - * \param match Pointer to location to receive result - * \return CSS_OK. - * - * \post \a match with contain true if the node matches and false otherwise. - */ -css_error node_is_target(void *pw, void *node, bool *match) -{ - /** \todo Support target */ - - *match = false; - - return CSS_OK; -} - -/** - * Callback to determine if a node has the given language - * - * \param pw HTML document - * \param node DOM node - * \param lang Language specifier to match - * \param match Pointer to location to receive result - * \return CSS_OK. - * - * \post \a match will contain true if the node matches and false otherwise. - */ -css_error node_is_lang(void *pw, void *node, - lwc_string *lang, bool *match) -{ - /** \todo Support languages */ - - *match = false; - - return CSS_OK; -} - -/** - * Callback to retrieve the User-Agent defaults for a CSS property. - * - * \param pw HTML document - * \param property Property to retrieve defaults for - * \param hint Pointer to hint object to populate - * \return CSS_OK on success, - * CSS_INVALID if the property should not have a user-agent default. - */ -css_error ua_default_for_property(void *pw, uint32_t property, css_hint *hint) -{ - if (property == CSS_PROP_COLOR) { - hint->data.color = 0xff000000; - hint->status = CSS_COLOR_COLOR; - } else if (property == CSS_PROP_FONT_FAMILY) { - hint->data.strings = NULL; - switch (nsoption_int(font_default)) { - case PLOT_FONT_FAMILY_SANS_SERIF: - hint->status = CSS_FONT_FAMILY_SANS_SERIF; - break; - case PLOT_FONT_FAMILY_SERIF: - hint->status = CSS_FONT_FAMILY_SERIF; - break; - case PLOT_FONT_FAMILY_MONOSPACE: - hint->status = CSS_FONT_FAMILY_MONOSPACE; - break; - case PLOT_FONT_FAMILY_CURSIVE: - hint->status = CSS_FONT_FAMILY_CURSIVE; - break; - case PLOT_FONT_FAMILY_FANTASY: - hint->status = CSS_FONT_FAMILY_FANTASY; - break; - } - } else if (property == CSS_PROP_QUOTES) { - /** \todo Not exactly useful :) */ - hint->data.strings = NULL; - hint->status = CSS_QUOTES_NONE; - } else if (property == CSS_PROP_VOICE_FAMILY) { - /** \todo Fix this when we have voice-family done */ - hint->data.strings = NULL; - hint->status = 0; - } else { - return CSS_INVALID; - } - - return CSS_OK; -} - -css_error set_libcss_node_data(void *pw, void *node, void *libcss_node_data) -{ - dom_node *n = node; - dom_exception err; - void *old_node_data; - - /* Set this node's node data */ - err = dom_node_set_user_data(n, - corestring_dom___ns_key_libcss_node_data, - libcss_node_data, nscss_dom_user_data_handler, - (void *) &old_node_data); - if (err != DOM_NO_ERR) { - return CSS_NOMEM; - } - - assert(old_node_data == NULL); - - return CSS_OK; -} - -css_error get_libcss_node_data(void *pw, void *node, void **libcss_node_data) -{ - dom_node *n = node; - dom_exception err; - - /* Get this node's node data */ - err = dom_node_get_user_data(n, - corestring_dom___ns_key_libcss_node_data, - libcss_node_data); - if (err != DOM_NO_ERR) { - return CSS_NOMEM; - } - - return CSS_OK; -} diff --git a/css/select.h b/css/select.h deleted file mode 100644 index 0e0be9578..000000000 --- a/css/select.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef NETSURF_CSS_SELECT_H_ -#define NETSURF_CSS_SELECT_H_ - -#include <stdint.h> - -#include <dom/dom.h> - -#include "css/css.h" - -struct content; -struct nsurl; - -/** - * Selection context - */ -typedef struct nscss_select_ctx -{ - css_select_ctx *ctx; - bool quirks; - struct nsurl *base_url; - lwc_string *universal; - const css_computed_style *parent_style; -} nscss_select_ctx; - -css_stylesheet *nscss_create_inline_style(const uint8_t *data, size_t len, - const char *charset, const char *url, bool allow_quirks); - -css_select_results *nscss_get_style(nscss_select_ctx *ctx, dom_node *n, - uint64_t media, const css_stylesheet *inline_style); - -css_computed_style *nscss_get_blank_style(nscss_select_ctx *ctx, - const css_computed_style *parent); - - -css_error named_ancestor_node(void *pw, void *node, - const css_qname *qname, void **ancestor); -css_error node_is_visited(void *pw, void *node, bool *match); - -#endif diff --git a/css/utils.c b/css/utils.c deleted file mode 100644 index 9bf743cac..000000000 --- a/css/utils.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2004 James Bursa <james@netsurf-browser.org> - * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <assert.h> - -#include "css/utils.h" - -#include "utils/nsoption.h" -#include "utils/log.h" - -/** Screen DPI in fixed point units: defaults to 90, which RISC OS uses */ -css_fixed nscss_screen_dpi = F_90; - -/** - * Convert an absolute CSS length to points. - * - * \param length Length to convert - * \param unit Corresponding unit - * \return length in points - */ -css_fixed nscss_len2pt(css_fixed length, css_unit unit) -{ - /* Length must not be relative */ - assert(unit != CSS_UNIT_EM && unit != CSS_UNIT_EX); - - switch (unit) { - /* We assume the screen and any other output has the same dpi */ - /* 1in = DPIpx => 1px = (72/DPI)pt */ - case CSS_UNIT_PX: return FDIV(FMUL(length, F_72), nscss_screen_dpi); - /* 1in = 72pt */ - case CSS_UNIT_IN: return FMUL(length, F_72); - /* 1in = 2.54cm => 1cm = (72/2.54)pt */ - case CSS_UNIT_CM: return FMUL(length, - FDIV(F_72, FLTTOFIX(2.54))); - /* 1in = 25.4mm => 1mm = (72/25.4)pt */ - case CSS_UNIT_MM: return FMUL(length, - FDIV(F_72, FLTTOFIX(25.4))); - case CSS_UNIT_PT: return length; - /* 1pc = 12pt */ - case CSS_UNIT_PC: return FMUL(length, INTTOFIX(12)); - default: break; - } - - return 0; -} - - -/** - * Convert a CSS length to pixels. - * - * \param length Length to convert - * \param unit Corresponding unit - * \param style Computed style applying to length. May be NULL if unit is - * neither em nor ex - * \return length in pixels - */ -css_fixed nscss_len2px(css_fixed length, css_unit unit, - const css_computed_style *style) -{ - /* We assume the screen and any other output has the same dpi */ - css_fixed px_per_unit; - - assert(style != NULL || (unit != CSS_UNIT_EM && unit != CSS_UNIT_EX)); - - switch (unit) { - case CSS_UNIT_EM: - case CSS_UNIT_EX: - { - css_fixed font_size = 0; - css_unit font_unit = CSS_UNIT_PT; - - css_computed_font_size(style, &font_size, &font_unit); - - /* Convert to points */ - font_size = nscss_len2pt(font_size, font_unit); - - /* Clamp to configured minimum */ - if (font_size < FDIV(INTTOFIX(nsoption_int(font_min_size)), F_10)) { - font_size = FDIV(INTTOFIX(nsoption_int(font_min_size)), F_10); - } - - /* Convert to pixels (manually, to maximise precision) - * 1in = 72pt => 1pt = (DPI/72)px */ - px_per_unit = FDIV(FMUL(font_size, nscss_screen_dpi), F_72); - - /* Scale ex units: we use a fixed ratio of 1ex = 0.6em */ - if (unit == CSS_UNIT_EX) - px_per_unit = FMUL(px_per_unit, FLTTOFIX(0.6)); - } - break; - case CSS_UNIT_PX: - px_per_unit = F_1; - break; - /* 1in = DPIpx */ - case CSS_UNIT_IN: - px_per_unit = nscss_screen_dpi; - break; - /* 1in = 2.54cm => 1cm = (DPI/2.54)px */ - case CSS_UNIT_CM: - px_per_unit = FDIV(nscss_screen_dpi, FLTTOFIX(2.54)); - break; - /* 1in = 25.4mm => 1mm = (DPI/25.4)px */ - case CSS_UNIT_MM: - px_per_unit = FDIV(nscss_screen_dpi, FLTTOFIX(25.4)); - break; - /* 1in = 72pt => 1pt = (DPI/72)px */ - case CSS_UNIT_PT: - px_per_unit = FDIV(nscss_screen_dpi, F_72); - break; - /* 1pc = 12pt => 1in = 6pc => 1pc = (DPI/6)px */ - case CSS_UNIT_PC: - px_per_unit = FDIV(nscss_screen_dpi, INTTOFIX(6)); - break; - default: - px_per_unit = 0; - break; - } - - /* Ensure we round px_per_unit to the nearest whole number of pixels: - * the use of FIXTOINT() below will truncate. */ - px_per_unit += F_0_5; - - /* Calculate total number of pixels */ - return FMUL(length, TRUNCATEFIX(px_per_unit)); -} - diff --git a/css/utils.h b/css/utils.h deleted file mode 100644 index e9650db97..000000000 --- a/css/utils.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef NETSURF_CSS_UTILS_H_ -#define NETSURF_CSS_UTILS_H_ - -#include "css/css.h" -#include "desktop/plot_style.h" - -/* DPI of the screen, in fixed point units */ -extern css_fixed nscss_screen_dpi; - -/** - * Convert a CSS color to a NetSurf colour primitive - * - * ARGB -> (1-A)BGR - * - * \param c The CSS color to convert - * \return Corresponding NetSurf colour primitive - */ -#define nscss_color_to_ns(c) \ - ( ((~c) & 0xff000000) | \ - ((( c) & 0xff0000 ) >> 16) | \ - (( c) & 0xff00 ) | \ - ((( c) & 0xff ) << 16)) - - -/** - * Convert a NetSurf color to a CSS colour primitive - * - * (1-A)BGR -> ARGB - * - * \param c The NetSurf color to convert - * \return Corresponding CSS colour primitive - */ -#define ns_color_to_nscss(c) \ - ( ((~c) & 0xff000000) | \ - ((( c) & 0xff0000 ) >> 16) | \ - (( c) & 0xff00 ) | \ - ((( c) & 0xff ) << 16)) - -/** - * Determine if a CSS color primitive is transparent - * - * \param color The CSS color to consider - * \return True if the color is transparent, false otherwise - */ -#define nscss_color_is_transparent(color) \ - (((color) >> 24) == 0) - -css_fixed nscss_len2pt(css_fixed length, css_unit unit); -css_fixed nscss_len2px(css_fixed length, css_unit unit, - const css_computed_style *style); - -#endif |