summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--render/box.c9
-rw-r--r--render/box.h7
-rw-r--r--render/box_construct.c53
-rw-r--r--render/html.c14
-rw-r--r--render/html.h9
5 files changed, 70 insertions, 22 deletions
diff --git a/render/box.c b/render/box.c
index 37fc6f1d0..3ae85b1dd 100644
--- a/render/box.c
+++ b/render/box.c
@@ -66,6 +66,7 @@ struct box * box_create(struct css_style *style,
box->space = 0;
box->clone = 0;
box->href = href;
+ box->target = 0;
box->title = title;
box->columns = 1;
box->rows = 1;
@@ -475,11 +476,13 @@ void box_dump(struct box *box, unsigned int depth)
fprintf(stderr, "(object '%s') ", box->object->url);
if (box->style)
css_dump_style(box->style);
- if (box->href != 0)
+ if (box->href)
fprintf(stderr, " -> '%s'", box->href);
- if (box->title != 0)
+ if (box->target)
+ fprintf(stderr, " |%s|", box->target);
+ if (box->title)
fprintf(stderr, " [%s]", box->title);
- if (box->id != 0)
+ if (box->id)
fprintf(stderr, " <%s>", box->id);
if (box->type == BOX_INLINE || box->type == BOX_INLINE_END)
fprintf(stderr, " inline_end %p", box->inline_end);
diff --git a/render/box.h b/render/box.h
index 405683fe7..05d74cfe2 100644
--- a/render/box.h
+++ b/render/box.h
@@ -159,6 +159,7 @@ struct box {
unsigned int clone : 1;
char *href; /**< Link, or 0. */
+ const char *target; /**< Link target, or 0. */
char *title; /**< Title, or 0. */
unsigned int columns; /**< Number of columns for TABLE / TABLE_CELL. */
@@ -233,6 +234,12 @@ struct object_param {
struct object_param *next;
};
+/** Frame target names (constant pointers to save duplicating the strings many
+ * times). We convert _blank to _top for user-friendliness. */
+extern const char *TARGET_SELF;
+extern const char *TARGET_PARENT;
+extern const char *TARGET_TOP;
+
#define UNKNOWN_WIDTH INT_MAX
#define UNKNOWN_MAX_WIDTH INT_MAX
diff --git a/render/box_construct.c b/render/box_construct.c
index b338f2f5f..93551c75e 100644
--- a/render/box_construct.c
+++ b/render/box_construct.c
@@ -69,6 +69,12 @@ static const content_type image_types[] = {
#define MAX_SPAN (100)
+/* the strings are not important, since we just compare the pointers */
+const char *TARGET_SELF = "_self";
+const char *TARGET_PARENT = "_parent";
+const char *TARGET_TOP = "_top";
+
+
static bool convert_xml_to_box(xmlNode *n, struct content *content,
struct css_style *parent_style,
struct box *parent, struct box **inline_container,
@@ -480,7 +486,7 @@ bool box_construct_element(xmlNode *n, struct content *content,
if (style->background_image.type == CSS_BACKGROUND_IMAGE_URI) {
if (!html_fetch_object(content, style->background_image.uri,
box, image_types, content->available_width,
- 1000, true))
+ 1000, true, 0))
return false;
}
@@ -1135,9 +1141,9 @@ bool box_a(BOX_SPECIAL_PARAMS)
return false;
if (url) {
box->href = talloc_strdup(content, url);
+ free(url);
if (!box->href)
return false;
- free(url);
}
}
@@ -1145,6 +1151,27 @@ bool box_a(BOX_SPECIAL_PARAMS)
if (!box_get_attribute(n, "name", content, &box->id))
return false;
+ /* target frame [16.3] */
+ if ((s = xmlGetProp(n, (const xmlChar *) "target"))) {
+ if (!strcmp(s, "_blank") || !strcmp(s, "_top"))
+ box->target = TARGET_TOP;
+ else if (!strcmp(s, "_parent"))
+ box->target = TARGET_PARENT;
+ else if (!strcmp(s, "_self"))
+ /* the default may have been overridden by a
+ * <base target=...>, so this is different to 0 */
+ box->target = TARGET_SELF;
+ else if (('a' <= s[0] && s[0] <= 'z') ||
+ ('A' <= s[0] && s[0] <= 'Z')) { /* [6.16] */
+ box->target = talloc_strdup(content, s);
+ if (!box->target) {
+ xmlFree(s);
+ return false;
+ }
+ }
+ xmlFree(s);
+ }
+
return true;
}
@@ -1189,7 +1216,7 @@ bool box_image(BOX_SPECIAL_PARAMS)
/* start fetch */
ok = html_fetch_object(content, url, box, image_types,
- content->available_width, 1000, false);
+ content->available_width, 1000, false, 0);
free(url);
return ok;
}
@@ -1297,7 +1324,7 @@ bool box_object(BOX_SPECIAL_PARAMS)
/* start fetch (MIME type is ok or not specified) */
if (!html_fetch_object(content, params->data, box, 0,
- content->available_width, 1000, false))
+ content->available_width, 1000, false, 0))
return false;
/* convert children and place into fallback */
@@ -1457,7 +1484,7 @@ bool box_frameset(BOX_SPECIAL_PARAMS)
unsigned int row, col;
unsigned int rows = 1, cols = 1;
int object_width, object_height;
- char *s, *s1, *url;
+ char *s, *s1, *url, *name;
struct box *row_box;
struct box *cell_box;
struct box *frameset_box;
@@ -1603,14 +1630,20 @@ bool box_frameset(BOX_SPECIAL_PARAMS)
continue;
}
- LOG(("frame, url '%s'", url));
+ name = xmlGetProp(c, (const xmlChar *) "name");
+
+ LOG(("frame, url '%s', name '%s'", url, name));
if (!html_fetch_object(content, url,
cell_box, 0,
- object_width, object_height, false))
+ object_width, object_height, false,
+ name))
return false;
free(url);
+ if (name)
+ xmlFree(name);
+
c = c->next;
}
}
@@ -1647,7 +1680,7 @@ bool box_iframe(BOX_SPECIAL_PARAMS)
/* start fetch */
ok = html_fetch_object(content, url, box, 0,
- content->available_width, 0, false);
+ content->available_width, 0, false, 0);
free(url);
return ok;
@@ -1840,7 +1873,7 @@ bool box_input(BOX_SPECIAL_PARAMS)
if (!html_fetch_object(content, url,
box, image_types,
content->available_width,
- 1000, false)) {
+ 1000, false, 0)) {
free(url);
goto no_memory;
}
@@ -2291,7 +2324,7 @@ bool box_embed(BOX_SPECIAL_PARAMS)
/* start fetch */
return html_fetch_object(content, params->data, box, 0,
- content->available_width, 1000, false);
+ content->available_width, 1000, false, 0);
}
/**
diff --git a/render/html.c b/render/html.c
index e5ce41b23..2d84f3a17 100644
--- a/render/html.c
+++ b/render/html.c
@@ -744,21 +744,22 @@ void html_convert_css_callback(content_msg msg, struct content *css,
/**
* Start a fetch for an object required by a page.
*
- * \param c content structure
- * \param url URL of object to fetch (copied)
- * \param box box that will contain the object
+ * \param c content structure
+ * \param url URL of object to fetch (copied)
+ * \param box box that will contain the object
* \param permitted_types array of types, terminated by CONTENT_UNKNOWN,
* or 0 if all types except OTHER and UNKNOWN acceptable
* \param available_width estimate of width of object
* \param available_height estimate of height of object
- * \param background this is a background image
+ * \param background this is a background image
+ * \param frame name of frame, or 0 if not a frame (copied)
* \return true on success, false on memory exhaustion
*/
bool html_fetch_object(struct content *c, char *url, struct box *box,
const content_type *permitted_types,
int available_width, int available_height,
- bool background)
+ bool background, char *frame)
{
unsigned int i = c->data.html.object_count;
struct content_html_object *object;
@@ -788,6 +789,9 @@ bool html_fetch_object(struct content *c, char *url, struct box *box,
c->data.html.object[i].permitted_types = permitted_types;
c->data.html.object[i].background = background;
c->data.html.object[i].content = c_fetch;
+ c->data.html.object[i].frame = 0;
+ if (frame)
+ c->data.html.object[i].frame = talloc_strdup(c, frame);
c->data.html.object_count++;
c->active++;
diff --git a/render/html.h b/render/html.h
index 3bc71d834..9a0077af4 100644
--- a/render/html.h
+++ b/render/html.h
@@ -43,7 +43,8 @@ struct content_html_object {
/** Pointer to array of permitted content_type, terminated by
* CONTENT_UNKNOWN, or 0 if any type is acceptable. */
const content_type *permitted_types;
- bool background; /** Is this object a background image? */
+ bool background; /**< This object is a background image. */
+ char *frame; /**< Name of frame, or 0 if not a frame. */
};
/** Data specific to CONTENT_HTML. */
@@ -78,10 +79,10 @@ struct content_html_data {
struct content_html_object *object;
/** Forms, in reverse order to document. */
struct form *forms;
- /** Hash table of imagemaps */
+ /** Hash table of imagemaps. */
struct imagemap **imagemaps;
- /**< Browser window containing this document, or 0 if not open. */
+ /** Browser window containing this document, or 0 if not open. */
struct browser_window *bw;
};
@@ -97,7 +98,7 @@ void html_destroy(struct content *c);
bool html_fetch_object(struct content *c, char *url, struct box *box,
const content_type *permitted_types,
int available_width, int available_height,
- bool background);
+ bool background, char *frame);
void html_stop(struct content *c);
void html_open(struct content *c, struct browser_window *bw,
struct content *page, struct box *box,