summaryrefslogtreecommitdiff
path: root/render
diff options
context:
space:
mode:
authorJames Bursa <james@netsurf-browser.org>2003-04-05 21:38:06 +0000
committerJames Bursa <james@netsurf-browser.org>2003-04-05 21:38:06 +0000
commit2253e38be8cbcf4243e43fc0d317cfda08bffeb2 (patch)
tree2adcb8330dc2bb0a152a61733f1ec943984f2d53 /render
parent75768e67001bcf292f9e8bbbe8139a7432835092 (diff)
downloadnetsurf-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.c49
-rw-r--r--render/box.h5
-rw-r--r--render/html.c123
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;
}