mirror of
https://github.com/netsurf-browser/netsurf
synced 2025-02-23 18:04:48 +03:00
[project @ 2003-04-05 15:35:55 by bursa]
Use hash-table to store CSS rules. svn path=/import/netsurf/; revision=113
This commit is contained in:
parent
4421b2e633
commit
004f6c31e3
33
css/css.c
33
css/css.c
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* $Id: css.c,v 1.1 2003/04/04 15:19:31 bursa Exp $
|
||||
* $Id: css.c,v 1.2 2003/04/05 15:35:55 bursa Exp $
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
@ -74,12 +74,13 @@ const struct css_style css_blank_style = {
|
||||
|
||||
void css_create(struct content *c)
|
||||
{
|
||||
unsigned int i;
|
||||
LOG(("content %p", c));
|
||||
c->data.css = xcalloc(1, sizeof(*c->data.css));
|
||||
css_lex_init(&c->data.css->lexer);
|
||||
c->data.css->parser = css_parser_Alloc(malloc);
|
||||
c->data.css->rule = 0;
|
||||
c->data.css->last_rule = 0;
|
||||
for (i = 0; i != HASH_SIZE; i++)
|
||||
c->data.css->rule[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -168,11 +169,12 @@ void css_get_style(struct css_stylesheet * stylesheet, struct css_selector * sel
|
||||
unsigned int selectors, struct css_style * style)
|
||||
{
|
||||
struct node *r, *n, *m;
|
||||
unsigned int i;
|
||||
unsigned int hash, i;
|
||||
|
||||
LOG(("stylesheet %p, selectors %u", stylesheet, selectors));
|
||||
|
||||
for (r = stylesheet->rule; r != 0; r = r->next) {
|
||||
|
||||
hash = css_hash(selector[selectors - 1].element);
|
||||
for (r = stylesheet->rule[hash]; r != 0; r = r->next) {
|
||||
i = selectors - 1;
|
||||
n = r;
|
||||
/* compare element */
|
||||
@ -218,14 +220,11 @@ void css_get_style(struct css_stylesheet * stylesheet, struct css_selector * sel
|
||||
matched:
|
||||
/* TODO: sort by specificity */
|
||||
LOG(("matched rule %p", r));
|
||||
css_dump_style(r->style);
|
||||
css_cascade(style, r->style);
|
||||
|
||||
not_matched:
|
||||
|
||||
}
|
||||
|
||||
css_dump_style(style);
|
||||
}
|
||||
|
||||
|
||||
@ -239,12 +238,6 @@ void css_parse_property_list(struct css_style * style, char * str)
|
||||
* dump a style
|
||||
*/
|
||||
|
||||
static void dump_length(const struct css_length * const length)
|
||||
{
|
||||
LOG(("%g%s", length->value,
|
||||
css_unit_name[length->unit]));
|
||||
}
|
||||
|
||||
#define DUMP_LENGTH(pre, len, post) LOG((pre "%g%s" post, (len)->value, css_unit_name[(len)->unit]));
|
||||
|
||||
void css_dump_style(const struct css_style * const style)
|
||||
@ -389,6 +382,16 @@ void css_cascade(struct css_style * const style, const struct css_style * const
|
||||
}
|
||||
|
||||
|
||||
unsigned int css_hash(const char *s)
|
||||
{
|
||||
unsigned int z = 0;
|
||||
for (; *s != 0; s++)
|
||||
z += *s;
|
||||
return z % HASH_SIZE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
int main()
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* $Id: css.h,v 1.1 2003/04/04 15:19:31 bursa Exp $
|
||||
* $Id: css.h,v 1.2 2003/04/05 15:35:55 bursa Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETSURF_CSS_CSS_H_
|
||||
@ -136,11 +136,12 @@ struct node {
|
||||
|
||||
#include "netsurf/css/scanner.h"
|
||||
|
||||
#define HASH_SIZE 47
|
||||
|
||||
struct css_stylesheet {
|
||||
yyscan_t lexer;
|
||||
void *parser;
|
||||
struct node *rule;
|
||||
struct node *last_rule;
|
||||
struct node *rule[HASH_SIZE];
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -166,6 +167,7 @@ void css_free_node(struct node *node);
|
||||
void css_add_ruleset(struct css_stylesheet *stylesheet,
|
||||
struct node *selector,
|
||||
struct node *declaration);
|
||||
unsigned int css_hash(const char *s);
|
||||
|
||||
void css_parser_Trace(FILE *TraceFILE, char *zTracePrompt);
|
||||
void *css_parser_Alloc(void *(*mallocProc)(int));
|
||||
|
105
css/ruleset.c
105
css/ruleset.c
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* $Id: ruleset.c,v 1.1 2003/04/04 15:19:31 bursa Exp $
|
||||
* $Id: ruleset.c,v 1.2 2003/04/05 15:35:55 bursa Exp $
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
@ -28,6 +28,7 @@ struct font_size_entry {
|
||||
};
|
||||
|
||||
|
||||
static int compare_selectors(struct node *n0, struct node *n1);
|
||||
static int parse_length(struct css_length * const length, const struct node * const v);
|
||||
static colour parse_colour(const struct node * const v);
|
||||
static void parse_background_color(struct css_style * const s, const struct node * const v);
|
||||
@ -102,41 +103,87 @@ void css_add_ruleset(struct css_stylesheet *stylesheet,
|
||||
struct node *selector,
|
||||
struct node *declaration)
|
||||
{
|
||||
struct node *n, *last;
|
||||
struct node *n, *sel, *next_sel;
|
||||
struct css_style *style;
|
||||
unsigned int hash;
|
||||
|
||||
/* construct the struct css_style */
|
||||
style = xcalloc(1, sizeof(*style));
|
||||
memcpy(style, &css_blank_style, sizeof(*style));
|
||||
for (sel = selector; sel != 0; sel = next_sel) {
|
||||
next_sel = sel->next;
|
||||
|
||||
for (n = declaration; n != 0; n = n->next) {
|
||||
struct property_entry *p;
|
||||
assert(n->type == NODE_DECLARATION && n->data != 0 && n->left != 0);
|
||||
p = bsearch(n->data, property_table,
|
||||
sizeof(property_table) / sizeof(property_table[0]),
|
||||
sizeof(property_table[0]), strcasecmp);
|
||||
if (p == 0)
|
||||
continue;
|
||||
p->parse(style, n->left);
|
||||
/* check if this selector is already present */
|
||||
hash = css_hash(sel->data);
|
||||
for (n = stylesheet->rule[hash]; n != 0; n = n->next)
|
||||
if (compare_selectors(sel, n))
|
||||
break;
|
||||
if (n == 0) {
|
||||
/* not present: construct a new struct css_style */
|
||||
style = xcalloc(1, sizeof(*style));
|
||||
memcpy(style, &css_blank_style, sizeof(*style));
|
||||
sel->style = style;
|
||||
sel->next = stylesheet->rule[hash];
|
||||
stylesheet->rule[hash] = sel;
|
||||
} else {
|
||||
/* already exists: augument existing style */
|
||||
style = n->style;
|
||||
sel->next = 0;
|
||||
css_free_node(sel);
|
||||
}
|
||||
|
||||
/* fill in the declarations */
|
||||
for (n = declaration; n != 0; n = n->next) {
|
||||
struct property_entry *p;
|
||||
assert(n->type == NODE_DECLARATION && n->data != 0 && n->left != 0);
|
||||
p = bsearch(n->data, property_table,
|
||||
sizeof(property_table) / sizeof(property_table[0]),
|
||||
sizeof(property_table[0]), strcasecmp);
|
||||
if (p == 0)
|
||||
continue;
|
||||
p->parse(style, n->left);
|
||||
}
|
||||
}
|
||||
|
||||
/*css_dump_style(style);*/
|
||||
|
||||
/* add selectors to the stylesheet */
|
||||
/* TODO: merge with identical selector */
|
||||
for (n = selector; n != 0; n = n->next) {
|
||||
n->style = style;
|
||||
last = n;
|
||||
}
|
||||
|
||||
if (stylesheet->rule == 0)
|
||||
stylesheet->rule = selector;
|
||||
else
|
||||
stylesheet->last_rule->next = selector;
|
||||
stylesheet->last_rule = last;
|
||||
}
|
||||
|
||||
|
||||
int compare_selectors(struct node *n0, struct node *n1)
|
||||
{
|
||||
struct node *m0, *m1;
|
||||
unsigned int count0, count1;
|
||||
|
||||
/* compare element name */
|
||||
if (!((n0->data == 0 && n1->data == 0) ||
|
||||
(n0->data != 0 && n1->data != 0 && strcasecmp(n0->data, n1->data) == 0)))
|
||||
return 0;
|
||||
|
||||
if (n0->comb != n1->comb)
|
||||
return 0;
|
||||
|
||||
/* compare classes and ids */
|
||||
for (m0 = n0->left; m0 != 0; m0 = m0->next)
|
||||
count0++;
|
||||
for (m1 = n1->left; m1 != 0; m1 = m1->next)
|
||||
count1++;
|
||||
if (count0 != count1)
|
||||
return 0;
|
||||
for (m0 = n0->left; m0 != 0; m0 = m0->next) {
|
||||
int found = 0;
|
||||
for (m1 = n1->left; m1 != 0; m1 = m1->next) {
|
||||
/* TODO: should this be case sensitive for IDs? */
|
||||
if (m0->type == m1->type && strcasecmp(m0->data, m1->data) == 0) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* compare ancestors */
|
||||
if (n0->comb == COMB_NONE)
|
||||
return 1;
|
||||
|
||||
return compare_selectors(n0->right, n1->right);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user