diff options
author | James Bursa <james@netsurf-browser.org> | 2003-04-05 21:38:06 +0000 |
---|---|---|
committer | James Bursa <james@netsurf-browser.org> | 2003-04-05 21:38:06 +0000 |
commit | 2253e38be8cbcf4243e43fc0d317cfda08bffeb2 (patch) | |
tree | 2adcb8330dc2bb0a152a61733f1ec943984f2d53 /render | |
parent | 75768e67001bcf292f9e8bbbe8139a7432835092 (diff) | |
download | netsurf-2253e38be8cbcf4243e43fc0d317cfda08bffeb2.tar.gz netsurf-2253e38be8cbcf4243e43fc0d317cfda08bffeb2.tar.bz2 |
[project @ 2003-04-05 21:38:06 by bursa]
External stylesheets.
svn path=/import/netsurf/; revision=115
Diffstat (limited to 'render')
-rw-r--r-- | render/box.c | 49 | ||||
-rw-r--r-- | render/box.h | 5 | ||||
-rw-r--r-- | render/html.c | 123 |
3 files changed, 137 insertions, 40 deletions
diff --git a/render/box.c b/render/box.c index 11093c52b..b8ef34c9b 100644 --- a/render/box.c +++ b/render/box.c @@ -1,5 +1,5 @@ /** - * $Id: box.c,v 1.36 2003/04/04 15:19:31 bursa Exp $ + * $Id: box.c,v 1.37 2003/04/05 21:38:06 bursa Exp $ */ #include <assert.h> @@ -26,14 +26,15 @@ static struct box * box_create(xmlNode * node, box_type type, struct css_style * char *href); static char * tolat1(xmlChar * s); static struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style, - struct css_stylesheet * stylesheet, + struct content ** stylesheet, unsigned int stylesheet_count, struct css_selector ** selector, unsigned int depth, struct box * parent, struct box * inline_container, char *href, struct font_set *fonts, struct gui_gadget* current_select, struct formoption* current_option, struct gui_gadget* current_textarea, struct form* current_form, struct page_elements* elements); -static struct css_style * box_get_style(struct css_stylesheet * stylesheet, struct css_style * parent_style, +static struct css_style * box_get_style(struct content ** stylesheet, + unsigned int stylesheet_count, struct css_style * parent_style, xmlNode * n, struct css_selector * selector, unsigned int depth); static void box_normalise_block(struct box *block); static void box_normalise_table(struct box *table); @@ -144,7 +145,7 @@ char * tolat1(xmlChar * s) */ void xml_to_box(xmlNode * n, struct css_style * parent_style, - struct css_stylesheet * stylesheet, + struct content ** stylesheet, unsigned int stylesheet_count, struct css_selector ** selector, unsigned int depth, struct box * parent, struct box * inline_container, char *href, struct font_set *fonts, @@ -153,7 +154,7 @@ void xml_to_box(xmlNode * n, struct css_style * parent_style, struct page_elements* elements) { LOG(("node %p", n)); - convert_xml_to_box(n, parent_style, stylesheet, + convert_xml_to_box(n, parent_style, stylesheet, stylesheet_count, selector, depth, parent, inline_container, href, fonts, current_select, current_option, current_textarea, current_form, elements); LOG(("normalising")); @@ -161,7 +162,7 @@ void xml_to_box(xmlNode * n, struct css_style * parent_style, } struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style, - struct css_stylesheet * stylesheet, + struct content ** stylesheet, unsigned int stylesheet_count, struct css_selector ** selector, unsigned int depth, struct box * parent, struct box * inline_container, char *href, struct font_set *fonts, @@ -188,9 +189,10 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style, (*selector)[depth].class = (*selector)[depth].id = 0; if ((s = (char *) xmlGetProp(n, (const xmlChar *) "class"))) { (*selector)[depth].class = s; - free(s); + /*free(s);*/ } - style = box_get_style(stylesheet, parent_style, n, *selector, depth + 1); + 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) return inline_container; @@ -326,7 +328,8 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style, box_add_child(parent, box); inline_container_c = 0; for (c = n->children; c != 0; c = c->next) - inline_container_c = convert_xml_to_box(c, style, stylesheet, + inline_container_c = convert_xml_to_box(c, style, + stylesheet, stylesheet_count, selector, depth + 1, box, inline_container_c, href, fonts, current_select, current_option, current_textarea, current_form, elements); @@ -336,7 +339,8 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style, assert(box == 0); /* special inline elements have already been added to the inline container above */ for (c = n->children; c != 0; c = c->next) - inline_container = convert_xml_to_box(c, style, stylesheet, + inline_container = convert_xml_to_box(c, style, + stylesheet, stylesheet_count, selector, depth + 1, parent, inline_container, href, fonts, current_select, current_option, current_textarea, current_form, elements); @@ -345,7 +349,7 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style, box = box_create(n, BOX_TABLE, style, href); box_add_child(parent, box); for (c = n->children; c != 0; c = c->next) - convert_xml_to_box(c, style, stylesheet, + convert_xml_to_box(c, style, stylesheet, stylesheet_count, selector, depth + 1, box, 0, href, fonts, current_select, current_option, current_textarea, current_form, elements); @@ -358,7 +362,8 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style, box_add_child(parent, box); inline_container_c = 0; for (c = n->children; c != 0; c = c->next) - inline_container_c = convert_xml_to_box(c, style, stylesheet, + inline_container_c = convert_xml_to_box(c, style, + stylesheet, stylesheet_count, selector, depth + 1, box, inline_container_c, href, fonts, current_select, current_option, current_textarea, current_form, elements); @@ -368,7 +373,7 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style, box = box_create(n, BOX_TABLE_ROW, style, href); box_add_child(parent, box); for (c = n->children; c != 0; c = c->next) - convert_xml_to_box(c, style, stylesheet, + convert_xml_to_box(c, style, stylesheet, stylesheet_count, selector, depth + 1, box, 0, href, fonts, current_select, current_option, current_textarea, current_form, elements); @@ -384,7 +389,8 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style, box_add_child(parent, box); inline_container_c = 0; for (c = n->children; c != 0; c = c->next) - inline_container_c = convert_xml_to_box(c, style, stylesheet, + inline_container_c = convert_xml_to_box(c, style, + stylesheet, stylesheet_count, selector, depth + 1, box, inline_container_c, href, fonts, current_select, current_option, current_textarea, current_form, elements); @@ -404,14 +410,25 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style, * get the style for an element */ -struct css_style * box_get_style(struct css_stylesheet * stylesheet, struct css_style * parent_style, +struct css_style * box_get_style(struct content ** stylesheet, + unsigned int stylesheet_count, struct css_style * parent_style, xmlNode * n, struct css_selector * selector, unsigned int depth) { struct css_style * style = xcalloc(1, sizeof(struct css_style)); + struct css_style * style_new = xcalloc(1, sizeof(struct css_style)); char * s; + unsigned int i; memcpy(style, parent_style, sizeof(struct css_style)); - css_get_style(stylesheet, selector, depth, style); + memcpy(style_new, &css_blank_style, sizeof(struct css_style)); + 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_cascade(style, style_new); + free(style_new); if ((s = (char *) xmlGetProp(n, (const xmlChar *) "align"))) { if (strcmp((const char *) n->name, "table") == 0 || diff --git a/render/box.h b/render/box.h index 4477d24c1..21e80a096 100644 --- a/render/box.h +++ b/render/box.h @@ -1,5 +1,5 @@ /** - * $Id: box.h,v 1.21 2003/04/04 15:19:31 bursa Exp $ + * $Id: box.h,v 1.22 2003/04/05 21:38:06 bursa Exp $ */ #ifndef _NETSURF_RENDER_BOX_H_ @@ -133,7 +133,8 @@ struct page_elements * interface */ -void xml_to_box(xmlNode * n, struct css_style * parent_style, struct css_stylesheet * stylesheet, +void xml_to_box(xmlNode * n, struct css_style * parent_style, + struct content ** stylesheet, unsigned int stylesheet_count, struct css_selector ** selector, unsigned int depth, struct box * parent, struct box * inline_container, char *href, struct font_set *fonts, diff --git a/render/html.c b/render/html.c index 9b2508c65..63bab48c0 100644 --- a/render/html.c +++ b/render/html.c @@ -1,9 +1,10 @@ /** - * $Id: html.c,v 1.7 2003/04/04 15:19:31 bursa Exp $ + * $Id: html.c,v 1.8 2003/04/05 21:38:06 bursa Exp $ */ #include <assert.h> #include <string.h> +#include <strings.h> #include <stdlib.h> #include "netsurf/content/fetch.h" #include "netsurf/content/fetchcache.h" @@ -14,9 +15,16 @@ #include "netsurf/utils/log.h" -static void html_convert_callback(fetchcache_msg msg, struct content *css, +struct fetch_data { + struct content *c; + unsigned int i; +}; + + +static void html_convert_css_callback(fetchcache_msg msg, struct content *css, void *p, const char *error); static void html_title(struct content *c); +static void html_find_stylesheets(struct content *c); void html_create(struct content *c) @@ -47,6 +55,8 @@ void html_process_data(struct content *c, char *data, unsigned long size) 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; htmlParseChunk(c->data.html.parser, "", 0, 1); c->data.html.document = c->data.html.parser->myDoc; @@ -66,19 +76,29 @@ int html_convert(struct content *c, unsigned int width, unsigned int height) LOG(("No markup")); return 1; } - if (stricmp((const char *) c->data.html.markup->name, "html")) { + if (strcmp((const char *) c->data.html.markup->name, "html")) { LOG(("Not html")); return 1; } html_title(c); + /* get stylesheets */ + html_find_stylesheets(c); + c->data.html.stylesheet_content = xcalloc(c->data.html.stylesheet_count, + sizeof(*c->data.html.stylesheet_content)); + c->error = 0; c->active = 0; - fetchcache("file:///%3CNetSurf$Dir%3E/Resources/CSS", 0, - html_convert_callback, c, width, height); - c->active++; + 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); + } while (c->active != 0) { fetch_poll(); @@ -89,6 +109,8 @@ int html_convert(struct content *c, unsigned int width, unsigned int height) /* TODO: clean up */ 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)); @@ -102,7 +124,8 @@ int html_convert(struct content *c, unsigned int width, unsigned int height) c->data.html.fonts = font_new_set(); LOG(("XML to box")); - xml_to_box(c->data.html.markup, c->data.html.style, c->data.html.stylesheet, + xml_to_box(c->data.html.markup, c->data.html.style, + c->data.html.stylesheet_content, c->data.html.stylesheet_count, &selector, 0, c->data.html.layout, 0, 0, c->data.html.fonts, 0, 0, 0, 0, &c->data.html.elements); /*box_dump(c->data.html.layout->children, 0);*/ @@ -118,18 +141,24 @@ int html_convert(struct content *c, unsigned int width, unsigned int height) } -void html_convert_callback(fetchcache_msg msg, struct content *css, +void html_convert_css_callback(fetchcache_msg msg, struct content *css, void *p, const char *error) { - struct content *c = p; + struct fetch_data *data = p; + struct content *c = data->c; + unsigned int i = data->i; switch (msg) { case FETCHCACHE_OK: - /* TODO: store struct content *css somewhere in c */ - c->data.html.stylesheet = css->data.css; + free(data); + LOG(("got stylesheet '%s'", c->data.html.stylesheet_url[i])); + c->data.html.stylesheet_content[i] = css; + /*css_dump_stylesheet(css->data.css);*/ c->active--; break; case FETCHCACHE_BADTYPE: case FETCHCACHE_ERROR: + free(data); + c->data.html.stylesheet_content[i] = 0; c->active--; c->error = 1; break; @@ -145,27 +174,77 @@ void html_convert_callback(fetchcache_msg msg, struct content *css, void html_title(struct content *c) { - xmlNode *node = c->data.html.markup; + xmlNode *head = c->data.html.markup->children; + xmlNode *node; c->title = 0; - while (node != 0) { - if (node->type == XML_ELEMENT_NODE) { - if (stricmp(node->name, "html") == 0) { - node = node->children; + if (strcmp(head->name, "head") != 0) + return; + for (node = head->children; node != 0; node = node->next) { + if (strcmp(node->name, "title") == 0) { + c->title = xmlNodeGetContent(node); + return; + } + } +} + + +void html_find_stylesheets(struct content *c) +{ + xmlNode *head = c->data.html.markup->children; + xmlNode *node; + char *rel, *type, *media, *href; + unsigned int count = 1; + + c->data.html.stylesheet_url = xcalloc(1, sizeof(*c->data.html.stylesheet_url)); + c->data.html.stylesheet_url[0] = "file:///%3CNetSurf$Dir%3E/Resources/CSS"; + + if (strcmp(head->name, "head") != 0) + return; + for (node = head->children; node != 0; node = node->next) { + if (strcmp(node->name, "link") == 0) { + /* rel='stylesheet' */ + if (!(rel = (char *) xmlGetProp(node, (const xmlChar *) "rel"))) + continue; + if (strcasecmp(rel, "stylesheet") != 0) { + free(rel); continue; } - if (stricmp(node->name, "head") == 0) { - node = node->children; + free(rel); + + /* type='text/css' */ + if (!(type = (char *) xmlGetProp(node, (const xmlChar *) "type"))) + continue; + if (strcmp(type, "text/css") != 0) { + free(type); continue; } - if (stricmp(node->name, "title") == 0) { - c->title = xmlNodeGetContent(node); - return; + free(type); + + /* media='screen' or not present */ + if ((media = (char *) xmlGetProp(node, (const xmlChar *) "media"))) { + if (strcasecmp(media, "screen") != 0) { + free(media); + continue; + } + free(media); } + + /* href='...' */ + if (!(href = (char *) xmlGetProp(node, (const xmlChar *) "href"))) + continue; + + count++; + c->data.html.stylesheet_url = xrealloc(c->data.html.stylesheet_url, + count * sizeof(*c->data.html.stylesheet_url)); + c->data.html.stylesheet_url[count - 1] = url_join(href, c->url); + LOG(("linked stylesheet '%s'", c->data.html.stylesheet_url[count - 1])); + free(href); } - node = node->next; } + + c->data.html.stylesheet_count = count; } |