mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-23 20:46:50 +03:00
[project @ 2005-04-13 21:58:28 by bursa]
Add fallback field to struct box for object fallback content. Add some checks for tree consistency to box_dump(). Rename struct plugin_params to object_param. Clean up box_object(), box_embed(), box_iframe(), and box_image(). Implement object fallback to contents if the fetch or conversion fails. svn path=/import/netsurf/; revision=1627
This commit is contained in:
parent
4ebe390f8d
commit
11bc5345c5
61
render/box.c
61
render/box.c
@ -75,6 +75,7 @@ struct box * box_create(struct css_style *style,
|
|||||||
box->children = NULL;
|
box->children = NULL;
|
||||||
box->last = NULL;
|
box->last = NULL;
|
||||||
box->parent = NULL;
|
box->parent = NULL;
|
||||||
|
box->fallback = NULL;
|
||||||
box->float_children = NULL;
|
box->float_children = NULL;
|
||||||
box->next_float = NULL;
|
box->next_float = NULL;
|
||||||
box->col = NULL;
|
box->col = NULL;
|
||||||
@ -167,45 +168,10 @@ void box_free_box(struct box *box)
|
|||||||
form_free_control(box->gadget);
|
form_free_control(box->gadget);
|
||||||
}
|
}
|
||||||
|
|
||||||
box_free_object_params(box->object_params);
|
|
||||||
|
|
||||||
talloc_free(box);
|
talloc_free(box);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Free an object parameter structure.
|
|
||||||
*
|
|
||||||
* \param op object parameter structure to free
|
|
||||||
*/
|
|
||||||
|
|
||||||
void box_free_object_params(struct object_params *op)
|
|
||||||
{
|
|
||||||
struct plugin_params *a, *b;
|
|
||||||
|
|
||||||
if (!op)
|
|
||||||
return;
|
|
||||||
|
|
||||||
free(op->data);
|
|
||||||
free(op->type);
|
|
||||||
free(op->codetype);
|
|
||||||
free(op->codebase);
|
|
||||||
free(op->classid);
|
|
||||||
free(op->basehref);
|
|
||||||
|
|
||||||
for (a = op->params; a; a = b) {
|
|
||||||
b = a->next;
|
|
||||||
free(a->name);
|
|
||||||
free(a->value);
|
|
||||||
free(a->type);
|
|
||||||
free(a->valuetype);
|
|
||||||
free(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the absolute coordinates of a box.
|
* Find the absolute coordinates of a box.
|
||||||
*
|
*
|
||||||
@ -434,7 +400,7 @@ struct box *box_find_by_id(struct box *box, const char *id)
|
|||||||
void box_dump(struct box *box, unsigned int depth)
|
void box_dump(struct box *box, unsigned int depth)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
struct box * c;
|
struct box *c, *prev;
|
||||||
|
|
||||||
for (i = 0; i != depth; i++)
|
for (i = 0; i != depth; i++)
|
||||||
fprintf(stderr, " ");
|
fprintf(stderr, " ");
|
||||||
@ -486,6 +452,27 @@ void box_dump(struct box *box, unsigned int depth)
|
|||||||
fprintf(stderr, " next_float %p", box->next_float);
|
fprintf(stderr, " next_float %p", box->next_float);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
for (c = box->children; c; c = c->next)
|
for (c = box->children; c->next; c = c->next)
|
||||||
|
;
|
||||||
|
if (box->last != c)
|
||||||
|
fprintf(stderr, "warning: box->last %p (should be %p) "
|
||||||
|
"(box %p)\n", box->last, c, box);
|
||||||
|
for (prev = 0, c = box->children; c; prev = c, c = c->next) {
|
||||||
|
if (c->parent != box)
|
||||||
|
fprintf(stderr, "warning: box->parent %p (should be "
|
||||||
|
"%p) (box on next line)\n",
|
||||||
|
c->parent, box);
|
||||||
|
if (c->prev != prev)
|
||||||
|
fprintf(stderr, "warning: box->prev %p (should be "
|
||||||
|
"%p) (box on next line)\n",
|
||||||
|
c->prev, prev);
|
||||||
box_dump(c, depth + 1);
|
box_dump(c, depth + 1);
|
||||||
|
}
|
||||||
|
if (box->fallback) {
|
||||||
|
for (i = 0; i != depth; i++)
|
||||||
|
fprintf(stderr, " ");
|
||||||
|
fprintf(stderr, "fallback:\n");
|
||||||
|
for (c = box->fallback; c; c = c->next)
|
||||||
|
box_dump(c, depth + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
43
render/box.h
43
render/box.h
@ -81,6 +81,8 @@
|
|||||||
struct box;
|
struct box;
|
||||||
struct column;
|
struct column;
|
||||||
struct css_style;
|
struct css_style;
|
||||||
|
struct object_params;
|
||||||
|
struct object_param;
|
||||||
|
|
||||||
|
|
||||||
/** Type of a struct box. */
|
/** Type of a struct box. */
|
||||||
@ -92,27 +94,6 @@ typedef enum {
|
|||||||
BOX_INLINE_BLOCK, BOX_BR, BOX_TEXT
|
BOX_INLINE_BLOCK, BOX_BR, BOX_TEXT
|
||||||
} box_type;
|
} box_type;
|
||||||
|
|
||||||
/* parameters for <object> and related elements */
|
|
||||||
struct object_params {
|
|
||||||
char* data;
|
|
||||||
char* type;
|
|
||||||
char* codetype;
|
|
||||||
char* codebase;
|
|
||||||
char* classid;
|
|
||||||
struct plugin_params* params;
|
|
||||||
/* not a parameter but stored here for convenience */
|
|
||||||
char* basehref;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
struct plugin_params {
|
|
||||||
char* name;
|
|
||||||
char* value;
|
|
||||||
char* type;
|
|
||||||
char* valuetype;
|
|
||||||
struct plugin_params* next;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Node in box tree. All dimensions are in pixels. */
|
/** Node in box tree. All dimensions are in pixels. */
|
||||||
struct box {
|
struct box {
|
||||||
/** Type of box. */
|
/** Type of box. */
|
||||||
@ -181,6 +162,7 @@ struct box {
|
|||||||
struct box *children; /**< First child box, or 0. */
|
struct box *children; /**< First child box, or 0. */
|
||||||
struct box *last; /**< Last child box, or 0. */
|
struct box *last; /**< Last child box, or 0. */
|
||||||
struct box *parent; /**< Parent box, or 0. */
|
struct box *parent; /**< Parent box, or 0. */
|
||||||
|
struct box *fallback; /**< Fallback children for object, or 0. */
|
||||||
|
|
||||||
/** First float child box, or 0. Float boxes are in the tree twice, in
|
/** First float child box, or 0. Float boxes are in the tree twice, in
|
||||||
* this list for the block box which defines the area for floats, and
|
* this list for the block box which defines the area for floats, and
|
||||||
@ -221,6 +203,25 @@ struct column {
|
|||||||
int max;
|
int max;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Parameters for <object> and similar elements. */
|
||||||
|
struct object_params {
|
||||||
|
char *data;
|
||||||
|
char *type;
|
||||||
|
char *codetype;
|
||||||
|
char *codebase;
|
||||||
|
char *classid;
|
||||||
|
struct object_param *params;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Linked list of <object> parameters. */
|
||||||
|
struct object_param {
|
||||||
|
char *name;
|
||||||
|
char *value;
|
||||||
|
char *type;
|
||||||
|
char *valuetype;
|
||||||
|
struct object_param *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#define UNKNOWN_WIDTH INT_MAX
|
#define UNKNOWN_WIDTH INT_MAX
|
||||||
#define UNKNOWN_MAX_WIDTH INT_MAX
|
#define UNKNOWN_MAX_WIDTH INT_MAX
|
||||||
|
@ -105,7 +105,6 @@ static bool box_object(BOX_SPECIAL_PARAMS);
|
|||||||
static bool box_embed(BOX_SPECIAL_PARAMS);
|
static bool box_embed(BOX_SPECIAL_PARAMS);
|
||||||
/*static bool box_applet(BOX_SPECIAL_PARAMS);*/
|
/*static bool box_applet(BOX_SPECIAL_PARAMS);*/
|
||||||
static bool box_iframe(BOX_SPECIAL_PARAMS);
|
static bool box_iframe(BOX_SPECIAL_PARAMS);
|
||||||
static bool plugin_decode(struct content* content, struct box* box);
|
|
||||||
static bool box_get_attribute(xmlNode *n, const char *attribute,
|
static bool box_get_attribute(xmlNode *n, const char *attribute,
|
||||||
void *context, char **value);
|
void *context, char **value);
|
||||||
static bool box_extract_link(const char *rel, const char *base, char **result);
|
static bool box_extract_link(const char *rel, const char *base, char **result);
|
||||||
@ -957,6 +956,7 @@ bool box_a(BOX_SPECIAL_PARAMS)
|
|||||||
box->href = talloc_strdup(content, url);
|
box->href = talloc_strdup(content, url);
|
||||||
if (!box->href)
|
if (!box->href)
|
||||||
return false;
|
return false;
|
||||||
|
free(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -974,14 +974,14 @@ bool box_a(BOX_SPECIAL_PARAMS)
|
|||||||
|
|
||||||
bool box_image(BOX_SPECIAL_PARAMS)
|
bool box_image(BOX_SPECIAL_PARAMS)
|
||||||
{
|
{
|
||||||
char *s, *url, *s1;
|
bool ok;
|
||||||
xmlChar *s2;
|
char *s, *url;
|
||||||
url_func_result res;
|
xmlChar *alt, *src;
|
||||||
|
|
||||||
/* handle alt text */
|
/* handle alt text */
|
||||||
if ((s2 = xmlGetProp(n, (const xmlChar *) "alt"))) {
|
if ((alt = xmlGetProp(n, (const xmlChar *) "alt"))) {
|
||||||
s = squash_whitespace(s2);
|
s = squash_whitespace(alt);
|
||||||
xmlFree(s2);
|
xmlFree(alt);
|
||||||
if (!s)
|
if (!s)
|
||||||
return false;
|
return false;
|
||||||
box->text = talloc_strdup(content, s);
|
box->text = talloc_strdup(content, s);
|
||||||
@ -997,33 +997,20 @@ bool box_image(BOX_SPECIAL_PARAMS)
|
|||||||
if (box->usemap && box->usemap[0] == '#')
|
if (box->usemap && box->usemap[0] == '#')
|
||||||
box->usemap++;
|
box->usemap++;
|
||||||
|
|
||||||
/* img without src is an error */
|
/* get image URL */
|
||||||
if (!(s = (char *) xmlGetProp(n, (const xmlChar *) "src")))
|
if (!(src = xmlGetProp(n, (const xmlChar *) "src")))
|
||||||
return true;
|
return true;
|
||||||
|
if (!box_extract_link((char *) src, content->data.html.base_url, &url))
|
||||||
/* remove leading and trailing whitespace */
|
|
||||||
s1 = strip(s);
|
|
||||||
res = url_join(s1, content->data.html.base_url, &url);
|
|
||||||
xmlFree(s);
|
|
||||||
if (res == URL_FUNC_NOMEM)
|
|
||||||
return false;
|
return false;
|
||||||
else if (res == URL_FUNC_FAILED)
|
xmlFree(src);
|
||||||
return true;
|
if (!url)
|
||||||
|
|
||||||
if (strcmp(url, content->data.html.base_url) == 0)
|
|
||||||
/* if url is equivalent to the parent's url,
|
|
||||||
* we've got infinite inclusion: ignore */
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* start fetch */
|
/* start fetch */
|
||||||
if (!html_fetch_object(content, url, box, image_types,
|
ok = html_fetch_object(content, url, box, image_types,
|
||||||
content->available_width, 1000, false)) {
|
content->available_width, 1000, false);
|
||||||
free(url);
|
free(url);
|
||||||
return false;
|
return ok;
|
||||||
}
|
|
||||||
free(url);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1033,93 +1020,120 @@ bool box_image(BOX_SPECIAL_PARAMS)
|
|||||||
|
|
||||||
bool box_object(BOX_SPECIAL_PARAMS)
|
bool box_object(BOX_SPECIAL_PARAMS)
|
||||||
{
|
{
|
||||||
struct object_params *po;
|
struct object_params *params;
|
||||||
struct plugin_params *pp = NULL;
|
struct object_param *param;
|
||||||
|
xmlChar *codebase, *classid, *data;
|
||||||
xmlNode *c;
|
xmlNode *c;
|
||||||
|
struct box *inline_container = 0;
|
||||||
po = talloc(content, struct object_params);
|
|
||||||
if (!po)
|
|
||||||
return false;
|
|
||||||
po->data = 0;
|
|
||||||
po->type = 0;
|
|
||||||
po->codetype = 0;
|
|
||||||
po->codebase = 0;
|
|
||||||
po->classid = 0;
|
|
||||||
po->params = 0;
|
|
||||||
po->basehref = 0;
|
|
||||||
|
|
||||||
if (!box_get_attribute(n, "data", content, &po->data))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!box_get_attribute(n, "usemap", content, &box->usemap))
|
if (!box_get_attribute(n, "usemap", content, &box->usemap))
|
||||||
return false;
|
return false;
|
||||||
if (box->usemap && box->usemap[0] == '#')
|
if (box->usemap && box->usemap[0] == '#')
|
||||||
box->usemap++;
|
box->usemap++;
|
||||||
|
|
||||||
if (!box_get_attribute(n, "type", content, &po->type))
|
params = talloc(content, struct object_params);
|
||||||
return false;
|
if (!params)
|
||||||
if (!box_get_attribute(n, "codetype", content, &po->codetype))
|
|
||||||
return false;
|
|
||||||
if (!box_get_attribute(n, "codebase", content, &po->codebase))
|
|
||||||
return false;
|
|
||||||
if (!box_get_attribute(n, "classid", content, &po->classid))
|
|
||||||
return false;
|
return false;
|
||||||
|
params->data = 0;
|
||||||
|
params->type = 0;
|
||||||
|
params->codetype = 0;
|
||||||
|
params->codebase = 0;
|
||||||
|
params->classid = 0;
|
||||||
|
params->params = 0;
|
||||||
|
|
||||||
/* parameters
|
/* codebase, classid, and data are URLs (codebase is the base for the
|
||||||
* parameter data is stored in a singly linked list.
|
* other two) */
|
||||||
* po->params points to the head of the list.
|
if ((codebase = xmlGetProp(n, (const xmlChar *) "codebase"))) {
|
||||||
* new parameters are added to the head of the list.
|
if (!box_extract_link((char *) codebase,
|
||||||
*/
|
content->data.html.base_url, ¶ms->codebase))
|
||||||
|
return false;
|
||||||
|
xmlFree(codebase);
|
||||||
|
}
|
||||||
|
if (!params->codebase)
|
||||||
|
params->codebase = content->data.html.base_url;
|
||||||
|
|
||||||
|
if ((classid = xmlGetProp(n, (const xmlChar *) "codebase"))) {
|
||||||
|
if (!box_extract_link((char *) classid, params->codebase,
|
||||||
|
¶ms->classid))
|
||||||
|
return false;
|
||||||
|
xmlFree(classid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((data = xmlGetProp(n, (const xmlChar *) "data"))) {
|
||||||
|
if (!box_extract_link((char *) data, params->codebase,
|
||||||
|
¶ms->data))
|
||||||
|
return false;
|
||||||
|
xmlFree(data);
|
||||||
|
}
|
||||||
|
if (!params->data)
|
||||||
|
/* objects without data are ignored */
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* codetype and type are MIME types */
|
||||||
|
if (!box_get_attribute(n, "codetype", params, ¶ms->codetype))
|
||||||
|
return false;
|
||||||
|
if (!box_get_attribute(n, "type", params, ¶ms->type))
|
||||||
|
return false;
|
||||||
|
if (params->type && content_lookup(params->type) == CONTENT_OTHER)
|
||||||
|
/* can't handle this MIME type */
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* add parameters to linked list */
|
||||||
for (c = n->children; c; c = c->next) {
|
for (c = n->children; c; c = c->next) {
|
||||||
if (c->type != XML_ELEMENT_NODE)
|
if (c->type != XML_ELEMENT_NODE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strcmp((const char *) c->name, "param") != 0)
|
if (strcmp((const char *) c->name, "param") != 0)
|
||||||
/* The first non-param child is the start
|
/* The first non-param child is the start of the alt
|
||||||
* of the alt html. Therefore, we should
|
* html. Therefore, we should break out of this loop. */
|
||||||
* break out of this loop.
|
|
||||||
*/
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
pp = talloc(content, struct plugin_params);
|
param = talloc(params, struct object_param);
|
||||||
if (!pp)
|
if (!param)
|
||||||
return false;
|
return false;
|
||||||
pp->name = 0;
|
param->name = 0;
|
||||||
pp->value = 0;
|
param->value = 0;
|
||||||
pp->type = 0;
|
param->type = 0;
|
||||||
pp->valuetype = 0;
|
param->valuetype = 0;
|
||||||
pp->next = 0;
|
param->next = 0;
|
||||||
|
|
||||||
if (!box_get_attribute(c, "name", content, &pp->name))
|
if (!box_get_attribute(c, "name", param, ¶m->name))
|
||||||
return false;
|
return false;
|
||||||
if (!box_get_attribute(c, "value", content, &pp->value))
|
if (!box_get_attribute(c, "value", param, ¶m->value))
|
||||||
return false;
|
return false;
|
||||||
if (!box_get_attribute(c, "type", content, &pp->type))
|
if (!box_get_attribute(c, "type", param, ¶m->type))
|
||||||
return false;
|
return false;
|
||||||
if (!box_get_attribute(c, "valuetype", content, &pp->valuetype))
|
if (!box_get_attribute(c, "valuetype", param,
|
||||||
return false;
|
¶m->valuetype))
|
||||||
if (!pp->valuetype) {
|
|
||||||
pp->valuetype = talloc_strdup(content, "data");
|
|
||||||
if (!pp->valuetype)
|
|
||||||
return false;
|
return false;
|
||||||
|
if (!param->valuetype)
|
||||||
|
param->valuetype = "data";
|
||||||
|
|
||||||
|
param->next = params->params;
|
||||||
|
params->params = param;
|
||||||
}
|
}
|
||||||
|
|
||||||
pp->next = po->params;
|
box->object_params = params;
|
||||||
po->params = pp;
|
|
||||||
|
/* start fetch (MIME type is ok or not specified) */
|
||||||
|
if (!html_fetch_object(content, params->data, box, 0,
|
||||||
|
content->available_width, 1000, false))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* convert children and place into fallback */
|
||||||
|
for (c = n->children; c; c = c->next) {
|
||||||
|
if (!convert_xml_to_box(c, content, box->style, box,
|
||||||
|
&inline_container, 0, 0))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
box->fallback = box->children;
|
||||||
|
box->children = box->last = 0;
|
||||||
|
|
||||||
box->object_params = po;
|
*convert_children = false;
|
||||||
|
|
||||||
/* start fetch */
|
|
||||||
if (!plugin_decode(content, box))
|
|
||||||
*convert_children = true;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0 /**
|
||||||
/**
|
|
||||||
* "Java applet" [13.4].
|
* "Java applet" [13.4].
|
||||||
*
|
*
|
||||||
* \todo This needs reworking to be compliant to the spec
|
* \todo This needs reworking to be compliant to the spec
|
||||||
@ -1131,7 +1145,7 @@ struct box_result box_applet(xmlNode *n, struct box_status *status,
|
|||||||
{
|
{
|
||||||
struct box *box;
|
struct box *box;
|
||||||
struct object_params *po;
|
struct object_params *po;
|
||||||
struct plugin_params *pp = NULL;
|
struct object_param *pp = NULL;
|
||||||
char *s;
|
char *s;
|
||||||
xmlNode *c;
|
xmlNode *c;
|
||||||
|
|
||||||
@ -1183,7 +1197,7 @@ struct box_result box_applet(xmlNode *n, struct box_status *status,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strcmp((const char *) c->name, "param") == 0) {
|
if (strcmp((const char *) c->name, "param") == 0) {
|
||||||
pp = calloc(1, sizeof(struct plugin_params));
|
pp = calloc(1, sizeof(struct object_param));
|
||||||
if (!pp)
|
if (!pp)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
@ -1459,34 +1473,23 @@ bool box_frameset(BOX_SPECIAL_PARAMS)
|
|||||||
|
|
||||||
bool box_iframe(BOX_SPECIAL_PARAMS)
|
bool box_iframe(BOX_SPECIAL_PARAMS)
|
||||||
{
|
{
|
||||||
struct object_params *po;
|
bool ok;
|
||||||
char *s;
|
char *url;
|
||||||
|
xmlChar *src;
|
||||||
|
|
||||||
po = talloc(content, struct object_params);
|
/* get frame URL */
|
||||||
if (!po)
|
if (!(src = xmlGetProp(n, (const xmlChar *) "src")))
|
||||||
|
return true;
|
||||||
|
if (!box_extract_link((char *) src, content->data.html.base_url, &url))
|
||||||
return false;
|
return false;
|
||||||
po->data = 0;
|
if (!url)
|
||||||
po->type = 0;
|
return true;
|
||||||
po->codetype = 0;
|
|
||||||
po->codebase = 0;
|
|
||||||
po->classid = 0;
|
|
||||||
po->params = 0;
|
|
||||||
po->basehref = 0;
|
|
||||||
|
|
||||||
/* iframe src */
|
|
||||||
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src"))) {
|
|
||||||
po->data = talloc_strdup(content, s);
|
|
||||||
xmlFree(s);
|
|
||||||
if (!po->data)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
box->object_params = po;
|
|
||||||
|
|
||||||
/* start fetch */
|
/* start fetch */
|
||||||
plugin_decode(content, box);
|
ok = html_fetch_object(content, url, box, 0,
|
||||||
|
content->available_width, 1000, false);
|
||||||
return true;
|
free(url);
|
||||||
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2054,66 +2057,60 @@ bool box_textarea(BOX_SPECIAL_PARAMS)
|
|||||||
|
|
||||||
bool box_embed(BOX_SPECIAL_PARAMS)
|
bool box_embed(BOX_SPECIAL_PARAMS)
|
||||||
{
|
{
|
||||||
struct object_params *po;
|
struct object_params *params;
|
||||||
struct plugin_params *pp = NULL;
|
struct object_param *param;
|
||||||
char *s;
|
xmlChar *src;
|
||||||
xmlAttr *a;
|
xmlAttr *a;
|
||||||
|
|
||||||
po = talloc(content, struct object_params);
|
params = talloc(content, struct object_params);
|
||||||
if (!po)
|
if (!params)
|
||||||
return false;
|
return false;
|
||||||
po->data = 0;
|
params->data = 0;
|
||||||
po->type = 0;
|
params->type = 0;
|
||||||
po->codetype = 0;
|
params->codetype = 0;
|
||||||
po->codebase = 0;
|
params->codebase = 0;
|
||||||
po->classid = 0;
|
params->classid = 0;
|
||||||
po->params = 0;
|
params->params = 0;
|
||||||
po->basehref = 0;
|
|
||||||
|
|
||||||
/* embed src */
|
/* src is a URL */
|
||||||
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src")) != NULL) {
|
if (!(src = xmlGetProp(n, (const xmlChar *) "src")))
|
||||||
LOG(("embed '%s'", s));
|
return true;
|
||||||
po->data = talloc_strdup(content, s);
|
if (!box_extract_link((char *) src, content->data.html.base_url,
|
||||||
xmlFree(s);
|
¶ms->data))
|
||||||
if (!po->data)
|
|
||||||
return false;
|
return false;
|
||||||
}
|
xmlFree(src);
|
||||||
|
if (!params->data)
|
||||||
|
return true;
|
||||||
|
|
||||||
/**
|
/* add attributes as parameters to linked list */
|
||||||
* we munge all other attributes into a plugin_parameter structure
|
|
||||||
*/
|
|
||||||
for (a = n->properties; a; a = a->next) {
|
for (a = n->properties; a; a = a->next) {
|
||||||
pp = talloc(content, struct plugin_params);
|
if (strcasecmp((const char *) a->name, "src") == 0)
|
||||||
if (!pp)
|
continue;
|
||||||
return false;
|
if (!a->children || !a->children->content)
|
||||||
pp->name = 0;
|
continue;
|
||||||
pp->value = 0;
|
|
||||||
pp->type = 0;
|
|
||||||
pp->valuetype = 0;
|
|
||||||
pp->next = 0;
|
|
||||||
|
|
||||||
if (strcasecmp((const char *) a->name, "src") != 0 &&
|
param = talloc(content, struct object_param);
|
||||||
a->children && a->children->content) {
|
if (!param)
|
||||||
pp->name = talloc_strdup(content,
|
return false;
|
||||||
(const char *) a->name);
|
param->name = talloc_strdup(content, (const char *) a->name);
|
||||||
pp->value = talloc_strdup(content,
|
param->value = talloc_strdup(content,
|
||||||
(char *) a->children->content);
|
(char *) a->children->content);
|
||||||
pp->valuetype = talloc_strdup(content, "data");
|
param->type = 0;
|
||||||
if (!pp->name || !pp->value || !pp->valuetype)
|
param->valuetype = "data";
|
||||||
|
param->next = 0;
|
||||||
|
|
||||||
|
if (!param->name || !param->value)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
pp->next = po->params;
|
param->next = params->params;
|
||||||
po->params = pp;
|
params->params = param;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
box->object_params = po;
|
box->object_params = params;
|
||||||
|
|
||||||
/* start fetch */
|
/* start fetch */
|
||||||
/* embeds have no content, so we don't care if this returns false */
|
return html_fetch_object(content, params->data, box, 0,
|
||||||
plugin_decode(content, box);
|
content->available_width, 1000, false);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2121,153 +2118,6 @@ bool box_embed(BOX_SPECIAL_PARAMS)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
bool plugin_decode(struct content *content, struct box *box)
|
|
||||||
{
|
|
||||||
char *codebase, *url = NULL;
|
|
||||||
struct object_params *po;
|
|
||||||
struct plugin_params *pp;
|
|
||||||
url_func_result res;
|
|
||||||
|
|
||||||
assert(content && box);
|
|
||||||
|
|
||||||
po = box->object_params;
|
|
||||||
|
|
||||||
/* Check if the codebase attribute is defined.
|
|
||||||
* If it is not, set it to the codebase of the current document.
|
|
||||||
*/
|
|
||||||
if (po->codebase == 0)
|
|
||||||
res = url_join("./", content->data.html.base_url,
|
|
||||||
&codebase);
|
|
||||||
else
|
|
||||||
res = url_join(po->codebase, content->data.html.base_url,
|
|
||||||
&codebase);
|
|
||||||
|
|
||||||
if (res != URL_FUNC_OK)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* free pre-existing codebase */
|
|
||||||
if (po->codebase)
|
|
||||||
talloc_free(po->codebase);
|
|
||||||
|
|
||||||
po->codebase = talloc_strdup(content, codebase);
|
|
||||||
if (!po->codebase) {
|
|
||||||
free(codebase);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* no longer need this */
|
|
||||||
free(codebase);
|
|
||||||
|
|
||||||
/* Set basehref */
|
|
||||||
po->basehref = talloc_strdup(content, content->data.html.base_url);
|
|
||||||
if (!po->basehref)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (po->data == 0 && po->classid == 0)
|
|
||||||
/* no data => ignore this object */
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (po->data == 0 && po->classid != 0) {
|
|
||||||
/* just classid specified */
|
|
||||||
if (strncasecmp(po->classid, "clsid:", 6) == 0) {
|
|
||||||
if (strcasecmp(po->classid, "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000") == 0) {
|
|
||||||
/* Flash */
|
|
||||||
for (pp = po->params;
|
|
||||||
pp != 0 &&
|
|
||||||
strcasecmp(pp->name, "movie") != 0;
|
|
||||||
pp = pp->next)
|
|
||||||
/* no body */;
|
|
||||||
if (pp == 0)
|
|
||||||
return false;
|
|
||||||
res = url_join(pp->value, po->basehref, &url);
|
|
||||||
if (res != URL_FUNC_OK)
|
|
||||||
return false;
|
|
||||||
/* munge the codebase */
|
|
||||||
res = url_join("./",
|
|
||||||
content->data.html.base_url,
|
|
||||||
&codebase);
|
|
||||||
if (res != URL_FUNC_OK) {
|
|
||||||
free(url);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (po->codebase)
|
|
||||||
talloc_free(po->codebase);
|
|
||||||
po->codebase = talloc_strdup(content,
|
|
||||||
codebase);
|
|
||||||
free(codebase);
|
|
||||||
if (!po->codebase) {
|
|
||||||
free(url);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LOG(("ActiveX object"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
res = url_join(po->classid, po->codebase, &url);
|
|
||||||
if (res != URL_FUNC_OK)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* jmb - I'm not convinced by this */
|
|
||||||
/* The java plugin doesn't need the .class extension
|
|
||||||
* so we strip it.
|
|
||||||
*/
|
|
||||||
if (strcasecmp(&po->classid[strlen(po->classid)-6],
|
|
||||||
".class") == 0)
|
|
||||||
po->classid[strlen(po->classid)-6] = 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* just data (or both) specified - data takes precedence */
|
|
||||||
res = url_join(po->data, po->codebase, &url);
|
|
||||||
if (res != URL_FUNC_OK)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if the declared mime type is understandable.
|
|
||||||
* Checks type and codetype attributes.
|
|
||||||
*/
|
|
||||||
if (po->type != 0 && content_lookup(po->type) == CONTENT_OTHER)
|
|
||||||
goto no_handler;
|
|
||||||
if (po->codetype != 0 &&
|
|
||||||
content_lookup(po->codetype) == CONTENT_OTHER)
|
|
||||||
goto no_handler;
|
|
||||||
|
|
||||||
/* Ensure that the object to be included isn't this document */
|
|
||||||
if (strcasecmp(url, content->data.html.base_url) == 0)
|
|
||||||
goto no_handler;
|
|
||||||
|
|
||||||
/* 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).
|
|
||||||
*/
|
|
||||||
if (!html_fetch_object(content, url, box, 0, 1000, 1000, false))
|
|
||||||
goto no_handler;
|
|
||||||
free(url);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
no_handler:
|
|
||||||
free(url);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of an XML element's attribute.
|
* Get the value of an XML element's attribute.
|
||||||
*
|
*
|
||||||
|
@ -45,6 +45,8 @@ static void html_object_callback(content_msg msg, struct content *object,
|
|||||||
void *p1, void *p2, union content_msg_data data);
|
void *p1, void *p2, union content_msg_data data);
|
||||||
static void html_object_done(struct box *box, struct content *object,
|
static void html_object_done(struct box *box, struct content *object,
|
||||||
bool background);
|
bool background);
|
||||||
|
static void html_object_failed(struct box *box, struct content *content,
|
||||||
|
bool background);
|
||||||
static bool html_object_type_permitted(const content_type type,
|
static bool html_object_type_permitted(const content_type type,
|
||||||
const content_type *permitted_types);
|
const content_type *permitted_types);
|
||||||
|
|
||||||
@ -799,7 +801,10 @@ void html_object_callback(content_msg msg, struct content *object,
|
|||||||
content_add_error(c, "?", 0);
|
content_add_error(c, "?", 0);
|
||||||
content_set_status(c, messages_get("BadObject"));
|
content_set_status(c, messages_get("BadObject"));
|
||||||
content_broadcast(c, CONTENT_MSG_STATUS, data);
|
content_broadcast(c, CONTENT_MSG_STATUS, data);
|
||||||
content_remove_user(object, html_object_callback, c, (void*)i);
|
content_remove_user(object, html_object_callback, c,
|
||||||
|
(void *) i);
|
||||||
|
html_object_failed(box, c,
|
||||||
|
c->data.html.object[i].background);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CONTENT_MSG_READY:
|
case CONTENT_MSG_READY:
|
||||||
@ -815,7 +820,8 @@ void html_object_callback(content_msg msg, struct content *object,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CONTENT_MSG_DONE:
|
case CONTENT_MSG_DONE:
|
||||||
html_object_done(box, object, c->data.html.object[i].background);
|
html_object_done(box, object,
|
||||||
|
c->data.html.object[i].background);
|
||||||
c->active--;
|
c->active--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -826,6 +832,8 @@ void html_object_callback(content_msg msg, struct content *object,
|
|||||||
content_set_status(c, messages_get("ObjError"),
|
content_set_status(c, messages_get("ObjError"),
|
||||||
data.error);
|
data.error);
|
||||||
content_broadcast(c, CONTENT_MSG_STATUS, data);
|
content_broadcast(c, CONTENT_MSG_STATUS, data);
|
||||||
|
html_object_failed(box, c,
|
||||||
|
c->data.html.object[i].background);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CONTENT_MSG_STATUS:
|
case CONTENT_MSG_STATUS:
|
||||||
@ -951,6 +959,93 @@ void html_object_done(struct box *box, struct content *object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle object fetching or loading failure.
|
||||||
|
*
|
||||||
|
* \param box box containing object which failed to load
|
||||||
|
* \param content document of type CONTENT_HTML
|
||||||
|
* \param background the object was the background image for the box
|
||||||
|
*
|
||||||
|
* Any fallback content for the object is made visible.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void html_object_failed(struct box *box, struct content *content,
|
||||||
|
bool background)
|
||||||
|
{
|
||||||
|
struct box *b, *ic;
|
||||||
|
|
||||||
|
if (background)
|
||||||
|
return;
|
||||||
|
if (!box->fallback)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* make fallback boxes into children or siblings, as appropriate */
|
||||||
|
if (box->type != BOX_INLINE) {
|
||||||
|
/* easy case: fallbacks become children */
|
||||||
|
assert(box->type == BOX_BLOCK ||
|
||||||
|
box->type == BOX_TABLE_CELL ||
|
||||||
|
box->type == BOX_INLINE_BLOCK);
|
||||||
|
box->children = box->fallback;
|
||||||
|
box->last = box->children;
|
||||||
|
while (box->last->next)
|
||||||
|
box->last = box->last->next;
|
||||||
|
box->fallback = 0;
|
||||||
|
box_normalise_block(box, content);
|
||||||
|
} else {
|
||||||
|
assert(box->parent->type == BOX_INLINE_CONTAINER);
|
||||||
|
if (box->fallback->type == BOX_INLINE_CONTAINER &&
|
||||||
|
!box->fallback->next) {
|
||||||
|
/* the fallback is a single inline container: splice
|
||||||
|
* it into this inline container */
|
||||||
|
for (b = box->fallback->children; b; b = b->next)
|
||||||
|
b->parent = box->parent;
|
||||||
|
box->fallback->last->next = box->next;
|
||||||
|
if (!box->next)
|
||||||
|
box->parent->last = box->fallback->last;
|
||||||
|
box->next = box->fallback->children;
|
||||||
|
box->next->prev = box;
|
||||||
|
box->fallback = 0;
|
||||||
|
} else {
|
||||||
|
if (box->next) {
|
||||||
|
/* split this inline container into two inline
|
||||||
|
* containers */
|
||||||
|
ic = box_create(0, 0, 0, 0, content);
|
||||||
|
if (!ic) {
|
||||||
|
warn_user("NoMemory", 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ic->type = BOX_INLINE_CONTAINER;
|
||||||
|
box_insert_sibling(box->parent, ic);
|
||||||
|
ic->children = box->next;
|
||||||
|
ic->last = box->parent->last;
|
||||||
|
ic->children->prev = 0;
|
||||||
|
box->next = 0;
|
||||||
|
box->parent->last = box;
|
||||||
|
for (b = ic->children; b; b = b->next)
|
||||||
|
b->parent = ic;
|
||||||
|
}
|
||||||
|
/* insert the fallback after the parent */
|
||||||
|
for (b = box->fallback; b->next; b = b->next)
|
||||||
|
b->parent = box->parent->parent;
|
||||||
|
b->parent = box->parent->parent;
|
||||||
|
/* [b is the last fallback box] */
|
||||||
|
b->next = box->parent->next;
|
||||||
|
if (b->next)
|
||||||
|
b->next->prev = b;
|
||||||
|
box->parent->next = box->fallback;
|
||||||
|
box->fallback->prev = box->parent;
|
||||||
|
box->fallback = 0;
|
||||||
|
box_normalise_block(box->parent->parent, content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* invalidate parent min, max widths */
|
||||||
|
for (b = box->parent; b; b = b->parent)
|
||||||
|
b->max_width = UNKNOWN_MAX_WIDTH;
|
||||||
|
box->width = UNKNOWN_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a type is in a list.
|
* Check if a type is in a list.
|
||||||
*
|
*
|
||||||
|
@ -90,7 +90,7 @@ static void plugin_stream_write_callback(void *p);
|
|||||||
static void plugin_write_stream_as_file(struct content *c);
|
static void plugin_write_stream_as_file(struct content *c);
|
||||||
static void plugin_destroy_stream(struct content *c);
|
static void plugin_destroy_stream(struct content *c);
|
||||||
static bool plugin_write_parameters_file(struct content *c,
|
static bool plugin_write_parameters_file(struct content *c,
|
||||||
struct object_params *params);
|
struct object_params *params, const char *base);
|
||||||
static int plugin_calculate_rsize(const char* name, const char* data,
|
static int plugin_calculate_rsize(const char* name, const char* data,
|
||||||
const char* mime);
|
const char* mime);
|
||||||
static bool plugin_add_item_to_pilist(struct plugin_param_item **pilist,
|
static bool plugin_add_item_to_pilist(struct plugin_param_item **pilist,
|
||||||
@ -207,13 +207,13 @@ void plugin_open(struct content *c, struct browser_window *bw,
|
|||||||
struct object_params *params)
|
struct object_params *params)
|
||||||
{
|
{
|
||||||
bool standalone = false;
|
bool standalone = false;
|
||||||
|
const char *base;
|
||||||
char sysvar[25];
|
char sysvar[25];
|
||||||
char *varval;
|
char *varval;
|
||||||
plugin_full_message_open pmo;
|
plugin_full_message_open pmo;
|
||||||
wimp_window_state state;
|
wimp_window_state state;
|
||||||
os_error *error;
|
os_error *error;
|
||||||
|
|
||||||
|
|
||||||
if (option_no_plugins)
|
if (option_no_plugins)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -235,11 +235,6 @@ void plugin_open(struct content *c, struct browser_window *bw,
|
|||||||
warn_user("NoMemory", 0);
|
warn_user("NoMemory", 0);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
params->basehref = strdup(c->url);
|
|
||||||
if (!params->basehref) {
|
|
||||||
warn_user("NoMemory", 0);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
standalone = true;
|
standalone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,8 +244,15 @@ void plugin_open(struct content *c, struct browser_window *bw,
|
|||||||
*/
|
*/
|
||||||
c->data.plugin.box = box;
|
c->data.plugin.box = box;
|
||||||
|
|
||||||
|
if (params->codebase)
|
||||||
|
base = params->codebase;
|
||||||
|
else if (page)
|
||||||
|
base = page->data.html.base_url;
|
||||||
|
else
|
||||||
|
base = c->url;
|
||||||
|
|
||||||
LOG(("writing parameters file"));
|
LOG(("writing parameters file"));
|
||||||
if (!plugin_write_parameters_file(c, params))
|
if (!plugin_write_parameters_file(c, params, base))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
LOG(("creating sysvar"));
|
LOG(("creating sysvar"));
|
||||||
@ -325,7 +327,6 @@ error:
|
|||||||
if (standalone) {
|
if (standalone) {
|
||||||
free(params->type);
|
free(params->type);
|
||||||
free(params->data);
|
free(params->data);
|
||||||
free(params->basehref);
|
|
||||||
free(params);
|
free(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1071,12 +1072,13 @@ void plugin_destroy_stream(struct content *c)
|
|||||||
*
|
*
|
||||||
* \param c Content to write parameters for
|
* \param c Content to write parameters for
|
||||||
* \param params Plugin parameters struct
|
* \param params Plugin parameters struct
|
||||||
|
* \param base base URL for object
|
||||||
* \return true on success, false otherwise
|
* \return true on success, false otherwise
|
||||||
*/
|
*/
|
||||||
bool plugin_write_parameters_file(struct content *c,
|
bool plugin_write_parameters_file(struct content *c,
|
||||||
struct object_params *params)
|
struct object_params *params, const char *base)
|
||||||
{
|
{
|
||||||
struct plugin_params *p;
|
struct object_param *p;
|
||||||
struct plugin_param_item *ppi;
|
struct plugin_param_item *ppi;
|
||||||
struct plugin_param_item *pilist = 0;
|
struct plugin_param_item *pilist = 0;
|
||||||
char bgcolor[10] = {0};
|
char bgcolor[10] = {0};
|
||||||
@ -1163,8 +1165,7 @@ bool plugin_write_parameters_file(struct content *c,
|
|||||||
|
|
||||||
/* BASEHREF */
|
/* BASEHREF */
|
||||||
if (!plugin_add_item_to_pilist(&pilist, PLUGIN_PARAMETER_SPECIAL,
|
if (!plugin_add_item_to_pilist(&pilist, PLUGIN_PARAMETER_SPECIAL,
|
||||||
"BASEHREF",
|
"BASEHREF", base,
|
||||||
(const char *)params->basehref,
|
|
||||||
NULL))
|
NULL))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user