1
0
Fork 0

[css] Added experimental libcss code (config option document.css.libcss)

Was not tested.
This commit is contained in:
Witold Filipczyk 2023-02-28 18:38:33 +01:00
parent 967e5d5f09
commit ed86daabe0
17 changed files with 1859 additions and 142 deletions

View File

@ -406,10 +406,12 @@ if conf_data.get('CONFIG_ECMASCRIPT_SMJS') or conf_data.get('CONFIG_QUICKJS') or
deps += curldeps
endif
conf_data.set('CONFIG_LIBCSS', false)
if conf_data.get('CONFIG_ECMASCRIPT_SMJS') or conf_data.get('CONFIG_QUICKJS') or conf_data.get('CONFIG_MUJS')
cssdeps = dependency('libcss', static: st, version: '>=0.9.1')
deps += cssdeps
conf_data.set('CONFIG_LIBCSS', 1)
conf_data.set('CONFIG_LIBCSS', true)
endif
if conf_data.get('CONFIG_SCRIPTING_LUA')

View File

@ -35,7 +35,11 @@ union option_info css_options_info[] = {
INIT_OPT_BOOL("document.css", N_("Enable CSS"),
"enable", OPT_ZERO, 1,
N_("Enable adding of CSS style info to documents.")),
#ifdef CONFIG_LIBCSS
INIT_OPT_BOOL("document.css", N_("Prefer libcss"),
"libcss", OPT_ZERO, 0,
N_("Enable experimental code using the libcss library instead of builtin implementation.")),
#endif
INIT_OPT_BOOL("document.css", N_("Ignore \"display: none\""),
"ignore_display_none", OPT_ZERO, 1,
N_("When enabled, elements are rendered, even when their "

1615
src/document/css2/css.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,61 +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/>.
*/
#ifndef netsurf_css_css_h_
#define netsurf_css_css_h_
#include <stdint.h>
#ifndef EL__DOCUMENT_CSS2_CSS_H
#define EL__DOCUMENT_CSS2_CSS_H
#include <libcss/libcss.h>
#include "utils/errors.h"
#ifdef __cplusplus
extern "C" {
#endif
struct hlcache_handle;
struct html_context;
struct html_element;
struct uri;
/**
* Imported stylesheet record
*/
struct nscss_import {
struct hlcache_handle *c; /**< Content containing sheet */
};
css_error resolve_url(void *pw, const char *base, lwc_string *rel, lwc_string **abs);
void select_css(struct html_context *html_context, struct html_element *element);
void parse_css(struct html_context *html_context, char *name);
void import_css2(struct html_context *html_context, struct uri *uri);
/**
* Initialise the CSS content handler
*
* \return NSERROR_OK on success or error code on faliure
*/
nserror nscss_init(void);
/**
* 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);
/**
* 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(struct hlcache_handle *h, uint32_t *n);
#ifdef __cplusplus
}
#endif
#endif

View File

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

View File

@ -1,4 +1,3 @@
#ifndef EL__DOCUMENT_HTML_INTERNAL_H
#define EL__DOCUMENT_HTML_INTERNAL_H
@ -6,6 +5,12 @@
#include "document/html/parser.h"
#include "util/lists.h"
#ifdef CONFIG_LIBCSS
#undef restrict
#define restrict __restrict
#include <libcss/libcss.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -41,18 +46,38 @@ enum html_whitespace_state {
HTML_SPACE_ADD,
};
#ifdef CONFIG_LIBCSS
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;
struct el_sheet {
LIST_HEAD(struct el_sheet);
css_stylesheet *sheet;
};
#endif
struct html_context {
#ifdef CONFIG_CSS
#ifdef CONFIG_LIBCSS
struct document *document;
#else
LIST_OF(struct el_sheet) sheets;
css_select_ctx *select_ctx;
/* The default stylesheet is initially merged into it. When parsing CSS
* from <style>-tags and external stylesheets if enabled is merged
* added to it. */
#endif
struct css_stylesheet css_styles;
#endif
#endif
/* These are global per-document base values, alterable by the <base>
* element. */
struct uri *base_href;
@ -144,7 +169,7 @@ struct html_context {
#define html_top ((struct html_element *) html_context->stack.next)
#define html_bottom ((struct html_element *) html_context->stack.prev)
#define elformat (html_top->attr)
#define elformat (html_top->attr)
#define par_elformat (html_top->parattr)
#define html_is_preformatted() (elformat.style.attr & AT_PREFORMATTED)
@ -158,10 +183,14 @@ void html_focusable(struct html_context *html_context, char *a);
void html_skip(struct html_context *html_context, char *a);
char *get_target(struct document_options *options, char *a);
void
import_css_stylesheet(struct css_stylesheet *css, struct uri *base_uri,
void import_css_stylesheet(struct css_stylesheet *css, struct uri *base_uri,
const char *unterminated_url, int len);
#ifdef CONFIG_LIBCSS
void import_css2_stylesheet(struct html_context *, struct uri *base_uri,
const char *unterminated_url, int len);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -49,6 +49,11 @@
/* Unsafe macros */
#include "document/html/internal.h"
#ifdef CONFIG_LIBCSS
#include <libcss/libcss.h>
#include "document/css2/css.h"
#endif
/* TODO: This needs rewrite. Yes, no kidding. */
static int
@ -201,6 +206,48 @@ add_fragment_identifier(struct html_context *html_context,
}
#ifdef CONFIG_CSS
#ifdef CONFIG_LIBCSS
void
import_css2_stylesheet(struct html_context *html_context, struct uri *base_uri, const char *unterminated_url, int len)
{
char *url;
char *import_url;
struct uri *uri;
assert(html_context);
assert(base_uri);
if (!html_context->options->css_enable
|| !html_context->options->css_import)
return;
/* unterminated_url might not end with '\0', but join_urls
* requires that, so make a copy. */
url = memacpy(unterminated_url, len);
if (!url) return;
/* HTML <head> urls should already be fine but we can.t detect them. */
import_url = join_urls(base_uri, url);
mem_free(url);
if (!import_url) return;
uri = get_uri(import_url, URI_BASE);
mem_free(import_url);
if (!uri) return;
/* 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);
}
#endif
void
import_css_stylesheet(struct css_stylesheet *css, struct uri *base_uri,
const char *unterminated_url, int len)
@ -778,10 +825,9 @@ init_html_parser(struct uri *uri, struct document *document,
#ifdef CONFIG_CSS
#ifdef CONFIG_LIBCSS
html_context->document = document;
#else
#endif
html_context->css_styles.import = import_css_stylesheet;
init_css_selector_set(&html_context->css_styles.selectors);
#endif
#endif
init_list(html_context->stack);
@ -837,7 +883,7 @@ init_html_parser(struct uri *uri, struct document *document,
html_top->invisible = 0;
html_top->name = NULL;
html_top->namelen = 0;
html_top->namelen = 0;
html_top->options = NULL;
html_top->linebreak = 1;
html_top->type = ELEMENT_DONT_KILL;
@ -847,13 +893,26 @@ init_html_parser(struct uri *uri, struct document *document,
#ifdef CONFIG_CSS
#ifdef CONFIG_LIBCSS
#else
html_context->css_styles.import_data = html_context;
if (options->libcss_enable) {
if (options->css_enable) {
css_error code;
if (options->css_enable)
mirror_css_stylesheet(&default_stylesheet,
&html_context->css_styles);
init_list(html_context->sheets);
/* prepare a selection context containing the stylesheet */
code = css_select_ctx_create(&html_context->select_ctx);
if (code != CSS_OK) {
//fprintf(stderr, "css_select_ctx_create code=%d\n", code);
}
}
} else
#endif
do {
html_context->css_styles.import_data = html_context;
if (options->css_enable)
mirror_css_stylesheet(&default_stylesheet,
&html_context->css_styles);
} while (0);
#endif
return html_context;
@ -864,12 +923,22 @@ done_html_parser(struct html_context *html_context)
{
#ifdef CONFIG_CSS
#ifdef CONFIG_LIBCSS
#else
if (html_context->options->css_enable)
done_css_stylesheet(&html_context->css_styles);
if (html_context->options->libcss_enable) {
if (html_context->options->css_enable) {
struct el_sheet *el;
css_error code = css_select_ctx_destroy(html_context->select_ctx);
foreach (el, html_context->sheets) {
code = css_stylesheet_destroy(el->sheet);
}
free_list(html_context->sheets);
}
} else
#endif
do {
if (html_context->options->css_enable)
done_css_stylesheet(&html_context->css_styles);
} while (0);
#endif
mem_free(html_context->base_target);
done_uri(html_context->base_href);

View File

@ -54,8 +54,6 @@ struct text_attrib {
struct text_attrib_color color;
#ifdef CONFIG_CSS
#ifdef CONFIG_LIBCSS
#else
/* Bug 766: CSS speedup. 56% of CPU time was going to
* get_attr_value(). Of those calls, 97% were asking for "id"
* or "class". So cache the results. start_element() sets up
@ -63,7 +61,6 @@ struct text_attrib {
* otherwise they remain NULL. */
char *id;
char *class_;
#endif
#endif
char *select;

View File

@ -187,13 +187,15 @@ html_apply_canvas_bgcolor(struct html_context *html_context)
{
#ifdef CONFIG_CSS
#ifdef CONFIG_LIBCSS
#else
if (!html_context->options->libcss_enable)
#endif
/* If there are any CSS twaks regarding bgcolor, make sure we will get
* it _and_ prefer it over bgcolor attribute. */
do {
if (html_context->options->css_enable)
css_apply(html_context, html_top, &html_context->css_styles,
&html_context->stack);
#endif
} while (0);
#endif
if (par_elformat.color.background != elformat.style.color.background) {

View File

@ -924,17 +924,28 @@ html_link(struct html_context *html_context, char *a,
#ifdef CONFIG_CSS
#ifdef CONFIG_LIBCSS
#else
if (link.type == LT_STYLESHEET
&& supports_html_media_attr(link.media)) {
int len = strlen(link.href);
if (html_context->options->libcss_enable) {
if (link.type == LT_STYLESHEET
&& supports_html_media_attr(link.media)) {
int len = strlen(link.href);
import_css_stylesheet(&html_context->css_styles,
html_context->base_href, link.href, len);
}
import_css2_stylesheet(html_context, html_context->base_href, link.href, len);
}
if (!link_display) goto free_and_return;
if (!link_display) goto free_and_return;
} else
#endif
do {
if (link.type == LT_STYLESHEET
&& supports_html_media_attr(link.media)) {
int len = strlen(link.href);
import_css_stylesheet(&html_context->css_styles,
html_context->base_href, link.href, len);
}
if (!link_display) goto free_and_return;
} while (0);
#endif
/* Ignore few annoying links.. */

View File

@ -16,6 +16,9 @@
#include "document/css/apply.h"
#include "document/css/css.h"
#include "document/css/parser.h"
#ifdef CONFIG_LIBCSS
#include "document/css2/css.h"
#endif
#include "document/html/parser/forms.h"
#include "document/html/parser/general.h"
#include "document/html/parser/link.h"
@ -857,10 +860,7 @@ start_element(struct element_info *ei,
struct par_attrib old_format;
int restore_format;
#ifdef CONFIG_CSS
#ifdef CONFIG_LIBCSS
#else
struct css_selector *selector = NULL;
#endif
#endif
/* If the currently top element on the stack cannot contain other
@ -900,19 +900,30 @@ start_element(struct element_info *ei,
/* If this is a style tag, parse it. */
#ifdef CONFIG_CSS
#ifdef CONFIG_LIBCSS
#else
if (ei->open == html_style && html_context->options->css_enable) {
char *media
= get_attr_val(attr, "media", html_context->doc_cp);
int support = supports_html_media_attr(media);
mem_free_if(media);
if (html_context->options->libcss_enable) {
if (ei->open == html_style && html_context->options->css_enable) {
char *media = get_attr_val(attr, "media", html_context->doc_cp);
int support = supports_html_media_attr(media);
mem_free_if(media);
if (support)
css_parse_stylesheet(&html_context->css_styles,
html_context->base_href,
html, eof);
}
if (support) {
parse_css(html_context, name);
}
}
} else
#endif
do {
if (ei->open == html_style && html_context->options->css_enable) {
char *media = get_attr_val(attr, "media", html_context->doc_cp);
int support = supports_html_media_attr(media);
mem_free_if(media);
if (support)
css_parse_stylesheet(&html_context->css_styles,
html_context->base_href,
html, eof);
}
} while (0);
#endif
/* If this element is inline, non-nestable, and not <li>, and the next
@ -984,33 +995,39 @@ start_element(struct element_info *ei,
/* Apply CSS styles. */
#ifdef CONFIG_CSS
#ifdef CONFIG_LIBCSS
#else
if (html_top->options && html_context->options->css_enable) {
/* XXX: We should apply CSS otherwise as well, but that'll need
* some deeper changes in order to have options filled etc.
* Probably just applying CSS from more places, since we
* usually have type != ET_NESTABLE when we either (1)
* rescan on your own from somewhere else (2) html_stack_dup()
* in our own way. --pasky */
mem_free_set(&html_top->attr.id,
get_attr_val(attr, "id", html_context->doc_cp));
mem_free_set(&html_top->attr.class_,
get_attr_val(attr, "class", html_context->doc_cp));
/* Call it now to gain some of the stuff which might affect
* formatting of some elements. */
/* FIXME: The caching of the CSS selector is broken, since t can
* lead to wrong styles being applied to following elements, so
* disabled for now. */
selector = get_css_selector_for_element(html_context, html_top,
if (html_context->options->libcss_enable) {
if (html_context->options->css_enable) {
select_css(html_context, html_top);
}
} else
#endif
do {
if (html_top->options && html_context->options->css_enable) {
/* XXX: We should apply CSS otherwise as well, but that'll need
* some deeper changes in order to have options filled etc.
* Probably just applying CSS from more places, since we
* usually have type != ET_NESTABLE when we either (1)
* rescan on your own from somewhere else (2) html_stack_dup()
* in our own way. --pasky */
mem_free_set(&html_top->attr.id,
get_attr_val(attr, "id", html_context->doc_cp));
mem_free_set(&html_top->attr.class_,
get_attr_val(attr, "class", html_context->doc_cp));
/* Call it now to gain some of the stuff which might affect
* formatting of some elements. */
/* FIXME: The caching of the CSS selector is broken, since t can
* lead to wrong styles being applied to following elements, so
* disabled for now. */
selector = get_css_selector_for_element(html_context, html_top,
&html_context->css_styles,
&html_context->stack);
if (selector) {
apply_css_selector_style(html_context, html_top, selector);
done_css_selector(selector);
if (selector) {
apply_css_selector_style(html_context, html_top, selector);
done_css_selector(selector);
}
}
}
#endif
} while (0);
#endif
/* 1. Put any linebreaks that the element calls for, and 2. register
@ -1029,19 +1046,25 @@ start_element(struct element_info *ei,
/* Apply CSS styles again. */
#ifdef CONFIG_CSS
#ifdef CONFIG_LIBCSS
#else
if (selector && html_top->options) {
/* Call it now to override default colors of the elements. */
selector = get_css_selector_for_element(html_context, html_top,
if (html_context->options->libcss_enable) {
if (html_context->options->css_enable) {
select_css(html_context, html_top);
}
} else
#endif
do {
if (selector && html_top->options) {
/* Call it now to override default colors of the elements. */
selector = get_css_selector_for_element(html_context, html_top,
&html_context->css_styles,
&html_context->stack);
if (selector) {
apply_css_selector_style(html_context, html_top, selector);
done_css_selector(selector);
if (selector) {
apply_css_selector_style(html_context, html_top, selector);
done_css_selector(selector);
}
}
}
#endif
} while (0);
#endif
/* If this element was not <br>, clear the was_br flag. */

View File

@ -1,4 +1,3 @@
#ifndef EL__DOCUMENT_HTML_PARSER_PARSE_H
#define EL__DOCUMENT_HTML_PARSER_PARSE_H

View File

@ -122,11 +122,8 @@ kill_html_stack_item(struct html_context *html_context, struct html_element *e)
mem_free_if(e->attr.select);
#ifdef CONFIG_CSS
#ifdef CONFIG_LIBCSS
#else
mem_free_if(e->attr.id);
mem_free_if(e->attr.class_);
#endif
#endif
mem_free_if(e->attr.onclick);
@ -171,10 +168,7 @@ html_stack_dup(struct html_context *html_context, enum html_element_mortality_ty
if (ep->attr.select) e->attr.select = stracpy(ep->attr.select);
#ifdef CONFIG_CSS
#ifdef CONFIG_LIBCSS
#else
e->attr.id = e->attr.class_ = NULL;
#endif
#endif
/* We don't want to propagate these. */
/* XXX: For sure? --pasky */

View File

@ -1,6 +1,9 @@
if conf_data.get('CONFIG_CSS') and conf_data.get('CONFIG_DOM')
if conf_data.get('CONFIG_CSS')
subdir('css')
endif
if conf_data.get('CONFIG_LIBCSS')
subdir('css2')
endif
if conf_data.get('CONFIG_DOM')
subdir('dom')
endif

View File

@ -75,6 +75,9 @@ init_document_options(struct session *ses, struct document_options *doo)
/* Boolean options. */
#ifdef CONFIG_CSS
#ifdef CONFIG_LIBCSS
doo->libcss_enable = get_opt_bool("document.css.libcss", ses);
#endif
doo->css_enable = get_opt_bool("document.css.enable", ses);
doo->css_ignore_display_none = get_opt_bool("document.css.ignore_display_none", ses);
doo->css_import = get_opt_bool("document.css.import", ses);

View File

@ -76,6 +76,9 @@ struct document_options {
/* XXX: Keep boolean options grouped to save padding */
#ifdef CONFIG_CSS
#ifdef CONFIG_LIBCSS
unsigned int libcss_enable:1;
#endif
/** @name CSS stuff
* @{ */
unsigned int css_enable:1;

View File

@ -13,5 +13,5 @@
</style>
<style>) I, love, garbage { dont: you? } </style>
<a href="foo" style="color:">no value</a>
<div style="{background:#fff}">white bg</div>
<div style="background:#fff">white bg</div>
<p>should become red when we start supporting escaping of string delimiters</p>