From 46edb645e1a08fb76835e4b3b8960ec3cce5e298 Mon Sep 17 00:00:00 2001 From: James Bursa Date: Sun, 6 Apr 2003 18:09:34 +0000 Subject: [project @ 2003-04-06 18:09:34 by bursa] @import, more status messages. svn path=/import/netsurf/; revision=116 --- content/content.c | 3 +- content/content.h | 12 ++- content/fetchcache.c | 12 ++- css/css.c | 209 ++++++++++++++++++++++++++++++++++++++++++++------- css/css.h | 9 ++- css/parser.y | 7 +- css/ruleset.c | 6 +- makefile | 4 +- render/box.c | 4 +- render/html.c | 11 ++- 10 files changed, 229 insertions(+), 48 deletions(-) diff --git a/content/content.c b/content/content.c index be528d787..439c0fba2 100644 --- a/content/content.c +++ b/content/content.c @@ -1,5 +1,5 @@ /** - * $Id: content.c,v 1.5 2003/04/05 21:38:06 bursa Exp $ + * $Id: content.c,v 1.6 2003/04/06 18:09:34 bursa Exp $ */ #include @@ -74,6 +74,7 @@ struct content * content_create(content_type type, char *url) c->type = type; c->status = CONTENT_LOADING; c->size = sizeof(struct content); + c->status_callback = 0; handler_map[type].create(c); return c; } diff --git a/content/content.h b/content/content.h index b0711488d..ff0dbc6dd 100644 --- a/content/content.h +++ b/content/content.h @@ -1,5 +1,5 @@ /** - * $Id: content.h,v 1.4 2003/04/05 21:38:06 bursa Exp $ + * $Id: content.h,v 1.5 2003/04/06 18:09:34 bursa Exp $ */ #ifndef _NETSURF_DESKTOP_CONTENT_H_ @@ -57,7 +57,6 @@ struct content unsigned int stylesheet_count; char **stylesheet_url; struct content **stylesheet_content; - struct css_stylesheet* stylesheet; struct css_style* style; struct { struct box_position start; @@ -69,7 +68,12 @@ struct content struct page_elements elements; } html; - struct css_stylesheet *css; + struct + { + struct css_stylesheet *css; + unsigned int import_count; + struct content **import_content; + } css; struct { @@ -84,6 +88,8 @@ struct content char *title; unsigned int active; int error; + void (*status_callback)(void *p, const char *status); + void *status_p; }; diff --git a/content/fetchcache.c b/content/fetchcache.c index 3d2529f68..9adaee544 100644 --- a/content/fetchcache.c +++ b/content/fetchcache.c @@ -1,5 +1,5 @@ /** - * $Id: fetchcache.c,v 1.5 2003/03/08 20:26:31 bursa Exp $ + * $Id: fetchcache.c,v 1.6 2003/04/06 18:09:34 bursa Exp $ */ #include @@ -24,6 +24,7 @@ struct fetchcache { static void fetchcache_free(struct fetchcache *fc); static void fetchcache_callback(fetchcache_msg msg, void *p, char *data, unsigned long size); +static void status_callback(void *p, const char *status); void fetchcache(const char *url, char *referer, @@ -81,6 +82,8 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size) free(fc); } else { fc->c = content_create(type, fc->url); + fc->c->status_callback = status_callback; + fc->c->status_p = fc; } free(mime_type); break; @@ -119,6 +122,13 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size) } +void status_callback(void *p, const char *status) +{ + struct fetchcache *fc = p; + fc->callback(FETCHCACHE_STATUS, fc->c, fc->p, status); +} + + #ifdef TEST #include diff --git a/css/css.c b/css/css.c index b48d4a684..490add5b7 100644 --- a/css/css.c +++ b/css/css.c @@ -1,5 +1,5 @@ /** - * $Id: css.c,v 1.4 2003/04/05 21:38:06 bursa Exp $ + * $Id: css.c,v 1.5 2003/04/06 18:09:34 bursa Exp $ */ #include @@ -7,10 +7,13 @@ #include #include #define CSS_INTERNALS -#define NDEBUG +#undef NDEBUG #include "netsurf/content/content.h" +#include "netsurf/content/fetch.h" +#include "netsurf/content/fetchcache.h" #include "netsurf/css/css.h" #include "netsurf/css/parser.h" +#include "netsurf/desktop/gui.h" #include "netsurf/utils/log.h" #include "netsurf/utils/utils.h" @@ -23,6 +26,13 @@ struct decl { struct rule * rule; }; +struct fetch_data { + struct content *c; + unsigned int i; +}; + +void css_atimport_callback(fetchcache_msg msg, struct content *css, + void *p, const char *error); void css_dump_style(const struct css_style * const style); @@ -78,11 +88,14 @@ 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.css = xcalloc(1, sizeof(*c->data.css.css)); + css_lex_init(&c->data.css.css->lexer); + c->data.css.css->parser = css_parser_Alloc(malloc); for (i = 0; i != HASH_SIZE; i++) - c->data.css->rule[i] = 0; + c->data.css.css->rule[i] = 0; + c->data.css.import_count = 0; + c->data.css.import_content = xcalloc(0, sizeof(*c->data.css.import_content)); + c->active = 0; } @@ -90,30 +103,36 @@ void css_process_data(struct content *c, char *data, unsigned long size) { int token; YY_BUFFER_STATE buffer; - struct parse_params param = {0, c->data.css, 0}; + struct parse_params param = {0, c, 0}; LOG(("content %p, size %lu", c, size)); - buffer = css__scan_bytes(data, size, c->data.css->lexer); - while ((token = css_lex(c->data.css->lexer))) { - css_parser_(c->data.css->parser, token, - strdup(css_get_text(c->data.css->lexer)), + buffer = css__scan_bytes(data, size, c->data.css.css->lexer); + while ((token = css_lex(c->data.css.css->lexer))) { + css_parser_(c->data.css.css->parser, token, + strdup(css_get_text(c->data.css.css->lexer)), ¶m); } - css__delete_buffer(buffer, c->data.css->lexer); + css__delete_buffer(buffer, c->data.css.css->lexer); } int css_convert(struct content *c, unsigned int width, unsigned int height) { - struct parse_params param = {0, c->data.css, 0}; + struct parse_params param = {0, c, 0}; LOG(("content %p", c)); - css_parser_(c->data.css->parser, 0, 0, ¶m); + css_parser_(c->data.css.css->parser, 0, 0, ¶m); - css_parser_Free(c->data.css->parser, free); - css_lex_destroy(c->data.css->lexer); + css_parser_Free(c->data.css.css->parser, free); + css_lex_destroy(c->data.css.css->lexer); + + /* complete fetch of any imported stylesheets */ + while (c->active != 0) { + fetch_poll(); + gui_multitask(); + } return 0; } @@ -131,7 +150,21 @@ void css_reformat(struct content *c, unsigned int width, unsigned int height) void css_destroy(struct content *c) { - xfree(c->data.css); + unsigned int i; + struct node *r; + + for (i = 0; i != HASH_SIZE; i++) { + for (r = c->data.css.css->rule[i]; r != 0; r = r->next) + xfree(r->style); + css_free_node(c->data.css.css->rule[i]); + } + xfree(c->data.css.css); + + /* imported stylesheets */ + for (i = 0; i != c->data.css.import_count; i++) + if (c->data.css.import_content[i] != 0) + cache_free(c->data.css.import_content[i]); + xfree(c->data.css.import_content); } @@ -169,14 +202,131 @@ void css_free_node(struct node *node) } +void css_atimport(struct content *c, struct node *node) +{ + char *s, *url; + int string = 0, screen = 1; + struct fetch_data *fetch_data; + + LOG(("@import rule")); + + /* uri(...) or "..." */ + switch (node->type) { + case NODE_URI: + LOG(("URI '%s'", node->data)); + for (s = node->data + 4; + *s == ' ' || *s == '\t' || *s == '\r' || + *s == '\n' || *s == '\f'; + s++) + ; + if (*s == '\'' || *s == '"') { + string = 1; + s++; + } + url = xstrdup(s); + for (s = url + strlen(url) - 2; + *s == ' ' || *s == '\t' || *s == '\r' || + *s == '\n' || *s == '\f'; + s--) + ; + if (string) + *s = 0; + else + *(s + 1) = 0; + break; + case NODE_STRING: + LOG(("STRING '%s'", node->data)); + url = xstrdup(node->data + 1); + *(url + strlen(url) - 1) = 0; + break; + default: + return; + } + + /* media not specified, 'screen', or 'all' */ + for (node = node->next; node != 0; node = node->next) { + screen = 0; + if (node->type != NODE_IDENT) { + free(url); + return; + } + LOG(("medium '%s'", node->data)); + if (strcmp(node->data, "screen") == 0 || strcmp(node->data, "all") == 0) { + screen = 1; + break; + } + node = node->next; + if (node == 0 || node->type != NODE_COMMA) { + free(url); + return; + } + } + if (!screen) { + free(url); + return; + } + + /* start the fetch */ + c->data.css.import_count++; + c->data.css.import_content = xrealloc(c->data.css.import_content, + c->data.css.import_count * sizeof(*c->data.css.import_content)); + + fetch_data = xcalloc(1, sizeof(*fetch_data)); + fetch_data->c = c; + fetch_data->i = c->data.css.import_count - 1; + c->active++; + fetchcache(url_join(url, c->url), c->url, css_atimport_callback, + fetch_data, c->width, c->height); + + free(url); +} + + +void css_atimport_callback(fetchcache_msg msg, struct content *css, + void *p, const char *error) +{ + struct fetch_data *data = p; + struct content *c = data->c; + unsigned int i = data->i; + switch (msg) { + case FETCHCACHE_OK: + free(data); + LOG(("got imported stylesheet '%s'", css->url)); + c->data.css.import_content[i] = css; + /*css_dump_stylesheet(css->data.css);*/ + c->active--; + break; + case FETCHCACHE_BADTYPE: + case FETCHCACHE_ERROR: + free(data); + c->data.css.import_content[i] = 0; + c->active--; + c->error = 1; + break; + case FETCHCACHE_STATUS: + /* TODO: need to add a way of sending status to the + * owning window */ + break; + default: + assert(0); + } +} + + + + -void css_get_style(struct css_stylesheet * stylesheet, struct css_selector * selector, + + + +void css_get_style(struct content *c, struct css_selector * selector, unsigned int selectors, struct css_style * style) { + struct css_stylesheet *stylesheet = c->data.css.css; struct node *r, *n, *m; unsigned int hash, i, done_empty = 0; - LOG(("stylesheet %p, selectors %u", stylesheet, selectors)); + /*LOG(("stylesheet '%s'", c->url));*/ hash = css_hash(selector[selectors - 1].element); for (r = stylesheet->rule[hash]; ; r = r->next) { @@ -185,31 +335,30 @@ void css_get_style(struct css_stylesheet * stylesheet, struct css_selector * sel done_empty = 1; } if (r == 0) - return; + break; i = selectors - 1; n = r; /* compare element */ if (n->data != 0) if (strcasecmp(selector[i].element, n->data) != 0) goto not_matched; - LOG(("top element '%s' matched", selector[i].element)); + /*LOG(("top element '%s' matched", selector[i].element));*/ while (1) { /* class and id */ for (m = n->left; m != 0; m = m->next) { if (m->type == NODE_ID) { /* TODO: check if case sensitive */ - if (strcmp(selector[i].id, m->data) != 0) + if (strcmp(selector[i].id, m->data + 1) != 0) goto not_matched; } else if (m->type == NODE_CLASS) { /* TODO: check if case sensitive */ - LOG(("comparing class '%s' against '%s'", selector[i].class, m->data)); if (strcmp(selector[i].class, m->data) != 0) goto not_matched; } else { goto not_matched; } } - LOG(("class and id matched")); + /*LOG(("class and id matched"));*/ /* ancestors etc. */ if (n->comb == COMB_NONE) goto matched; /* match successful */ @@ -219,13 +368,13 @@ void css_get_style(struct css_stylesheet * stylesheet, struct css_selector * sel n = n->right; if (n->data == 0) goto not_matched; /* TODO: handle this case */ - LOG(("searching for ancestor '%s'", n->data)); + /*LOG(("searching for ancestor '%s'", n->data));*/ while (i != 0 && strcasecmp(selector[i - 1].element, n->data) != 0) i--; if (i == 0) goto not_matched; i--; - LOG(("found")); + /*LOG(("found"));*/ } else { /* TODO: COMB_PRECEDED, COMB_PARENT */ goto not_matched; @@ -234,12 +383,18 @@ void css_get_style(struct css_stylesheet * stylesheet, struct css_selector * sel matched: /* TODO: sort by specificity */ - LOG(("matched rule %p", r)); + /*LOG(("matched rule %p", r));*/ css_merge(style, r->style); not_matched: } + + /* imported stylesheets */ + for (i = 0; i != c->data.css.import_count; i++) + if (c->data.css.import_content[i] != 0) + css_get_style(c->data.css.import_content[i], selector, + selectors, style); } diff --git a/css/css.h b/css/css.h index a2ac5f4c7..c0b92ac65 100644 --- a/css/css.h +++ b/css/css.h @@ -1,5 +1,5 @@ /** - * $Id: css.h,v 1.4 2003/04/05 21:38:06 bursa Exp $ + * $Id: css.h,v 1.5 2003/04/06 18:09:34 bursa Exp $ */ #ifndef _NETSURF_CSS_CSS_H_ @@ -146,7 +146,7 @@ struct css_stylesheet { struct parse_params { int ruleset_only; - struct css_stylesheet *stylesheet; + struct content *stylesheet; struct node *declaration; }; @@ -170,7 +170,8 @@ void css_destroy(struct content *c); struct node * css_new_node(node_type type, char *data, struct node *left, struct node *right); void css_free_node(struct node *node); -void css_add_ruleset(struct css_stylesheet *stylesheet, +void css_atimport(struct content *c, struct node *node); +void css_add_ruleset(struct content *c, struct node *selector, struct node *declaration); void css_add_declarations(struct css_style *style, struct node *declaration); @@ -184,7 +185,7 @@ void css_parser_(void *yyp, int yymajor, char* yyminor, #endif -void css_get_style(struct css_stylesheet * stylesheet, struct css_selector * selector, +void css_get_style(struct content *c, struct css_selector * selector, unsigned int selectors, struct css_style * style); void css_cascade(struct css_style * const style, const struct css_style * const apply); void css_merge(struct css_style * const style, const struct css_style * const apply); diff --git a/css/parser.y b/css/parser.y index 8625c900f..50d793dad 100644 --- a/css/parser.y +++ b/css/parser.y @@ -1,5 +1,5 @@ /** - * $Id: parser.y,v 1.5 2003/04/05 16:24:43 bursa Exp $ + * $Id: parser.y,v 1.6 2003/04/06 18:09:34 bursa Exp $ */ /* @@ -36,7 +36,10 @@ statement ::= ruleset. statement ::= at_rule. at_rule ::= ATKEYWORD any_list block. -at_rule ::= ATKEYWORD any_list SEMI. +at_rule ::= ATKEYWORD(A) any_list(B) SEMI. + { if (strcasecmp(A, "@import") == 0) + css_atimport(param->stylesheet, B); + free(A); css_free_node(B); } block ::= LBRACE block_body RBRACE. block_body ::= . diff --git a/css/ruleset.c b/css/ruleset.c index 6b16c96b7..79587611e 100644 --- a/css/ruleset.c +++ b/css/ruleset.c @@ -1,5 +1,5 @@ /** - * $Id: ruleset.c,v 1.4 2003/04/05 21:38:06 bursa Exp $ + * $Id: ruleset.c,v 1.5 2003/04/06 18:09:34 bursa Exp $ */ #include @@ -7,6 +7,7 @@ #include #include #define CSS_INTERNALS +#define NDEBUG #include "netsurf/css/css.h" #include "netsurf/utils/log.h" #include "netsurf/utils/utils.h" @@ -99,10 +100,11 @@ static const struct font_size_entry font_size_table[] = { * css_add_ruleset -- add a ruleset to a stylesheet */ -void css_add_ruleset(struct css_stylesheet *stylesheet, +void css_add_ruleset(struct content *c, struct node *selector, struct node *declaration) { + struct css_stylesheet *stylesheet = c->data.css.css; struct node *n, *sel, *next_sel; struct css_style *style; unsigned int hash; diff --git a/makefile b/makefile index 05efea58f..3b0ead684 100644 --- a/makefile +++ b/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.16 2003/04/04 15:19:31 bursa Exp $ +# $Id: makefile,v 1.17 2003/04/06 18:09:34 bursa Exp $ all: !NetSurf/!RunImage,ff8 clean: @@ -62,7 +62,7 @@ utils/arm-riscos-aof/%.o: utils/%.c $(HEADERS) css/css_enum.c css/css_enum.h: css/css_enums css/makeenum cd ..; /usr/bin/perl netsurf/css/makeenum netsurf/css/css_enum < netsurf/css/css_enums -css/parser.c css/parser.h: css/parser.y +css/parser.c: css/parser.y -cd css; lemon parser.y css/scanner.c css/scanner.h: css/scanner.l diff --git a/render/box.c b/render/box.c index b8ef34c9b..46c20c073 100644 --- a/render/box.c +++ b/render/box.c @@ -1,5 +1,5 @@ /** - * $Id: box.c,v 1.37 2003/04/05 21:38:06 bursa Exp $ + * $Id: box.c,v 1.38 2003/04/06 18:09:34 bursa Exp $ */ #include @@ -424,7 +424,7 @@ struct css_style * box_get_style(struct content ** stylesheet, for (i = 0; i != stylesheet_count; i++) { if (stylesheet[i] != 0) { assert(stylesheet[i]->type == CONTENT_CSS); - css_get_style(stylesheet[i]->data.css, selector, depth, style_new); + css_get_style(stylesheet[i], selector, depth, style_new); } } css_cascade(style, style_new); diff --git a/render/html.c b/render/html.c index 63bab48c0..829e437fa 100644 --- a/render/html.c +++ b/render/html.c @@ -1,5 +1,5 @@ /** - * $Id: html.c,v 1.8 2003/04/05 21:38:06 bursa Exp $ + * $Id: html.c,v 1.9 2003/04/06 18:09:34 bursa Exp $ */ #include @@ -33,7 +33,6 @@ void html_create(struct content *c) c->data.html.document = NULL; c->data.html.markup = NULL; c->data.html.layout = NULL; - c->data.html.stylesheet = NULL; c->data.html.style = NULL; c->data.html.fonts = NULL; } @@ -57,6 +56,7 @@ int html_convert(struct content *c, unsigned int width, unsigned int height) struct css_selector* selector = xcalloc(1, sizeof(struct css_selector)); struct fetch_data *fetch_data; unsigned int i; + char status[80]; htmlParseChunk(c->data.html.parser, "", 0, 1); c->data.html.document = c->data.html.parser->myDoc; @@ -101,6 +101,10 @@ int html_convert(struct content *c, unsigned int width, unsigned int height) } while (c->active != 0) { + if (c->status_callback != 0) { + sprintf(status, "Loading %u stylesheets", c->active); + c->status_callback(c->status_p, status); + } fetch_poll(); gui_multitask(); } @@ -110,8 +114,6 @@ int html_convert(struct content *c, unsigned int width, unsigned int height) return 1; } - c->data.html.stylesheet = c->data.html.stylesheet_content[0]->data.css; - LOG(("Copying base style")); c->data.html.style = xcalloc(1, sizeof(struct css_style)); memcpy(c->data.html.style, &css_base_style, sizeof(struct css_style)); @@ -123,6 +125,7 @@ int html_convert(struct content *c, unsigned int width, unsigned int height) c->data.html.fonts = font_new_set(); + c->status_callback(c->status_p, "Formatting document"); LOG(("XML to box")); xml_to_box(c->data.html.markup, c->data.html.style, c->data.html.stylesheet_content, c->data.html.stylesheet_count, -- cgit v1.2.3