From 63b6455f7365507ce502369b738ecc09e54e25ed Mon Sep 17 00:00:00 2001 From: James Bursa Date: Sun, 13 Apr 2003 12:50:10 +0000 Subject: [project @ 2003-04-13 12:50:10 by bursa] style element, CSS fixes, id selectors. svn path=/import/netsurf/; revision=124 --- !NetSurf/Resources/CSS,f79 | 5 ++- !NetSurf/Resources/intro,faf | 2 +- content/content.h | 3 +- css/css.h | 3 +- css/parser.y | 8 ++-- css/ruleset.c | 55 +++++++++++++++++++----- render/box.c | 41 ++++++++++++------ render/html.c | 100 +++++++++++++++++++++++++++++-------------- render/layout.c | 16 ++++++- 9 files changed, 167 insertions(+), 66 deletions(-) diff --git a/!NetSurf/Resources/CSS,f79 b/!NetSurf/Resources/CSS,f79 index 9bdc141d8..55400d14d 100644 --- a/!NetSurf/Resources/CSS,f79 +++ b/!NetSurf/Resources/CSS,f79 @@ -1,6 +1,6 @@ html { font-size: medium } -address, blockquote, body, br, dd, div, +address, blockquote, body, br, dd, div, dl, dt, fieldset, form, h1, h2, h3, h4, h5, h6, html, object, ol, p, ul, @@ -19,7 +19,7 @@ col { display: table-column } colgroup { display: table-column-group } td, th { display: table-cell } caption { display: table-caption } -img { display:inline} +img { color: #0b0; font-style: italic; } h1 { font-size: xx-large; font-weight: bold; } h2 { font-size: x-large; } @@ -31,6 +31,7 @@ b, strong { font-weight: bold; } i, em { font-style: italic; } a { color: #00f; } th { font-weight: bold; } +td { text-align: left; } hr { background-color: #000; height: 1px; } diff --git a/!NetSurf/Resources/intro,faf b/!NetSurf/Resources/intro,faf index b2edb88e7..e79aff807 100644 --- a/!NetSurf/Resources/intro,faf +++ b/!NetSurf/Resources/intro,faf @@ -30,6 +30,7 @@ text-align, float, width & height) fetching
  • Memory cache
  • External CSS files
  • +
  • <style> element
  • In Progress

    @@ -37,7 +38,6 @@ fetching
  • Improved memory handling (currently exits when memory is exhausted)
  • Forms (display but don't submit)
  • Images (stand-alone JPEGs so far)
  • -
  • <style> element

  • diff --git a/content/content.h b/content/content.h index 381a36bf5..ce7f05248 100644 --- a/content/content.h +++ b/content/content.h @@ -1,5 +1,5 @@ /** - * $Id: content.h,v 1.7 2003/04/10 21:44:45 bursa Exp $ + * $Id: content.h,v 1.8 2003/04/13 12:50:10 bursa Exp $ */ #ifndef _NETSURF_DESKTOP_CONTENT_H_ @@ -59,7 +59,6 @@ struct content htmlParserCtxt* parser; struct box* layout; unsigned int stylesheet_count; - char **stylesheet_url; struct content **stylesheet_content; struct css_style* style; struct { diff --git a/css/css.h b/css/css.h index c0b92ac65..2e89345c5 100644 --- a/css/css.h +++ b/css/css.h @@ -1,5 +1,5 @@ /** - * $Id: css.h,v 1.5 2003/04/06 18:09:34 bursa Exp $ + * $Id: css.h,v 1.6 2003/04/13 12:50:10 bursa Exp $ */ #ifndef _NETSURF_CSS_CSS_H_ @@ -190,5 +190,6 @@ void css_get_style(struct content *c, struct css_selector * selector, 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); void css_parse_property_list(struct css_style * style, char * str); +colour named_colour(const char *name); #endif diff --git a/css/parser.y b/css/parser.y index 50d793dad..81414e5d0 100644 --- a/css/parser.y +++ b/css/parser.y @@ -1,5 +1,5 @@ /** - * $Id: parser.y,v 1.6 2003/04/06 18:09:34 bursa Exp $ + * $Id: parser.y,v 1.7 2003/04/13 12:50:10 bursa Exp $ */ /* @@ -51,7 +51,7 @@ block_body ::= block_body SEMI. ruleset ::= selector_list(A) LBRACE declaration_list(B) RBRACE. { css_add_ruleset(param->stylesheet, A, B); css_free_node(B); } -ruleset ::= any_list_1(A) LBRACE declaration_list(B) RBRACE. +/*ruleset ::= any_list_1(A) LBRACE declaration_list(B) RBRACE. { css_free_node(A); css_free_node(B); } /* not CSS2 */ ruleset ::= LBRACE declaration_list(A) RBRACE. /* this form of ruleset not used in CSS2 @@ -120,8 +120,8 @@ any_list(A) ::= . { A = 0; } any_list(A) ::= any(B) any_list(C). { B->next = C; A = B; } -any_list_1(A) ::= any(B) any_list(C). - { B->next = C; A = B; } +/*any_list_1(A) ::= any(B) any_list(C). + { B->next = C; A = B; }*/ any(A) ::= IDENT(B). { A = css_new_node(NODE_IDENT, B, 0, 0); } any(A) ::= NUMBER(B). diff --git a/css/ruleset.c b/css/ruleset.c index 57f4f6946..0fa366f3e 100644 --- a/css/ruleset.c +++ b/css/ruleset.c @@ -1,5 +1,5 @@ /** - * $Id: ruleset.c,v 1.6 2003/04/10 21:44:45 bursa Exp $ + * $Id: ruleset.c,v 1.7 2003/04/13 12:50:10 bursa Exp $ */ #include @@ -62,25 +62,26 @@ static const struct property_entry property_table[] = { { "width", parse_width }, }; -/* table of standard colour names: MUST be sorted by colour name */ +/* table of standard colour names: MUST be sorted by colour name + * note: colour is 0xbbggrr */ static const struct colour_entry colour_table[] = { - { "aqua", 0x00ffff }, + { "aqua", 0xffff00 }, { "black", 0x000000 }, - { "blue", 0x0000ff }, + { "blue", 0xff0000 }, { "fuchsia", 0xff00ff }, { "gray", 0x808080 }, { "green", 0x008000 }, { "lime", 0x00ff00 }, - { "maroon", 0x800000 }, - { "navy", 0x000080 }, - { "olive", 0x808000 }, + { "maroon", 0x000080 }, + { "navy", 0x800000 }, + { "olive", 0x008080 }, { "purple", 0x800080 }, - { "red", 0xff0000 }, + { "red", 0x0000ff }, { "silver", 0xc0c0c0 }, - { "teal", 0x008080 }, + { "teal", 0x808000 }, { "transparent", TRANSPARENT }, { "white", 0xffffff }, - { "yellow", 0xffff00 }, + { "yellow", 0x00ffff }, }; /* table of font sizes: MUST be sorted by name */ @@ -112,6 +113,26 @@ void css_add_ruleset(struct content *c, for (sel = selector; sel != 0; sel = next_sel) { next_sel = sel->next; + /*LOG(("+++")); + for (n = sel; n != 0; n = n->right) { + struct node *m; + if (n->data != 0) + fprintf(stderr, "%s", n->data); + for (m = n->left; m != 0; m = m->next) { + switch (m->type) { + case NODE_ID: fprintf(stderr, "%s", m->data); break; + case NODE_CLASS: fprintf(stderr, ".%s", m->data); break; + default: fprintf(stderr, "unexpected node"); + } + } + fprintf(stderr, " "); + } + fprintf(stderr, "\n");*/ + + /* skip empty selectors */ + if (sel->left == 0 && sel->data == 0) + continue; + /* check if this selector is already present */ hash = css_hash(sel->data); for (n = stylesheet->rule[hash]; n != 0; n = n->next) @@ -160,7 +181,7 @@ int compare_selectors(struct node *n0, struct node *n1) { struct node *m0, *m1; unsigned int count0 = 0, count1 = 0; - + /* compare element name */ if (!((n0->data == 0 && n1->data == 0) || (n0->data != 0 && n1->data != 0 && strcmp(n0->data, n1->data) == 0))) @@ -216,6 +237,18 @@ int parse_length(struct css_length * const length, const struct node * const v) } +colour named_colour(const char *name) +{ + struct colour_entry *col; + col = bsearch(name, colour_table, + sizeof(colour_table) / sizeof(colour_table[0]), + sizeof(colour_table[0]), strcasecmp); + if (col == 0) + return TRANSPARENT; + return col->col; +} + + colour parse_colour(const struct node * const v) { colour c = TRANSPARENT; diff --git a/render/box.c b/render/box.c index a94088fa6..f99715659 100644 --- a/render/box.c +++ b/render/box.c @@ -1,5 +1,5 @@ /** - * $Id: box.c,v 1.40 2003/04/11 21:06:51 bursa Exp $ + * $Id: box.c,v 1.41 2003/04/13 12:50:10 bursa Exp $ */ #include @@ -148,10 +148,11 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style, { struct box * box = 0; struct box * inline_container_c; - struct css_style * style; + struct css_style * style = 0; xmlNode * c; char * s; char * text = 0; + xmlChar *s2; assert(n != 0 && parent_style != 0 && stylesheet != 0 && selector != 0 && parent != 0 && fonts != 0); @@ -163,15 +164,17 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style, *selector = xrealloc(*selector, (depth + 1) * sizeof(struct css_selector)); (*selector)[depth].element = (const char *) n->name; (*selector)[depth].class = (*selector)[depth].id = 0; - if ((s = (char *) xmlGetProp(n, (const xmlChar *) "class"))) { - (*selector)[depth].class = s; - /*free(s);*/ - } + if ((s = (char *) xmlGetProp(n, (const xmlChar *) "class"))) + (*selector)[depth].class = s; /* TODO: free this later */ + if ((s = (char *) xmlGetProp(n, (const xmlChar *) "id"))) + (*selector)[depth].id = s; style = box_get_style(stylesheet, stylesheet_count, parent_style, n, *selector, depth + 1); LOG(("display: %s", css_display_name[style->display])); - if (style->display == CSS_DISPLAY_NONE) + if (style->display == CSS_DISPLAY_NONE) { + free(style); return inline_container; + } /* special elements */ if (strcmp((const char *) n->name, "a") == 0) { @@ -187,13 +190,18 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style, LOG(("image")); /*box = box_image(n, style, href); add_img_element(elements, box->img);*/ - if (style->display == CSS_DISPLAY_INLINE) { + /*if (style->display == CSS_DISPLAY_INLINE) { if ((s = (char *) xmlGetProp(n, (const xmlChar *) "alt"))) { text = squash_tolat1(s); xfree(s); } - } + }*/ /* TODO: block images, start fetch */ + if ((s2 = xmlGetProp(n, (const xmlChar *) "alt"))) { + xmlNode *alt = xmlNewText(s2); + free(s2); + xmlAddChild(n, alt); + } } else if (strcmp((const char *) n->name, "textarea") == 0) { char * content = xmlNodeGetContent(n); @@ -213,7 +221,7 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style, for (c = n->children; c != 0; c = c->next) { if (strcmp((const char *) c->name, "option") == 0) { char * content = xmlNodeGetContent(c); - char * thistext = tolat1(content); + char * thistext = squash_tolat1(content); LOG(("option")); current_option = box_option(c, style, current_select); option_addtext(current_option, thistext); @@ -242,6 +250,8 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style, inline_container->last->space = 1; } xfree(text); + if (style != 0) + free(style); return inline_container; } } @@ -283,7 +293,6 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style, parent = box_create(BOX_FLOAT_LEFT, 0, href); if (style->float_ == CSS_FLOAT_RIGHT) parent->type = BOX_FLOAT_RIGHT; box_add_child(inline_container, parent); - style->float_ = CSS_FLOAT_NONE; if (style->display == CSS_DISPLAY_INLINE) style->display = CSS_DISPLAY_BLOCK; @@ -309,7 +318,9 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style, selector, depth + 1, box, inline_container_c, href, fonts, current_select, current_option, current_textarea, current_form, elements); - inline_container = 0; + if (style->float_ == CSS_FLOAT_NONE) + /* continue in this inline container if this is a float */ + inline_container = 0; break; case CSS_DISPLAY_INLINE: /* inline elements get no box, but their children do */ assert(box == 0); /* special inline elements have already been @@ -423,6 +434,8 @@ struct css_style * box_get_style(struct content ** stylesheet, unsigned int r, g, b; if (s[0] == '#' && sscanf(s + 1, "%2x%2x%2x", &r, &g, &b) == 3) style->background_color = (b << 16) | (g << 8) | r; + else if (s[0] != '#') + style->background_color = named_colour(s); free(s); } @@ -437,6 +450,8 @@ struct css_style * box_get_style(struct content ** stylesheet, unsigned int r, g, b; if (s[0] == '#' && sscanf(s + 1, "%2x%2x%2x", &r, &g, &b) == 3) style->color = (b << 16) | (g << 8) | r; + else if (s[0] != '#') + style->color = named_colour(s); free(s); } @@ -452,6 +467,8 @@ struct css_style * box_get_style(struct content ** stylesheet, unsigned int r, g, b; if (s[0] == '#' && sscanf(s + 1, "%2x%2x%2x", &r, &g, &b) == 3) style->color = (b << 16) | (g << 8) | r; + else if (s[0] != '#') + style->color = named_colour(s); free(s); } } diff --git a/render/html.c b/render/html.c index f3f547e88..9b38b7378 100644 --- a/render/html.c +++ b/render/html.c @@ -1,5 +1,5 @@ /** - * $Id: html.c,v 1.13 2003/04/11 21:06:51 bursa Exp $ + * $Id: html.c,v 1.14 2003/04/13 12:50:10 bursa Exp $ */ #include @@ -91,22 +91,10 @@ int html_convert(struct content *c, unsigned int width, unsigned int height) html_title(c, head); /* get stylesheets */ - html_find_stylesheets(c, head); - c->data.html.stylesheet_content = xcalloc(c->data.html.stylesheet_count, - sizeof(*c->data.html.stylesheet_content)); - c->error = 0; c->active = 0; - for (i = 0; i != c->data.html.stylesheet_count; i++) { - fetch_data = xcalloc(1, sizeof(*fetch_data)); - fetch_data->c = c; - fetch_data->i = i; - c->active++; - fetchcache(c->data.html.stylesheet_url[i], c->url, - html_convert_css_callback, - fetch_data, width, height, 1 << CONTENT_CSS); - } + html_find_stylesheets(c, head); while (c->active != 0) { if (c->status_callback != 0) { @@ -142,12 +130,11 @@ int html_convert(struct content *c, unsigned int width, unsigned int height) xmlFreeDoc(document); cache_free(c->data.html.stylesheet_content[0]); - for (i = 1; i != c->data.html.stylesheet_count; i++) { + if (c->data.html.stylesheet_content[1] != 0) + content_destroy(c->data.html.stylesheet_content[1]); + for (i = 2; i != c->data.html.stylesheet_count; i++) if (c->data.html.stylesheet_content[i] != 0) cache_free(c->data.html.stylesheet_content[i]); - xfree(c->data.html.stylesheet_url[i]); - } - xfree(c->data.html.stylesheet_url); xfree(c->data.html.stylesheet_content); c->status_callback(c->status_p, "Formatting document"); @@ -171,7 +158,7 @@ void html_convert_css_callback(fetchcache_msg msg, struct content *css, switch (msg) { case FETCHCACHE_OK: free(data); - LOG(("got stylesheet '%s'", c->data.html.stylesheet_url[i])); + LOG(("got stylesheet '%s'", css->url)); c->data.html.stylesheet_content[i] = css; /*css_dump_stylesheet(css->data.css);*/ c->active--; @@ -214,12 +201,22 @@ void html_title(struct content *c, xmlNode *head) void html_find_stylesheets(struct content *c, xmlNode *head) { xmlNode *node; - char *rel, *type, *media, *href; - unsigned int count = 1; + char *rel, *type, *media, *href, *data, *url; + unsigned int i = 2; + struct fetch_data *fetch_data; + + /* stylesheet 0 is the base style sheet, stylesheet 1 is any