1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-09-27 02:56:18 -04:00

[css] Removed css2 (xml code)

This commit is contained in:
Witold Filipczyk 2023-05-05 20:23:40 +02:00
parent 946c2e11f6
commit 6da8ab303f
19 changed files with 649 additions and 6859 deletions

View File

@ -3,7 +3,6 @@ include $(top_builddir)/Makefile.config
SUBDIRS-$(CONFIG_CSS) += css
SUBDIRS-$(CONFIG_DOM) += dom
SUBDIRS-$(CONFIG_LIBCSS) += css2
SUBDIRS-$(CONFIG_LIBDOM) += libdom
SUBDIRS = gemini html plain

View File

@ -1,6 +0,0 @@
top_builddir=../../..
include $(top_builddir)/Makefile.config
OBJS = css.obj
include $(top_srcdir)/Makefile.lib

View File

@ -1,831 +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 "utils/errors.h"
#include "utils/corestrings.h"
#include "utils/utils.h"
#include "utils/http.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "content/content_protected.h"
#include "content/content_factory.h"
#include "content/fetch.h"
#include "content/hlcache.h"
#include "desktop/system_colour.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_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);
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;
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) {
content_broadcast_error(&result->base, NSERROR_NOMEM, NULL);
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(&params, &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
*/
static bool
nscss_process_data(struct content *c, const char *data, unsigned int size)
{
nscss_content *css = (nscss_content *) c;
css_error error;
error = nscss_process_css_data(&css->data, data, size);
if (error != CSS_OK && error != CSS_NEEDDATA) {
content_broadcast_error(c, NSERROR_CSS, NULL);
}
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;
css_error error;
error = nscss_convert_css_data(&css->data);
if (error != CSS_OK) {
content_broadcast_error(c, NSERROR_CSS, NULL);
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) {
NSLOG(netsurf, INFO, "Failed converting %p %s (%d)",
c, url, error);
} else {
NSLOG(netsurf, INFO, "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 uint8_t *data;
size_t 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,
(char *)data,
(unsigned int)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;
}
/* exported interface documented in netsurf/css.h */
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;
}
/* exported interface documented in netsurf/css.h */
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)
{
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) {
content_broadcast_error(c, NSERROR_CSS, NULL);
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
* \return CSS_OK on success, appropriate error otherwise
*/
css_error nscss_handle_import(void *pw, css_stylesheet *parent,
lwc_string *url)
{
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 */
/** \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
NSLOG(netsurf, INFO, "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
NSLOG(netsurf, INFO, "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
NSLOG(netsurf, INFO, "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(&params, &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,
};
/* exported interface documented in netsurf/css.h */
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;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,30 +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_
/**
* 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);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,55 +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 <libcss/libcss.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 retrieved
* \param[out] hints retrieved 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);
/**
* 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);
#endif

View File

@ -1,63 +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 <libcss/libcss.h>
#include "utils/nsurl.h"
#include "css/internal.h"
/* exported interface documented in content/handlers/css/internal.h */
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;
}

View File

@ -1,35 +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_
/**
* 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);
#endif

View File

@ -1 +0,0 @@
srcs += files('css.cpp')

View File

@ -1,59 +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 <libcss/libcss.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 *root_style;
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,
const css_media *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

View File

@ -1,259 +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 "utils/nsoption.h"
#include "utils/log.h"
#include "css/utils.h"
/** Screen DPI in fixed point units: defaults to 90, which RISC OS uses */
css_fixed nscss_screen_dpi = F_90;
/** Medium screen density for device viewing distance. */
css_fixed nscss_baseline_pixel_density = F_96;
/**
* Map viewport-relative length units to either vh or vw.
*
* Non-viewport-relative units are unchanged.
*
* \param[in] ctx Length conversion context.
* \param[in] unit Unit to map.
* \return the mapped unit.
*/
static inline css_unit css_utils__fudge_viewport_units(
const nscss_len_ctx *ctx,
css_unit unit)
{
switch (unit) {
case CSS_UNIT_VI:
assert(ctx->root_style != NULL);
if (css_computed_writing_mode(ctx->root_style) ==
CSS_WRITING_MODE_HORIZONTAL_TB) {
unit = CSS_UNIT_VW;
} else {
unit = CSS_UNIT_VH;
}
break;
case CSS_UNIT_VB:
assert(ctx->root_style != NULL);
if (css_computed_writing_mode(ctx->root_style) ==
CSS_WRITING_MODE_HORIZONTAL_TB) {
unit = CSS_UNIT_VH;
} else {
unit = CSS_UNIT_VW;
}
break;
case CSS_UNIT_VMIN:
if (ctx->vh < ctx->vw) {
unit = CSS_UNIT_VH;
} else {
unit = CSS_UNIT_VW;
}
break;
case CSS_UNIT_VMAX:
if (ctx->vh > ctx->vw) {
unit = CSS_UNIT_VH;
} else {
unit = CSS_UNIT_VW;
}
break;
default: break;
}
return unit;
}
/* exported interface documented in content/handlers/css/utils.h */
css_fixed nscss_len2pt(
const nscss_len_ctx *ctx,
css_fixed length,
css_unit unit)
{
/* Length must not be relative */
assert(unit != CSS_UNIT_EM &&
unit != CSS_UNIT_EX &&
unit != CSS_UNIT_CAP &&
unit != CSS_UNIT_CH &&
unit != CSS_UNIT_IC &&
unit != CSS_UNIT_REM &&
unit != CSS_UNIT_RLH);
unit = css_utils__fudge_viewport_units(ctx, unit);
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), F_96);
/* 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)));
/* 1in = 101.6q => 1mm = (72/101.6)pt */
case CSS_UNIT_Q: return FMUL(length,
FDIV(F_72, FLTTOFIX(101.6)));
case CSS_UNIT_PT: return length;
/* 1pc = 12pt */
case CSS_UNIT_PC: return FMUL(length, INTTOFIX(12));
case CSS_UNIT_VH: return FDIV(FMUL(FDIV(FMUL(length, ctx->vh), F_100), F_72), F_96);
case CSS_UNIT_VW: return FDIV(FMUL(FDIV(FMUL(length,ctx->vw), F_100), F_72), F_96);
default: break;
}
return 0;
}
/* exported interface documented in content/handlers/css/utils.h */
css_fixed nscss_len2px(
const nscss_len_ctx *ctx,
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;
unit = css_utils__fudge_viewport_units(ctx, unit);
switch (unit) {
case CSS_UNIT_EM:
case CSS_UNIT_EX:
case CSS_UNIT_CAP:
case CSS_UNIT_CH:
case CSS_UNIT_IC:
{
css_fixed font_size = 0;
css_unit font_unit = CSS_UNIT_PT;
assert(style != NULL);
css_computed_font_size(style, &font_size, &font_unit);
/* Convert to points */
font_size = nscss_len2pt(ctx, 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, F_96), F_72);
/* Scale non-em units to em. We have fixed ratios. */
switch (unit) {
case CSS_UNIT_EX:
px_per_unit = FMUL(px_per_unit, FLTTOFIX(0.6));
break;
case CSS_UNIT_CAP:
px_per_unit = FMUL(px_per_unit, FLTTOFIX(0.9));
break;
case CSS_UNIT_CH:
px_per_unit = FMUL(px_per_unit, FLTTOFIX(0.4));
break;
case CSS_UNIT_IC:
px_per_unit = FMUL(px_per_unit, FLTTOFIX(1.1));
break;
default: break;
}
}
break;
case CSS_UNIT_PX:
px_per_unit = F_1;
break;
/* 1in = 96 CSS pixels */
case CSS_UNIT_IN:
px_per_unit = F_96;
break;
/* 1in = 2.54cm => 1cm = (DPI/2.54)px */
case CSS_UNIT_CM:
px_per_unit = FDIV(F_96, FLTTOFIX(2.54));
break;
/* 1in = 25.4mm => 1mm = (DPI/25.4)px */
case CSS_UNIT_MM:
px_per_unit = FDIV(F_96, FLTTOFIX(25.4));
break;
/* 1in = 101.6q => 1q = (DPI/101.6)px */
case CSS_UNIT_Q:
px_per_unit = FDIV(F_96, FLTTOFIX(101.6));
break;
/* 1in = 72pt => 1pt = (DPI/72)px */
case CSS_UNIT_PT:
px_per_unit = FDIV(F_96, F_72);
break;
/* 1pc = 12pt => 1in = 6pc => 1pc = (DPI/6)px */
case CSS_UNIT_PC:
px_per_unit = FDIV(F_96, INTTOFIX(6));
break;
case CSS_UNIT_REM:
{
css_fixed font_size = 0;
css_unit font_unit = CSS_UNIT_PT;
assert(ctx->root_style != NULL);
css_computed_font_size(ctx->root_style,
&font_size, &font_unit);
/* Convert to points */
font_size = nscss_len2pt(ctx, 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, F_96), F_72);
break;
}
/* 1rlh = <user_font_size>pt => 1rlh = (DPI/user_font_size)px */
case CSS_UNIT_RLH:
px_per_unit = FDIV(F_96, FDIV(
INTTOFIX(nsoption_int(font_size)),
INTTOFIX(10)));
break;
case CSS_UNIT_VH:
px_per_unit = FDIV(ctx->vh, F_100);
break;
case CSS_UNIT_VW:
px_per_unit = FDIV(ctx->vw, F_100);
break;
default:
px_per_unit = 0;
break;
}
px_per_unit = nscss_pixels_css_to_physical(px_per_unit);
/* 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));
}

View File

@ -1,176 +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 <libcss/libcss.h>
#include "netsurf/css.h"
/** DPI of the screen, in fixed point units */
extern css_fixed nscss_screen_dpi;
/** Medium screen density for device viewing distance. */
extern css_fixed nscss_baseline_pixel_density;
/**
* Length conversion context data.
*/
typedef struct nscss_len_ctx {
/**
* Viewport width in px.
* Only used if unit is vh, vw, vi, vb, vmin, or vmax.
*/
int vw;
/**
* Viewport height in px.
* Only used if unit is vh, vw, vi, vb, vmin, or vmax.
*/
int vh;
/**
* Computed style for the document root element.
* May be NULL if unit is not rem, or rlh.
*/
const css_computed_style *root_style;
} nscss_len_ctx;
/**
* Convert an absolute CSS length to points.
*
* \param[in] ctx Length conversion context.
* \param[in] length Absolute CSS length.
* \param[in] unit Unit of the length.
* \return length in points
*/
css_fixed nscss_len2pt(
const nscss_len_ctx *ctx,
css_fixed length,
css_unit unit);
/**
* Convert a CSS length to pixels.
*
* \param[in] ctx Length conversion context.
* \param[in] length Length to convert.
* \param[in] unit Corresponding unit.
* \param[in] style Computed style applying to length.
* May be NULL if unit is not em, ex, cap, ch, or ic.
* \return length in pixels
*/
css_fixed nscss_len2px(
const nscss_len_ctx *ctx,
css_fixed length,
css_unit unit,
const css_computed_style *style);
/**
* Convert css pixels to physical pixels.
*
* \param[in] css_pixels Length in css pixels.
* \return length in physical pixels
*/
static inline css_fixed nscss_pixels_css_to_physical(
css_fixed css_pixels)
{
return FDIV(FMUL(css_pixels, nscss_screen_dpi),
nscss_baseline_pixel_density);
}
/**
* Convert physical pixels to css pixels.
*
* \param[in] physical_pixels Length in physical pixels.
* \return length in css pixels
*/
static inline css_fixed nscss_pixels_physical_to_css(
css_fixed physical_pixels)
{
return FDIV(FMUL(physical_pixels, nscss_baseline_pixel_density),
nscss_screen_dpi);
}
/**
* Temporary helper wrappers for for libcss computed style getter, while
* we don't support flexbox related property values.
*/
static inline uint8_t ns_computed_display(
const css_computed_style *style, bool root)
{
uint8_t value = css_computed_display(style, root);
if (value == CSS_DISPLAY_FLEX) {
return CSS_DISPLAY_BLOCK;
} else if (value == CSS_DISPLAY_INLINE_FLEX) {
return CSS_DISPLAY_INLINE_BLOCK;
}
return value;
}
static inline uint8_t ns_computed_display_static(
const css_computed_style *style)
{
uint8_t value = css_computed_display_static(style);
if (value == CSS_DISPLAY_FLEX) {
return CSS_DISPLAY_BLOCK;
} else if (value == CSS_DISPLAY_INLINE_FLEX) {
return CSS_DISPLAY_INLINE_BLOCK;
}
return value;
}
static inline uint8_t ns_computed_min_height(
const css_computed_style *style,
css_fixed *length, css_unit *unit)
{
uint8_t value = css_computed_min_height(style, length, unit);
if (value == CSS_MIN_HEIGHT_AUTO) {
value = CSS_MIN_HEIGHT_SET;
*length = 0;
*unit = CSS_UNIT_PX;
}
return value;
}
static inline uint8_t ns_computed_min_width(
const css_computed_style *style,
css_fixed *length, css_unit *unit)
{
uint8_t value = css_computed_min_width(style, length, unit);
if (value == CSS_MIN_WIDTH_AUTO) {
value = CSS_MIN_WIDTH_SET;
*length = 0;
*unit = CSS_UNIT_PX;
}
return value;
}
#endif

