summaryrefslogtreecommitdiff
path: root/render/html.c
diff options
context:
space:
mode:
authorJames Bursa <james@netsurf-browser.org>2003-06-17 19:24:21 +0000
committerJames Bursa <james@netsurf-browser.org>2003-06-17 19:24:21 +0000
commit0c0ff3c59631d0968c888279195ea40d4a7fd824 (patch)
treef94b64c20bc361664de61ef8993be7693ad2a08d /render/html.c
parentce6dbbb5db1d4ffe77ca99411ddb2d19694eff9c (diff)
downloadnetsurf-0c0ff3c59631d0968c888279195ea40d4a7fd824.tar.gz
netsurf-0c0ff3c59631d0968c888279195ea40d4a7fd824.tar.bz2
[project @ 2003-06-17 19:24:20 by bursa]
Change fetchcache system to store loading contents in cache. svn path=/import/netsurf/; revision=180
Diffstat (limited to 'render/html.c')
-rw-r--r--render/html.c271
1 files changed, 153 insertions, 118 deletions
diff --git a/render/html.c b/render/html.c
index 304de133c..ab6b55560 100644
--- a/render/html.c
+++ b/render/html.c
@@ -1,32 +1,29 @@
/**
- * $Id: html.c,v 1.18 2003/06/05 13:17:55 philpem Exp $
+ * $Id: html.c,v 1.19 2003/06/17 19:24:21 bursa Exp $
*/
#include <assert.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
+#include "netsurf/content/content.h"
#include "netsurf/content/fetch.h"
#include "netsurf/content/fetchcache.h"
+#ifdef riscos
#include "netsurf/desktop/gui.h"
+#endif
#include "netsurf/render/html.h"
#include "netsurf/render/layout.h"
#include "netsurf/utils/utils.h"
#include "netsurf/utils/log.h"
-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_convert_css_callback(content_msg msg, struct content *css,
+ void *p1, void *p2, const char *error);
static void html_title(struct content *c, xmlNode *head);
static void html_find_stylesheets(struct content *c, xmlNode *head);
-static void html_image_callback(fetchcache_msg msg, struct content *image,
- void *p, const char *error);
+static void html_object_callback(content_msg msg, struct content *object,
+ void *p1, void *p2, const char *error);
void html_create(struct content *c)
@@ -43,6 +40,8 @@ void html_create(struct content *c)
void html_process_data(struct content *c, char *data, unsigned long size)
{
unsigned long x;
+ LOG(("content %s, size %lu", c->url, size));
+ cache_dump();
for (x = 0; x + CHUNK <= size; x += CHUNK) {
htmlParseChunk(c->data.html.parser, data + x, CHUNK, 0);
gui_multitask();
@@ -100,16 +99,19 @@ int html_convert(struct content *c, unsigned int width, unsigned int height)
/* XML tree and stylesheets not required past this point */
xmlFreeDoc(document);
- cache_free(c->data.html.stylesheet_content[0]);
+ content_remove_user(c->data.html.stylesheet_content[0],
+ html_convert_css_callback, c, 0);
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]);
+ content_remove_user(c->data.html.stylesheet_content[i],
+ html_convert_css_callback, c, i);
xfree(c->data.html.stylesheet_content);
/* layout the box tree */
- c->status_callback(c->status_p, "Formatting document");
+ sprintf(c->status_message, "Formatting document");
+ content_broadcast(c, CONTENT_MSG_STATUS, 0);
LOG(("Layout document"));
layout_document(c->data.html.layout->children, width);
/*box_dump(c->data.html.layout->children, 0);*/
@@ -117,38 +119,53 @@ int html_convert(struct content *c, unsigned int width, unsigned int height)
c->width = c->data.html.layout->children->width;
c->height = c->data.html.layout->children->height;
- if (c->active != 0)
- c->status = CONTENT_PENDING;
+ if (c->active == 0)
+ c->status = CONTENT_STATUS_DONE;
+ else
+ c->status = CONTENT_STATUS_READY;
return 0;
}
-void html_convert_css_callback(fetchcache_msg msg, struct content *css,
- void *p, const char *error)
+void html_convert_css_callback(content_msg msg, struct content *css,
+ void *p1, void *p2, const char *error)
{
- struct fetch_data *data = p;
- struct content *c = data->c;
- unsigned int i = data->i;
+ struct content *c = p1;
+ unsigned int i = (unsigned int) p2;
switch (msg) {
- case FETCHCACHE_OK:
- free(data);
+ case CONTENT_MSG_LOADING:
+ /* check that the stylesheet is really CSS */
+ if (css->type != CONTENT_CSS) {
+ c->data.html.stylesheet_content[i] = 0;
+ c->active--;
+ c->error = 1;
+ sprintf(c->status_message, "Warning: stylesheet is not CSS");
+ content_broadcast(c, CONTENT_MSG_STATUS, 0);
+ content_remove_user(css, html_convert_css_callback, c, i);
+ }
+ break;
+
+ case CONTENT_MSG_READY:
+ break;
+
+ case CONTENT_MSG_DONE:
LOG(("got stylesheet '%s'", css->url));
- c->data.html.stylesheet_content[i] = css;
- /*css_dump_stylesheet(css->data.css);*/
c->active--;
break;
- case FETCHCACHE_BADTYPE:
- case FETCHCACHE_ERROR:
- free(data);
+
+ case CONTENT_MSG_ERROR:
c->data.html.stylesheet_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 */
+
+ case CONTENT_MSG_STATUS:
+ sprintf(c->status_message, "Loading %u stylesheets: %s",
+ c->active, css->status_message);
+ content_broadcast(c, CONTENT_MSG_STATUS, 0);
break;
+
default:
assert(0);
}
@@ -177,9 +194,8 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
{
xmlNode *node, *node2;
char *rel, *type, *media, *href, *data, *url;
- char status[80];
unsigned int i = 2;
- struct fetch_data *fetch_data;
+ unsigned int last_active = 0;
/* stylesheet 0 is the base style sheet, stylesheet 1 is any <style> elements */
c->data.html.stylesheet_content = xcalloc(2, sizeof(*c->data.html.stylesheet_content));
@@ -189,13 +205,17 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
c->error = 0;
c->active = 0;
- fetch_data = xcalloc(1, sizeof(*fetch_data));
- fetch_data->c = c;
- fetch_data->i = 0;
- c->active++;
- fetchcache("file:///%3CNetSurf$Dir%3E/Resources/CSS", c->url,
+ c->data.html.stylesheet_content[0] = fetchcache(
+#ifdef riscos
+ "file:///%3CNetSurf$Dir%3E/Resources/CSS",
+#else
+ "file:///home/james/Projects/netsurf/CSS",
+#endif
+ c->url,
html_convert_css_callback,
- fetch_data, c->width, c->height, 1 << CONTENT_CSS);
+ c, 0, c->width, c->height);
+ if (c->data.html.stylesheet_content[0]->status != CONTENT_STATUS_DONE)
+ c->active++;
for (node = head == 0 ? 0 : head->children; node != 0; node = node->next) {
if (strcmp(node->name, "link") == 0) {
@@ -238,24 +258,23 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
/* start fetch */
c->data.html.stylesheet_content = xrealloc(c->data.html.stylesheet_content,
(i + 1) * sizeof(*c->data.html.stylesheet_content));
- fetch_data = xcalloc(1, sizeof(*fetch_data));
- fetch_data->c = c;
- fetch_data->i = i;
- c->active++;
- fetchcache(url, c->url, html_convert_css_callback,
- fetch_data, c->width, c->height, 1 << CONTENT_CSS);
+ c->data.html.stylesheet_content[i] = fetchcache(url, c->url,
+ html_convert_css_callback, c, i,
+ c->width, c->height);
+ if (c->data.html.stylesheet_content[i]->status != CONTENT_STATUS_DONE)
+ c->active++;
free(url);
i++;
} else if (strcmp(node->name, "style") == 0) {
- /* type='text/css' */
- if (!(type = (char *) xmlGetProp(node, (const xmlChar *) "type")))
- continue;
- if (strcmp(type, "text/css") != 0) {
+ /* type='text/css', or not present (invalid but common) */
+ if ((type = (char *) xmlGetProp(node, (const xmlChar *) "type"))) {
+ if (strcmp(type, "text/css") != 0) {
+ xmlFree(type);
+ continue;
+ }
xmlFree(type);
- continue;
}
- xmlFree(type);
/* media contains 'screen' or 'all' or not present */
if ((media = (char *) xmlGetProp(node, (const xmlChar *) "media"))) {
@@ -269,8 +288,10 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
/* create stylesheet */
LOG(("style element"));
- if (c->data.html.stylesheet_content[1] == 0)
- c->data.html.stylesheet_content[1] = content_create(CONTENT_CSS, c->url);
+ if (c->data.html.stylesheet_content[1] == 0) {
+ c->data.html.stylesheet_content[1] = content_create(c->url);
+ content_set_type(c->data.html.stylesheet_content[1], CONTENT_CSS);
+ }
/* can't just use xmlNodeGetContent(node), because that won't give
* the content of comments which may be used to 'hide' the content */
@@ -290,71 +311,80 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
/* complete the fetches */
while (c->active != 0) {
- if (c->status_callback != 0) {
- sprintf(status, "Loading %u stylesheets", c->active);
- c->status_callback(c->status_p, status);
+ if (c->active != last_active) {
+ sprintf(c->status_message, "Loading %u stylesheets", c->active);
+ content_broadcast(c, CONTENT_MSG_STATUS, 0);
+ last_active = c->active;
}
fetch_poll();
gui_multitask();
}
if (c->error) {
- c->status_callback(c->status_p, "Warning: some stylesheets failed to load");
+ sprintf(c->status_message, "Warning: some stylesheets failed to load");
+ content_broadcast(c, CONTENT_MSG_STATUS, 0);
}
}
-void html_fetch_image(struct content *c, char *url, struct box *box)
+void html_fetch_object(struct content *c, char *url, struct box *box)
{
struct fetch_data *fetch_data;
+ unsigned int i = c->data.html.object_count;
/* add to object list */
c->data.html.object = xrealloc(c->data.html.object,
- (c->data.html.object_count + 1) *
- sizeof(*c->data.html.object));
- c->data.html.object[c->data.html.object_count].url = url;
- c->data.html.object[c->data.html.object_count].content = 0;
- c->data.html.object[c->data.html.object_count].box = box;
+ (i + 1) * sizeof(*c->data.html.object));
+ c->data.html.object[i].url = url;
+ c->data.html.object[i].box = box;
/* start fetch */
- fetch_data = xcalloc(1, sizeof(*fetch_data));
- fetch_data->c = c;
- fetch_data->i = c->data.html.object_count;
+ c->data.html.object[i].content = fetchcache(url, c->url,
+ html_object_callback,
+ c, i, 0, 0);
+ if (c->data.html.object[i].content->status != CONTENT_STATUS_DONE)
+ c->active++;
c->data.html.object_count++;
- c->active++;
- fetchcache(url, c->url,
- html_image_callback,
- fetch_data, 0, 0,
- (1 << CONTENT_JPEG) | (1 << CONTENT_PNG) |
- (1 << CONTENT_GIF));
}
-void html_image_callback(fetchcache_msg msg, struct content *image,
- void *p, const char *error)
+void html_object_callback(content_msg msg, struct content *object,
+ void *p1, void *p2, const char *error)
{
- struct fetch_data *data = p;
- struct content *c = data->c;
- unsigned int i = data->i;
+ struct content *c = p1;
+ unsigned int i = (unsigned int) p2;
struct box *box = c->data.html.object[i].box;
switch (msg) {
- case FETCHCACHE_OK:
- LOG(("got image '%s'", image->url));
- box->object = image;
- c->data.html.object[i].content = image;
+ case CONTENT_MSG_LOADING:
+ if (CONTENT_OTHER <= c->type) {
+ c->data.html.object[i].content = 0;
+ c->active--;
+ c->error = 1;
+ sprintf(c->status_message, "Warning: bad object type");
+ content_broadcast(c, CONTENT_MSG_STATUS, 0);
+ content_remove_user(object, html_object_callback, c, i);
+ }
+ break;
+
+ case CONTENT_MSG_READY:
+ break;
+
+ case CONTENT_MSG_DONE:
+ LOG(("got object '%s'", object->url));
+ box->object = object;
/* set dimensions to object dimensions if auto */
if (box->style->width.width == CSS_WIDTH_AUTO) {
box->style->width.width = CSS_WIDTH_LENGTH;
box->style->width.value.length.unit = CSS_UNIT_PX;
- box->style->width.value.length.value = image->width;
- box->min_width = box->max_width = box->width = image->width;
+ box->style->width.value.length.value = object->width;
+ box->min_width = box->max_width = box->width = object->width;
/* invalidate parent min, max widths */
if (box->parent->max_width != UNKNOWN_MAX_WIDTH) {
struct box *b = box->parent;
- if (b->min_width < image->width)
- b->min_width = image->width;
- if (b->max_width < image->width)
- b->max_width = image->width;
+ if (b->min_width < object->width)
+ b->min_width = object->width;
+ if (b->max_width < object->width)
+ b->max_width = object->width;
for (b = b->parent;
b != 0 && b->max_width != UNKNOWN_MAX_WIDTH;
b = b->parent)
@@ -364,7 +394,7 @@ void html_image_callback(fetchcache_msg msg, struct content *image,
if (box->style->height.height == CSS_HEIGHT_AUTO) {
box->style->height.height = CSS_HEIGHT_LENGTH;
box->style->height.length.unit = CSS_UNIT_PX;
- box->style->height.length.value = image->height;
+ box->style->height.length.value = object->height;
}
/* remove alt text */
if (box->text != 0) {
@@ -377,49 +407,53 @@ void html_image_callback(fetchcache_msg msg, struct content *image,
box->children = 0;
}*/
/* TODO: recalculate min, max width */
- /* drop through */
- case FETCHCACHE_BADTYPE:
- case FETCHCACHE_ERROR:
- if (c->active == 1 && c->status == CONTENT_PENDING) {
- /* all images have arrived */
- content_reformat(c, c->available_width, 0);
- /*box_dump(c->data.html.layout->children, 0);*/
- }
c->active--;
- if (c->active == 0)
- sprintf(c->status_message, "Document done");
- else
- sprintf(c->status_message, "Loading %i images", c->active);
- free(data);
break;
- case FETCHCACHE_STATUS:
- /* TODO: need to add a way of sending status to the
- * owning window */
+
+ case CONTENT_MSG_ERROR:
+ c->data.html.object[i].content = 0;
+ c->active--;
+ c->error = 1;
+ sprintf(c->status_message, "Image error: %s", error);
+ content_broadcast(c, CONTENT_MSG_STATUS, 0);
+ break;
+
+ case CONTENT_MSG_STATUS:
+ sprintf(c->status_message, "Loading %i objects: %s",
+ c->active, object->status_message);
break;
+
default:
assert(0);
}
+
+ LOG(("%i active", c->active));
+ if (c->active == 0) {
+ /* all objects have arrived */
+ content_reformat(c, c->available_width, 0);
+ c->status = CONTENT_STATUS_DONE;
+ content_broadcast(c, CONTENT_MSG_DONE, 0);
+ }
+ if (c->active == 0)
+ sprintf(c->status_message, "Document done");
+ else
+ sprintf(c->status_message, "Loading %i objects", c->active);
}
void html_revive(struct content *c, unsigned int width, unsigned int height)
{
unsigned int i;
- struct fetch_data *fetch_data;
- /* reload images and fix pointers */
+ /* reload objects and fix pointers */
for (i = 0; i != c->data.html.object_count; i++) {
if (c->data.html.object[i].content != 0) {
- fetch_data = xcalloc(1, sizeof(*fetch_data));
- fetch_data->c = c;
- fetch_data->i = i;
- c->active++;
- fetchcache(c->data.html.object[i].url, c->url,
- html_image_callback,
- fetch_data, 0, 0,
- (1 << CONTENT_JPEG) |
- (1 << CONTENT_PNG) |
- (1 << CONTENT_GIF));
+ c->data.html.object[i].content = fetchcache(
+ c->data.html.object[i].url, c->url,
+ html_object_callback,
+ c, i, 0, 0);
+ if (c->data.html.object[i].content->status != CONTENT_STATUS_DONE)
+ c->active++;
}
}
@@ -428,7 +462,7 @@ void html_revive(struct content *c, unsigned int width, unsigned int height)
c->height = c->data.html.layout->children->height;
if (c->active != 0)
- c->status = CONTENT_PENDING;
+ c->status = CONTENT_STATUS_READY;
}
@@ -458,7 +492,8 @@ void html_destroy(struct content *c)
for (i = 0; i != c->data.html.object_count; i++) {
LOG(("object %i %p", i, c->data.html.object[i].content));
if (c->data.html.object[i].content != 0)
- cache_free(c->data.html.object[i].content);
+ content_remove_user(c->data.html.object[i].content,
+ html_object_callback, c, i);
free(c->data.html.object[i].url);
}
free(c->data.html.object);