summaryrefslogtreecommitdiff
path: root/render
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2011-03-10 23:08:34 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2011-03-10 23:08:34 +0000
commit8f3ed71cbab75c6445a4f13e4e1bc8b768a452b1 (patch)
tree56ad8b2d2a1b28dcb99130508f28fbdd9b1e686a /render
parent02361309edbc5d2cbf1cd79e555ca6c6348b2920 (diff)
downloadnetsurf-8f3ed71cbab75c6445a4f13e4e1bc8b768a452b1.tar.gz
netsurf-8f3ed71cbab75c6445a4f13e4e1bc8b768a452b1.tar.bz2
Keep child objects of a HTML content in a list, instead of an array
svn path=/trunk/netsurf/; revision=11963
Diffstat (limited to 'render')
-rw-r--r--render/box_construct.c3
-rw-r--r--render/html.c231
-rw-r--r--render/html.h13
3 files changed, 128 insertions, 119 deletions
diff --git a/render/box_construct.c b/render/box_construct.c
index 44fcb54b1..b80dbdbe6 100644
--- a/render/box_construct.c
+++ b/render/box_construct.c
@@ -190,9 +190,6 @@ bool xml_to_box(xmlNode *n, struct content *c)
root.float_children = NULL;
root.next_float = NULL;
- c->data.html.object_count = 0;
- c->data.html.object = 0;
-
/* The root box's style */
if (!convert_xml_to_box(n, c, NULL, &root,
&inline_container, 0, 0, 0))
diff --git a/render/html.c b/render/html.c
index 4a27ec250..8d5246855 100644
--- a/render/html.c
+++ b/render/html.c
@@ -66,7 +66,7 @@ static bool html_find_stylesheets(struct content *c, xmlNode *html);
static bool html_process_style_element(struct content *c, unsigned int *index,
xmlNode *style);
static void html_inline_style_done(struct content_css_data *css, void *pw);
-static bool html_replace_object(struct content *c, unsigned int i,
+static bool html_replace_object(struct content_html_object *object,
const char *url);
static nserror html_object_callback(hlcache_handle *object,
const hlcache_event *event, void *pw);
@@ -123,15 +123,14 @@ bool html_create(struct content *c, const http_parameter *params)
html->stylesheet_count = 0;
html->stylesheets = NULL;
html->select_ctx = NULL;
- html->object_count = 0;
- html->object = NULL;
+ html->num_objects = 0;
+ html->object_list = NULL;
html->forms = NULL;
html->imagemaps = NULL;
html->bw = NULL;
html->frameset = NULL;
html->iframe = NULL;
html->page = NULL;
- html->index = 0;
html->box = NULL;
html->font_func = &nsfont;
@@ -1250,9 +1249,7 @@ bool html_fetch_object(struct content *c, const char *url, struct box *box,
int available_width, int available_height,
bool background)
{
- unsigned int i = c->data.html.object_count;
struct content_html_object *object;
- hlcache_handle *c_fetch;
hlcache_child_context child;
char *url2;
url_func_result res;
@@ -1268,30 +1265,38 @@ bool html_fetch_object(struct content *c, const char *url, struct box *box,
return res != URL_FUNC_NOMEM;
}
+ object = talloc(c, struct content_html_object);
+ if (object == NULL) {
+ free(url2);
+ return false;
+ }
+
+ object->parent = c;
+ object->next = NULL;
+ object->content = NULL;
+ object->box = box;
+ object->permitted_types = permitted_types;
+ object->background = background;
+
error = hlcache_handle_retrieve(url2, 0, content__get_url(c), NULL,
- html_object_callback, c, &child, permitted_types,
- &c_fetch);
+ html_object_callback, object, &child, permitted_types,
+ &object->content);
/* No longer need normalized url */
free(url2);
- if (error == NSERROR_OK) {
- /* add to object list */
- object = talloc_realloc(c, c->data.html.object,
- struct content_html_object, i + 1);
- if (object == NULL) {
- hlcache_handle_release(c_fetch);
- return false;
- }
- c->data.html.object = object;
- c->data.html.object[i].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_count++;
- c->active++;
- }
-
+ if (error != NSERROR_OK) {
+ talloc_free(object);
+ return error != NSERROR_NOMEM;
+ }
+
+ /* add to object list */
+ object->next = c->data.html.object_list;
+ c->data.html.object_list = object;
+
+ c->data.html.num_objects++;
+ c->active++;
+
return error != NSERROR_NOMEM;
}
@@ -1299,34 +1304,36 @@ bool html_fetch_object(struct content *c, const char *url, struct box *box,
/**
* Start a fetch for an object required by a page, replacing an existing object.
*
- * \param c content of type CONTENT_HTML
- * \param i index of object to replace in c->data.html.object
+ * \param object Object to replace
* \param url URL of object to fetch (copied)
* \return true on success, false on memory exhaustion
*/
-bool html_replace_object(struct content *c, unsigned int i, const char *url)
+bool html_replace_object(struct content_html_object *object, const char *url)
{
- hlcache_handle *c_fetch;
+ struct content *c;
hlcache_child_context child;
struct content *page;
char *url2;
url_func_result res;
nserror error;
- assert(c->type == CONTENT_HTML);
+ assert(object != NULL);
+
+ c = object->parent;
child.charset = c->data.html.encoding;
child.quirks = c->quirks;
- if (c->data.html.object[i].content) {
+ if (object->content != NULL) {
/* remove existing object */
- if (content_get_status(c->data.html.object[i].content) !=
- CONTENT_STATUS_DONE)
+ if (content_get_status(object->content) != CONTENT_STATUS_DONE)
c->active--;
- hlcache_handle_release(c->data.html.object[i].content);
- c->data.html.object[i].content = NULL;
- c->data.html.object[i].box->object = NULL;
+
+ hlcache_handle_release(object->content);
+ object->content = NULL;
+
+ object->box->object = NULL;
}
res = url_normalize(url, &url2);
@@ -1336,16 +1343,14 @@ bool html_replace_object(struct content *c, unsigned int i, const char *url)
/* initialise fetch */
error = hlcache_handle_retrieve(url2, 0, content__get_url(c), NULL,
html_object_callback, c, &child,
- c->data.html.object[i].permitted_types,
- &c_fetch);
+ object->permitted_types,
+ &object->content);
free(url2);
if (error != NSERROR_OK)
return false;
- c->data.html.object[i].content = c_fetch;
-
for (page = c; page; page = page->data.html.page) {
assert(page->type == CONTENT_HTML);
page->active++;
@@ -1363,21 +1368,11 @@ bool html_replace_object(struct content *c, unsigned int i, const char *url)
nserror html_object_callback(hlcache_handle *object,
const hlcache_event *event, void *pw)
{
- struct content *c = pw;
- unsigned int i;
- struct content_html_object *o;
+ struct content_html_object *o = pw;
+ struct content *c = o->parent;
int x, y;
struct box *box;
- /* Find object record in parent */
- for (i = 0, o = c->data.html.object; i != c->data.html.object_count;
- i++, o++) {
- if (o->content == object)
- break;
- }
-
- assert(i != c->data.html.object_count);
-
box = o->box;
switch (event->type) {
@@ -1388,7 +1383,7 @@ nserror html_object_callback(hlcache_handle *object,
if (c->data.html.bw != NULL)
content_open(object,
c->data.html.bw, c,
- i, box,
+ 0, box,
box->object_params);
break;
}
@@ -1404,8 +1399,7 @@ nserror html_object_callback(hlcache_handle *object,
html_set_status(c, messages_get("BadObject"));
content_broadcast(c, CONTENT_MSG_STATUS, event->data);
- html_object_failed(box, c,
- c->data.html.object[i].background);
+ html_object_failed(box, c, o->background);
break;
case CONTENT_MSG_READY:
@@ -1480,10 +1474,22 @@ nserror html_object_callback(hlcache_handle *object,
break;
case CONTENT_MSG_REFRESH:
- if (content_get_type(object) == CONTENT_HTML)
+ if (content_get_type(object) == CONTENT_HTML) {
+ struct content_html_object *o;
+
+ for (o = c->data.html.object_list; o != NULL;
+ o = o->next) {
+ if (o->content == object)
+ break;
+ }
+
+ assert(o != NULL);
+
/* only for HTML objects */
schedule(event->data.delay * 100,
- html_object_refresh, object);
+ html_object_refresh, o);
+ }
+
break;
default:
@@ -1592,23 +1598,21 @@ bool html_object_type_permitted(const content_type type,
void html_object_refresh(void *p)
{
- hlcache_handle *h = (hlcache_handle *) p;
- struct content *c = hlcache_handle_get_content(h);
+ struct content_html_object *object = p;
const char *refresh_url;
- assert(content_get_type(h) == CONTENT_HTML);
+ assert(content_get_type(object->content) == CONTENT_HTML);
- refresh_url = content_get_refresh_url(h);
+ refresh_url = content_get_refresh_url(object->content);
/* Ignore if refresh URL has gone
* (may happen if fetch errored) */
if (refresh_url == NULL)
return;
- content_invalidate_reuse_data(h);
+ content_invalidate_reuse_data(object->content);
- if (!html_replace_object(c->data.html.page, c->data.html.index,
- refresh_url)) {
+ if (!html_replace_object(object, refresh_url)) {
/** \todo handle memory exhaustion */
}
}
@@ -1619,23 +1623,23 @@ void html_object_refresh(void *p)
void html_stop(struct content *c)
{
- unsigned int i;
- hlcache_handle *object;
+ struct content_html_object *object;
assert(c->status == CONTENT_STATUS_READY);
- for (i = 0; i != c->data.html.object_count; i++) {
- object = c->data.html.object[i].content;
- if (object == NULL)
+ for (object = c->data.html.object_list; object != NULL;
+ object = object->next) {
+ if (object->content == NULL)
continue;
- if (content_get_status(object) == CONTENT_STATUS_DONE)
+ if (content_get_status(object->content) == CONTENT_STATUS_DONE)
; /* already loaded: do nothing */
- else if (content_get_status(object) == CONTENT_STATUS_READY)
- hlcache_handle_abort(object);
+ else if (content_get_status(object->content) ==
+ CONTENT_STATUS_READY)
+ hlcache_handle_abort(object->content);
else {
- hlcache_handle_release(object);
- c->data.html.object[i].content = NULL;
+ hlcache_handle_release(object->content);
+ object->content = NULL;
}
}
c->status = CONTENT_STATUS_DONE;
@@ -1770,16 +1774,20 @@ void html_destroy(struct content *c)
}
/* Free objects */
- for (i = 0; i != html->object_count; i++) {
- LOG(("object %i %p", i, html->object[i].content));
- if (html->object[i].content != NULL) {
- if (content_get_type(html->object[i].content) ==
- CONTENT_HTML)
- schedule_remove(html_object_refresh,
- html->object[i].content);
-
- hlcache_handle_release(html->object[i].content);
+ while (html->object_list != NULL) {
+ struct content_html_object *victim = html->object_list;
+
+ LOG(("object %p", victim->content));
+
+ if (victim->content != NULL) {
+ if (content_get_type(victim->content) == CONTENT_HTML)
+ schedule_remove(html_object_refresh, victim);
+
+ hlcache_handle_release(victim->content);
}
+
+ html->object_list = victim->next;
+ talloc_free(victim);
}
}
@@ -1844,18 +1852,18 @@ bool html_clone(const struct content *old, struct content *new_content)
void html_set_status(struct content *c, const char *extra)
{
unsigned int stylesheets = 0, objects = 0;
- if (c->data.html.object_count == 0)
+ if (c->data.html.num_objects == 0)
stylesheets = c->data.html.stylesheet_count - c->active;
else {
stylesheets = c->data.html.stylesheet_count;
- objects = c->data.html.object_count - c->active;
+ objects = c->data.html.num_objects - c->active;
}
content_set_status(c, "%u/%u %s %u/%u %s %s",
stylesheets, c->data.html.stylesheet_count,
messages_get((c->data.html.stylesheet_count == 1) ?
"styl" : "styls"),
- objects, c->data.html.object_count,
- messages_get((c->data.html.object_count == 1) ?
+ objects, c->data.html.num_objects,
+ messages_get((c->data.html.num_objects == 1) ?
"obj" : "objs"),
extra);
}
@@ -1869,21 +1877,25 @@ void html_open(struct content *c, struct browser_window *bw,
struct content *page, unsigned int index, struct box *box,
struct object_params *params)
{
- unsigned int i;
+ struct content_html_object *object, *next;
+
c->data.html.bw = bw;
c->data.html.page = page;
- c->data.html.index = index;
c->data.html.box = box;
- for (i = 0; i != c->data.html.object_count; i++) {
- if (c->data.html.object[i].content == 0)
+
+ for (object = c->data.html.object_list; object != NULL; object = next) {
+ next = object->next;
+
+ if (object->content == NULL)
continue;
- if (content_get_type(c->data.html.object[i].content) ==
- CONTENT_UNKNOWN)
+
+ if (content_get_type(object->content) == CONTENT_UNKNOWN)
continue;
- content_open(c->data.html.object[i].content,
- bw, c, i,
- c->data.html.object[i].box,
- c->data.html.object[i].box->object_params);
+
+ content_open(object->content,
+ bw, c, 0,
+ object->box,
+ object->box->object_params);
}
}
@@ -1894,24 +1906,23 @@ void html_open(struct content *c, struct browser_window *bw,
void html_close(struct content *c)
{
- unsigned int i;
+ struct content_html_object *object, *next;
c->data.html.bw = 0;
- for (i = 0; i != c->data.html.object_count; i++) {
- if (c->data.html.object[i].content == NULL)
+ for (object = c->data.html.object_list; object != NULL; object = next) {
+ next = object->next;
+
+ if (object->content == NULL)
continue;
- if (content_get_type(c->data.html.object[i].content) ==
- CONTENT_UNKNOWN)
+ if (content_get_type(object->content) == CONTENT_UNKNOWN)
continue;
- if (content_get_type(c->data.html.object[i].content) ==
- CONTENT_HTML)
- schedule_remove(html_object_refresh,
- c->data.html.object[i].content);
+ if (content_get_type(object->content) == CONTENT_HTML)
+ schedule_remove(html_object_refresh, object);
- content_close(c->data.html.object[i].content);
+ content_close(object->content);
}
}
@@ -2124,7 +2135,7 @@ struct html_stylesheet *html_get_stylesheets(hlcache_handle *h, unsigned int *n)
*
* \param h Content to retrieve objects from
* \param n Pointer to location to receive number of objects
- * \return Pointer to array of objects
+ * \return Pointer to list of objects
*/
struct content_html_object *html_get_objects(hlcache_handle *h, unsigned int *n)
{
@@ -2134,9 +2145,9 @@ struct content_html_object *html_get_objects(hlcache_handle *h, unsigned int *n)
assert(c->type == CONTENT_HTML);
assert(n != NULL);
- *n = c->data.html.object_count;
+ *n = c->data.html.num_objects;
- return c->data.html.object;
+ return c->data.html.object_list;
}
/**
diff --git a/render/html.h b/render/html.h
index c06252a4f..ac91f97f0 100644
--- a/render/html.h
+++ b/render/html.h
@@ -85,6 +85,9 @@ typedef enum {
/** An object (<img>, <object>, etc.) in a CONTENT_HTML document. */
struct content_html_object {
+ struct content *parent; /**< Parent document */
+ struct content_html_object *next; /**< Next in chain */
+
struct hlcache_handle *content; /**< Content, or 0. */
struct box *box; /**< Node in box tree containing it. */
/** Pointer to array of permitted content_type, terminated by
@@ -157,10 +160,10 @@ struct content_html_data {
/**< Style selection context */
css_select_ctx *select_ctx;
- /** Number of entries in object. */
- unsigned int object_count;
- /** Objects. Each may be 0. */
- struct content_html_object *object;
+ /** Number of entries in object_list. */
+ unsigned int num_objects;
+ /** List of objects. */
+ struct content_html_object *object_list;
/** Forms, in reverse order to document. */
struct form *forms;
/** Hash table of imagemaps. */
@@ -178,8 +181,6 @@ struct content_html_data {
/** Content of type CONTENT_HTML containing this, or 0 if not an object
* within a page. */
struct content *page;
- /** Index in page->data.html.object, or 0 if not an object. */
- unsigned int index;
/** Box containing this, or 0 if not an object. */
struct box *box;
};