|
|
|
@ -93,7 +93,8 @@ static struct box * convert_xml_to_box(xmlNode * n, struct content *content,
|
|
|
|
|
struct box_status status);
|
|
|
|
|
static struct css_style * box_get_style(struct content *c,
|
|
|
|
|
struct content ** stylesheet,
|
|
|
|
|
unsigned int stylesheet_count, struct css_style * parent_style,
|
|
|
|
|
unsigned int stylesheet_count,
|
|
|
|
|
struct css_style * parent_style,
|
|
|
|
|
xmlNode * n);
|
|
|
|
|
static void box_text_transform(char *s, unsigned int len,
|
|
|
|
|
css_text_transform tt);
|
|
|
|
@ -119,7 +120,8 @@ static struct box_result box_button(xmlNode *n, struct box_status *status,
|
|
|
|
|
struct css_style *style);
|
|
|
|
|
static struct box_result box_frameset(xmlNode *n, struct box_status *status,
|
|
|
|
|
struct css_style *style);
|
|
|
|
|
static void add_option(xmlNode* n, struct form_control* current_select, const char *text);
|
|
|
|
|
static void add_option(xmlNode* n, struct form_control* current_select,
|
|
|
|
|
const char *text);
|
|
|
|
|
static void box_normalise_block(struct box *block, pool box_pool);
|
|
|
|
|
static void box_normalise_table(struct box *table, pool box_pool);
|
|
|
|
|
void box_normalise_table_row_group(struct box *row_group,
|
|
|
|
@ -308,7 +310,7 @@ void xml_to_box(xmlNode *n, struct content *c)
|
|
|
|
|
|
|
|
|
|
/* mapping from CSS display to box type
|
|
|
|
|
* this table must be in sync with css/css_enums */
|
|
|
|
|
static box_type box_map[] = {
|
|
|
|
|
static const box_type box_map[] = {
|
|
|
|
|
0, /*CSS_DISPLAY_INHERIT,*/
|
|
|
|
|
BOX_INLINE, /*CSS_DISPLAY_INLINE,*/
|
|
|
|
|
BOX_BLOCK, /*CSS_DISPLAY_BLOCK,*/
|
|
|
|
@ -369,13 +371,13 @@ struct box * convert_xml_to_box(xmlNode * n, struct content *content,
|
|
|
|
|
style->display = CSS_DISPLAY_BLOCK;
|
|
|
|
|
|
|
|
|
|
/* extract title attribute, if present */
|
|
|
|
|
if ((title0 = xmlGetProp(n, (const xmlChar *) "title"))) {
|
|
|
|
|
if ((title0 = xmlGetProp(n, (const xmlChar *) "title")) != NULL) {
|
|
|
|
|
status.title = title = squash_whitespace(title0);
|
|
|
|
|
xmlFree(title0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* extract id attribute, if present */
|
|
|
|
|
if ((title0 = xmlGetProp(n, (const xmlChar *) "id"))) {
|
|
|
|
|
if ((title0 = xmlGetProp(n, (const xmlChar *) "id")) != NULL) {
|
|
|
|
|
status.id = id = squash_whitespace(title0);
|
|
|
|
|
xmlFree(title0);
|
|
|
|
|
}
|
|
|
|
@ -590,13 +592,13 @@ struct box * convert_xml_to_box(xmlNode * n, struct content *content,
|
|
|
|
|
/* new inline container unless this is a float */
|
|
|
|
|
inline_container = 0;
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "colspan"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "colspan")) != NULL) {
|
|
|
|
|
int colspan = atoi(s);
|
|
|
|
|
if (1 <= colspan && colspan <= 100)
|
|
|
|
|
box->columns = colspan;
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
}
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "rowspan"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "rowspan")) != NULL) {
|
|
|
|
|
if ((box->rows = strtol(s, 0, 10)) == 0)
|
|
|
|
|
box->rows = 1;
|
|
|
|
|
xmlFree(s);
|
|
|
|
@ -660,7 +662,7 @@ struct css_style * box_get_style(struct content *c,
|
|
|
|
|
the spec. Many browsers seem to allow it on other elements too,
|
|
|
|
|
so let's be generic ;)
|
|
|
|
|
*/
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "background"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "background")) != NULL) {
|
|
|
|
|
style->background_image.type = CSS_BACKGROUND_IMAGE_URI;
|
|
|
|
|
/**\todo This will leak memory. */
|
|
|
|
|
res = url_join(s, c->data.html.base_url, &style->background_image.uri);
|
|
|
|
@ -674,7 +676,7 @@ struct css_style * box_get_style(struct content *c,
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "bgcolor"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "bgcolor")) != NULL) {
|
|
|
|
|
unsigned int r, g, b;
|
|
|
|
|
if (s[0] == '#' && sscanf(s + 1, "%2x%2x%2x", &r, &g, &b) == 3)
|
|
|
|
|
style->background_color = (b << 16) | (g << 8) | r;
|
|
|
|
@ -683,7 +685,7 @@ struct css_style * box_get_style(struct content *c,
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "color"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "color")) != NULL) {
|
|
|
|
|
unsigned int r, g, b;
|
|
|
|
|
if (s[0] == '#' && sscanf(s + 1, "%2x%2x%2x", &r, &g, &b) == 3)
|
|
|
|
|
style->color = (b << 16) | (g << 8) | r;
|
|
|
|
@ -692,7 +694,7 @@ struct css_style * box_get_style(struct content *c,
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "height"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "height")) != NULL) {
|
|
|
|
|
float value = atof(s);
|
|
|
|
|
if (value < 0 || strlen(s) == 0) {
|
|
|
|
|
/* ignore negative values and height="" */
|
|
|
|
@ -708,7 +710,7 @@ struct css_style * box_get_style(struct content *c,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (strcmp((const char *) n->name, "input") == 0) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "size"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "size")) != NULL) {
|
|
|
|
|
int size = atoi(s);
|
|
|
|
|
if (0 < size) {
|
|
|
|
|
char *type = (char *) xmlGetProp(n, (const xmlChar *) "type");
|
|
|
|
@ -729,7 +731,7 @@ struct css_style * box_get_style(struct content *c,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (strcmp((const char *) n->name, "body") == 0) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "text"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "text")) != NULL) {
|
|
|
|
|
unsigned int r, g, b;
|
|
|
|
|
if (s[0] == '#' && sscanf(s + 1, "%2x%2x%2x", &r, &g, &b) == 3)
|
|
|
|
|
style->color = (b << 16) | (g << 8) | r;
|
|
|
|
@ -739,7 +741,7 @@ struct css_style * box_get_style(struct content *c,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "width"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "width")) != NULL) {
|
|
|
|
|
float value = atof(s);
|
|
|
|
|
if (value < 0 || strlen(s) == 0) {
|
|
|
|
|
/* ignore negative values and width="" */
|
|
|
|
@ -755,7 +757,7 @@ struct css_style * box_get_style(struct content *c,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (strcmp((const char *) n->name, "textarea") == 0) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "rows"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "rows")) != NULL) {
|
|
|
|
|
int value = atoi(s);
|
|
|
|
|
if (0 < value) {
|
|
|
|
|
style->height.height = CSS_HEIGHT_LENGTH;
|
|
|
|
@ -764,7 +766,7 @@ struct css_style * box_get_style(struct content *c,
|
|
|
|
|
}
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
}
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "cols"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "cols")) != NULL) {
|
|
|
|
|
int value = atoi(s);
|
|
|
|
|
if (0 < value) {
|
|
|
|
|
style->width.width = CSS_WIDTH_LENGTH;
|
|
|
|
@ -775,7 +777,7 @@ struct css_style * box_get_style(struct content *c,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "style"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "style")) != NULL) {
|
|
|
|
|
struct css_style astyle;
|
|
|
|
|
memcpy(&astyle, &css_empty_style, sizeof(struct css_style));
|
|
|
|
|
css_parse_property_list(c, &astyle, s);
|
|
|
|
@ -847,11 +849,11 @@ struct box_result box_a(xmlNode *n, struct box_status *status,
|
|
|
|
|
char *s, *s1;
|
|
|
|
|
char *id = status->id;
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "href")))
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "href")) != NULL)
|
|
|
|
|
status->href = s;
|
|
|
|
|
|
|
|
|
|
/* name and id share the same namespace */
|
|
|
|
|
if ((s1 = (char *) xmlGetProp(n, (const xmlChar *) "name"))) {
|
|
|
|
|
if ((s1 = (char *) xmlGetProp(n, (const xmlChar *) "name")) != NULL) {
|
|
|
|
|
if (status->id && strcmp(status->id, s1) == 0) {
|
|
|
|
|
/* both specified and they match => ok */
|
|
|
|
|
id = status->id;
|
|
|
|
@ -908,7 +910,7 @@ struct box_result box_image(xmlNode *n, struct box_status *status,
|
|
|
|
|
status->content->data.html.box_pool);
|
|
|
|
|
|
|
|
|
|
/* handle alt text */
|
|
|
|
|
if ((s2 = xmlGetProp(n, (const xmlChar *) "alt"))) {
|
|
|
|
|
if ((s2 = xmlGetProp(n, (const xmlChar *) "alt")) != NULL) {
|
|
|
|
|
box->text = squash_whitespace(s2);
|
|
|
|
|
box->length = strlen(box->text);
|
|
|
|
|
box->font = nsfont_open(status->content->data.html.fonts, style);
|
|
|
|
@ -916,11 +918,11 @@ struct box_result box_image(xmlNode *n, struct box_status *status,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* img without src is an error */
|
|
|
|
|
if (!(s = (char *) xmlGetProp(n, (const xmlChar *) "src")))
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src")) == NULL)
|
|
|
|
|
return (struct box_result) {box, false, false};
|
|
|
|
|
|
|
|
|
|
/* imagemap associated with this image */
|
|
|
|
|
if ((map = xmlGetProp(n, (const xmlChar *) "usemap"))) {
|
|
|
|
|
if ((map = xmlGetProp(n, (const xmlChar *) "usemap")) != NULL) {
|
|
|
|
|
if (map[0] == '#') {
|
|
|
|
|
box->usemap = xstrdup(map+1);
|
|
|
|
|
}
|
|
|
|
@ -963,8 +965,7 @@ struct box_result box_form(xmlNode *n, struct box_status *status,
|
|
|
|
|
box = box_create(style, status->href, status->title, status->id,
|
|
|
|
|
status->content->data.html.box_pool);
|
|
|
|
|
|
|
|
|
|
s = (char *) xmlGetProp(n, (const xmlChar *) "action");
|
|
|
|
|
if (!s) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "action")) == NULL) {
|
|
|
|
|
/* the action attribute is required */
|
|
|
|
|
return (struct box_result) {box, true, false};
|
|
|
|
|
}
|
|
|
|
@ -973,10 +974,10 @@ struct box_result box_form(xmlNode *n, struct box_status *status,
|
|
|
|
|
form->action = s;
|
|
|
|
|
|
|
|
|
|
form->method = method_GET;
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "method"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "method")) != NULL) {
|
|
|
|
|
if (strcasecmp(s, "post") == 0) {
|
|
|
|
|
form->method = method_POST_URLENC;
|
|
|
|
|
if ((s2 = (char *) xmlGetProp(n, (const xmlChar *) "enctype"))) {
|
|
|
|
|
if ((s2 = (char *) xmlGetProp(n, (const xmlChar *) "enctype")) != NULL) {
|
|
|
|
|
if (strcasecmp(s2, "multipart/form-data") == 0)
|
|
|
|
|
form->method = method_POST_MULTIPART;
|
|
|
|
|
xmlFree(s2);
|
|
|
|
@ -1018,7 +1019,7 @@ struct box_result box_textarea(xmlNode *n, struct box_status *status,
|
|
|
|
|
else
|
|
|
|
|
box->gadget->form = 0;
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "name"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "name")) != NULL) {
|
|
|
|
|
box->gadget->name = strdup(s);
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
if (!box->gadget->name) {
|
|
|
|
@ -1095,7 +1096,7 @@ struct box_result box_select(xmlNode *n, struct box_status *status,
|
|
|
|
|
gadget->form = 0;
|
|
|
|
|
|
|
|
|
|
gadget->data.select.multiple = false;
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "multiple"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "multiple")) != NULL) {
|
|
|
|
|
gadget->data.select.multiple = true;
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
}
|
|
|
|
@ -1129,7 +1130,7 @@ struct box_result box_select(xmlNode *n, struct box_status *status,
|
|
|
|
|
return (struct box_result) {0, false, false};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "name"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "name")) != NULL) {
|
|
|
|
|
gadget->name = strdup(s);
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
if (!gadget->name) {
|
|
|
|
@ -1193,7 +1194,7 @@ void add_option(xmlNode* n, struct form_control* current_select, const char *tex
|
|
|
|
|
current_select->data.select.last_item->next = option;
|
|
|
|
|
current_select->data.select.last_item = option;
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "value"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "value")) != NULL) {
|
|
|
|
|
option->value = xstrdup(s);
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
} else {
|
|
|
|
@ -1212,7 +1213,7 @@ void add_option(xmlNode* n, struct form_control* current_select, const char *tex
|
|
|
|
|
option->selected = option->initial_selected = false;
|
|
|
|
|
option->text = text;
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "selected"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "selected")) != NULL) {
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
if (current_select->data.select.num_selected == 0 ||
|
|
|
|
|
current_select->data.select.multiple) {
|
|
|
|
@ -1260,7 +1261,7 @@ struct box_result box_input(xmlNode *n, struct box_status *status,
|
|
|
|
|
return (struct box_result) {0, false, true};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "value"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "value")) != NULL) {
|
|
|
|
|
gadget->value = strdup(s);
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
if (!gadget->value) {
|
|
|
|
@ -1283,12 +1284,12 @@ struct box_result box_input(xmlNode *n, struct box_status *status,
|
|
|
|
|
}
|
|
|
|
|
gadget->box = box;
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "checked"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "checked")) != NULL) {
|
|
|
|
|
gadget->selected = true;
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "value"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "value")) != NULL) {
|
|
|
|
|
gadget->value = strdup(s);
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
if (!gadget->value) {
|
|
|
|
@ -1340,7 +1341,7 @@ struct box_result box_input(xmlNode *n, struct box_status *status,
|
|
|
|
|
status->content->data.html.box_pool);
|
|
|
|
|
inline_box->type = BOX_INLINE;
|
|
|
|
|
inline_box->style_clone = 1;
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "value"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "value")) != NULL) {
|
|
|
|
|
inline_box->text = s;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
@ -1362,7 +1363,7 @@ struct box_result box_input(xmlNode *n, struct box_status *status,
|
|
|
|
|
}
|
|
|
|
|
gadget->box = box;
|
|
|
|
|
gadget->type = GADGET_IMAGE;
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar*) "src"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar*) "src")) != NULL) {
|
|
|
|
|
res = url_join(s, status->content->data.html.base_url, &url);
|
|
|
|
|
/* if url is equivalent to the parent's url,
|
|
|
|
|
* we've got infinite inclusion. stop it here.
|
|
|
|
@ -1419,7 +1420,7 @@ struct box *box_input_text(xmlNode *n, struct box_status *status,
|
|
|
|
|
box->gadget->box = box;
|
|
|
|
|
|
|
|
|
|
box->gadget->maxlength = 100;
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "maxlength"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "maxlength")) != NULL) {
|
|
|
|
|
box->gadget->maxlength = atoi(s);
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
}
|
|
|
|
@ -1491,7 +1492,7 @@ struct box_result box_button(xmlNode *n, struct box_status *status,
|
|
|
|
|
else
|
|
|
|
|
box->gadget->form = 0;
|
|
|
|
|
box->gadget->box = box;
|
|
|
|
|
if ((s = xmlGetProp(n, (const xmlChar *) "name"))) {
|
|
|
|
|
if ((s = xmlGetProp(n, (const xmlChar *) "name")) != NULL) {
|
|
|
|
|
box->gadget->name = strdup((char *) s);
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
if (!box->gadget->name) {
|
|
|
|
@ -1499,7 +1500,7 @@ struct box_result box_button(xmlNode *n, struct box_status *status,
|
|
|
|
|
return (struct box_result) {0, false, true};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ((s = xmlGetProp(n, (const xmlChar *) "value"))) {
|
|
|
|
|
if ((s = xmlGetProp(n, (const xmlChar *) "value")) != NULL) {
|
|
|
|
|
box->gadget->value = strdup((char *) s);
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
if (!box->gadget->value) {
|
|
|
|
@ -2073,7 +2074,7 @@ struct box_result box_object(xmlNode *n, struct box_status *status,
|
|
|
|
|
po->params = 0;
|
|
|
|
|
|
|
|
|
|
/* object data */
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "data"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "data")) != NULL) {
|
|
|
|
|
res = url_join(s, status->content->data.html.base_url, &url);
|
|
|
|
|
/* if url is equivalent to the parent's url,
|
|
|
|
|
* we've got infinite inclusion. stop it here.
|
|
|
|
@ -2090,43 +2091,34 @@ struct box_result box_object(xmlNode *n, struct box_status *status,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* imagemap associated with this object */
|
|
|
|
|
if ((map = xmlGetProp(n, (const xmlChar *) "usemap"))) {
|
|
|
|
|
if (map[0] == '#') {
|
|
|
|
|
box->usemap = xstrdup(map+1);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
box->usemap = xstrdup(map);
|
|
|
|
|
}
|
|
|
|
|
if ((map = xmlGetProp(n, (const xmlChar *) "usemap")) != NULL) {
|
|
|
|
|
box->usemap = (map[0] == '#') ? xstrdup(map+1) : xstrdup(map);
|
|
|
|
|
xmlFree(map);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* object type */
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "type"))) {
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "type")) != NULL) {
|
|
|
|
|
po->type = strdup(s);
|
|
|
|
|
LOG(("type: %s", s));
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* object codetype */
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "codetype"))) {
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "codetype")) != NULL) {
|
|
|
|
|
po->codetype = strdup(s);
|
|
|
|
|
LOG(("codetype: %s", s));
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* object codebase */
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "codebase"))) {
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "codebase")) != NULL) {
|
|
|
|
|
po->codebase = strdup(s);
|
|
|
|
|
LOG(("codebase: %s", s));
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* object classid */
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "classid"))) {
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "classid")) != NULL) {
|
|
|
|
|
po->classid = strdup(s);
|
|
|
|
|
LOG(("classid: %s", s));
|
|
|
|
|
xmlFree(s);
|
|
|
|
@ -2137,9 +2129,8 @@ struct box_result box_object(xmlNode *n, struct box_status *status,
|
|
|
|
|
* po->params points to the head of the list.
|
|
|
|
|
* new parameters are added to the head of the list.
|
|
|
|
|
*/
|
|
|
|
|
for (c = n->children; c != 0; c = c->next) {
|
|
|
|
|
for (c = n->children; c != NULL; c = c->next) {
|
|
|
|
|
if (strcmp((const char *) c->name, "param") == 0) {
|
|
|
|
|
|
|
|
|
|
pp = xcalloc(1, sizeof(*pp));
|
|
|
|
|
|
|
|
|
|
/* initialise pp struct */
|
|
|
|
@ -2149,34 +2140,33 @@ struct box_result box_object(xmlNode *n, struct box_status *status,
|
|
|
|
|
pp->type = 0;
|
|
|
|
|
pp->next = 0;
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(c, (const xmlChar *) "name"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(c, (const xmlChar *) "name")) != NULL) {
|
|
|
|
|
pp->name = strdup(s);
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
}
|
|
|
|
|
if ((s = (char *) xmlGetProp(c, (const xmlChar *) "value"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(c, (const xmlChar *) "value")) != NULL) {
|
|
|
|
|
pp->value = strdup(s);
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
}
|
|
|
|
|
if ((s = (char *) xmlGetProp(c, (const xmlChar *) "type"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(c, (const xmlChar *) "type")) != NULL) {
|
|
|
|
|
pp->type = strdup(s);
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
}
|
|
|
|
|
if ((s = (char *) xmlGetProp(c, (const xmlChar *) "valuetype"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(c, (const xmlChar *) "valuetype")) != NULL) {
|
|
|
|
|
pp->valuetype = strdup(s);
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
pp->valuetype = strdup("data");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pp->next = po->params;
|
|
|
|
|
po->params = pp;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* The first non-param child is the start of the
|
|
|
|
|
* alt html. Therefore, we should break out of this loop.
|
|
|
|
|
} else {
|
|
|
|
|
/* The first non-param child is the start
|
|
|
|
|
* of the alt html. Therefore, we should
|
|
|
|
|
* break out of this loop.
|
|
|
|
|
*/
|
|
|
|
|
/** \todo: following statement is *not* breaking the loop ?! Is comment or code wrong here ? */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -2218,7 +2208,7 @@ struct box_result box_embed(xmlNode *n, struct box_status *status,
|
|
|
|
|
po->params = 0;
|
|
|
|
|
|
|
|
|
|
/* embed src */
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src")) != NULL) {
|
|
|
|
|
res = url_join(s, status->content->data.html.base_url, &url);
|
|
|
|
|
/* if url is equivalent to the parent's url,
|
|
|
|
|
* we've got infinite inclusion. stop it here.
|
|
|
|
@ -2237,8 +2227,7 @@ struct box_result box_embed(xmlNode *n, struct box_status *status,
|
|
|
|
|
/**
|
|
|
|
|
* we munge all other attributes into a plugin_parameter structure
|
|
|
|
|
*/
|
|
|
|
|
for(a=n->properties; a!=0; a=a->next) {
|
|
|
|
|
|
|
|
|
|
for (a=n->properties; a != NULL; a=a->next) {
|
|
|
|
|
pp = xcalloc(1, sizeof(*pp));
|
|
|
|
|
|
|
|
|
|
/* initialise pp struct */
|
|
|
|
@ -2248,11 +2237,10 @@ struct box_result box_embed(xmlNode *n, struct box_status *status,
|
|
|
|
|
pp->type = 0;
|
|
|
|
|
pp->next = 0;
|
|
|
|
|
|
|
|
|
|
if(strcasecmp((const char*)a->name, "src") != 0) {
|
|
|
|
|
if (strcasecmp((const char*)a->name, "src") != 0) {
|
|
|
|
|
pp->name = strdup((const char*)a->name);
|
|
|
|
|
pp->value = strdup((char*)a->children->content);
|
|
|
|
|
pp->valuetype = strdup("data");
|
|
|
|
|
|
|
|
|
|
pp->next = po->params;
|
|
|
|
|
po->params = pp;
|
|
|
|
|
}
|
|
|
|
@ -2294,7 +2282,7 @@ struct box_result box_applet(xmlNode *n, struct box_status *status,
|
|
|
|
|
po->params = 0;
|
|
|
|
|
|
|
|
|
|
/* code */
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "code"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "code")) != NULL) {
|
|
|
|
|
res = url_join(s, status->content->data.html.base_url, &url);
|
|
|
|
|
/* if url is equivalent to the parent's url,
|
|
|
|
|
* we've got infinite inclusion. stop it here.
|
|
|
|
@ -2311,8 +2299,7 @@ struct box_result box_applet(xmlNode *n, struct box_status *status,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* object codebase */
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "codebase"))) {
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "codebase")) != NULL) {
|
|
|
|
|
po->codebase = strdup(s);
|
|
|
|
|
LOG(("codebase: %s", s));
|
|
|
|
|
xmlFree(s);
|
|
|
|
@ -2325,7 +2312,6 @@ struct box_result box_applet(xmlNode *n, struct box_status *status,
|
|
|
|
|
*/
|
|
|
|
|
for (c = n->children; c != 0; c = c->next) {
|
|
|
|
|
if (strcmp((const char *) c->name, "param") == 0) {
|
|
|
|
|
|
|
|
|
|
pp = xcalloc(1, sizeof(*pp));
|
|
|
|
|
|
|
|
|
|
/* initialise pp struct */
|
|
|
|
@ -2335,34 +2321,33 @@ struct box_result box_applet(xmlNode *n, struct box_status *status,
|
|
|
|
|
pp->type = 0;
|
|
|
|
|
pp->next = 0;
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(c, (const xmlChar *) "name"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(c, (const xmlChar *) "name")) != NULL) {
|
|
|
|
|
pp->name = strdup(s);
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
}
|
|
|
|
|
if ((s = (char *) xmlGetProp(c, (const xmlChar *) "value"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(c, (const xmlChar *) "value")) != NULL) {
|
|
|
|
|
pp->value = strdup(s);
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
}
|
|
|
|
|
if ((s = (char *) xmlGetProp(c, (const xmlChar *) "type"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(c, (const xmlChar *) "type")) != NULL) {
|
|
|
|
|
pp->type = strdup(s);
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
}
|
|
|
|
|
if ((s = (char *) xmlGetProp(c, (const xmlChar *) "valuetype"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(c, (const xmlChar *) "valuetype")) != NULL) {
|
|
|
|
|
pp->valuetype = strdup(s);
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
pp->valuetype = strdup("data");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pp->next = po->params;
|
|
|
|
|
po->params = pp;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* The first non-param child is the start of the
|
|
|
|
|
* alt html. Therefore, we should break out of this loop.
|
|
|
|
|
} else {
|
|
|
|
|
/* The first non-param child is the start
|
|
|
|
|
* of the alt html. Therefore, we should
|
|
|
|
|
* break out of this loop.
|
|
|
|
|
*/
|
|
|
|
|
/** \todo: following statement is *not* breaking the loop ?! Is comment or code wrong here ? */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -2370,7 +2355,7 @@ struct box_result box_applet(xmlNode *n, struct box_status *status,
|
|
|
|
|
box->object_params = po;
|
|
|
|
|
|
|
|
|
|
/* start fetch */
|
|
|
|
|
if(plugin_decode(status->content, url, box, po))
|
|
|
|
|
if (plugin_decode(status->content, url, box, po))
|
|
|
|
|
return (struct box_result) {box, false, false};
|
|
|
|
|
|
|
|
|
|
return (struct box_result) {box, true, false};
|
|
|
|
@ -2403,7 +2388,7 @@ struct box_result box_iframe(xmlNode *n, struct box_status *status,
|
|
|
|
|
po->params = 0;
|
|
|
|
|
|
|
|
|
|
/* iframe src */
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src")) != NULL) {
|
|
|
|
|
res = url_join(s, status->content->data.html.base_url, &url);
|
|
|
|
|
/* if url is equivalent to the parent's url,
|
|
|
|
|
* we've got infinite inclusion. stop it here.
|
|
|
|
@ -2436,7 +2421,7 @@ struct box_result box_iframe(xmlNode *n, struct box_status *status,
|
|
|
|
|
*
|
|
|
|
|
* Returns false if the object could not be handled.
|
|
|
|
|
*
|
|
|
|
|
* TODO: reformat, plug failure leaks
|
|
|
|
|
* TODO: plug failure leaks
|
|
|
|
|
*/
|
|
|
|
|
bool plugin_decode(struct content* content, char* url, struct box* box,
|
|
|
|
|
struct object_params* po)
|
|
|
|
@ -2447,7 +2432,7 @@ bool plugin_decode(struct content* content, char* url, struct box* box,
|
|
|
|
|
/* Check if the codebase attribute is defined.
|
|
|
|
|
* If it is not, set it to the codebase of the current document.
|
|
|
|
|
*/
|
|
|
|
|
if(po->codebase == 0)
|
|
|
|
|
if (po->codebase == 0)
|
|
|
|
|
res = url_join("./", content->data.html.base_url, &po->codebase);
|
|
|
|
|
else
|
|
|
|
|
res = url_join(po->codebase, content->data.html.base_url, &po->codebase);
|
|
|
|
@ -2465,17 +2450,18 @@ bool plugin_decode(struct content* content, char* url, struct box* box,
|
|
|
|
|
* If neither are specified or if classid begins "clsid:",
|
|
|
|
|
* we can't handle this object.
|
|
|
|
|
*/
|
|
|
|
|
if(po->data == 0 && po->classid == 0) {
|
|
|
|
|
if (po->data == 0 && po->classid == 0)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if(po->data == 0 && po->classid != 0) {
|
|
|
|
|
if(strncasecmp(po->classid, "clsid:", 6) == 0) {
|
|
|
|
|
|
|
|
|
|
if (po->data == 0 && po->classid != 0) {
|
|
|
|
|
if (strncasecmp(po->classid, "clsid:", 6) == 0) {
|
|
|
|
|
/* Flash */
|
|
|
|
|
if(strcasecmp(po->classid, "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000") == 0) {
|
|
|
|
|
for(pp = po->params; pp != 0 &&
|
|
|
|
|
(strcasecmp(pp->name, "movie") != 0);
|
|
|
|
|
pp = pp->next);
|
|
|
|
|
if(pp == 0)
|
|
|
|
|
if (strcasecmp(po->classid, "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000") == 0) {
|
|
|
|
|
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)
|
|
|
|
@ -2491,8 +2477,7 @@ bool plugin_decode(struct content* content, char* url, struct box* box,
|
|
|
|
|
LOG(("ActiveX object - n0"));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
} else {
|
|
|
|
|
res = url_join(po->classid, po->codebase, &url);
|
|
|
|
|
if (res != URL_FUNC_OK)
|
|
|
|
|
return false;
|
|
|
|
@ -2500,12 +2485,11 @@ bool plugin_decode(struct content* content, char* url, struct box* box,
|
|
|
|
|
/* The java plugin doesn't need the .class extension
|
|
|
|
|
* so we strip it.
|
|
|
|
|
*/
|
|
|
|
|
if(strcasecmp((&po->classid[strlen(po->classid)-6]),
|
|
|
|
|
if (strcasecmp(&po->classid[strlen(po->classid)-6],
|
|
|
|
|
".class") == 0)
|
|
|
|
|
po->classid[strlen(po->classid)-6] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
} else {
|
|
|
|
|
res = url_join(po->data, po->codebase, &url);
|
|
|
|
|
if (res != URL_FUNC_OK)
|
|
|
|
|
return false;
|
|
|
|
@ -2514,21 +2498,18 @@ bool plugin_decode(struct content* content, char* url, struct box* box,
|
|
|
|
|
/* Check if the declared mime type is understandable.
|
|
|
|
|
* Checks type and codetype attributes.
|
|
|
|
|
*/
|
|
|
|
|
if(po->type != 0) {
|
|
|
|
|
if (content_lookup(po->type) == CONTENT_OTHER)
|
|
|
|
|
if (po->type != 0 && content_lookup(po->type) == CONTENT_OTHER)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if(po->codetype != 0) {
|
|
|
|
|
if (content_lookup(po->codetype) == CONTENT_OTHER)
|
|
|
|
|
if (po->codetype != 0 && 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.
|
|
|
|
|
* 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).
|
|
|
|
|
* 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, 0, 1000, 1000, false);
|
|
|
|
|
|
|
|
|
@ -2558,7 +2539,7 @@ struct box_result box_frameset(xmlNode *n, struct box_status *status,
|
|
|
|
|
box->type = BOX_TABLE;
|
|
|
|
|
|
|
|
|
|
/* parse rows and columns */
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "rows"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "rows")) != NULL) {
|
|
|
|
|
row_height = box_parse_multi_lengths(s, &rows);
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
if (!row_height) {
|
|
|
|
@ -2567,7 +2548,7 @@ struct box_result box_frameset(xmlNode *n, struct box_status *status,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "cols"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "cols")) != NULL) {
|
|
|
|
|
col_width = box_parse_multi_lengths(s, &cols);
|
|
|
|
|
xmlFree(s);
|
|
|
|
|
if (!col_width) {
|
|
|
|
@ -2684,8 +2665,7 @@ struct box_result box_frameset(xmlNode *n, struct box_status *status,
|
|
|
|
|
object_box->style_clone = 1;
|
|
|
|
|
box_add_child(cell_box, object_box);
|
|
|
|
|
|
|
|
|
|
if (!(s = (char *) xmlGetProp(c,
|
|
|
|
|
(const xmlChar *) "src"))) {
|
|
|
|
|
if ((s = (char *) xmlGetProp(c, (const xmlChar *) "src")) == NULL) {
|
|
|
|
|
c = c->next;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
@ -2734,16 +2714,15 @@ struct box_multi_length *box_parse_multi_lengths(const char *s,
|
|
|
|
|
unsigned int *count)
|
|
|
|
|
{
|
|
|
|
|
char *end;
|
|
|
|
|
unsigned int i, n = 1;
|
|
|
|
|
unsigned int i, n;
|
|
|
|
|
struct box_multi_length *length;
|
|
|
|
|
|
|
|
|
|
for (i = 0; s[i]; i++)
|
|
|
|
|
for (i = 0, n = 1; s[i]; i++)
|
|
|
|
|
if (s[i] == ',')
|
|
|
|
|
n++;
|
|
|
|
|
|
|
|
|
|
length = malloc(sizeof *length * n);
|
|
|
|
|
if (!length)
|
|
|
|
|
return 0;
|
|
|
|
|
if ((length = malloc(sizeof *length * n)) == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i != n; i++) {
|
|
|
|
|
while (isspace(*s))
|
|
|
|
@ -2934,7 +2913,7 @@ struct box *box_object_at_point(struct content *c, int x, int y)
|
|
|
|
|
|
|
|
|
|
assert(c->type == CONTENT_HTML);
|
|
|
|
|
|
|
|
|
|
while ((box = box_at_point(box, x, y, &box_x, &box_y, &content))) {
|
|
|
|
|
while ((box = box_at_point(box, x, y, &box_x, &box_y, &content)) != NULL) {
|
|
|
|
|
if (box->style &&
|
|
|
|
|
box->style->visibility == CSS_VISIBILITY_HIDDEN)
|
|
|
|
|
continue;
|
|
|
|
@ -2953,7 +2932,7 @@ struct box *box_object_at_point(struct content *c, int x, int y)
|
|
|
|
|
* \param id id to look for
|
|
|
|
|
* \return the box or 0 if not found
|
|
|
|
|
*/
|
|
|
|
|
struct box *box_find_by_id(struct box *box, char *id)
|
|
|
|
|
struct box *box_find_by_id(struct box *box, const char *id)
|
|
|
|
|
{
|
|
|
|
|
struct box *a, *b;
|
|
|
|
|
|
|
|
|
@ -2965,5 +2944,5 @@ struct box *box_find_by_id(struct box *box, char *id)
|
|
|
|
|
return b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|