[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:
James Bursa 2003-04-05 15:35:55 +00:00
parent 4421b2e633
commit 004f6c31e3
3 changed files with 99 additions and 47 deletions

View File

@ -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()

View File

@ -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));

View File

@ -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);
}
/**