From 9317e33d0bb597543239ced2e100ece042cf416f Mon Sep 17 00:00:00 2001 From: James Bursa Date: Wed, 9 Jul 2003 21:33:01 +0000 Subject: [project @ 2003-07-09 21:33:01 by bursa] More work on and plugins. svn path=/import/netsurf/; revision=213 --- render/box.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++-------- render/box.h | 18 +++++++++ render/html.c | 47 +++++++++++++----------- render/layout.c | 26 +------------ 4 files changed, 143 insertions(+), 60 deletions(-) (limited to 'render') diff --git a/render/box.c b/render/box.c index dca53b4e9..d71c1112b 100644 --- a/render/box.c +++ b/render/box.c @@ -84,6 +84,8 @@ static struct result box_applet(xmlNode *n, struct status *status, static struct form* create_form(xmlNode* n); static void add_form_element(struct page_elements* pe, struct form* f); static void add_gadget_element(struct page_elements* pe, struct gui_gadget* g); +static bool plugin_decode(struct content* content, char* url, struct box* box, + struct object_params* po); /* element_table must be sorted by name */ struct element_entry { @@ -156,6 +158,8 @@ struct box * box_create(struct css_style * style, box->font = 0; box->gadget = 0; box->object = 0; + box->object_params = 0; + box->plugin_state = 0; #endif return box; } @@ -1344,6 +1348,8 @@ void box_free_box(struct box *box) else if (box->parent->href != box->href) xmlFree(box->href); } + + /* TODO: free object_params and plugin_state */ } @@ -1394,7 +1400,7 @@ struct result box_object(xmlNode *n, struct status *status, struct css_style *style) { struct box *box; - struct plugin_object *po; + struct object_params *po; char *s, *url; box = box_create(style, status->href, 0); @@ -1453,25 +1459,23 @@ struct result box_object(xmlNode *n, struct status *status, } /* object width */ - if ((s = (char *) xmlGetProp(n, (const xmlChar *) "width"))) { - - po->width = (unsigned int)atoi(s); - LOG(("width: %u", (unsigned int)atoi(s))); - xmlFree(s); - } + if (style->width.width == CSS_WIDTH_LENGTH) + po->width = len(&style->width.value.length, style); /* object height */ - if ((s = (char *) xmlGetProp(n, (const xmlChar *) "height"))) { + if (style->height.height == CSS_HEIGHT_LENGTH) + po->height = len(&style->height.length, style); - po->height = (unsigned int)atoi(s); - LOG(("height: %u", (unsigned int)atoi(s))); - xmlFree(s); - } + /* TODO: go through children looking for , and add + * somewhere in po */ + + box->object_params = po; /* start fetch */ - plugin_decode(status->content, url, box, po); + if (plugin_decode(status->content, url, box, po)) + return (struct result) {box, 0}; - return (struct result) {box, 0}; + return (struct result) {box, 1}; } /** @@ -1482,7 +1486,7 @@ struct result box_embed(xmlNode *n, struct status *status, struct css_style *style) { struct box *box; - struct plugin_object *po; + struct object_params *po; char *s, *url; box = box_create(style, status->href, 0); @@ -1508,6 +1512,8 @@ struct result box_embed(xmlNode *n, struct status *status, xmlFree(s); } + box->object_params = po; + /* start fetch */ plugin_decode(status->content, url, box, po); @@ -1540,3 +1546,79 @@ struct result box_applet(xmlNode *n, struct status *status, return (struct result) {box,0}; } + + +/** + * plugin_decode + * This function checks that the contents of the plugin_object struct + * are valid. If they are, it initiates the fetch process. If they are + * not, it exits, leaving the box structure as it was on entry. This is + * necessary as there are multiple ways of declaring an object's attributes. + * + * Returns false if the object could not be handled. + * + * TODO: alt html + * params - create parameters file and put the filename string + * somewhere such that it is accessible from plugin_create. + */ +bool plugin_decode(struct content* content, char* url, struct box* box, + struct object_params* po) +{ + os_error *e; + unsigned int *fv; + + /* Check if the codebase attribute is defined. + * If it is not, set it to the codebase of the current document. + */ + if(po->codebase == 0) + po->codebase = strdup(content->url); + else + po->codebase = url_join(po->codebase, content->url); + + /* Check that we have some data specified. + * First, check the data attribute. + * Second, check the classid attribute. + * The data attribute takes precedence. + * If neither are specified or if classid begins "clsid:", + * we can't handle this object. + */ + if(po->data == 0 && po->classid == 0) { + return false; + } + if(po->data == 0 && po->classid != 0) { + if(strnicmp(po->classid, "clsid:", 6) == 0) { + LOG(("ActiveX object - n0")); + return false; + } + else { + url = url_join(po->classid, po->codebase); + } + } + else { + url = url_join(po->data, po->codebase); + } + + /* Check if the declared mime type is understandable. + * Checks type and codetype attributes. + */ + if(po->type != 0) { + if (content_lookup(po->type) == CONTENT_OTHER) + return false; + } + if(po->codetype != 0) { + if (content_lookup(po->codetype) == CONTENT_OTHER) + return false; + } + + /* If we've got to here, the object declaration has provided us with + * enough data to enable us to have a go at downloading and displaying it. + * + * We may still find that the object has a MIME type that we can't handle + * when we fetch it (if the type was not specified or is different to that + * given in the attributes). + */ + html_fetch_object(content, url, box); + + return true; +} + diff --git a/render/box.h b/render/box.h index 5a16ecd9c..b67d6e7b1 100644 --- a/render/box.h +++ b/render/box.h @@ -81,6 +81,23 @@ struct gui_gadget { } data; }; +/* state of a plugin handling this box, platform dependent */ +struct plugin_state; + +/* parameters for and related elements */ +struct object_params { + char* data; + char* type; + char* codetype; + char* codebase; + char* classid; + char* paramds; /* very likely to change */ + unsigned int* width; + unsigned int* height; + /* not a parameter, but stored here for convenience */ + struct plugin_state *plugin_state; +}; + struct box { box_type type; struct css_style * style; @@ -105,6 +122,7 @@ struct box { struct font_data *font; struct gui_gadget* gadget; struct content* object; /* usually an image */ + struct object_params *object_params; }; struct form diff --git a/render/html.c b/render/html.c index 60d218121..b8db76ad1 100644 --- a/render/html.c +++ b/render/html.c @@ -96,6 +96,8 @@ int html_convert(struct content *c, unsigned int width, unsigned int height) /* convert xml tree to box tree */ LOG(("XML to box")); + sprintf(c->status_message, "Processing document"); + content_broadcast(c, CONTENT_MSG_STATUS, 0); xml_to_box(html, c); /*box_dump(c->data.html.layout->children, 0);*/ @@ -103,18 +105,18 @@ int html_convert(struct content *c, unsigned int width, unsigned int height) xmlFreeDoc(document); content_remove_user(c->data.html.stylesheet_content[0], - html_convert_css_callback, c, 0); + html_convert_css_callback, c, 0, 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) content_remove_user(c->data.html.stylesheet_content[i], - html_convert_css_callback, c, i); + html_convert_css_callback, c, i, 0); xfree(c->data.html.stylesheet_content); /* layout the box tree */ - sprintf(c->status_message, "Formatting document"); - content_broadcast(c, CONTENT_MSG_STATUS, 0); + 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);*/ @@ -145,7 +147,7 @@ void html_convert_css_callback(content_msg msg, struct content *css, 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); + content_remove_user(css, html_convert_css_callback, c, i, 0); } break; @@ -173,7 +175,7 @@ void html_convert_css_callback(content_msg msg, struct content *css, c->active--; c->data.html.stylesheet_content[i] = fetchcache( error, c->url, html_convert_css_callback, - c, i, css->width, css->height); + c, i, css->width, css->height, 0); if (c->data.html.stylesheet_content[i]->status != CONTENT_STATUS_DONE) c->active++; break; @@ -225,7 +227,7 @@ void html_find_stylesheets(struct content *c, xmlNode *head) #endif c->url, html_convert_css_callback, - c, 0, c->width, c->height); + c, 0, c->width, c->height, 0); if (c->data.html.stylesheet_content[0]->status != CONTENT_STATUS_DONE) c->active++; @@ -275,7 +277,7 @@ void html_find_stylesheets(struct content *c, xmlNode *head) (i + 1) * sizeof(*c->data.html.stylesheet_content)); c->data.html.stylesheet_content[i] = fetchcache(url, c->url, html_convert_css_callback, c, i, - c->width, c->height); + c->width, c->height, 0); if (c->data.html.stylesheet_content[i]->status != CONTENT_STATUS_DONE) c->active++; free(url); @@ -356,7 +358,7 @@ void html_fetch_object(struct content *c, char *url, struct box *box) /* start fetch */ c->data.html.object[i].content = fetchcache(url, c->url, html_object_callback, - c, i, 0, 0); + c, i, 0, 0, box->object_params); c->active++; if (c->data.html.object[i].content->status == CONTENT_STATUS_DONE) html_object_callback(CONTENT_MSG_DONE, @@ -379,7 +381,7 @@ void html_object_callback(content_msg msg, struct content *object, 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); + content_remove_user(object, html_object_callback, c, i, 0); } break; @@ -447,7 +449,8 @@ void html_object_callback(content_msg msg, struct content *object, c->data.html.object[i].url = xstrdup(error); c->data.html.object[i].content = fetchcache( error, c->url, html_object_callback, - c, i, 0, 0); + c, i, 0, 0, + c->data.html.object[i].box->object_params); if (c->data.html.object[i].content->status != CONTENT_STATUS_DONE) c->active++; break; @@ -479,7 +482,8 @@ void html_revive(struct content *c, unsigned int width, unsigned int height) c->data.html.object[i].content = fetchcache( c->data.html.object[i].url, c->url, html_object_callback, - c, i, 0, 0); + c, i, 0, 0, + c->data.html.object[i].box->object_params); if (c->data.html.object[i].content->status != CONTENT_STATUS_DONE) c->active++; } @@ -507,6 +511,16 @@ void html_destroy(struct content *c) unsigned int i; LOG(("content %p", 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) + content_remove_user(c->data.html.object[i].content, + html_object_callback, c, i, + c->data.html.object[i].box->object_params); + free(c->data.html.object[i].url); + } + free(c->data.html.object); + LOG(("layout %p", c->data.html.layout)); if (c->data.html.layout != 0) box_free(c->data.html.layout); @@ -516,14 +530,5 @@ void html_destroy(struct content *c) LOG(("title %p", c->title)); if (c->title != 0) xfree(c->title); - - 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) - 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); } diff --git a/render/layout.c b/render/layout.c index 14e9258f2..1fb27b77c 100644 --- a/render/layout.c +++ b/render/layout.c @@ -32,8 +32,6 @@ * internal functions */ -static signed long len(struct css_length * length, struct css_style * style); - static void layout_node(struct box * box, unsigned long width, struct box * cont, unsigned long cx, unsigned long cy); static void layout_block(struct box * box, unsigned long width, struct box * cont, @@ -54,26 +52,6 @@ static void calculate_widths(struct box *box); static void calculate_inline_container_widths(struct box *box); static void calculate_table_widths(struct box *table); -/** - * convert a struct css_length to pixels - */ - -signed long len(struct css_length * length, struct css_style * style) -{ - assert(!((length->unit == CSS_UNIT_EM || length->unit == CSS_UNIT_EX) && style == 0)); - switch (length->unit) { - case CSS_UNIT_EM: return length->value * len(&style->font_size.value.length, 0); - case CSS_UNIT_EX: return length->value * len(&style->font_size.value.length, 0) * 0.6; - case CSS_UNIT_PX: return length->value; - case CSS_UNIT_IN: return length->value * 90.0; - case CSS_UNIT_CM: return length->value * 35.0; - case CSS_UNIT_MM: return length->value * 3.5; - case CSS_UNIT_PT: return length->value * 90.0 / 72.0; - case CSS_UNIT_PC: return length->value * 90.0 / 6.0; - default: break; - } - return 0; -} /** * layout algorithm @@ -196,7 +174,7 @@ void layout_block(struct box * box, unsigned long width, struct box * cont, switch (style->width.width) { case CSS_WIDTH_LENGTH: - box->width = len(&style->width.value.length, box->style); + box->width = len(&style->width.value.length, style); break; case CSS_WIDTH_PERCENT: box->width = width * style->width.value.percent / 100; @@ -210,7 +188,7 @@ void layout_block(struct box * box, unsigned long width, struct box * cont, box->height = layout_block_children(box, box->width, cont, cx, cy); switch (style->height.height) { case CSS_HEIGHT_LENGTH: - box->height = len(&style->height.length, box->style); + box->height = len(&style->height.length, style); break; case CSS_HEIGHT_AUTO: default: -- cgit v1.2.3