View File

@ -51,7 +51,7 @@
#ifdef CONFIG_LIBCSS
#include <libcss/libcss.h>
#include "document/css2/css.h"
#include "document/libdom/css.h"
#endif
/* TODO: This needs rewrite. Yes, no kidding. */

View File

@ -17,7 +17,7 @@
#include "document/css/css.h"
#include "document/css/parser.h"
#ifdef CONFIG_LIBCSS
#include "document/css2/css.h"
#include "document/libdom/css.h"
#endif
#include "document/html/parser/forms.h"
#include "document/html/parser/general.h"

View File

@ -1,36 +1,23 @@
/*
* 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/>.
*/
/* CSS */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <assert.h>
#include <string.h>
#include <strings.h>
#include "elinks.h"
#include "utils/nsoption.h"
#include "utils/corestrings.h"
#include "utils/log.h"
#include "utils/nsurl.h"
#include "netsurf/plot_style.h"
#include "netsurf/url_db.h"
#include "desktop/system_colour.h"
#include <stdio.h>
#include <dom/dom.h>
#include <dom/bindings/hubbub/parser.h>
#include <libcss/libcss.h>
#include "css/internal.h"
#include "css/hints.h"
#include "css/select.h"
#include "cache/cache.h"
#include "document/html/internal.h"
#include "document/libdom/css.h"
#include "document/libdom/mapa.h"
#include "document/libdom/corestrings.h"
#include "util/string.h"
#define UNUSED(a)
static css_error node_name(void *pw, void *node, css_qname *qname);
static css_error node_classes(void *pw, void *node,
@ -91,9 +78,110 @@ static css_error set_libcss_node_data(void *pw, void *node,
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,
static css_error compute_font_size(void *pw, const css_hint *parent,
css_hint *size);
static css_error named_ancestor_node(void *pw, void *node,
const css_qname *qname, void **ancestor);
static css_error node_is_visited(void *pw, void *node, bool *match);
static css_error node_presentational_hint(void *pw, void *node,
uint32_t *nhints, css_hint **hints);
static css_error node_presentational_hint(void *pw, void *node,
uint32_t *nhints, css_hint **hints)
{
//fprintf(stderr, "%s: node=%s\n", __FUNCTION__, node);
// UNUSED(pw);
// UNUSED(node);
*nhints = 0;
*hints = NULL;
return CSS_OK;
}
css_error
resolve_url(void *pw, const char *base, lwc_string *rel, lwc_string **abs)
{
// fprintf(stderr, "resolve_url: base=%s\n", base);
// fprintf(stderr, "rel=%s\n", lwc_string_data(rel));
lwc_error lerror;
char *url = straconcat(base, lwc_string_data(rel), NULL);
if (!url) {
*abs = NULL;
return CSS_NOMEM;
}
lerror = lwc_intern_string(url, strlen(url), abs);
if (lerror != lwc_error_ok) {
*abs = NULL;
return lerror == lwc_error_oom ? CSS_NOMEM : CSS_INVALID;
}
// fprintf(stderr, "abs=%s\n", lwc_string_data(*abs));
return CSS_OK;
}
/**
* 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 = resolve_url;
params.resolve_pw = NULL;
params.import = NULL;
params.import_pw = NULL;
params.color = NULL;// ns_system_colour;
params.color_pw = NULL;
params.font = NULL;
params.font_pw = NULL;
error = css_stylesheet_create(&params, &sheet);
if (error != CSS_OK) {
fprintf(stderr, "Failed creating sheet: %d", error);
return NULL;
}
error = css_stylesheet_append_data(sheet, data, len);
if (error != CSS_OK && error != CSS_NEEDDATA) {
fprintf(stderr, "failed appending data: %d", error);
css_stylesheet_destroy(sheet);
return NULL;
}
error = css_stylesheet_data_done(sheet);
if (error != CSS_OK) {
fprintf(stderr, "failed completing parse: %d", error);
css_stylesheet_destroy(sheet);
return NULL;
}
return sheet;
}
/**
* Selection callback table for libcss
@ -135,66 +223,11 @@ static css_select_handler selection_handler = {
node_is_lang,
node_presentational_hint,
ua_default_for_property,
nscss_compute_font_size,
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(&params, &sheet);
if (error != CSS_OK) {
NSLOG(netsurf, INFO, "Failed creating sheet: %d", error);
return NULL;
}
error = css_stylesheet_append_data(sheet, data, len);
if (error != CSS_OK && error != CSS_NEEDDATA) {
NSLOG(netsurf, INFO, "failed appending data: %d", error);
css_stylesheet_destroy(sheet);
return NULL;
}
error = css_stylesheet_data_done(sheet);
if (error != CSS_OK) {
NSLOG(netsurf, INFO, "failed completing parse: %d", error);
css_stylesheet_destroy(sheet);
return NULL;
}
return sheet;
}
/* Handler for libcss_node_data, stored as libdom node user data */
static void nscss_dom_user_data_handler(dom_node_operation operation,
@ -214,7 +247,7 @@ static void nscss_dom_user_data_handler(dom_node_operation operation,
CSS_NODE_CLONED,
NULL, src, dst, data);
if (error != CSS_OK)
NSLOG(netsurf, INFO,
fprintf(stderr,
"Failed to clone libcss_node_data.");
break;
@ -223,7 +256,7 @@ static void nscss_dom_user_data_handler(dom_node_operation operation,
CSS_NODE_MODIFIED,
NULL, src, NULL, data);
if (error != CSS_OK)
NSLOG(netsurf, INFO,
fprintf(stderr,
"Failed to update libcss_node_data.");
break;
@ -234,12 +267,12 @@ static void nscss_dom_user_data_handler(dom_node_operation operation,
CSS_NODE_DELETED,
NULL, src, NULL, data);
if (error != CSS_OK)
NSLOG(netsurf, INFO,
fprintf(stderr,
"Failed to delete libcss_node_data.");
break;
default:
NSLOG(netsurf, INFO, "User data operation not handled.");
fprintf(stderr, "User data operation not handled.");
assert(0);
}
}
@ -278,7 +311,7 @@ css_select_results *nscss_get_style(nscss_select_ctx *ctx, dom_node *n,
* element's style */
error = css_computed_style_compose(ctx->parent_style,
styles->styles[CSS_PSEUDO_ELEMENT_NONE],
nscss_compute_font_size, ctx,
compute_font_size, ctx,
&composed);
if (error != CSS_OK) {
css_select_results_destroy(styles);
@ -310,7 +343,7 @@ css_select_results *nscss_get_style(nscss_select_ctx *ctx, dom_node *n,
error = css_computed_style_compose(
styles->styles[CSS_PSEUDO_ELEMENT_NONE],
styles->styles[pseudo_element],
nscss_compute_font_size, ctx,
compute_font_size, ctx,
&composed);
if (error != CSS_OK) {
/* TODO: perhaps this shouldn't be quite so
@ -349,7 +382,7 @@ css_computed_style *nscss_get_blank_style(nscss_select_ctx *ctx,
/* TODO: Do we really need to compose? Initial style shouldn't
* have any inherited properties. */
error = css_computed_style_compose(parent, partial,
nscss_compute_font_size, ctx, &composed);
compute_font_size, ctx, &composed);
css_computed_style_destroy(partial);
if (error != CSS_OK) {
css_computed_style_destroy(composed);
@ -369,118 +402,66 @@ css_computed_style *nscss_get_blank_style(nscss_select_ctx *ctx,
*
* \post \a size will be an absolute font size
*/
css_error nscss_compute_font_size(void *pw, const css_hint *parent,
css_hint *size)
css_error 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 */
#if 0
static css_hint_length sizes[] = {
{ FLTTOFIX(6.75), CSS_UNIT_PT },
{ FLTTOFIX(7.50), CSS_UNIT_PT },
{ FLTTOFIX(9.75), CSS_UNIT_PT },
{ FLTTOFIX(12.0), CSS_UNIT_PT },
{ FLTTOFIX(13.5), CSS_UNIT_PT },
{ FLTTOFIX(18.0), CSS_UNIT_PT },
{ FLTTOFIX(24.0), CSS_UNIT_PT }
};
css_hint_length parent_size;
const css_hint_length *parent_size;
UNUSED(pw);
/* 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;
parent_size = &sizes[CSS_FONT_SIZE_MEDIUM - 1];
} 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;
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;
size->data.length = sizes[size->status - 1];
} 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;
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;
FMUL(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.unit == CSS_UNIT_CAP ||
size->data.length.unit == CSS_UNIT_CH ||
size->data.length.unit == CSS_UNIT_IC) {
size->data.length.unit == CSS_UNIT_EX) {
size->data.length.value =
FMUL(size->data.length.value, parent_size.value);
FMUL(size->data.length.value, parent_size->value);
switch (size->data.length.unit) {
case CSS_UNIT_EX:
/* 1ex = 0.6em in NetSurf */
if (size->data.length.unit == CSS_UNIT_EX) {
size->data.length.value = FMUL(size->data.length.value,
FLTTOFIX(0.6));
break;
case CSS_UNIT_CAP:
/* Height of captals. 1cap = 0.9em in NetSurf. */
size->data.length.value = FMUL(size->data.length.value,
FLTTOFIX(0.9));
break;
case CSS_UNIT_CH:
/* Width of '0'. 1ch = 0.4em in NetSurf. */
size->data.length.value = FMUL(size->data.length.value,
FLTTOFIX(0.4));
break;
case CSS_UNIT_IC:
/* Width of U+6C43. 1ic = 1.1em in NetSurf. */
size->data.length.value = FMUL(size->data.length.value,
FLTTOFIX(1.1));
break;
default:
/* No scaling required for EM. */
break;
}
size->data.length.unit = parent_size.unit;
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;
} else if (size->data.length.unit == CSS_UNIT_REM) {
nscss_select_ctx *ctx = pw;
if (parent == NULL) {
size->data.length.value = parent_size.value;
size->data.length.unit = parent_size.unit;
} else {
css_computed_font_size(ctx->root_style,
&parent_size.value,
&size->data.length.unit);
size->data.length.value = FMUL(
size->data.length.value,
parent_size.value);
}
} else if (size->data.length.unit == CSS_UNIT_RLH) {
/** TODO: Convert root element line-height to absolute value. */
size->data.length.value = FMUL(size->data.length.value, FDIV(
INTTOFIX(nsoption_int(font_size)),
INTTOFIX(10)));
size->data.length.unit = CSS_UNIT_PT;
parent_size->value), FLTTOFIX(100));
size->data.length.unit = parent_size->unit;
}
#endif
size->data.length.unit = CSS_UNIT_EM;
size->data.length.value = FMUL(1, 1);
size->status = CSS_FONT_SIZE_DIMENSION;
return CSS_OK;
@ -1596,6 +1577,7 @@ css_error node_is_link(void *pw, void *n, bool *match)
*/
css_error node_is_visited(void *pw, void *node, bool *match)
{
#if 0
nscss_select_ctx *ctx = pw;
nsurl *url;
nserror error;
@ -1649,7 +1631,8 @@ css_error node_is_visited(void *pw, void *node, bool *match)
*match = true;
nsurl_unref(url);
#endif
*match = false;
return CSS_OK;
}
@ -1818,30 +1801,16 @@ css_error node_is_lang(void *pw, void *node,
*/
css_error ua_default_for_property(void *pw, uint32_t property, css_hint *hint)
{
UNUSED(pw);
if (property == CSS_PROP_COLOR) {
hint->data.color = 0xff000000;
hint->data.color = 0x00000000;
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;
}
hint->status = CSS_FONT_FAMILY_SANS_SERIF;
} else if (property == CSS_PROP_QUOTES) {
/** \todo Not exactly useful :) */
/* Not exactly useful :) */
hint->data.strings = NULL;
hint->status = CSS_QUOTES_NONE;
} else if (property == CSS_PROP_VOICE_FAMILY) {
@ -1890,3 +1859,484 @@ css_error get_libcss_node_data(void *pw, void *node, void **libcss_node_data)
return CSS_OK;
}
static void
apply_color(struct html_context *html_context, struct html_element *html_element, css_color color_shade)
{
if (use_document_fg_colors(html_context->options)) {
html_element->attr.style.color.foreground = color_shade & 0x00ffffff;
}
}
static void
apply_background_color(struct html_context *html_context, struct html_element *html_element, css_color color_shade)
{
if (use_document_bg_colors(html_context->options)) {
html_element->attr.style.color.background = color_shade & 0x00ffffff;
}
}
static void
apply_font_attribute(struct html_context *html_context,
struct html_element *element, bool underline, bool bold)
{
int add = 0;
int rem = 0;
if (underline) {
add |= AT_UNDERLINE;
} else {
rem |= AT_UNDERLINE;
}
if (bold) {
add |= AT_BOLD;
} else {
rem |= AT_BOLD;
}
element->attr.style.attr |= add;
element->attr.style.attr &= ~rem;
}
static void
apply_list_style(struct html_context *html_context, struct html_element *element, uint8_t list_type)
{
element->parattr.list_number = 1;
switch (list_type) {
case CSS_LIST_STYLE_TYPE_DISC:
element->parattr.list_number = 0;
element->parattr.flags = P_DISC;
break;
case CSS_LIST_STYLE_TYPE_CIRCLE:
element->parattr.list_number = 0;
element->parattr.flags = P_O;
break;
case CSS_LIST_STYLE_TYPE_SQUARE:
element->parattr.list_number = 0;
element->parattr.flags = P_SQUARE;
break;
case CSS_LIST_STYLE_TYPE_DECIMAL:
element->parattr.flags = P_NUMBER;
break;
case CSS_LIST_STYLE_TYPE_DECIMAL_LEADING_ZERO:
element->parattr.flags = P_NUMBER;
break;
case CSS_LIST_STYLE_TYPE_LOWER_ALPHA:
element->parattr.flags = P_alpha;
break;
case CSS_LIST_STYLE_TYPE_LOWER_ROMAN:
element->parattr.flags = P_roman;
break;
case CSS_LIST_STYLE_TYPE_UPPER_ALPHA:
element->parattr.flags = P_ALPHA;
break;
case CSS_LIST_STYLE_TYPE_UPPER_ROMAN:
element->parattr.flags = P_ROMAN;
break;
case CSS_LIST_STYLE_TYPE_NONE:
element->parattr.flags = P_NO_BULLET;
break;
case CSS_LIST_STYLE_TYPE_LOWER_LATIN:
element->parattr.flags = P_alpha;
break;
case CSS_LIST_STYLE_TYPE_UPPER_LATIN:
element->parattr.flags = P_ALPHA;
break;
case CSS_LIST_STYLE_TYPE_ARMENIAN:
element->parattr.flags = P_NUMBER;
break;
case CSS_LIST_STYLE_TYPE_GEORGIAN:
element->parattr.flags = P_NUMBER;
break;
case CSS_LIST_STYLE_TYPE_LOWER_GREEK:
element->parattr.flags = P_NUMBER;
break;
default:
element->parattr.list_number = 0;
break;
}
}
static void
apply_display(struct html_context *html_context, struct html_element *element, uint8_t display)
{
switch (display) {
case CSS_DISPLAY_INLINE:
// element->linebreak = 0;
break;
case CSS_DISPLAY_BLOCK:
/* 1 or 2, that is the question. I went for 2 since it
* gives a more "blocky" feel and it's more common.
* YMMV. */
element->linebreak = 2;
break;
case CSS_DISPLAY_NONE:
if (!html_context->options->css_ignore_display_none)
element->invisible = 2;
break;
default:
//INTERNAL("Bad prop->value.display %d", prop->value.display);
break;
}
}
static void
apply_text_align(struct html_context *html_context, struct html_element *element, uint8_t text_align)
{
switch (text_align) {
case CSS_TEXT_ALIGN_LEFT:
element->parattr.align = ALIGN_LEFT;
break;
case CSS_TEXT_ALIGN_RIGHT:
element->parattr.align = ALIGN_RIGHT;
break;
case CSS_TEXT_ALIGN_CENTER:
element->parattr.align = ALIGN_CENTER;
break;
case CSS_TEXT_ALIGN_JUSTIFY:
element->parattr.align = ALIGN_JUSTIFY;
break;
default:
element->parattr.align = 0;
break;
}
}
static void
apply_font_style(struct html_context *html_context, struct html_element *element, uint8_t font_style)
{
int add = 0;
int rem = 0;
switch (font_style) {
case CSS_FONT_STYLE_NORMAL:
rem |= AT_ITALIC;
break;
case CSS_FONT_STYLE_ITALIC:
case CSS_FONT_STYLE_OBLIQUE:
add |= AT_ITALIC;
default:
break;
}
element->attr.style.attr |= add;
element->attr.style.attr &= ~rem;
}
static bool
is_bold(int val)
{
switch (val) {
case CSS_FONT_WEIGHT_100:
case CSS_FONT_WEIGHT_200:
case CSS_FONT_WEIGHT_300:
case CSS_FONT_WEIGHT_400:
case CSS_FONT_WEIGHT_NORMAL:
case CSS_FONT_WEIGHT_500:
case CSS_FONT_WEIGHT_600:
default:
return false;
case CSS_FONT_WEIGHT_700:
case CSS_FONT_WEIGHT_BOLD:
case CSS_FONT_WEIGHT_800:
case CSS_FONT_WEIGHT_900:
return true;
}
}
void
select_css(struct html_context *html_context, struct html_element *html_element)
{
css_error code;
uint8_t color_type;
css_color color_shade;
css_select_results *style;
css_stylesheet *inline_style = NULL;
dom_document *doc = NULL; /* document, loaded into libdom */
dom_node *root = NULL; /* root element of document */
dom_exception exc;
css_media media = {
.type = CSS_MEDIA_SCREEN,
};
int offset = html_element->name - html_context->document->text;
dom_node *el = (dom_node *)find_in_map(html_context->document->element_map, offset);
if (!el) {
return;
}
dom_string *s;
dom_exception err;
nscss_select_ctx ctx = {0};
/* Firstly, construct inline stylesheet, if any */
err = dom_element_get_attribute(el, corestring_dom_style, &s);
if (err != DOM_NO_ERR)
return;
if (s != NULL) {
inline_style = nscss_create_inline_style(
(const uint8_t *) dom_string_data(s),
dom_string_byte_length(s),
"utf-8",
"",
false);
dom_string_unref(s);
if (inline_style == NULL)
return;
}
/* Populate selection context */
ctx.ctx = html_context->select_ctx;
ctx.quirks = false; //(c->quirks == DOM_DOCUMENT_QUIRKS_MODE_FULL);
// ctx.base_url = c->base_url;
// ctx.universal = c->universal;
/// ctx.root_style = root_style;
/// ctx.parent_style = parent_style;
/* Select style for element */
style = nscss_get_style(&ctx, el, &media, inline_style);
/* No longer need inline style */
if (inline_style != NULL) {
css_stylesheet_destroy(inline_style);
}
if (!style) {
return;
}
color_type = css_computed_color(
style->styles[CSS_PSEUDO_ELEMENT_NONE],
&color_shade);
if (color_type) {
apply_color(html_context, html_element, color_shade);
}
color_type = css_computed_background_color(
style->styles[CSS_PSEUDO_ELEMENT_NONE],
&color_shade);
if (color_shade) {
apply_background_color(html_context, html_element, color_shade);
}
bool underline = css_computed_text_decoration(style->styles[CSS_PSEUDO_ELEMENT_NONE]) & CSS_TEXT_DECORATION_UNDERLINE;
bool bold = is_bold(css_computed_font_weight(style->styles[CSS_PSEUDO_ELEMENT_NONE]));
apply_font_attribute(html_context, html_element, underline, bold);
uint8_t font_style = css_computed_font_style(style->styles[CSS_PSEUDO_ELEMENT_NONE]);
if (font_style) {
apply_font_style(html_context, html_element, font_style);
}
uint8_t list_type = css_computed_list_style_type(style->styles[CSS_PSEUDO_ELEMENT_NONE]);
if (list_type) {
apply_list_style(html_context, html_element, list_type);
}
doc = html_context->document->dom;
/* Get root element */
exc = dom_document_get_document_element(doc, &root);
if (exc != DOM_NO_ERR) {
fprintf(stderr, "Exception raised for get_document_element\n");
//dom_node_unref(doc);
} else if (root == NULL) {
fprintf(stderr, "Broken: root == NULL\n");
//dom_node_unref(doc);
}
bool is_root = (root == el);
if (root) {
dom_node_unref(root);
}
uint8_t display = css_computed_display(style->styles[CSS_PSEUDO_ELEMENT_NONE], is_root);
if (display) {
apply_display(html_context, html_element, display);
}
uint8_t text_align = css_computed_text_align(style->styles[CSS_PSEUDO_ELEMENT_NONE]);
if (text_align) {
apply_text_align(html_context, html_element, text_align);
}
code = css_select_results_destroy(style);
if (code != CSS_OK) {
fprintf(stderr, "css_computed_style_destroy code=%d\n", code);
}
}
static css_error
handle_import(void *pw, css_stylesheet *parent, lwc_string *url)
{
struct html_context *html_context = (struct html_context *)pw;
struct uri *uri = get_uri(lwc_string_data(url), URI_BASE);
if (!uri) {
return CSS_NOMEM;
}
/* Request the imported stylesheet as part of the document ... */
html_context->special_f(html_context, SP_STYLESHEET, uri);
/* ... and then attempt to import from the cache. */
import_css2(html_context, uri);
done_uri(uri);
return CSS_OK;
}
static void
parse_css_common(struct html_context *html_context, const char *text, int length)
{
css_error code;
size_t size;
uint32_t count;
css_stylesheet_params params;
css_stylesheet *sheet;
params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1;
params.level = CSS_LEVEL_21;
params.charset = "UTF-8";
params.url = join_urls(html_context->base_href, "");
params.title = NULL;
params.allow_quirks = false;
params.inline_style = false;
params.resolve = resolve_url;
params.resolve_pw = NULL;
params.import = handle_import;
params.import_pw = html_context;
params.color = NULL;
params.color_pw = NULL;
params.font = NULL;
params.font_pw = NULL;
/* create a stylesheet */
code = css_stylesheet_create(&params, &sheet);
if (code != CSS_OK) {
fprintf(stderr, "css_stylesheet_create code=%d\n", code);
return;
}
code = css_stylesheet_append_data(sheet, (const uint8_t *) text, length);
if (code != CSS_OK && code != CSS_NEEDDATA) {
fprintf(stderr, "css_stylesheet_append_data code=%d\n", code);
return;
}
code = css_stylesheet_data_done(sheet);
if (code != CSS_OK) {
fprintf(stderr, "css_stylesheet_data_done code=%d\n", code);
return;
}
code = css_stylesheet_size(sheet, &size);
code = css_select_ctx_append_sheet(html_context->select_ctx, sheet, CSS_ORIGIN_AUTHOR,
NULL);
if (code != CSS_OK) {
fprintf(stderr, "css_select_ctx_append_sheet code=%d\n", code);
return;
}
struct el_sheet *el_sheet = (struct el_sheet *)mem_alloc(sizeof(*el_sheet));
if (el_sheet) {
el_sheet->sheet = sheet;
add_to_list(html_context->sheets, el_sheet);
}
code = css_select_ctx_count_sheets(html_context->select_ctx, &count);
if (code != CSS_OK) {
fprintf(stderr, "css_select_ctx_count_sheets code=%d\n", code);
}
}
void
parse_css(struct html_context *html_context, char *name)
{
int offset = name - html_context->document->text;
dom_node *el = (dom_node *)find_in_map(html_context->document->element_map, offset);
dom_node *n, *next;
dom_exception err;
if (!el) {
return;
}
struct string buf;
if (!init_string(&buf)) {
return;
}
n = el;
err = dom_node_get_first_child(n, &n);
if (err != DOM_NO_ERR) {
goto end;
}
while (n != NULL) {
dom_node_type ntype;
err = dom_node_get_node_type(n, &ntype);
if (err != DOM_NO_ERR) {
dom_node_unref(n);
goto end;
}
if (ntype == DOM_TEXT_NODE) {
dom_string *str;
err = dom_node_get_text_content(n, &str);
if (err == DOM_NO_ERR && str != NULL) {
int length = dom_string_byte_length(str);
const char *string_text = dom_string_data(str);
if (!((length == 1) && (*string_text == '\n'))) {
add_bytes_to_string(&buf, string_text, length);
}
dom_string_unref(str);
}
}
err = dom_node_get_next_sibling(n, &next);
if (err != DOM_NO_ERR) {
dom_node_unref(n);
goto end;
}
dom_node_unref(n);
n = next;
}
parse_css_common(html_context, buf.source, buf.length);
end:
done_string(&buf);
}
void
import_css2(struct html_context *html_context, struct uri *uri)
{
/* Do we have it in the cache? (TODO: CSS cache) */
struct cache_entry *cached;
struct fragment *fragment;
if (!uri) { //|| css->import_level >= MAX_REDIRECTS)
return;
}
cached = get_redirected_cache_entry(uri);
if (!cached) return;
fragment = get_cache_fragment(cached);
if (fragment) {
// css->import_level++;
parse_css_common(html_context, fragment->data, fragment->length);
// css_parse_stylesheet(css, uri, fragment->data, end);
// css->import_level--;
}
}

View File

@ -1,5 +1,5 @@
#ifndef EL__DOCUMENT_CSS2_CSS_H
#define EL__DOCUMENT_CSS2_CSS_H
#ifndef EL__DOCUMENT_LIBDOM_CSS_H
#define EL__DOCUMENT_LIBDOM_CSS_H
#include <libcss/libcss.h>

View File

@ -4,9 +4,6 @@ endif
if conf_data.get('CONFIG_DOM')
subdir('dom')
endif
if conf_data.get('CONFIG_LIBCSS')
subdir('css2')
endif
if conf_data.get('CONFIG_LIBDOM')
subdir('libdom')
endif