summaryrefslogtreecommitdiff
path: root/render
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@netsurf-browser.org>2010-03-28 12:56:39 +0000
committerDaniel Silverstone <dsilvers@netsurf-browser.org>2010-03-28 12:56:39 +0000
commit270ef59a98d34fef418fb6cd27e46f3edc912948 (patch)
tree9d363b42d441640e1d2dbff3ba548a2cdf8d67a9 /render
parent21da4f5bdf74c6654730c32dfcc1c6b3d24da4b4 (diff)
downloadnetsurf-270ef59a98d34fef418fb6cd27e46f3edc912948.tar.gz
netsurf-270ef59a98d34fef418fb6cd27e46f3edc912948.tar.bz2
Merge jmb/new-cache; r=dsilvers,rs=vince
svn path=/trunk/netsurf/; revision=10180
Diffstat (limited to 'render')
-rw-r--r--render/box.c76
-rw-r--r--render/box.h10
-rw-r--r--render/box_construct.c6
-rw-r--r--render/directory.c16
-rw-r--r--render/directory.h4
-rw-r--r--render/favicon.c163
-rw-r--r--render/favicon.h3
-rw-r--r--render/form.c31
-rw-r--r--render/form.h13
-rw-r--r--render/html.c925
-rw-r--r--render/html.h43
-rw-r--r--render/html_redraw.c157
-rw-r--r--render/imagemap.c20
-rw-r--r--render/imagemap.h4
-rw-r--r--render/layout.c118
-rw-r--r--render/textplain.c112
-rw-r--r--render/textplain.h20
17 files changed, 954 insertions, 767 deletions
diff --git a/render/box.c b/render/box.c
index b355e68d1..e09a4772c 100644
--- a/render/box.c
+++ b/render/box.c
@@ -26,7 +26,8 @@
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
-#include "content/content.h"
+#include "content/content_protected.h"
+#include "content/hlcache.h"
#include "css/css.h"
#include "css/dump.h"
#include "desktop/scroll.h"
@@ -312,7 +313,7 @@ void box_bounds(struct box *box, struct rect *r)
struct box *box_at_point(struct box *box, const int x, const int y,
int *box_x, int *box_y,
- struct content **content)
+ hlcache_handle **content)
{
int bx = *box_x, by = *box_y;
struct box *child, *sibling;
@@ -321,11 +322,14 @@ struct box *box_at_point(struct box *box, const int x, const int y,
assert(box);
/* drill into HTML objects */
- if (box->object) {
- if (box->object->type == CONTENT_HTML &&
- box->object->data.html.layout) {
+ if (box->object != NULL) {
+ struct box *layout;
+
+ if (content_get_type(box->object) == CONTENT_HTML &&
+ (layout = html_get_box_tree(box->object)) !=
+ NULL) {
*content = box->object;
- box = box->object->data.html.layout;
+ box = layout;
} else {
goto siblings;
}
@@ -503,20 +507,24 @@ bool box_contains_point(struct box *box, int x, int y, bool *physically)
/**
* Find the box containing an object at the given coordinates, if any.
*
- * \param c content to search, must have type CONTENT_HTML
+ * \param h content to search, must have type CONTENT_HTML
* \param x coordinates in document units
* \param y coordinates in document units
*/
-struct box *box_object_at_point(struct content *c, int x, int y)
+struct box *box_object_at_point(hlcache_handle *h, int x, int y)
{
- struct box *box = c->data.html.layout;
+ struct content *c = hlcache_handle_get_content(h);
+ struct box *box;
int box_x = 0, box_y = 0;
- struct content *content = c;
+ hlcache_handle *content = h;
struct box *object_box = 0;
+ assert(c != NULL);
assert(c->type == CONTENT_HTML);
+ box = c->data.html.layout;
+
while ((box = box_at_point(box, x, y, &box_x, &box_y, &content))) {
if (box->style && css_computed_visibility(box->style) ==
CSS_VISIBILITY_HIDDEN)
@@ -533,20 +541,24 @@ struct box *box_object_at_point(struct content *c, int x, int y)
/**
* Find the box containing an href at the given coordinates, if any.
*
- * \param c content to search, must have type CONTENT_HTML
+ * \param h content to search, must have type CONTENT_HTML
* \param x coordinates in document units
* \param y coordinates in document units
*/
-struct box *box_href_at_point(struct content *c, int x, int y)
+struct box *box_href_at_point(hlcache_handle *h, int x, int y)
{
- struct box *box = c->data.html.layout;
+ struct content *c = hlcache_handle_get_content(h);
+ struct box *box;
int box_x = 0, box_y = 0;
- struct content *content = c;
+ hlcache_handle *content = h;
struct box *href_box = 0;
+ assert(c != NULL);
assert(c->type == CONTENT_HTML);
+ box = c->data.html.layout;
+
while ((box = box_at_point(box, x, y, &box_x, &box_y, &content))) {
if (box->style && css_computed_visibility(box->style) ==
CSS_VISIBILITY_HIDDEN)
@@ -663,8 +675,10 @@ void box_dump(FILE *stream, struct box *box, unsigned int depth)
(int) box->length, box->text);
if (box->space)
fprintf(stream, "space ");
- if (box->object)
- fprintf(stream, "(object '%s') ", box->object->url);
+ if (box->object) {
+ fprintf(stream, "(object '%s') ",
+ content_get_url(box->object));
+ }
if (box->gadget)
fprintf(stream, "(gadget) ");
if (box->style)
@@ -860,42 +874,42 @@ bool box_duplicate_main_tree(struct box *box, struct content *c, int *count)
box->last = prev;
- if (box->object && option_suppress_images && (
+ if (box->object != NULL && option_suppress_images && (
#ifdef WITH_JPEG
- box->object->type == CONTENT_JPEG ||
+ content_get_type(box->object) == CONTENT_JPEG ||
#endif
#ifdef WITH_GIF
- box->object->type == CONTENT_GIF ||
+ content_get_type(box->object) == CONTENT_GIF ||
#endif
#ifdef WITH_BMP
- box->object->type == CONTENT_BMP ||
- box->object->type == CONTENT_ICO ||
+ content_get_type(box->object) == CONTENT_BMP ||
+ content_get_type(box->object) == CONTENT_ICO ||
#endif
#if defined(WITH_MNG) || defined(WITH_PNG)
- box->object->type == CONTENT_PNG ||
+ content_get_type(box->object) == CONTENT_PNG ||
#endif
#ifdef WITH_MNG
- box->object->type == CONTENT_JNG ||
- box->object->type == CONTENT_MNG ||
+ content_get_type(box->object) == CONTENT_JNG ||
+ content_get_type(box->object) == CONTENT_MNG ||
#endif
#if defined(WITH_SPRITE) || defined(WITH_NSSPRITE)
- box->object->type == CONTENT_SPRITE ||
+ content_get_type(box->object) == CONTENT_SPRITE ||
#endif
#ifdef WITH_DRAW
- box->object->type == CONTENT_DRAW ||
+ content_get_type(box->object) == CONTENT_DRAW ||
#endif
#ifdef WITH_PLUGIN
- box->object->type == CONTENT_PLUGIN ||
+ content_get_type(box->object) == CONTENT_PLUGIN ||
#endif
- box->object->type == CONTENT_DIRECTORY ||
+ content_get_type(box->object) == CONTENT_DIRECTORY ||
#ifdef WITH_THEME_INSTALL
- box->object->type == CONTENT_THEME ||
+ content_get_type(box->object) == CONTENT_THEME ||
#endif
#ifdef WITH_ARTWORKS
- box->object->type == CONTENT_ARTWORKS ||
+ content_get_type(box->object) == CONTENT_ARTWORKS ||
#endif
#if defined(WITH_NS_SVG) || defined(WITH_RSVG)
- box->object->type == CONTENT_SVG ||
+ content_get_type(box->object) == CONTENT_SVG ||
#endif
false))
box->object = NULL;
diff --git a/render/box.h b/render/box.h
index b53e0481c..665565f2f 100644
--- a/render/box.h
+++ b/render/box.h
@@ -239,10 +239,10 @@ struct box {
char *id; /**< value of id attribute (or name for anchors) */
/** Background image for this box, or 0 if none */
- struct content *background;
+ struct hlcache_handle *background;
/** Object in this box (usually an image), or 0 if none. */
- struct content* object;
+ struct hlcache_handle* object;
/** Parameters for the object, or 0. */
struct object_params *object_params;
};
@@ -307,9 +307,9 @@ void box_free_object_params(struct object_params *op);
void box_bounds(struct box *box, struct rect *r);
void box_coords(struct box *box, int *x, int *y);
struct box *box_at_point(struct box *box, const int x, const int y,
- int *box_x, int *box_y, struct content **content);
-struct box *box_object_at_point(struct content *c, int x, int y);
-struct box *box_href_at_point(struct content *c, int x, int y);
+ int *box_x, int *box_y, struct hlcache_handle **content);
+struct box *box_object_at_point(struct hlcache_handle *h, int x, int y);
+struct box *box_href_at_point(struct hlcache_handle *h, int x, int y);
struct box *box_find_by_id(struct box *box, const char *id);
bool box_visible(struct box *box);
void box_dump(FILE *stream, struct box *box, unsigned int depth);
diff --git a/render/box_construct.c b/render/box_construct.c
index bdab6159e..71d30ddae 100644
--- a/render/box_construct.c
+++ b/render/box_construct.c
@@ -35,7 +35,7 @@
#include <libxml/HTMLparser.h>
#include <libxml/parserInternals.h>
#include "utils/config.h"
-#include "content/content.h"
+#include "content/content_protected.h"
#include "css/css.h"
#include "css/utils.h"
#include "css/select.h"
@@ -841,9 +841,9 @@ css_computed_style *box_get_style(struct content *c,
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "style"))) {
inline_style = nscss_create_inline_style(
(uint8_t *) s, strlen(s),
- c->data.html.encoding, c->url,
+ c->data.html.encoding, content__get_url(c),
c->data.html.quirks != BINDING_QUIRKS_MODE_NONE,
- c->data.html.dict, myrealloc, c);
+ myrealloc, c);
xmlFree(s);
diff --git a/render/directory.c b/render/directory.c
index 82f24efa2..9f002d831 100644
--- a/render/directory.c
+++ b/render/directory.c
@@ -28,7 +28,7 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <time.h>
-#include "content/content.h"
+#include "content/content_protected.h"
#include "render/directory.h"
#include "render/html.h"
#include "utils/messages.h"
@@ -40,9 +40,8 @@ static const char header[] = "<html>\n<head>\n<title>\n";
static const char footer[] = "</pre>\n</body>\n</html>\n";
-bool directory_create(struct content *c, struct content *parent,
- const char *params[]) {
- if (!html_create(c, parent, params))
+bool directory_create(struct content *c, const struct http_parameter *params) {
+ if (!html_create(c, params))
/* html_create() must have broadcast MSG_ERROR already, so we
* don't need to. */
return false;
@@ -64,7 +63,7 @@ bool directory_convert(struct content *c, int width, int height) {
bool compare;
char *up;
- path = url_to_path(c->url);
+ path = url_to_path(content__get_url(c));
if (!path) {
msg_data.error = messages_get("NoMemory");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
@@ -100,9 +99,9 @@ bool directory_convert(struct content *c, int width, int height) {
binding_parse_chunk(c->data.html.parser_binding,
(uint8_t *) buffer, strlen(buffer));
- res = url_parent(c->url, &up);
+ res = url_parent(content__get_url(c), &up);
if (res == URL_FUNC_OK) {
- res = url_compare(c->url, up, false, &compare);
+ res = url_compare(content__get_url(c), up, false, &compare);
if ((res == URL_FUNC_OK) && !compare) {
snprintf(buffer, sizeof(buffer),
"<a href=\"..\">[..]</a>\n");
@@ -124,7 +123,8 @@ bool directory_convert(struct content *c, int width, int height) {
continue;
snprintf(buffer, sizeof(buffer), "<a href=\"%s/%s\">%s</a>\n",
- c->url, entry->d_name, entry->d_name);
+ content__get_url(c), entry->d_name,
+ entry->d_name);
binding_parse_chunk(c->data.html.parser_binding,
(uint8_t *) buffer, strlen(buffer));
diff --git a/render/directory.h b/render/directory.h
index a54d516fb..766593294 100644
--- a/render/directory.h
+++ b/render/directory.h
@@ -28,9 +28,9 @@
#include <stdbool.h>
#include "content/content_type.h"
+struct http_parameter;
-bool directory_create(struct content *c, struct content *parent,
- const char *params[]);
+bool directory_create(struct content *c, const struct http_parameter *params);
bool directory_convert(struct content *c, int width, int height);
void directory_destroy(struct content *c);
diff --git a/render/favicon.c b/render/favicon.c
index ec5caeae0..191c55e8a 100644
--- a/render/favicon.c
+++ b/render/favicon.c
@@ -18,8 +18,8 @@
*/
#include <string.h>
-#include "content/fetch.h"
-#include "content/fetchcache.h"
+#include "content/content_protected.h"
+#include "content/hlcache.h"
#include "render/favicon.h"
#include "render/html.h"
#include "utils/log.h"
@@ -29,8 +29,8 @@
#include "utils/utils.h"
static char *favicon_get_icon_ref(struct content *c, xmlNode *html);
-static void favicon_callback(content_msg msg, struct content *icon,
- intptr_t p1, intptr_t p2, union content_msg_data data);
+static nserror favicon_callback(hlcache_handle *icon,
+ const hlcache_event *event, void *pw);
/**
* retrieve 1 url reference to 1 favicon
@@ -39,68 +39,80 @@ static void favicon_callback(content_msg msg, struct content *icon,
*/
char *favicon_get_icon_ref(struct content *c, xmlNode *html)
{
- xmlNode *node;
- char *rel, *href, *url, *url2;
+ xmlNode *node = html;
+ char *rel, *href, *url, *url2 = NULL;
url_func_result res;
- union content_msg_data msg_data;
- url2 = NULL;
- node = html;
while (node) {
- if (node->children) { /* children */
+ if (node->children != NULL) { /* children */
node = node->children;
- } else if (node->next) { /* siblings */
+ } else if (node->next != NULL) { /* siblings */
node = node->next;
} else { /* ancestor siblings */
- while (node && !node->next)
+ while (node != NULL && node->next == NULL)
node = node->parent;
- if (!node)
+
+ if (node == NULL)
break;
+
node = node->next;
}
- assert(node);
+
+ assert(node != NULL);
if (node->type != XML_ELEMENT_NODE)
continue;
+
if (strcmp((const char *) node->name, "link") == 0) {
/* rel=<space separated list, including 'icon'> */
if ((rel = (char *) xmlGetProp(node,
(const xmlChar *) "rel")) == NULL)
continue;
+
if (strcasestr(rel, "icon") == 0) {
xmlFree(rel);
continue;
}
- LOG(("icon node found"));
+
if (strcasecmp(rel, "apple-touch-icon") == 0) {
xmlFree(rel);
continue;
}
+
xmlFree(rel);
- if (( href = (char *) xmlGetProp(node,
+
+ if ((href = (char *) xmlGetProp(node,
(const xmlChar *) "href")) == NULL)
continue;
- res = url_join(href, c->data.html.base_url,
- &url);
+
+ res = url_join(href, c->data.html.base_url, &url);
+
xmlFree(href);
+
if (res != URL_FUNC_OK)
continue;
- LOG(("most recent favicon '%s'", url));
+
if (url2 != NULL) {
free(url2);
url2 = NULL;
}
+
res = url_normalize(url, &url2);
+
free(url);
+
if (res != URL_FUNC_OK) {
url2 = NULL;
+
if (res == URL_FUNC_NOMEM)
- goto no_memory;
+ return NULL;
+
continue;
}
}
}
+
if (url2 == NULL) {
char *scheme;
@@ -123,12 +135,8 @@ char *favicon_get_icon_ref(struct content *c, xmlNode *html)
!= URL_FUNC_OK)
return NULL;
}
- LOG(("favicon %s", url2));
+
return url2;
-no_memory:
- msg_data.error = messages_get("NoMemory");
- /* content_broadcast(c, CONTENT_MSG_ERROR, msg_data); */
- return false;
}
/**
@@ -140,31 +148,27 @@ no_memory:
bool favicon_get_icon(struct content *c, xmlNode *html)
{
- char *url = favicon_get_icon_ref(c, html);
- struct content *favcontent = NULL;
+ char *url;
+ nserror error;
+
+ url = favicon_get_icon_ref(c, html);
if (url == NULL)
return false;
-
- favcontent = fetchcache(url, favicon_callback, (intptr_t) c, 0,
- c->width, c->height, true, 0, 0, false, false);
- free(url);
- if (favcontent == NULL)
- return false;
- c->data.html.favicon = favcontent;
-
- fetchcache_go(favcontent, c->url, favicon_callback, (intptr_t) c, 0,
- c->width, c->height, 0, 0, false, c);
+ error = hlcache_handle_retrieve(url, 0, NULL, NULL, c->width, c->height,
+ favicon_callback, c, NULL, &c->data.html.favicon);
+
+ free(url);
- return true;
+ return error == NSERROR_OK;
}
/**
* Callback for fetchcache() for linked favicon
*/
-void favicon_callback(content_msg msg, struct content *icon,
- intptr_t p1, intptr_t p2, union content_msg_data data)
+nserror favicon_callback(hlcache_handle *icon,
+ const hlcache_event *event, void *pw)
{
static const content_type permitted_types[] = {
#ifdef WITH_BMP
@@ -178,88 +182,57 @@ void favicon_callback(content_msg msg, struct content *icon,
#endif
CONTENT_UNKNOWN
};
- struct content *c = (struct content *) p1;
- unsigned int i = p2;
+ struct content *c = pw;
const content_type *type;
-
- switch (msg) {
+ switch (event->type) {
case CONTENT_MSG_LOADING:
/* check that the favicon is really a correct image type */
for (type = permitted_types; *type != CONTENT_UNKNOWN; type++)
- if (icon->type == *type)
+ if (content_get_type(icon) == *type)
break;
if (*type == CONTENT_UNKNOWN) {
- c->data.html.favicon = 0;
- LOG(("%s is not a favicon", icon->url));
+ union content_msg_data msg_data;
+
+ hlcache_handle_release(c->data.html.favicon);
+ c->data.html.favicon = NULL;
+ LOG(("%s is not a favicon", content_get_url(icon)));
content_add_error(c, "NotFavIco", 0);
- html_set_status(c, messages_get("NotFavIco"));
- content_broadcast(c, CONTENT_MSG_STATUS, data);
- content_remove_user(icon,
- favicon_callback,
- (intptr_t) c, i);
- if (!icon->user_list->next) {
- /* we were the only user and we don't want this
- * content, so stop it fetching and mark it as
- * having an error so it gets removed from the
- * cache next time content_clean() gets called
- */
- fetch_abort(icon->fetch);
- icon->fetch = 0;
- icon->status = CONTENT_STATUS_ERROR;
- }
+
+ msg_data.error = messages_get("NotFavIco");
+ content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
}
break;
case CONTENT_MSG_READY:
- break;
-
+ /* Fall through */
case CONTENT_MSG_DONE:
- LOG(("got favicon '%s'", icon->url));
break;
- case CONTENT_MSG_LAUNCH:
- /* Fall through */
case CONTENT_MSG_ERROR:
- LOG(("favicon %s failed: %s", icon->url, data.error));
- /* The favicon we were fetching may have been
- * redirected, in that case, the object pointers
- * will differ, so ensure that the object that's
- * in error is still in use by us before invalidating
- * the pointer */
- if (c->data.html.favicon == icon) {
- c->data.html.favicon = 0;
- content_add_error(c, "?", 0);
- }
- break;
+ LOG(("favicon %s failed: %s",
+ content_get_url(icon), event->data.error));
+ hlcache_handle_release(c->data.html.favicon);
+ c->data.html.favicon = NULL;
- case CONTENT_MSG_STATUS:
- html_set_status(c, icon->status_message);
- content_broadcast(c, CONTENT_MSG_STATUS, data);
- break;
-
- case CONTENT_MSG_NEWPTR:
- c->data.html.favicon = icon;
- break;
-
- case CONTENT_MSG_AUTH:
- c->data.html.favicon = 0;
content_add_error(c, "?", 0);
break;
- case CONTENT_MSG_SSL:
- c->data.html.favicon = 0;
- content_add_error(c, "?", 0);
+ case CONTENT_MSG_STATUS:
+ content_broadcast(c, CONTENT_MSG_STATUS, event->data);
break;
+
case CONTENT_MSG_REDRAW:
- /* currently no support for favicon animations */
+ /* Fall through */
case CONTENT_MSG_REFRESH:
- break;
+ /* Fall through */
case CONTENT_MSG_REFORMAT:
- /* would be unusual :) */
break;
+
default:
assert(0);
}
+
+ return NSERROR_OK;
}
diff --git a/render/favicon.h b/render/favicon.h
index 30030101a..428655ecd 100644
--- a/render/favicon.h
+++ b/render/favicon.h
@@ -20,7 +20,8 @@
#define _NETSURF_RENDER_FAVICON_H_
#include <libxml/tree.h>
-#include "content/content.h"
+
+struct content;
bool favicon_get_icon(struct content *c, xmlNode *html);
diff --git a/render/form.c b/render/form.c
index 968397a21..b81d2ca34 100644
--- a/render/form.c
+++ b/render/form.c
@@ -30,6 +30,7 @@
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
+#include "content/fetch.h"
#include "css/css.h"
#include "css/utils.h"
#include "desktop/gui.h"
@@ -308,18 +309,18 @@ bool form_add_option(struct form_control *control, char *value, char *text,
* \param form form to search for successful controls
* \param submit_button control used to submit the form, if any
* \param successful_controls updated to point to linked list of
- * form_successful_control, 0 if no controls
+ * fetch_multipart_data, 0 if no controls
* \return true on success, false on memory exhaustion
*
* See HTML 4.01 section 17.13.2.
*/
bool form_successful_controls(struct form *form,
struct form_control *submit_button,
- struct form_successful_control **successful_controls)
+ struct fetch_multipart_data **successful_controls)
{
struct form_control *control;
struct form_option *option;
- struct form_successful_control sentinel, *last_success, *success_new;
+ struct fetch_multipart_data sentinel, *last_success, *success_new;
char *value = NULL;
bool had_submit = false;
char *charset;
@@ -603,7 +604,7 @@ bool form_successful_controls(struct form *form,
no_memory:
warn_user("NoMemory", 0);
- form_free_successful(sentinel.next);
+ fetch_multipart_data_destroy(sentinel.next);
return false;
#undef ENCODE_ITEM
@@ -659,12 +660,12 @@ char *form_textarea_value(struct form_control *textarea)
* Encode controls using application/x-www-form-urlencoded.
*
* \param form form to which successful controls relate
- * \param control linked list of form_successful_control
+ * \param control linked list of fetch_multipart_data
* \return URL-encoded form, or 0 on memory exhaustion
*/
char *form_url_encode(struct form *form,
- struct form_successful_control *control)
+ struct fetch_multipart_data *control)
{
char *name, *value;
char *s = malloc(1), *s2;
@@ -713,24 +714,6 @@ char *form_url_encode(struct form *form,
return s;
}
-
-/**
- * Free a linked list of form_successful_control.
- *
- * \param control Pointer to head of list to free
- */
-
-void form_free_successful(struct form_successful_control *control)
-{
- struct form_successful_control *next;
- for (; control; control = next) {
- next = control->next;
- free(control->name);
- free(control->value);
- free(control);
- }
-}
-
/**
* Find an acceptable character set encoding with which to submit the form
*
diff --git a/render/form.h b/render/form.h
index a31c24975..d5026e039 100644
--- a/render/form.h
+++ b/render/form.h
@@ -125,14 +125,6 @@ struct form_option {
struct form_option* next;
};
-/** Successful control, as defined by HTML 4.01 17.13. */
-struct form_successful_control {
- bool file; /**< It's a file */
- char *name; /**< Control name. */
- char *value; /**< Current value. */
- struct form_successful_control *next; /**< Next in linked list. */
-};
-
/**
* Called by the select menu when it wants an area to be redrawn. The
* coordinates are menu origin relative.
@@ -157,10 +149,9 @@ bool form_add_option(struct form_control *control, char *value, char *text,
bool selected);
bool form_successful_controls(struct form *form,
struct form_control *submit_button,
- struct form_successful_control **successful_controls);
+ struct fetch_multipart_data **successful_controls);
char *form_url_encode(struct form *form,
- struct form_successful_control *control);
-void form_free_successful(struct form_successful_control *control);
+ struct fetch_multipart_data *control);
bool form_open_select_menu(void *client_data,
struct form_control *control,
diff --git a/render/html.c b/render/html.c
index 82becef5c..d63c68764 100644
--- a/render/html.c
+++ b/render/html.c
@@ -29,9 +29,10 @@
#include <strings.h>
#include <stdlib.h>
#include "utils/config.h"
-#include "content/content.h"
+#include "content/content_protected.h"
#include "content/fetch.h"
#include "content/fetchcache.h"
+#include "content/hlcache.h"
#include "desktop/browser.h"
#include "desktop/gui.h"
#include "desktop/options.h"
@@ -43,6 +44,7 @@
#include "render/html.h"
#include "render/imagemap.h"
#include "render/layout.h"
+#include "utils/http.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/talloc.h"
@@ -57,16 +59,18 @@
#define ALWAYS_DUMP_FRAMESET 0
#define ALWAYS_DUMP_BOX 0
-static void html_convert_css_callback(content_msg msg, struct content *css,
- intptr_t p1, intptr_t p2, union content_msg_data data);
+static nserror html_convert_css_callback(hlcache_handle *css,
+ const hlcache_event *event, void *pw);
static bool html_meta_refresh(struct content *c, xmlNode *head);
static bool html_head(struct content *c, xmlNode *head);
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_object_callback(content_msg msg, struct content *object,
- intptr_t p1, intptr_t p2, union content_msg_data data);
-static void html_object_done(struct box *box, struct content *object,
+static bool html_replace_object(struct content *c, unsigned int i,
+ const char *url);
+static nserror html_object_callback(hlcache_handle *object,
+ const hlcache_event *event, void *pw);
+static void html_object_done(struct box *box, hlcache_handle *object,
bool background);
static void html_object_failed(struct box *box, struct content *content,
bool background);
@@ -113,57 +117,45 @@ static void *myrealloc(void *ptr, size_t len, void *pw)
* created.
*/
-bool html_create(struct content *c, struct content *parent,
- const char *params[])
+bool html_create(struct content *c, const http_parameter *params)
{
- unsigned int i;
struct content_html_data *html = &c->data.html;
+ const char *charset;
union content_msg_data msg_data;
binding_error error;
- lwc_context *dict;
- lwc_error lerror;
+ nserror nerror;
html->parser_binding = NULL;
- html->document = 0;
+ html->document = NULL;
html->quirks = BINDING_QUIRKS_MODE_NONE;
- html->encoding = 0;
- html->base_url = c->url;
+ html->encoding = NULL;
+ html->base_url = (char *) content__get_url(c);
html->base_target = NULL;
- html->layout = 0;
+ html->layout = NULL;
html->background_colour = NS_TRANSPARENT;
html->stylesheet_count = 0;
html->stylesheets = NULL;
html->select_ctx = NULL;
html->object_count = 0;
- html->object = 0;
- html->forms = 0;
- html->imagemaps = 0;
- html->bw = 0;
- html->frameset = 0;
- html->iframe = 0;
- html->page = 0;
+ html->object = NULL;
+ html->forms = NULL;
+ html->imagemaps = NULL;
+ html->bw = NULL;
+ html->frameset = NULL;
+ html->iframe = NULL;
+ html->page = NULL;
html->index = 0;
- html->box = 0;
+ html->box = NULL;
html->font_func = &nsfont;
- lerror = lwc_create_context(myrealloc, c, &dict);
- if (lerror != lwc_error_ok) {
- error = BINDING_NOMEM;
- goto error;
- }
-
- html->dict = lwc_context_ref(dict);
-
- for (i = 0; params[i]; i += 2) {
- if (strcasecmp(params[i], "charset") == 0) {
- html->encoding = talloc_strdup(c, params[i + 1]);
- if (!html->encoding) {
- error = BINDING_NOMEM;
- goto error;
- }
- html->encoding_source = ENCODING_SOURCE_HEADER;
- break;
+ nerror = http_parameter_list_find_item(params, "charset", &charset);
+ if (nerror == NSERROR_OK) {
+ html->encoding = talloc_strdup(c, charset);
+ if (!html->encoding) {
+ error = BINDING_NOMEM;
+ goto error;
}
+ html->encoding_source = ENCODING_SOURCE_HEADER;
}
/* Create the parser binding */
@@ -294,10 +286,17 @@ encoding_change:
return false;
}
- /* Recurse to reprocess all that data. This is safe because
- * the encoding is now specified at parser-start which means
- * it cannot be changed again. */
- return html_process_data(c, c->source_data, c->source_size);
+ {
+ const char *source_data;
+ unsigned long source_size;
+
+ source_data = content__get_source_data(c, &source_size);
+
+ /* Recurse to reprocess all that data. This is safe because
+ * the encoding is now specified at parser-start which means
+ * it cannot be changed again. */
+ return html_process_data(c, (char *) source_data, source_size);
+ }
}
/**
@@ -321,11 +320,13 @@ bool html_convert(struct content *c, int width, int height)
binding_error err;
xmlNode *html, *head;
union content_msg_data msg_data;
+ unsigned long size;
unsigned int time_before, time_taken;
struct form *f;
/* finish parsing */
- if (c->source_size == 0) {
+ content__get_source_data(c, &size);
+ if (size == 0) {
/* Destroy current binding */
binding_destroy_tree(c->data.html.parser_binding);
@@ -502,8 +503,6 @@ bool html_convert(struct content *c, int width, int height)
binding_destroy_tree(c->data.html.parser_binding);
c->data.html.parser_binding = NULL;
- c->size += lwc_context_size(c->data.html.dict);
-
if (c->active == 0)
c->status = CONTENT_STATUS_DONE;
else
@@ -689,7 +688,7 @@ bool html_meta_refresh(struct content *c, xmlNode *head)
/* Just delay specified, so refresh current page */
xmlFree(content);
- c->refresh = talloc_strdup(c, c->url);
+ c->refresh = talloc_strdup(c, content__get_url(c));
if (!c->refresh) {
msg_data.error = messages_get("NoMemory");
content_broadcast(c,
@@ -808,67 +807,66 @@ bool html_find_stylesheets(struct content *c, xmlNode *html)
unsigned int last_active = 0;
union content_msg_data msg_data;
url_func_result res;
- struct nscss_import *stylesheets;
+ struct html_stylesheet *stylesheets;
+ hlcache_child_context child;
css_error error;
+ nserror ns_error;
+
+ child.charset = c->data.html.encoding;
+ child.quirks = c->quirks;
/* stylesheet 0 is the base style sheet,
* stylesheet 1 is the quirks mode style sheet,
* stylesheet 2 is the adblocking stylesheet */
- c->data.html.stylesheets = talloc_array(c, struct nscss_import,
+ c->data.html.stylesheets = talloc_array(c, struct html_stylesheet,
STYLESHEET_START);
if (c->data.html.stylesheets == NULL)
goto no_memory;
- c->data.html.stylesheets[STYLESHEET_BASE].c = NULL;
- c->data.html.stylesheets[STYLESHEET_BASE].media = CSS_MEDIA_ALL;
- c->data.html.stylesheets[STYLESHEET_QUIRKS].c = NULL;
- c->data.html.stylesheets[STYLESHEET_QUIRKS].media = CSS_MEDIA_ALL;
- c->data.html.stylesheets[STYLESHEET_ADBLOCK].c = NULL;
- c->data.html.stylesheets[STYLESHEET_ADBLOCK].media = CSS_MEDIA_ALL;
+ c->data.html.stylesheets[STYLESHEET_BASE].type =
+ HTML_STYLESHEET_EXTERNAL;
+ c->data.html.stylesheets[STYLESHEET_BASE].data.external = NULL;
+ c->data.html.stylesheets[STYLESHEET_QUIRKS].type =
+ HTML_STYLESHEET_EXTERNAL;
+ c->data.html.stylesheets[STYLESHEET_QUIRKS].data.external = NULL;
+ c->data.html.stylesheets[STYLESHEET_ADBLOCK].type =
+ HTML_STYLESHEET_EXTERNAL;
+ c->data.html.stylesheets[STYLESHEET_ADBLOCK].data.external = NULL;
c->data.html.stylesheet_count = STYLESHEET_START;
c->active = 0;
- c->data.html.stylesheets[STYLESHEET_BASE].c = fetchcache(
- default_stylesheet_url,
- html_convert_css_callback, (intptr_t) c,
- STYLESHEET_BASE, c->width, c->height,
- true, 0, 0, false, false);
- if (c->data.html.stylesheets[STYLESHEET_BASE].c == NULL)
+ ns_error = hlcache_handle_retrieve(default_stylesheet_url, 0,
+ content__get_url(c), NULL, c->width, c->height,
+ html_convert_css_callback, c, &child,
+ &c->data.html.stylesheets[
+ STYLESHEET_BASE].data.external);
+ if (ns_error != NSERROR_OK)
goto no_memory;
+
c->active++;
- fetchcache_go(c->data.html.stylesheets[STYLESHEET_BASE].c,
- c->url, html_convert_css_callback, (intptr_t) c,
- STYLESHEET_BASE, c->width, c->height,
- 0, 0, false, c);
if (c->data.html.quirks == BINDING_QUIRKS_MODE_FULL) {
- c->data.html.stylesheets[STYLESHEET_QUIRKS].c =
- fetchcache(quirks_stylesheet_url,
- html_convert_css_callback, (intptr_t) c,
- STYLESHEET_QUIRKS, c->width, c->height,
- true, 0, 0, false, false);
- if (c->data.html.stylesheets[STYLESHEET_QUIRKS].c == NULL)
+ ns_error = hlcache_handle_retrieve(quirks_stylesheet_url, 0,
+ content__get_url(c), NULL, c->width, c->height,
+ html_convert_css_callback, c, &child,
+ &c->data.html.stylesheets[
+ STYLESHEET_QUIRKS].data.external);
+ if (ns_error != NSERROR_OK)
goto no_memory;
+
c->active++;
- fetchcache_go(c->data.html.stylesheets[STYLESHEET_QUIRKS].c,
- c->url, html_convert_css_callback,
- (intptr_t) c, STYLESHEET_QUIRKS, c->width,
- c->height, 0, 0, false, c);
}
if (option_block_ads) {
- c->data.html.stylesheets[STYLESHEET_ADBLOCK].c =
- fetchcache(adblock_stylesheet_url,
- html_convert_css_callback, (intptr_t) c,
- STYLESHEET_ADBLOCK, c->width,
- c->height, true, 0, 0, false, false);
- if (c->data.html.stylesheets[STYLESHEET_ADBLOCK].c == NULL)
+ ns_error = hlcache_handle_retrieve(adblock_stylesheet_url, 0,
+ content__get_url(c), NULL, c->width, c->height,
+ html_convert_css_callback, c, &child,
+ &c->data.html.stylesheets[
+ STYLESHEET_ADBLOCK].data.external);
+ if (ns_error != NSERROR_OK)
goto no_memory;
+
c->active++;
- fetchcache_go(c->data.html.stylesheets[STYLESHEET_ADBLOCK].c,
- c->url, html_convert_css_callback,
- (intptr_t) c, STYLESHEET_ADBLOCK, c->width,
- c->height, 0, 0, false, c);
}
node = html;
@@ -958,29 +956,30 @@ bool html_find_stylesheets(struct content *c, xmlNode *html)
/* start fetch */
stylesheets = talloc_realloc(c,
c->data.html.stylesheets,
- struct nscss_import, i + 1);
+ struct html_stylesheet, i + 1);
if (stylesheets == NULL) {
free(url2);
goto no_memory;
}
c->data.html.stylesheets = stylesheets;
- /** \todo Reflect actual media specified in link */
- c->data.html.stylesheets[i].media = CSS_MEDIA_ALL;
- c->data.html.stylesheets[i].c = fetchcache(url2,
- html_convert_css_callback,
- (intptr_t) c, i, c->width, c->height,
- true, 0, 0, false, false);
+ c->data.html.stylesheet_count++;
+ c->data.html.stylesheets[i].type =
+ HTML_STYLESHEET_EXTERNAL;
+ ns_error = hlcache_handle_retrieve(url2, 0,
+ content__get_url(c), NULL,
+ c->width, c->height,
+ html_convert_css_callback, c, &child,
+ &c->data.html.stylesheets[i].
+ data.external);
+
free(url2);
- if (c->data.html.stylesheets[i].c == NULL)
+
+ if (ns_error != NSERROR_OK)
goto no_memory;
c->active++;
- fetchcache_go(c->data.html.stylesheets[i].c,
- c->url,
- html_convert_css_callback,
- (intptr_t) c, i, c->width, c->height,
- 0, 0, false, c);
+
i++;
} else if (strcmp((const char *) node->name, "style") == 0) {
if (!html_process_style_element(c, &i, node))
@@ -988,7 +987,7 @@ bool html_find_stylesheets(struct content *c, xmlNode *html)
}
}
- c->data.html.stylesheet_count = i;
+ assert(c->data.html.stylesheet_count == i);
/* complete the fetches */
while (c->active != 0) {
@@ -1002,7 +1001,7 @@ bool html_find_stylesheets(struct content *c, xmlNode *html)
}
/* check that the base stylesheet loaded; layout fails without it */
- if (c->data.html.stylesheets[STYLESHEET_BASE].c == NULL) {
+ if (c->data.html.stylesheets[STYLESHEET_BASE].data.external == NULL) {
msg_data.error = "Base stylesheet failed to load";
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
return false;
@@ -1015,11 +1014,30 @@ bool html_find_stylesheets(struct content *c, xmlNode *html)
/* Add sheets to it */
for (i = STYLESHEET_BASE; i != c->data.html.stylesheet_count; i++) {
- if (c->data.html.stylesheets[i].c != NULL) {
+ const struct html_stylesheet *hsheet =
+ &c->data.html.stylesheets[i];
+ css_stylesheet *sheet;
+ css_origin origin = CSS_ORIGIN_AUTHOR;
+
+ if (i < STYLESHEET_START)
+ origin = CSS_ORIGIN_UA;
+
+ if (hsheet->type == HTML_STYLESHEET_EXTERNAL &&
+ hsheet->data.external != NULL) {
+ struct content *s = hlcache_handle_get_content(
+ hsheet->data.external);
+
+ sheet = s-> data.css.sheet;
+ } else if (hsheet->type == HTML_STYLESHEET_INTERNAL) {
+ sheet = hsheet->data.internal->sheet;
+ } else {
+ sheet = NULL;
+ }
+
+ if (sheet != NULL) {
error = css_select_ctx_append_sheet(
- c->data.html.select_ctx,
- c->data.html.stylesheets[i].c->
- data.css.sheet);
+ c->data.html.select_ctx, sheet,
+ origin, CSS_MEDIA_SCREEN);
if (error != CSS_OK)
goto no_memory;
}
@@ -1050,9 +1068,9 @@ bool html_process_style_element(struct content *c, unsigned int *index,
xmlNode *child;
char *type, *media, *data;
union content_msg_data msg_data;
- struct nscss_import *stylesheets;
- struct nscss_import *sheet;
- const char *params[] = { 0 };
+ struct html_stylesheet *stylesheets;
+ struct content_css_data *sheet;
+ nserror error;
/* type='text/css', or not present (invalid but common) */
if ((type = (char *) xmlGetProp(style, (const xmlChar *) "type"))) {
@@ -1075,26 +1093,27 @@ bool html_process_style_element(struct content *c, unsigned int *index,
/* Extend array */
stylesheets = talloc_realloc(c, c->data.html.stylesheets,
- struct nscss_import, *index + 1);
+ struct html_stylesheet, *index + 1);
if (stylesheets == NULL)
goto no_memory;
c->data.html.stylesheets = stylesheets;
+ c->data.html.stylesheet_count++;
- /* create stylesheet */
- sheet = &c->data.html.stylesheets[(*index)];
+ c->data.html.stylesheets[(*index)].type = HTML_STYLESHEET_INTERNAL;
+ c->data.html.stylesheets[(*index)].data.internal = NULL;
- /** \todo Reflect specified media */
- sheet->media = CSS_MEDIA_ALL;
- sheet->c = content_create(c->data.html.base_url);
- if (sheet->c == NULL)
+ /* create stylesheet */
+ sheet = talloc(c, struct content_css_data);
+ if (sheet == NULL) {
+ c->data.html.stylesheet_count--;
goto no_memory;
+ }
- if (content_set_type(sheet->c,
- CONTENT_CSS, "text/css", params, c) == false) {
- /** \todo not necessarily caused by
- * memory exhaustion */
- sheet->c = NULL;
+ error = nscss_create_css_data(sheet,
+ c->data.html.base_url, NULL, c->data.html.quirks);
+ if (error != NSERROR_OK) {
+ c->data.html.stylesheet_count--;
goto no_memory;
}
@@ -1103,43 +1122,29 @@ bool html_process_style_element(struct content *c, unsigned int *index,
* the content */
for (child = style->children; child != 0; child = child->next) {
data = (char *) xmlNodeGetContent(child);
- if (content_process_data(sheet->c, data, strlen(data)) ==
+ if (nscss_process_css_data(sheet, data, strlen(data)) ==
false) {
xmlFree(data);
+ nscss_destroy_css_data(sheet);
+ talloc_free(sheet);
+ c->data.html.stylesheet_count--;
/** \todo not necessarily caused by
* memory exhaustion */
- sheet->c = NULL;
goto no_memory;
}
xmlFree(data);
}
/* Convert the content -- manually, as we want the result */
- if (sheet->c->source_allocated != sheet->c->source_size) {
- /* Minimise source data block */
- char *data = talloc_realloc(sheet->c, sheet->c->source_data,
- char, sheet->c->source_size);
-
- if (data != NULL) {
- sheet->c->source_data = data;
- sheet->c->source_allocated = sheet->c->source_size;
- }
- }
-
- if (nscss_convert(sheet->c, c->width, c->height)) {
- if (content_add_user(sheet->c,
- html_convert_css_callback,
- (intptr_t) c, (*index)) == false) {
- /* no memory */
- sheet->c = NULL;
- goto no_memory;
- }
- } else {
+ if (nscss_convert_css_data(sheet, c->width, c->height) != CSS_OK) {
/* conversion failed */
- sheet->c = NULL;
+ nscss_destroy_css_data(sheet);
+ talloc_free(sheet);
+ sheet = NULL;
}
/* Update index */
+ c->data.html.stylesheets[(*index)].data.internal = sheet;
(*index)++;
return true;
@@ -1155,36 +1160,40 @@ no_memory:
* Callback for fetchcache() for linked stylesheets.
*/
-void html_convert_css_callback(content_msg msg, struct content *css,
- intptr_t p1, intptr_t p2, union content_msg_data data)
+nserror html_convert_css_callback(hlcache_handle *css,
+ const hlcache_event *event, void *pw)
{
- struct content *c = (struct content *) p1;
- unsigned int i = p2;
+ struct content *parent = pw;
+ unsigned int i;
+ struct html_stylesheet *s;
+
+ /* Find sheet */
+ for (i = 0, s = parent->data.html.stylesheets;
+ i != parent->data.html.stylesheet_count; i++, s++) {
+ if (s->type == HTML_STYLESHEET_EXTERNAL &&
+ s->data.external == css)
+ break;
+ }
+
+ assert(i != parent->data.html.stylesheet_count);
- switch (msg) {
+ switch (event->type) {
case CONTENT_MSG_LOADING:
/* check that the stylesheet is really CSS */
- if (css->type != CONTENT_CSS) {
- c->data.html.stylesheets[i].c = NULL;
- c->active--;
- LOG(("%s is not CSS", css->url));
- content_add_error(c, "NotCSS", 0);
- html_set_status(c, messages_get("NotCSS"));
- content_broadcast(c, CONTENT_MSG_STATUS, data);
- content_remove_user(css,
- html_convert_css_callback,
- (intptr_t) c, i);
- if (css->user_list->next == NULL) {
- /* we were the only user and we
- * don't want this content, so
- * stop it fetching and mark it
- * as having an error so it gets
- * removed from the cache next time
- * content_clean() gets called */
- fetch_abort(css->fetch);
- css->fetch = 0;
- css->status = CONTENT_STATUS_ERROR;
- }
+ if (content_get_type(css) != CONTENT_CSS) {
+ hlcache_handle_release(css);
+ s->data.external = NULL;
+
+ parent->active--;
+
+ LOG(("%s is not CSS", content_get_url(css)));
+
+ content_add_error(parent, "NotCSS", 0);
+
+ html_set_status(parent, messages_get("NotCSS"));
+
+ content_broadcast(parent, CONTENT_MSG_STATUS,
+ event->data);
}
break;
@@ -1192,50 +1201,29 @@ void html_convert_css_callback(content_msg msg, struct content *css,
break;
case CONTENT_MSG_DONE:
- LOG(("got stylesheet '%s'", css->url));
- c->active--;
+ LOG(("got stylesheet '%s'", content_get_url(css)));
+ parent->active--;
break;
- case CONTENT_MSG_LAUNCH:
- /* Fall through */
case CONTENT_MSG_ERROR:
- LOG(("stylesheet %s failed: %s", css->url, data.error));
- /* The stylesheet we were fetching may have been
- * redirected, in that case, the object pointers
- * will differ, so ensure that the object that's
- * in error is still in use by us before invalidating
- * the pointer */
- if (c->data.html.stylesheets[i].c == css) {
- c->data.html.stylesheets[i].c = NULL;
- c->active--;
- content_add_error(c, "?", 0);
- }
+ LOG(("stylesheet %s failed: %s",
+ content_get_url(css), event->data.error));
+ hlcache_handle_release(css);
+ s->data.external = NULL;
+ parent->active--;
+ content_add_error(parent, "?", 0);
break;
case CONTENT_MSG_STATUS:
- html_set_status(c, css->status_message);
- content_broadcast(c, CONTENT_MSG_STATUS, data);
- break;
-
- case CONTENT_MSG_NEWPTR:
- c->data.html.stylesheets[i].c = css;
- break;
-
- case CONTENT_MSG_AUTH:
- c->data.html.stylesheets[i].c = NULL;
- c->active--;
- content_add_error(c, "?", 0);
- break;
-
- case CONTENT_MSG_SSL:
- c->data.html.stylesheets[i].c = NULL;
- c->active--;
- content_add_error(c, "?", 0);
+ html_set_status(parent, content_get_status_message(css));
+ content_broadcast(parent, CONTENT_MSG_STATUS, event->data);
break;
default:
assert(0);
}
+
+ return NSERROR_OK;
}
@@ -1260,9 +1248,14 @@ bool html_fetch_object(struct content *c, const char *url, struct box *box,
{
unsigned int i = c->data.html.object_count;
struct content_html_object *object;
- struct content *c_fetch;
+ hlcache_handle *c_fetch;
+ hlcache_child_context child;
char *url2;
url_func_result res;
+ nserror error;
+
+ child.charset = c->data.html.encoding;
+ child.quirks = c->quirks;
/* Normalize the URL */
res = url_normalize(url, &url2);
@@ -1271,23 +1264,22 @@ bool html_fetch_object(struct content *c, const char *url, struct box *box,
return res != URL_FUNC_NOMEM;
}
- /* initialise fetch */
- c_fetch = fetchcache(url2, html_object_callback,
- (intptr_t) c, i, available_width, available_height,
- true, 0, 0, false, false);
+ error = hlcache_handle_retrieve(url2, 0, content__get_url(c), NULL,
+ available_width, available_height,
+ html_object_callback, c, &child,
+ &c_fetch);
/* No longer need normalized url */
free(url2);
- if (!c_fetch)
+ if (error != NSERROR_OK)
return false;
/* add to object list */
object = talloc_realloc(c, c->data.html.object,
struct content_html_object, i + 1);
- if (!object) {
- content_remove_user(c_fetch, html_object_callback,
- (intptr_t) c, i);
+ if (object == NULL) {
+ hlcache_handle_release(c_fetch);
return false;
}
c->data.html.object = object;
@@ -1298,12 +1290,6 @@ bool html_fetch_object(struct content *c, const char *url, struct box *box,
c->data.html.object_count++;
c->active++;
- /* start fetch */
- fetchcache_go(c_fetch, c->url,
- html_object_callback, (intptr_t) c, i,
- available_width, available_height,
- 0, 0, false, c);
-
return true;
}
@@ -1314,31 +1300,31 @@ bool html_fetch_object(struct content *c, const char *url, struct box *box,
* \param c content of type CONTENT_HTML
* \param i index of object to replace in c->data.html.object
* \param url URL of object to fetch (copied)
- * \param post_urlenc url encoded post data, or 0 if none
- * \param post_multipart multipart post data, or 0 if none
* \return true on success, false on memory exhaustion
*/
-bool html_replace_object(struct content *c, unsigned int i, char *url,
- char *post_urlenc,
- struct form_successful_control *post_multipart)
+bool html_replace_object(struct content *c, unsigned int i, const char *url)
{
- struct content *c_fetch;
+ hlcache_handle *c_fetch;
+ hlcache_child_context child;
struct content *page;
char *url2;
url_func_result res;
+ nserror error;
assert(c->type == CONTENT_HTML);
+ child.charset = c->data.html.encoding;
+ child.quirks = c->quirks;
+
if (c->data.html.object[i].content) {
/* remove existing object */
- if (c->data.html.object[i].content->status !=
+ if (content_get_status(c->data.html.object[i].content) !=
CONTENT_STATUS_DONE)
c->active--;
- content_remove_user(c->data.html.object[i].content,
- html_object_callback, (intptr_t) c, i);
- c->data.html.object[i].content = 0;
- c->data.html.object[i].box->object = 0;
+ hlcache_handle_release(c->data.html.object[i].content);
+ c->data.html.object[i].content = NULL;
+ c->data.html.object[i].box->object = NULL;
}
res = url_normalize(url, &url2);
@@ -1346,15 +1332,15 @@ bool html_replace_object(struct content *c, unsigned int i, char *url,
return res != URL_FUNC_NOMEM;
/* initialise fetch */
- c_fetch = fetchcache(url2, html_object_callback,
- (intptr_t) c, i,
+ error = hlcache_handle_retrieve(url2, 0, content__get_url(c), NULL,
c->data.html.object[i].box->width,
c->data.html.object[i].box->height,
- false, post_urlenc, post_multipart, false, false);
+ html_object_callback, c, &child,
+ &c_fetch);
free(url2);
- if (!c_fetch)
+ if (error != NSERROR_OK)
return false;
c->data.html.object[i].content = c_fetch;
@@ -1365,13 +1351,6 @@ bool html_replace_object(struct content *c, unsigned int i, char *url,
page->status = CONTENT_STATUS_READY;
}
- /* start fetch */
- fetchcache_go(c_fetch, c->url,
- html_object_callback, (intptr_t) c, i,
- c->data.html.object[i].box->width,
- c->data.html.object[i].box->height,
- post_urlenc, post_multipart, false, c);
-
return true;
}
@@ -1380,157 +1359,146 @@ bool html_replace_object(struct content *c, unsigned int i, char *url,
* Callback for fetchcache() for objects.
*/
-void html_object_callback(content_msg msg, struct content *object,
- intptr_t p1, intptr_t p2, union content_msg_data data)
+nserror html_object_callback(hlcache_handle *object,
+ const hlcache_event *event, void *pw)
{
- struct content *c = (struct content *) p1;
- unsigned int i = p2;
+ struct content *c = pw;
+ unsigned int i;
+ struct content_html_object *o;
int x, y;
- struct box *box = c->data.html.object[i].box;
-
- switch (msg) {
- case CONTENT_MSG_LOADING:
- /* check if the type is acceptable for this object */
- if (html_object_type_permitted(object->type,
- c->data.html.object[i].permitted_types)) {
- if (c->data.html.bw)
- content_open(object,
- c->data.html.bw, c,
- i, box,
- box->object_params);
- break;
- }
+ struct box *box;
- /* not acceptable */
- c->data.html.object[i].content = 0;
- c->active--;
- content_add_error(c, "?", 0);
- html_set_status(c, messages_get("BadObject"));
- content_broadcast(c, CONTENT_MSG_STATUS, data);
- content_remove_user(object, html_object_callback,
- (intptr_t) c, i);
- if (!object->user_list->next) {
- /* we were the only user and we
- * don't want this content, so
- * stop it fetching and mark it
- * as having an error so it gets
- * removed from the cache next time
- * content_clean() gets called */
- fetch_abort(object->fetch);
- object->fetch = 0;
- object->status = CONTENT_STATUS_ERROR;
- }
- html_object_failed(box, c,
- c->data.html.object[i].background);
+ /* 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;
+ }
- case CONTENT_MSG_READY:
- if (object->type == CONTENT_HTML) {
- html_object_done(box, object,
- c->data.html.object[i].background);
- if (c->status == CONTENT_STATUS_READY ||
- c->status ==
- CONTENT_STATUS_DONE)
- content_reformat(c,
- c->available_width,
- c->height);
- }
- break;
+ assert(i != c->data.html.object_count);
- case CONTENT_MSG_DONE:
- html_object_done(box, object,
- c->data.html.object[i].background);
- c->active--;
- break;
+ box = o->box;
- case CONTENT_MSG_LAUNCH:
- /* Fall through */
- case CONTENT_MSG_ERROR:
- /* The object we were fetching may have been
- * redirected, in that case, the object pointers
- * will differ, so ensure that the object that's
- * in error is still in use by us before invalidating
- * the pointer */
- if (c->data.html.object[i].content == object) {
- c->data.html.object[i].content = 0;
- c->active--;
- content_add_error(c, "?", 0);
- html_set_status(c, data.error);
- content_broadcast(c, CONTENT_MSG_STATUS,
- data);
- html_object_failed(box, c,
- c->data.html.object[i].background);
- }
+ switch (event->type) {
+ case CONTENT_MSG_LOADING:
+ /* check if the type is acceptable for this object */
+ if (html_object_type_permitted(content_get_type(object),
+ o->permitted_types)) {
+ if (c->data.html.bw != NULL)
+ content_open(object,
+ c->data.html.bw, c,
+ i, box,
+ box->object_params);
break;
+ }
- case CONTENT_MSG_STATUS:
- html_set_status(c, object->status_message);
- /* content_broadcast(c, CONTENT_MSG_STATUS, 0); */
- break;
+ /* not acceptable */
+ hlcache_handle_release(object);
- case CONTENT_MSG_REFORMAT:
- break;
+ o->content = NULL;
- case CONTENT_MSG_REDRAW:
- if (!box_visible(box))
- break;
- box_coords(box, &x, &y);
- if (object == data.redraw.object) {
- data.redraw.x = data.redraw.x *
- box->width / object->width;
- data.redraw.y = data.redraw.y *
- box->height / object->height;
- data.redraw.width = data.redraw.width *
- box->width / object->width;
- data.redraw.height = data.redraw.height *
- box->height / object->height;
- data.redraw.object_width = box->width;
- data.redraw.object_height = box->height;
- }
- data.redraw.x += x + box->padding[LEFT];
- data.redraw.y += y + box->padding[TOP];
- data.redraw.object_x += x + box->padding[LEFT];
- data.redraw.object_y += y + box->padding[TOP];
- content_broadcast(c, CONTENT_MSG_REDRAW, data);
- break;
+ c->active--;
- case CONTENT_MSG_NEWPTR:
- c->data.html.object[i].content = object;
- break;
+ content_add_error(c, "?", 0);
+ html_set_status(c, messages_get("BadObject"));
+ content_broadcast(c, CONTENT_MSG_STATUS, event->data);
- case CONTENT_MSG_AUTH:
- c->data.html.object[i].content = 0;
- c->active--;
- content_add_error(c, "?", 0);
- break;
+ html_object_failed(box, c,
+ c->data.html.object[i].background);
+ break;
- case CONTENT_MSG_SSL:
- c->data.html.object[i].content = 0;
- c->active--;
- content_add_error(c, "?", 0);
- break;
+ case CONTENT_MSG_READY:
+ if (content_get_type(object) == CONTENT_HTML) {
+ html_object_done(box, object, o->background);
+ if (c->status == CONTENT_STATUS_READY ||
+ c->status == CONTENT_STATUS_DONE)
+ content__reformat(c,
+ c->available_width,
+ c->height);
+ }
+ break;
+
+ case CONTENT_MSG_DONE:
+ html_object_done(box, object, o->background);
+ c->active--;
+ break;
+
+ case CONTENT_MSG_ERROR:
+ hlcache_handle_release(object);
+
+ o->content = NULL;
+
+ c->active--;
+
+ content_add_error(c, "?", 0);
+ html_set_status(c, event->data.error);
+ content_broadcast(c, CONTENT_MSG_STATUS, event->data);
+ html_object_failed(box, c, o->background);
+ break;
+
+ case CONTENT_MSG_STATUS:
+ html_set_status(c, content_get_status_message(object));
+ /* content_broadcast(c, CONTENT_MSG_STATUS, 0); */
+ break;
+
+ case CONTENT_MSG_REFORMAT:
+ break;
- case CONTENT_MSG_REFRESH:
- if (object->type == CONTENT_HTML)
- /* only for HTML objects */
- schedule(data.delay * 100,
- html_object_refresh, object);
+ case CONTENT_MSG_REDRAW:
+ {
+ union content_msg_data data = event->data;
+
+ if (!box_visible(box))
break;
- default:
- assert(0);
+ box_coords(box, &x, &y);
+
+ if (hlcache_handle_get_content(object) ==
+ event->data.redraw.object) {
+ data.redraw.x = data.redraw.x *
+ box->width / content_get_width(object);
+ data.redraw.y = data.redraw.y *
+ box->height /
+ content_get_height(object);
+ data.redraw.width = data.redraw.width *
+ box->width / content_get_width(object);
+ data.redraw.height = data.redraw.height *
+ box->height /
+ content_get_height(object);
+ data.redraw.object_width = box->width;
+ data.redraw.object_height = box->height;
+ }
+
+ data.redraw.x += x + box->padding[LEFT];
+ data.redraw.y += y + box->padding[TOP];
+ data.redraw.object_x += x + box->padding[LEFT];
+ data.redraw.object_y += y + box->padding[TOP];
+
+ content_broadcast(c, CONTENT_MSG_REDRAW, data);
+ }
+ break;
+
+ case CONTENT_MSG_REFRESH:
+ if (content_get_type(object) == CONTENT_HTML)
+ /* only for HTML objects */
+ schedule(event->data.delay * 100,
+ html_object_refresh, object);
+ break;
+
+ default:
+ assert(0);
}
if (c->status == CONTENT_STATUS_READY && c->active == 0 &&
- (msg == CONTENT_MSG_LOADING ||
- msg == CONTENT_MSG_DONE ||
- msg == CONTENT_MSG_ERROR ||
- msg == CONTENT_MSG_AUTH)) {
+ (event->type == CONTENT_MSG_LOADING ||
+ event->type == CONTENT_MSG_DONE ||
+ event->type == CONTENT_MSG_ERROR)) {
/* all objects have arrived */
- content_reformat(c, c->available_width, c->height);
+ content__reformat(c, c->available_width, c->height);
html_set_status(c, "");
content_set_done(c);
}
+
/* If 1) the configuration option to reflow pages while objects are
* fetched is set
* 2) an object is newly fetched & converted,
@@ -1538,17 +1506,20 @@ void html_object_callback(content_msg msg, struct content *object,
* 4) the time since the previous reformat is more than the
* configured minimum time between reformats
* then reformat the page to display newly fetched objects */
- else if (option_incremental_reflow && msg == CONTENT_MSG_DONE &&
+ else if (option_incremental_reflow &&
+ event->type == CONTENT_MSG_DONE &&
(c->status == CONTENT_STATUS_READY ||
c->status == CONTENT_STATUS_DONE) &&
(wallclock() > c->reformat_time)) {
unsigned int time_before = wallclock(), time_taken;
- content_reformat(c, c->available_width, c->height);
+ content__reformat(c, c->available_width, c->height);
time_taken = wallclock() - time_before;
c->reformat_time = wallclock() +
((time_taken < option_min_reflow_period ?
option_min_reflow_period : time_taken * 1.25));
}
+
+ return NSERROR_OK;
}
@@ -1556,7 +1527,7 @@ void html_object_callback(content_msg msg, struct content *object,
* Update a box whose content has completed rendering.
*/
-void html_object_done(struct box *box, struct content *object,
+void html_object_done(struct box *box, hlcache_handle *object,
bool background)
{
struct box *b;
@@ -1714,7 +1685,7 @@ void html_object_refresh(void *p)
c->fresh = false;
if (!html_replace_object(c->data.html.page, c->data.html.index,
- c->refresh, 0, 0)) {
+ c->refresh)) {
/** \todo handle memory exhaustion */
}
}
@@ -1726,24 +1697,22 @@ void html_object_refresh(void *p)
void html_stop(struct content *c)
{
unsigned int i;
- struct content *object;
+ hlcache_handle *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)
+ if (object == NULL)
continue;
- if (object->status == CONTENT_STATUS_DONE)
+ if (content_get_status(object) == CONTENT_STATUS_DONE)
; /* already loaded: do nothing */
- else if (object->status == CONTENT_STATUS_READY)
- content_stop(object, html_object_callback,
- (intptr_t) c, i);
+ else if (content_get_status(object) == CONTENT_STATUS_READY)
+ content_stop(object, html_object_callback, NULL);
else {
- content_remove_user(c->data.html.object[i].content,
- html_object_callback, (intptr_t) c, i);
- c->data.html.object[i].content = 0;
+ hlcache_handle_release(object);
+ c->data.html.object[i].content = NULL;
}
}
c->status = CONTENT_STATUS_DONE;
@@ -1836,11 +1805,14 @@ void html_destroy(struct content *c)
/* Free stylesheets */
if (c->data.html.stylesheet_count) {
for (i = 0; i != c->data.html.stylesheet_count; i++) {
- if (c->data.html.stylesheets[i].c)
- content_remove_user(c->data.html.
- stylesheets[i].c,
- html_convert_css_callback,
- (intptr_t) c, i);
+ if (c->data.html.stylesheets[i].type ==
+ HTML_STYLESHEET_EXTERNAL) {
+ hlcache_handle_release(c->data.html.
+ stylesheets[i].data.external);
+ } else {
+ nscss_destroy_css_data(c->data.html.
+ stylesheets[i].data.internal);
+ }
}
}
@@ -1848,15 +1820,14 @@ void html_destroy(struct content *c)
for (i = 0; i != c->data.html.object_count; i++) {
LOG(("object %i %p", i, c->data.html.object[i].content));
if (c->data.html.object[i].content) {
- content_remove_user(c->data.html.object[i].content,
- html_object_callback, (intptr_t) c, i);
- if (c->data.html.object[i].content->type == CONTENT_HTML)
+ if (content_get_type(c->data.html.object[i].content) ==
+ CONTENT_HTML)
schedule_remove(html_object_refresh,
c->data.html.object[i].content);
+
+ hlcache_handle_release(c->data.html.object[i].content);
}
}
-
- lwc_context_unref(c->data.html.dict);
}
void html_destroy_frameset(struct content_html_frames *frameset) {
@@ -1942,7 +1913,8 @@ void html_open(struct content *c, struct browser_window *bw,
for (i = 0; i != c->data.html.object_count; i++) {
if (c->data.html.object[i].content == 0)
continue;
- if (c->data.html.object[i].content->type == CONTENT_UNKNOWN)
+ if (content_get_type(c->data.html.object[i].content) ==
+ CONTENT_UNKNOWN)
continue;
content_open(c->data.html.object[i].content,
bw, c, i,
@@ -1964,7 +1936,8 @@ void html_close(struct content *c)
for (i = 0; i != c->data.html.object_count; i++) {
if (c->data.html.object[i].content == 0)
continue;
- if (c->data.html.object[i].content->type == CONTENT_UNKNOWN)
+ if (content_get_type(c->data.html.object[i].content) ==
+ CONTENT_UNKNOWN)
continue;
content_close(c->data.html.object[i].content);
}
@@ -2023,3 +1996,173 @@ void html_dump_frameset(struct content_html_frames *frame,
}
#endif
+
+/**
+ * Retrieve HTML document tree
+ *
+ * \param h HTML content to retrieve document tree from
+ * \return Pointer to document tree
+ */
+xmlDoc *html_get_document(hlcache_handle *h)
+{
+ struct content *c = hlcache_handle_get_content(h);
+
+ assert(c != NULL);
+ assert(c->type == CONTENT_HTML);
+
+ return c->data.html.document;
+}
+
+/**
+ * Retrieve box tree
+ *
+ * \param h HTML content to retrieve tree from
+ * \return Pointer to box tree
+ *
+ * \todo This API must die, as must all use of the box tree outside render/
+ */
+struct box *html_get_box_tree(hlcache_handle *h)
+{
+ struct content *c = hlcache_handle_get_content(h);
+
+ assert(c != NULL);
+ assert(c->type == CONTENT_HTML);
+
+ return c->data.html.layout;
+}
+
+/**
+ * Retrieve the charset of an HTML document
+ *
+ * \param h Content to retrieve charset from
+ * \return Pointer to charset, or NULL
+ */
+const char *html_get_encoding(hlcache_handle *h)
+{
+ struct content *c = hlcache_handle_get_content(h);
+
+ assert(c != NULL);
+ assert(c->type == CONTENT_HTML);
+
+ return c->data.html.encoding;
+}
+
+/**
+ * Retrieve framesets used in an HTML document
+ *
+ * \param h Content to inspect
+ * \return Pointer to framesets, or NULL if none
+ */
+struct content_html_frames *html_get_frameset(hlcache_handle *h)
+{
+ struct content *c = hlcache_handle_get_content(h);
+
+ assert(c != NULL);
+ assert(c->type == CONTENT_HTML);
+
+ return c->data.html.frameset;
+}
+
+/**
+ * Retrieve iframes used in an HTML document
+ *
+ * \param h Content to inspect
+ * \return Pointer to iframes, or NULL if none
+ */
+struct content_html_iframe *html_get_iframe(hlcache_handle *h)
+{
+ struct content *c = hlcache_handle_get_content(h);
+
+ assert(c != NULL);
+ assert(c->type == CONTENT_HTML);
+
+ return c->data.html.iframe;
+}
+
+/**
+ * Retrieve an HTML content's base URL
+ *
+ * \param h Content to retrieve base target from
+ * \return Pointer to URL
+ */
+const char *html_get_base_url(hlcache_handle *h)
+{
+ struct content *c = hlcache_handle_get_content(h);
+
+ assert(c != NULL);
+ assert(c->type == CONTENT_HTML);
+
+ return c->data.html.base_url;
+}
+
+/**
+ * Retrieve an HTML content's base target
+ *
+ * \param h Content to retrieve base target from
+ * \return Pointer to target, or NULL if none
+ */
+const char *html_get_base_target(hlcache_handle *h)
+{
+ struct content *c = hlcache_handle_get_content(h);
+
+ assert(c != NULL);
+ assert(c->type == CONTENT_HTML);
+
+ return c->data.html.base_target;
+}
+
+/**
+ * Retrieve stylesheets used by HTML document
+ *
+ * \param h Content to retrieve stylesheets from
+ * \param n Pointer to location to receive number of sheets
+ * \return Pointer to array of stylesheets
+ */
+struct html_stylesheet *html_get_stylesheets(hlcache_handle *h, unsigned int *n)
+{
+ struct content *c = hlcache_handle_get_content(h);
+
+ assert(c != NULL);
+ assert(c->type == CONTENT_HTML);
+ assert(n != NULL);
+
+ *n = c->data.html.stylesheet_count;
+
+ return c->data.html.stylesheets;
+}
+
+/**
+ * Retrieve objects used by HTML document
+ *
+ * \param h Content to retrieve objects from
+ * \param n Pointer to location to receive number of objects
+ * \return Pointer to array of objects
+ */
+struct content_html_object *html_get_objects(hlcache_handle *h, unsigned int *n)
+{
+ struct content *c = hlcache_handle_get_content(h);
+
+ assert(c != NULL);
+ assert(c->type == CONTENT_HTML);
+ assert(n != NULL);
+
+ *n = c->data.html.object_count;
+
+ return c->data.html.object;
+}
+
+/**
+ * Retrieve favicon associated with an HTML document
+ *
+ * \param h HTML document to retrieve favicon from
+ * \return Pointer to favicon, or NULL if none
+ */
+hlcache_handle *html_get_favicon(hlcache_handle *h)
+{
+ struct content *c = hlcache_handle_get_content(h);
+
+ assert(c != NULL);
+ assert(c->type == CONTENT_HTML);
+
+ return c->data.html.favicon;
+}
diff --git a/render/html.h b/render/html.h
index 51abba3ba..5ce92ba3d 100644
--- a/render/html.h
+++ b/render/html.h
@@ -31,11 +31,13 @@
#include "desktop/plot_style.h"
#include "render/parser_binding.h"
+struct fetch_multipart_data;
struct box;
struct rect;
struct browser_window;
struct content;
-struct form_successful_control;
+struct hlcache_handle;
+struct http_parameter;
struct imagemap;
struct object_params;
struct plotters;
@@ -50,6 +52,18 @@ extern char *default_stylesheet_url;
extern char *adblock_stylesheet_url;
extern char *quirks_stylesheet_url;
+/**
+ * Container for stylesheets used by an HTML document
+ */
+struct html_stylesheet {
+ /** Type of sheet */
+ enum { HTML_STYLESHEET_EXTERNAL, HTML_STYLESHEET_INTERNAL } type;
+ union {
+ struct hlcache_handle *external;
+ struct content_css_data *internal;
+ } data; /**< Sheet data */
+};
+
struct frame_dimension {
float value;
enum {
@@ -68,7 +82,7 @@ typedef enum {
/** An object (<img>, <object>, etc.) in a CONTENT_HTML document. */
struct content_html_object {
- struct content *content; /**< Content, or 0. */
+ 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
* CONTENT_UNKNOWN, or 0 if any type is acceptable. */
@@ -120,8 +134,6 @@ struct content_html_data {
xmlDoc *document;
binding_quirks_mode quirks; /**< Quirkyness of document */
- lwc_context *dict; /**< Internment context for this document */
-
char *encoding; /**< Encoding of source, 0 if unknown. */
binding_encoding_source encoding_source;
/**< Source of encoding information. */
@@ -133,12 +145,12 @@ struct content_html_data {
colour background_colour; /**< Document background colour. */
const struct font_functions *font_func;
- struct content *favicon; /**< the favicon for the page */
+ struct hlcache_handle *favicon; /**< the favicon for the page */
/** Number of entries in stylesheet_content. */
unsigned int stylesheet_count;
/** Stylesheets. Each may be 0. */
- struct nscss_import *stylesheets;
+ struct html_stylesheet *stylesheets;
/**< Style selection context */
css_select_ctx *select_ctx;
@@ -173,8 +185,7 @@ struct content_html_data {
extern bool html_redraw_debug;
-bool html_create(struct content *c, struct content *parent,
- const char *params[]);
+bool html_create(struct content *c, const struct http_parameter *params);
bool html_process_data(struct content *c, char *data, unsigned int size);
bool html_convert(struct content *c, int width, int height);
void html_reformat(struct content *c, int width, int height);
@@ -183,9 +194,6 @@ bool html_fetch_object(struct content *c, const char *url, struct box *box,
const content_type *permitted_types,
int available_width, int available_height,
bool background);
-bool html_replace_object(struct content *c, unsigned int i, char *url,
- char *post_urlenc,
- struct form_successful_control *post_multipart);
void html_stop(struct content *c);
void html_open(struct content *c, struct browser_window *bw,
struct content *page, unsigned int index, struct box *box,
@@ -212,4 +220,17 @@ bool text_redraw(const char *utf8_text, size_t utf8_len,
float scale,
bool excluded);
+xmlDoc *html_get_document(struct hlcache_handle *h);
+struct box *html_get_box_tree(struct hlcache_handle *h);
+const char *html_get_encoding(struct hlcache_handle *h);
+struct content_html_frames *html_get_frameset(struct hlcache_handle *h);
+struct content_html_iframe *html_get_iframe(struct hlcache_handle *h);
+const char *html_get_base_url(struct hlcache_handle *h);
+const char *html_get_base_target(struct hlcache_handle *h);
+struct html_stylesheet *html_get_stylesheets(struct hlcache_handle *h,
+ unsigned int *n);
+struct content_html_object *html_get_objects(struct hlcache_handle *h,
+ unsigned int *n);
+struct hlcache_handle *html_get_favicon(struct hlcache_handle *h);
+
#endif
diff --git a/render/html_redraw.c b/render/html_redraw.c
index 2a5154035..3165e1d38 100644
--- a/render/html_redraw.c
+++ b/render/html_redraw.c
@@ -31,7 +31,7 @@
#include <string.h>
#include <math.h>
#include "utils/config.h"
-#include "content/content.h"
+#include "content/content_protected.h"
#include "css/css.h"
#include "css/utils.h"
#include "desktop/gui.h"
@@ -1589,31 +1589,35 @@ bool html_redraw_background(int x, int y, struct box *box, float scale,
}
/* handle background-repeat */
switch (css_computed_background_repeat(background->style)) {
- case CSS_BACKGROUND_REPEAT_REPEAT:
- repeat_x = repeat_y = true;
- /* optimisation: only plot the colour if
- * bitmap is not opaque */
- if (background->background->bitmap)
- plot_colour = !bitmap_get_opaque(
- background->background->bitmap);
- break;
- case CSS_BACKGROUND_REPEAT_REPEAT_X:
- repeat_x = true;
- break;
- case CSS_BACKGROUND_REPEAT_REPEAT_Y:
- repeat_y = true;
- break;
- case CSS_BACKGROUND_REPEAT_NO_REPEAT:
- break;
- default:
- break;
+ case CSS_BACKGROUND_REPEAT_REPEAT:
+ {
+ struct bitmap *bmp = content_get_bitmap(
+ background->background);
+ repeat_x = repeat_y = true;
+ /* optimisation: only plot the colour if
+ * bitmap is not opaque */
+ if (bmp != NULL)
+ plot_colour = !bitmap_get_opaque(bmp);
+ }
+ break;
+ case CSS_BACKGROUND_REPEAT_REPEAT_X:
+ repeat_x = true;
+ break;
+ case CSS_BACKGROUND_REPEAT_REPEAT_Y:
+ repeat_y = true;
+ break;
+ case CSS_BACKGROUND_REPEAT_NO_REPEAT:
+ break;
+ default:
+ break;
}
/* handle background-position */
css_computed_background_position(background->style,
&hpos, &hunit, &vpos, &vunit);
if (hunit == CSS_UNIT_PCT) {
- x += (width - background->background->width) *
+ x += (width -
+ content_get_width(background->background)) *
scale * FIXTOFLT(hpos) / 100.;
} else {
x += (int) (FIXTOFLT(nscss_len2px(hpos, hunit,
@@ -1621,7 +1625,8 @@ bool html_redraw_background(int x, int y, struct box *box, float scale,
}
if (vunit == CSS_UNIT_PCT) {
- y += (height - background->background->height) *
+ y += (height -
+ content_get_height(background->background)) *
scale * FIXTOFLT(vpos) / 100.;
} else {
y += (int) (FIXTOFLT(nscss_len2px(vpos, vunit,
@@ -1651,6 +1656,8 @@ bool html_redraw_background(int x, int y, struct box *box, float scale,
for (; clip_box; clip_box = clip_box->next) {
/* clip to child boxes if needed */
if (clip_to_children) {
+ struct bitmap *bmp = NULL;
+
assert(clip_box->type == BOX_TABLE_CELL);
/* update clip_* to the child cell */
@@ -1668,15 +1675,15 @@ bool html_redraw_background(int x, int y, struct box *box, float scale,
if (clip_x1 > px1) clip_x1 = px1;
if (clip_y1 > py1) clip_y1 = py1;
+ if (clip_box->background != NULL)
+ bmp = content_get_bitmap(clip_box->background);
+
/* <td> attributes override <tr> */
if ((clip_x0 >= clip_x1) || (clip_y0 >= clip_y1) ||
(css_computed_background_color(
clip_box->style, &bgcol) !=
CSS_BACKGROUND_COLOR_TRANSPARENT) ||
- (clip_box->background &&
- clip_box->background->bitmap &&
- bitmap_get_opaque(
- clip_box->background->bitmap)))
+ (bmp != NULL && bitmap_get_opaque(bmp)))
continue;
}
@@ -1693,35 +1700,30 @@ bool html_redraw_background(int x, int y, struct box *box, float scale,
}
/* and plot the image */
if (plot_content) {
+ width = content_get_width(background->background);
+ height = content_get_height(background->background);
+
if (!repeat_x) {
if (clip_x0 < x)
clip_x0 = x;
- if (clip_x1 > x +
- background->background->width *
- scale)
- clip_x1 = x + background->background->
- width * scale;
+ if (clip_x1 > x + width * scale)
+ clip_x1 = x + width * scale;
}
if (!repeat_y) {
if (clip_y0 < y)
clip_y0 = y;
- if (clip_y1 > y +
- background->background->height *
- scale)
- clip_y1 = y + background->background->
- height * scale;
+ if (clip_y1 > y + height * scale)
+ clip_y1 = y + height * scale;
}
/* valid clipping rectangles only */
if ((clip_x0 < clip_x1) && (clip_y0 < clip_y1)) {
if (!plot.clip(clip_x0, clip_y0,
clip_x1, clip_y1))
return false;
- if (!content_redraw_tiled(background->
- background, x, y,
- ceilf(background->background->
- width * scale),
- ceilf(background->background->
- height * scale),
+ if (!content_redraw_tiled(
+ background->background, x, y,
+ ceilf(width * scale),
+ ceilf(height * scale),
clip_x0, clip_y0,
clip_x1, clip_y1,
scale, *background_colour,
@@ -1784,32 +1786,35 @@ bool html_redraw_inline_background(int x, int y, struct box *box, float scale,
if (plot_content) {
/* handle background-repeat */
switch (css_computed_background_repeat(box->style)) {
- case CSS_BACKGROUND_REPEAT_REPEAT:
- repeat_x = repeat_y = true;
- /* optimisation: only plot the colour if
- * bitmap is not opaque */
- if (box->background->bitmap)
- plot_colour = !bitmap_get_opaque(
- box->background->bitmap);
- break;
- case CSS_BACKGROUND_REPEAT_REPEAT_X:
- repeat_x = true;
- break;
- case CSS_BACKGROUND_REPEAT_REPEAT_Y:
- repeat_y = true;
- break;
- case CSS_BACKGROUND_REPEAT_NO_REPEAT:
- break;
- default:
- break;
+ case CSS_BACKGROUND_REPEAT_REPEAT:
+ {
+ struct bitmap *bmp =
+ content_get_bitmap(box->background);
+ repeat_x = repeat_y = true;
+ /* optimisation: only plot the colour if
+ * bitmap is not opaque */
+ if (bmp != NULL)
+ plot_colour = !bitmap_get_opaque(bmp);
+ }
+ break;
+ case CSS_BACKGROUND_REPEAT_REPEAT_X:
+ repeat_x = true;
+ break;
+ case CSS_BACKGROUND_REPEAT_REPEAT_Y:
+ repeat_y = true;
+ break;
+ case CSS_BACKGROUND_REPEAT_NO_REPEAT:
+ break;
+ default:
+ break;
}
/* handle background-position */
css_computed_background_position(box->style,
&hpos, &hunit, &vpos, &vunit);
if (hunit == CSS_UNIT_PCT) {
- x += (px1 - px0 - box->background->width * scale) *
- FIXTOFLT(hpos) / 100.;
+ x += (px1 - px0 - content_get_width(box->background) *
+ scale) * FIXTOFLT(hpos) / 100.;
if (!repeat_x && ((hpos < 2 && !first) ||
(hpos > 98 && !last))){
@@ -1821,8 +1826,8 @@ bool html_redraw_inline_background(int x, int y, struct box *box, float scale,
}
if (vunit == CSS_UNIT_PCT) {
- y += (py1 - py0 - box->background->height * scale) *
- FIXTOFLT(vpos) / 100.;
+ y += (py1 - py0 - content_get_height(box->background) *
+ scale) * FIXTOFLT(vpos) / 100.;
} else {
y += (int) (FIXTOFLT(nscss_len2px(vpos, vunit,
box->style)) * scale);
@@ -1843,35 +1848,29 @@ bool html_redraw_inline_background(int x, int y, struct box *box, float scale,
}
/* and plot the image */
if (plot_content) {
+ int width = content_get_width(box->background);
+ int height = content_get_height(box->background);
+
if (!repeat_x) {
if (clip_x0 < x)
clip_x0 = x;
- if (clip_x1 > x +
- box->background->width *
- scale)
- clip_x1 = x + box->background->
- width * scale;
+ if (clip_x1 > x + width * scale)
+ clip_x1 = x + width * scale;
}
if (!repeat_y) {
if (clip_y0 < y)
clip_y0 = y;
- if (clip_y1 > y +
- box->background->height *
- scale)
- clip_y1 = y + box->background->
- height * scale;
+ if (clip_y1 > y + height * scale)
+ clip_y1 = y + height * scale;
}
/* valid clipping rectangles only */
if ((clip_x0 < clip_x1) && (clip_y0 < clip_y1)) {
if (!plot.clip(clip_x0, clip_y0,
clip_x1, clip_y1))
return false;
- if (!content_redraw_tiled(box->
- background, x, y,
- ceilf(box->background->
- width * scale),
- ceilf(box->background->
- height * scale),
+ if (!content_redraw_tiled(box->background, x, y,
+ ceilf(width * scale),
+ ceilf(height * scale),
clip_x0, clip_y0,
clip_x1, clip_y1,
scale, *background_colour,
diff --git a/render/imagemap.c b/render/imagemap.c
index d52e5bdd4..07a46d404 100644
--- a/render/imagemap.c
+++ b/render/imagemap.c
@@ -24,7 +24,8 @@
#include <stdbool.h>
#include <string.h>
#include <strings.h>
-#include "content/content.h"
+#include "content/content_protected.h"
+#include "content/hlcache.h"
#include "render/box.h"
#include "render/imagemap.h"
#include "utils/log.h"
@@ -626,20 +627,21 @@ void imagemap_freelist(struct mapentry *list)
/**
* Retrieve url associated with imagemap entry
*
- * \param c The containing content
- * \param key The map name to search for
- * \param x The left edge of the containing box
- * \param y The top edge of the containing box
- * \param click_x The horizontal location of the click
- * \param click_y The vertical location of the click
- * \param target Pointer to location to receive target pointer (if any)
+ * \param h The containing content
+ * \param key The map name to search for
+ * \param x The left edge of the containing box
+ * \param y The top edge of the containing box
+ * \param click_x The horizontal location of the click
+ * \param click_y The vertical location of the click
+ * \param target Pointer to location to receive target pointer (if any)
* \return The url associated with this area, or NULL if not found
*/
-const char *imagemap_get(struct content *c, const char *key,
+const char *imagemap_get(hlcache_handle *h, const char *key,
unsigned long x, unsigned long y,
unsigned long click_x, unsigned long click_y,
const char **target)
{
+ struct content *c = hlcache_handle_get_content(h);
unsigned int slot = 0;
struct imagemap *map;
struct mapentry *entry;
diff --git a/render/imagemap.h b/render/imagemap.h
index 34a0c3b5f..87a84c3dd 100644
--- a/render/imagemap.h
+++ b/render/imagemap.h
@@ -22,11 +22,13 @@
#include <libxml/HTMLtree.h>
struct content;
+struct hlcache_handle;
void imagemap_destroy(struct content *c);
void imagemap_dump(struct content *c);
bool imagemap_extract(xmlNode *node, struct content *c);
-const char *imagemap_get(struct content *c, const char *key,
+
+const char *imagemap_get(struct hlcache_handle *h, const char *key,
unsigned long x, unsigned long y,
unsigned long click_x, unsigned long click_y,
const char **target);
diff --git a/render/layout.c b/render/layout.c
index 45a075750..336be3e83 100644
--- a/render/layout.c
+++ b/render/layout.c
@@ -41,7 +41,7 @@
#include <math.h>
#include "css/css.h"
#include "css/utils.h"
-#include "content/content.h"
+#include "content/content_protected.h"
#include "desktop/gui.h"
#include "desktop/options.h"
#include "desktop/scroll.h"
@@ -256,12 +256,14 @@ bool layout_block_context(struct box *block, int viewport_height,
if (!layout_block_object(block))
return false;
if (block->height == AUTO) {
- if (block->object->width)
- block->height = block->object->height *
- (float) block->width /
- block->object->width;
+ if (content_get_width(block->object))
+ block->height =
+ content_get_height(block->object) *
+ (float) block->width /
+ content_get_width(block->object);
else
- block->height = block->object->height;
+ block->height =
+ content_get_height(block->object);
}
return true;
}
@@ -691,13 +693,13 @@ void layout_minmax_block(struct box *block,
}
if (block->object) {
- if (block->object->type == CONTENT_HTML) {
- layout_minmax_block(block->object->data.html.layout,
+ if (content_get_type(block->object) == CONTENT_HTML) {
+ layout_minmax_block(html_get_box_tree(block->object),
font_func);
- min = block->object->data.html.layout->min_width;
- max = block->object->data.html.layout->max_width;
+ min = html_get_box_tree(block->object)->min_width;
+ max = html_get_box_tree(block->object)->max_width;
} else {
- min = max = block->object->width;
+ min = max = content_get_width(block->object);
}
} else {
/* recurse through children */
@@ -795,9 +797,9 @@ bool layout_block_object(struct box *block)
LOG(("block %p, object %s, width %i", block, block->object->url,
block->width));
- if (block->object->type == CONTENT_HTML) {
+ if (content_get_type(block->object) == CONTENT_HTML) {
content_reformat(block->object, block->width, 1);
- block->height = block->object->height;
+ block->height = content_get_height(block->object);
} else {
/* this case handled already in
* layout_block_find_dimensions() */
@@ -837,25 +839,25 @@ void layout_block_find_dimensions(int available_width, int viewport_height,
&width, &height, &max_width, &min_width,
margin, padding, border);
- if (box->object && box->object->type != CONTENT_HTML) {
+ if (box->object && content_get_type(box->object) != CONTENT_HTML) {
/* block-level replaced element, see 10.3.4 and 10.6.2 */
if (width == AUTO && height == AUTO) {
- width = box->object->width;
- height = box->object->height;
+ width = content_get_width(box->object);
+ height = content_get_height(box->object);
} else if (width == AUTO) {
- if (box->object->height)
- width = box->object->width *
+ if (content_get_height(box->object))
+ width = content_get_width(box->object) *
(float) height /
- box->object->height;
+ content_get_height(box->object);
else
- width = box->object->width;
+ width = content_get_width(box->object);
} else if (height == AUTO) {
- if (box->object->width)
- height = box->object->height *
+ if (content_get_width(box->object))
+ height = content_get_height(box->object) *
(float) width /
- box->object->width;
+ content_get_width(box->object);
else
- height = box->object->height;
+ height = content_get_height(box->object);
}
}
@@ -1168,18 +1170,20 @@ void layout_float_find_dimensions(int available_width,
padding[RIGHT] += scrollbar_width;
padding[BOTTOM] += scrollbar_width;
- if (box->object && box->object->type != CONTENT_HTML) {
+ if (box->object && content_get_type(box->object) != CONTENT_HTML) {
/* Floating replaced element, with intrinsic width or height.
* See 10.3.6 and 10.6.2 */
if (width == AUTO && height == AUTO) {
- width = box->object->width;
- height = box->object->height;
+ width = content_get_width(box->object);
+ height = content_get_height(box->object);
} else if (width == AUTO)
- width = box->object->width * (float) height /
- box->object->height;
+ width = content_get_width(box->object) *
+ (float) height /
+ content_get_height(box->object);
else if (height == AUTO)
- height = box->object->height * (float) width /
- box->object->width;
+ height = content_get_height(box->object) *
+ (float) width /
+ content_get_width(box->object);
} else if (box->gadget && (box->gadget->type == GADGET_TEXTBOX ||
box->gadget->type == GADGET_PASSWORD ||
box->gadget->type == GADGET_FILE ||
@@ -2079,22 +2083,25 @@ bool layout_line(struct box *first, int *width, int *y,
if (b->object) {
if (b->width == AUTO && b->height == AUTO) {
- b->width = b->object->width;
- b->height = b->object->height;
+ b->width = content_get_width(b->object);
+ b->height = content_get_height(b->object);
} else if (b->width == AUTO) {
- if (b->object->height)
- b->width = b->object->width *
- (float) b->height /
- b->object->height;
+ if (content_get_height(b->object))
+ b->width =
+ content_get_width(b->object) *
+ (float) b->height /
+ content_get_height(b->object);
else
- b->width = b->object->width;
+ b->width = content_get_width(b->object);
} else if (b->height == AUTO) {
- if (b->object->width)
- b->height = b->object->height *
- (float) b->width /
- b->object->width;
+ if (content_get_width(b->object))
+ b->height =
+ content_get_height(b->object) *
+ (float) b->width /
+ content_get_width(b->object);
else
- b->height = b->object->height;
+ b->height =
+ content_get_height(b->object);
}
} else {
/* form control with no object */
@@ -2106,14 +2113,15 @@ bool layout_line(struct box *first, int *width, int *y,
CSS_UNIT_EM, b->style));
}
- if (b->object && b->object->type == CONTENT_HTML &&
- b->width != b->object->available_width) {
+ if (b->object && content_get_type(b->object) == CONTENT_HTML &&
+ b->width !=
+ content_get_available_width(b->object)) {
htype = css_computed_height(b->style, &value, &unit);
content_reformat(b->object, b->width, b->height);
if (htype == CSS_HEIGHT_AUTO)
- b->height = b->object->height;
+ b->height = content_get_height(b->object);
}
if (height < b->height)
@@ -2745,14 +2753,14 @@ struct box *layout_minmax_line(struct box *first,
if (b->object) {
if (width == AUTO && height == AUTO) {
- width = b->object->width;
+ width = content_get_width(b->object);
} else if (width == AUTO) {
- if (b->object->height)
- width = b->object->width *
- (float) height /
- b->object->height;
+ if (content_get_height(b->object))
+ width = content_get_width(b->object) *
+ (float) height /
+ content_get_height(b->object);
else
- width = b->object->width;
+ width = content_get_width(b->object);
}
fixed = frac = 0;
calculate_mbp_width(b->style, LEFT, true, true, true,
@@ -3709,9 +3717,11 @@ void layout_lists(struct box *box,
if (child->list_marker) {
marker = child->list_marker;
if (marker->object) {
- marker->width = marker->object->width;
+ marker->width =
+ content_get_width(marker->object);
marker->x = -marker->width;
- marker->height = marker->object->height;
+ marker->height =
+ content_get_height(marker->object);
marker->y = (line_height(marker->style) -
marker->height) / 2;
} else if (marker->text) {
diff --git a/render/textplain.c b/render/textplain.c
index 07f37610c..befa9aa50 100644
--- a/render/textplain.c
+++ b/render/textplain.c
@@ -28,7 +28,8 @@
#include <strings.h>
#include <math.h>
#include <iconv.h>
-#include "content/content.h"
+#include "content/content_protected.h"
+#include "content/hlcache.h"
#include "css/css.h"
#include "css/utils.h"
#include "desktop/gui.h"
@@ -39,6 +40,7 @@
#include "render/box.h"
#include "render/font.h"
#include "render/textplain.h"
+#include "utils/http.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/talloc.h"
@@ -72,14 +74,13 @@ static float textplain_line_height(void);
* Create a CONTENT_TEXTPLAIN.
*/
-bool textplain_create(struct content *c, struct content *parent,
- const char *params[])
+bool textplain_create(struct content *c, const http_parameter *params)
{
- unsigned int i;
char *utf8_data;
- const char *encoding = "iso-8859-1";
+ const char *encoding;
iconv_t iconv_cd;
union content_msg_data msg_data;
+ nserror error;
textplain_style.size = (option_font_size * FONT_SIZE_SCALE) / 10;
@@ -87,13 +88,9 @@ bool textplain_create(struct content *c, struct content *parent,
if (!utf8_data)
goto no_memory;
- for (i = 0; params[i]; i += 2) {
- if (strcasecmp(params[i], "charset") == 0) {
- encoding = talloc_strdup(c, params[i + 1]);
- if (!encoding)
- goto no_memory;
- break;
- }
+ error = http_parameter_list_find_item(params, "charset", &encoding);
+ if (error != NSERROR_OK) {
+ encoding = "Windows-1252";
}
iconv_cd = iconv_open("utf-8", encoding);
@@ -141,18 +138,22 @@ bool textplain_process_data(struct content *c, char *data, unsigned int size)
iconv_t iconv_cd = c->data.textplain.iconv_cd;
size_t count;
union content_msg_data msg_data;
+ const char *source_data;
+ unsigned long source_size;
+
+ source_data = content__get_source_data(c, &source_size);
do {
- char *inbuf = c->source_data + c->data.textplain.converted;
- size_t inbytesleft = c->source_size -
+ char *inbuf = (char *) source_data +
c->data.textplain.converted;
+ size_t inbytesleft = source_size - c->data.textplain.converted;
char *outbuf = c->data.textplain.utf8_data +
c->data.textplain.utf8_data_size;
size_t outbytesleft = c->data.textplain.utf8_data_allocated -
c->data.textplain.utf8_data_size;
count = iconv(iconv_cd, &inbuf, &inbytesleft,
&outbuf, &outbytesleft);
- c->data.textplain.converted = inbuf - c->source_data;
+ c->data.textplain.converted = inbuf - source_data;
c->data.textplain.utf8_data_size = c->data.textplain.
utf8_data_allocated - outbytesleft;
@@ -180,7 +181,7 @@ bool textplain_process_data(struct content *c, char *data, unsigned int size)
}
gui_multitask();
- } while (!(c->data.textplain.converted == c->source_size ||
+ } while (!(c->data.textplain.converted == source_size ||
(count == (size_t)(-1) && errno == EINVAL)));
return true;
@@ -466,6 +467,35 @@ bool textplain_redraw(struct content *c, int x, int y,
return true;
}
+/**
+ * Retrieve number of lines in content
+ *
+ * \param h Content to retrieve line count from
+ * \return Number of lines
+ */
+unsigned long textplain_line_count(hlcache_handle *h)
+{
+ struct content *c = hlcache_handle_get_content(h);
+
+ assert(c != NULL);
+
+ return c->data.textplain.physical_line_count;
+}
+
+/**
+ * Retrieve the size (in bytes) of text data
+ *
+ * \param h Content to retrieve size of
+ * \return Size, in bytes, of data
+ */
+size_t textplain_size(hlcache_handle *h)
+{
+ struct content *c = hlcache_handle_get_content(h);
+
+ assert(c != NULL);
+
+ return c->data.textplain.utf8_data_size;
+}
/**
* Return byte offset within UTF8 textplain content, given the co-ordinates
@@ -473,15 +503,16 @@ bool textplain_redraw(struct content *c, int x, int y,
* which to search (-1 = above-left, +1 = below-right) if the co-ordinates are not
* contained within a line.
*
- * \param c content of type CONTENT_TEXTPLAIN
+ * \param h content of type CONTENT_TEXTPLAIN
* \param x x ordinate of point
* \param y y ordinate of point
* \param dir direction of search if not within line
* \return byte offset of character containing (or nearest to) point
*/
-size_t textplain_offset_from_coords(struct content *c, int x, int y, int dir)
+size_t textplain_offset_from_coords(hlcache_handle *h, int x, int y, int dir)
{
+ struct content *c = hlcache_handle_get_content(h);
float line_height = textplain_line_height();
struct textplain_line *line;
const char *text;
@@ -489,6 +520,7 @@ size_t textplain_offset_from_coords(struct content *c, int x, int y, int dir)
size_t length;
int idx;
+ assert(c != NULL);
assert(c->type == CONTENT_TEXTPLAIN);
y = (int)((float)(y - MARGIN) / line_height);
@@ -552,19 +584,24 @@ size_t textplain_offset_from_coords(struct content *c, int x, int y, int dir)
* Given a byte offset within the text, return the line number
* of the line containing that offset (or -1 if offset invalid)
*
- * \param c content of type CONTENT_TEXTPLAIN
+ * \param h content of type CONTENT_TEXTPLAIN
* \param offset byte offset within textual representation
* \return line number, or -1 if offset invalid (larger than size)
*/
-int textplain_find_line(struct content *c, unsigned offset)
+int textplain_find_line(hlcache_handle *h, unsigned offset)
{
- struct textplain_line *line = c->data.textplain.physical_line;
- int nlines = c->data.textplain.physical_line_count;
+ struct content *c = hlcache_handle_get_content(h);
+ struct textplain_line *line;
+ int nlines;
int lineno = 0;
+ assert(c != NULL);
assert(c->type == CONTENT_TEXTPLAIN);
+ line = c->data.textplain.physical_line;
+ nlines = c->data.textplain.physical_line_count;
+
if (offset > c->data.textplain.utf8_data_size)
return -1;
@@ -622,30 +659,33 @@ int textplain_coord_from_offset(const char *text, size_t offset, size_t length)
* Given a range of byte offsets within a UTF8 textplain content,
* return a box that fully encloses the text
*
- * \param c content of type CONTENT_TEXTPLAIN
+ * \param h content of type CONTENT_TEXTPLAIN
* \param start byte offset of start of text range
* \param end byte offset of end
* \param r rectangle to be completed
*/
-void textplain_coords_from_range(struct content *c, unsigned start, unsigned end,
- struct rect *r)
+void textplain_coords_from_range(hlcache_handle *h, unsigned start,
+ unsigned end, struct rect *r)
{
+ struct content *c = hlcache_handle_get_content(h);
float line_height = textplain_line_height();
- char *utf8_data = c->data.textplain.utf8_data;
+ char *utf8_data;
struct textplain_line *line;
unsigned lineno = 0;
unsigned nlines;
+ assert(c != NULL);
assert(c->type == CONTENT_TEXTPLAIN);
assert(start <= end);
assert(end <= c->data.textplain.utf8_data_size);
+ utf8_data = c->data.textplain.utf8_data;
nlines = c->data.textplain.physical_line_count;
line = c->data.textplain.physical_line;
/* find start */
- lineno = textplain_find_line(c, start);
+ lineno = textplain_find_line(h, start);
r->y0 = (int)(MARGIN + lineno * line_height);
@@ -654,7 +694,7 @@ void textplain_coords_from_range(struct content *c, unsigned start, unsigned end
forwards most of the time */
/* find end */
- lineno = textplain_find_line(c, end);
+ lineno = textplain_find_line(h, end);
r->x0 = 0;
r->x1 = c->data.textplain.formatted_width;
@@ -677,18 +717,20 @@ void textplain_coords_from_range(struct content *c, unsigned start, unsigned end
/**
* Return a pointer to the requested line of text.
*
- * \param c content of type CONTENT_TEXTPLAIN
+ * \param h content of type CONTENT_TEXTPLAIN
* \param lineno line number
* \param poffset receives byte offset of line start within text
* \param plen receives length of returned line
* \return pointer to text, or NULL if invalid line number
*/
-char *textplain_get_line(struct content *c, unsigned lineno,
+char *textplain_get_line(hlcache_handle *h, unsigned lineno,
size_t *poffset, size_t *plen)
{
+ struct content *c = hlcache_handle_get_content(h);
struct textplain_line *line;
+ assert(c != NULL);
assert(c->type == CONTENT_TEXTPLAIN);
if (lineno >= c->data.textplain.physical_line_count)
@@ -706,20 +748,24 @@ char *textplain_get_line(struct content *c, unsigned lineno,
* text to fit the window width. Thus only hard newlines are preserved
* in the saved/copied text of a selection.
*
- * \param c content of type CONTENT_TEXTPLAIN
+ * \param h content of type CONTENT_TEXTPLAIN
* \param start starting byte offset within UTF-8 text
* \param end ending byte offset
* \param plen receives validated length
* \return pointer to text, or NULL if no text
*/
-char *textplain_get_raw_data(struct content *c, unsigned start, unsigned end,
+char *textplain_get_raw_data(hlcache_handle *h, unsigned start, unsigned end,
size_t *plen)
{
- size_t utf8_size = c->data.textplain.utf8_data_size;
+ struct content *c = hlcache_handle_get_content(h);
+ size_t utf8_size;
+ assert(c != NULL);
assert(c->type == CONTENT_TEXTPLAIN);
+ utf8_size = c->data.textplain.utf8_data_size;
+
/* any text at all? */
if (!utf8_size) return NULL;
diff --git a/render/textplain.h b/render/textplain.h
index 10609a71b..50e29c5be 100644
--- a/render/textplain.h
+++ b/render/textplain.h
@@ -28,6 +28,8 @@
#include <iconv.h>
struct content;
+struct hlcache_handle;
+struct http_parameter;
struct textplain_line {
size_t start;
@@ -46,8 +48,7 @@ struct content_textplain_data {
int formatted_width;
};
-bool textplain_create(struct content *c, struct content *parent,
- const char *params[]);
+bool textplain_create(struct content *c, const struct http_parameter *params);
bool textplain_process_data(struct content *c, char *data, unsigned int size);
bool textplain_convert(struct content *c, int width, int height);
void textplain_reformat(struct content *c, int width, int height);
@@ -58,16 +59,17 @@ bool textplain_redraw(struct content *c, int x, int y,
float scale, colour background_colour);
/* access to lines for text selection and searching */
-#define textplain_line_count(c) ((c)->data.textplain.physical_line_count)
-#define textplain_size(c) ((c)->data.textplain.utf8_data_size)
+unsigned long textplain_line_count(struct hlcache_handle *h);
+size_t textplain_size(struct hlcache_handle *h);
-size_t textplain_offset_from_coords(struct content *c, int x, int y, int dir);
-void textplain_coords_from_range(struct content *c,
+size_t textplain_offset_from_coords(struct hlcache_handle *h, int x, int y,
+ int dir);
+void textplain_coords_from_range(struct hlcache_handle *h,
unsigned start, unsigned end, struct rect *r);
-char *textplain_get_line(struct content *c, unsigned lineno,
+char *textplain_get_line(struct hlcache_handle *h, unsigned lineno,
size_t *poffset, size_t *plen);
-int textplain_find_line(struct content *c, unsigned offset);
-char *textplain_get_raw_data(struct content *c,
+int textplain_find_line(struct hlcache_handle *h, unsigned offset);
+char *textplain_get_raw_data(struct hlcache_handle *h,
unsigned start, unsigned end, size_t *plen);
#endif