summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--content/content.h5
-rw-r--r--desktop/browser.c119
-rw-r--r--render/html.c158
-rw-r--r--render/imagemap.c19
-rw-r--r--render/imagemap.h2
-rw-r--r--utils/errors.h16
6 files changed, 255 insertions, 64 deletions
diff --git a/content/content.h b/content/content.h
index b07af4fe1..649f54dfa 100644
--- a/content/content.h
+++ b/content/content.h
@@ -67,6 +67,7 @@ typedef enum {
CONTENT_MSG_READY, /**< may be displayed */
CONTENT_MSG_DONE, /**< finished */
CONTENT_MSG_ERROR, /**< error occurred */
+ CONTENT_MSG_ERRORCODE, /**< error occurred return nserror */
CONTENT_MSG_STATUS, /**< new status string */
CONTENT_MSG_REFORMAT, /**< content_reformat done */
CONTENT_MSG_REDRAW, /**< needs redraw (eg. new animation frame) */
@@ -96,7 +97,9 @@ struct content_rfc5988_link {
/** Extra data for some content_msg messages. */
union content_msg_data {
/** CONTENT_MSG_ERROR - Error message */
- const char *error;
+ const char *error;
+ /** CONTENT_MSG_ERRORCODE - Error code */
+ nserror errorcode;
/** CONTENT_MSG_REDRAW - Area of content which needs redrawing */
struct {
int x, y, width, height;
diff --git a/desktop/browser.c b/desktop/browser.c
index d3237f5ef..9fa359194 100644
--- a/desktop/browser.c
+++ b/desktop/browser.c
@@ -1187,6 +1187,121 @@ static void browser_window_update_favicon(hlcache_handle *c,
nsurl_unref(nsurl);
}
+/** window callback errorcode handling */
+void
+browser_window_callback_errorcode(hlcache_handle *c,
+ struct browser_window *bw,
+ nserror code)
+{
+ const char* message;
+
+ switch (code) {
+ case NSERROR_OK:
+ /**< No error */
+ message = messages_get("OK");
+ break;
+
+ case NSERROR_UNKNOWN:
+ /**< Unknown error */
+ message = messages_get("Unknown");
+ break;
+
+ case NSERROR_NOMEM:
+ /**< Memory exhaustion */
+ message = messages_get("NoMemory");
+ break;
+
+ case NSERROR_NO_FETCH_HANDLER:
+ /**< No fetch handler for URL scheme */
+ message = messages_get("NoHandler");
+ break;
+
+ case NSERROR_NOT_FOUND:
+ /**< Requested item not found */
+ message = messages_get("NotFound");
+ break;
+
+ case NSERROR_SAVE_FAILED:
+ /**< Failed to save data */
+ message = messages_get("SaveFailed");
+ break;
+
+ case NSERROR_CLONE_FAILED:
+ /**< Failed to clone handle */
+ message = messages_get("CloneFailed");
+ break;
+
+ case NSERROR_INIT_FAILED:
+ /**< Initialisation failed */
+ message = messages_get("InitFailed");
+ break;
+
+ case NSERROR_MNG_ERROR:
+ /**< An MNG error occurred */
+ message = messages_get("MNGError");
+ break;
+
+ case NSERROR_BAD_ENCODING:
+ /**< The character set is unknown */
+ message = messages_get("BadEncoding");
+ break;
+
+ case NSERROR_NEED_DATA:
+ /**< More data needed */
+ message = messages_get("NeedData");
+ break;
+
+ case NSERROR_BAD_PARAMETER:
+ /**< Bad Parameter */
+ message = messages_get("BadParameter");
+ break;
+
+ case NSERROR_INVALID:
+ /**< Invalid data */
+ message = messages_get("Invalid");
+ break;
+
+ case NSERROR_BOX_CONVERT:
+ /**< Box conversion failed */
+ message = messages_get("BoxConvert");
+ break;
+
+ case NSERROR_STOPPED:
+ /**< Content conversion stopped */
+ message = messages_get("Stopped");
+ break;
+
+ case NSERROR_DOM:
+ /**< DOM call returned error */
+ message = messages_get("ParsingFail");
+ break;
+
+ case NSERROR_BAD_URL:
+ /**< Bad URL */
+ message = messages_get("BadURL");
+ break;
+
+ }
+
+ browser_window_set_status(bw, message);
+
+ /* Only warn the user about errors in top-level windows */
+ if (bw->browser_window_type == BROWSER_WINDOW_NORMAL) {
+ warn_user(message, 0);
+ }
+
+ if (c == bw->loading_content) {
+ bw->loading_content = NULL;
+ } else if (c == bw->current_content) {
+ bw->current_content = NULL;
+ browser_window_remove_caret(bw);
+ }
+
+ hlcache_handle_release(c);
+
+ browser_window_stop_throbber(bw);
+}
+
/**
* Callback for fetchcache() for browser window fetches.
*/
@@ -1320,6 +1435,10 @@ nserror browser_window_callback(hlcache_handle *c,
browser_window_refresh, bw);
break;
+ case CONTENT_MSG_ERRORCODE:
+ browser_window_callback_errorcode(c, bw, event->data.errorcode);
+ break;
+
case CONTENT_MSG_ERROR:
browser_window_set_status(bw, event->data.error);
diff --git a/render/html.c b/render/html.c
index 09256a6fa..4e79e085e 100644
--- a/render/html.c
+++ b/render/html.c
@@ -113,13 +113,14 @@ static void html_box_convert_done(html_content *c, bool success)
LOG(("Done XML to box (%p)", c));
/* Clean up and report error if unsuccessful or aborted */
- if ((success == false) || c->aborted) {
+ if ((success == false) || (c->aborted)) {
+ if (success == false) {
+ msg_data.errorcode = NSERROR_BOX_CONVERT;
+ } else {
+ msg_data.errorcode = NSERROR_STOPPED;
+ }
html_destroy_objects(c);
- if (success == false)
- msg_data.error = messages_get("NoMemory");
- else
- msg_data.error = messages_get("Stopped");
- content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(&c->base, CONTENT_MSG_ERRORCODE, msg_data);
content_set_error(&c->base);
return;
}
@@ -134,19 +135,22 @@ static void html_box_convert_done(html_content *c, bool success)
exc = dom_document_get_document_element(c->document, (void *) &html);
if ((exc != DOM_NO_ERR) || (html == NULL)) {
+ /** @todo should this call html_destroy_objects(c);
+ * like the other error paths
+ */
LOG(("error retrieving html element from dom"));
- msg_data.error = messages_get("ParsingFail");
- content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
+ msg_data.errorcode = NSERROR_DOM;
+ content_broadcast(&c->base, CONTENT_MSG_ERRORCODE, msg_data);
content_set_error(&c->base);
return;
}
/* extract image maps - can't do this sensibly in xml_to_box */
- if (imagemap_extract(c) == false) {
+ msg_data.errorcode = imagemap_extract(c);
+ if (msg_data.errorcode != NSERROR_OK) {
LOG(("imagemap extraction failed"));
html_destroy_objects(c);
- msg_data.error = messages_get("NoMemory");
- content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(&c->base, CONTENT_MSG_ERRORCODE, msg_data);
content_set_error(&c->base);
dom_node_unref(html);
return;
@@ -159,8 +163,9 @@ static void html_box_convert_done(html_content *c, bool success)
content_set_ready(&c->base);
- if (c->base.active == 0)
+ if (c->base.active == 0) {
content_set_done(&c->base);
+ }
html_set_status(c, "");
dom_node_unref(html);
@@ -413,9 +418,62 @@ html_create(const content_handler *handler,
return NSERROR_OK;
}
+static nserror
+parse_chunk_to_nserror(dom_hubbub_error error)
+{
+ switch (error) {
+ /* HUBBUB_REPROCESS is not handled here because it can
+ * never occur outside the hubbub treebuilder
+ */
-static bool
+ case DOM_HUBBUB_OK:
+ /* parsed ok */
+ return NSERROR_OK;
+
+ case (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_PAUSED):
+ /* hubbub input paused */
+ return NSERROR_OK;
+
+ case DOM_HUBBUB_NOMEM:
+ /* out of memory error from DOM */
+ return NSERROR_NOMEM;
+
+ case (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_ENCODINGCHANGE):
+ /* encoding changed */
+ return NSERROR_ENCODING_CHANGE;
+
+ case (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_NOMEM):
+ /* out of memory error from parser */
+ return NSERROR_NOMEM;
+
+ case (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_BADPARM):
+ return NSERROR_BAD_PARAMETER;
+
+ case (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_INVALID):
+ return NSERROR_INVALID;
+
+ case (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_FILENOTFOUND):
+ return NSERROR_NOT_FOUND;
+
+ case (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_NEEDDATA):
+ return NSERROR_NEED_DATA;
+
+ case (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_BADENCODING):
+ return NSERROR_BAD_ENCODING;
+
+ case (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_UNKNOWN):
+ /* currently only generated by the libdom hubbub binding */
+ default:
+ /* unknown error */
+ /** @todo better error handling and reporting */
+ return NSERROR_UNKNOWN;
+ }
+ return NSERROR_UNKNOWN;
+}
+
+
+static nserror
html_process_encoding_change(struct content *c,
const char *data,
unsigned int size)
@@ -425,34 +483,30 @@ html_process_encoding_change(struct content *c,
const char *encoding;
const char *source_data;
unsigned long source_size;
- union content_msg_data msg_data;
/* Retrieve new encoding */
encoding = dom_hubbub_parser_get_encoding(html->parser,
&html->encoding_source);
-
if (encoding == NULL) {
- msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
- return false;
+ return NSERROR_NOMEM;
}
- if (html->encoding != NULL)
+ if (html->encoding != NULL) {
free(html->encoding);
+ }
html->encoding = strdup(encoding);
if (html->encoding == NULL) {
- msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
- return false;
+ return NSERROR_NOMEM;
}
/* Destroy binding */
dom_hubbub_parser_destroy(html->parser);
html->parser = NULL;
- if (html->document != NULL)
+ if (html->document != NULL) {
dom_node_unref(html->document);
+ }
/* Create new binding, using the new encoding */
html->parser = dom_hubbub_parser_create(html->encoding,
@@ -468,9 +522,7 @@ html_process_encoding_change(struct content *c,
free(html->encoding);
html->encoding = strdup("Windows-1252");
if (html->encoding == NULL) {
- msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
- return false;
+ return NSERROR_NOMEM;
}
html->parser = dom_hubbub_parser_create(html->encoding,
@@ -486,10 +538,7 @@ html_process_encoding_change(struct content *c,
* parser errors back instead of everything being
* OOM
*/
-
- msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
- return false;
+ return NSERROR_NOMEM;
}
}
@@ -498,21 +547,16 @@ html_process_encoding_change(struct content *c,
/* Reprocess all the data. This is safe because
* the encoding is now specified at parser start which means
- * it cannot be changed again. */
- error = dom_hubbub_parser_parse_chunk(html->parser, (const uint8_t *)source_data, source_size);
-
- if ((error == DOM_HUBBUB_OK) ||
- (error == (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_PAUSED))) {
- return true;
- }
-
- msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
-
- return false;
+ * it cannot be changed again.
+ */
+ error = dom_hubbub_parser_parse_chunk(html->parser,
+ (const uint8_t *)source_data,
+ source_size);
+ return parse_chunk_to_nserror(error);
}
+
/**
* Process data for CONTENT_HTML.
*/
@@ -524,21 +568,27 @@ html_process_data(struct content *c, const char *data, unsigned int size)
dom_hubbub_error error;
union content_msg_data msg_data;
- error = dom_hubbub_parser_parse_chunk(html->parser, (const uint8_t *) data, size);
+ msg_data.errorcode = NSERROR_OK; /* assume its all going to be ok */
- if ((error == DOM_HUBBUB_OK) ||
- (error == (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_PAUSED))) {
- return true;
- } else if (error == (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_ENCODINGCHANGE)) {
- return html_process_encoding_change(c, data, size);
- }
+ error = dom_hubbub_parser_parse_chunk(html->parser,
+ (const uint8_t *) data,
+ size);
- /** @todo better error handling and reporting */
- msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
- return false;
-
+ msg_data.errorcode = parse_chunk_to_nserror(error);
+
+ /* deal with encoding change */
+ if (msg_data.errorcode == NSERROR_ENCODING_CHANGE) {
+ msg_data.errorcode = html_process_encoding_change(c, data, size);
+ }
+
+ /* broadcast the error if necessary */
+ if (msg_data.errorcode != NSERROR_OK) {
+ content_broadcast(c, CONTENT_MSG_ERRORCODE, msg_data);
+ return false;
+ }
+
+ return true;
}
diff --git a/render/imagemap.c b/render/imagemap.c
index bf90443c4..c41b86d0b 100644
--- a/render/imagemap.c
+++ b/render/imagemap.c
@@ -251,23 +251,25 @@ void imagemap_dump(html_content *c)
* \param map_str A dom_string which is "map"
* \return false on memory exhaustion, true otherwise
*/
-bool
+nserror
imagemap_extract(html_content *c)
{
dom_nodelist *nlist;
dom_exception exc;
unsigned long mapnr;
uint32_t maybe_maps;
-
+ nserror ret = NSERROR_OK;
+
exc = dom_document_get_elements_by_tag_name(c->document,
corestring_dom_map,
&nlist);
if (exc != DOM_NO_ERR) {
- return false;
+ return NSERROR_DOM;
}
exc = dom_nodelist_get_length(nlist, &maybe_maps);
if (exc != DOM_NO_ERR) {
+ ret = NSERROR_DOM;
goto out_nlist;
}
@@ -276,6 +278,7 @@ imagemap_extract(html_content *c)
dom_string *name;
exc = dom_nodelist_item(nlist, mapnr, &node);
if (exc != DOM_NO_ERR) {
+ ret = NSERROR_DOM;
goto out_nlist;
}
@@ -283,6 +286,7 @@ imagemap_extract(html_content *c)
&name);
if (exc != DOM_NO_ERR) {
dom_node_unref(node);
+ ret = NSERROR_DOM;
goto out_nlist;
}
@@ -292,6 +296,7 @@ imagemap_extract(html_content *c)
&name);
if (exc != DOM_NO_ERR) {
dom_node_unref(node);
+ ret = NSERROR_DOM;
goto out_nlist;
}
}
@@ -301,6 +306,7 @@ imagemap_extract(html_content *c)
if (imagemap_extract_map(node, c, &entry) == false) {
dom_string_unref(name);
dom_node_unref(node);
+ ret = NSERROR_NOMEM; /** @todo check this */
goto out_nlist;
}
@@ -313,6 +319,7 @@ imagemap_extract(html_content *c)
(imagemap_add(c, name, entry) == false)) {
dom_string_unref(name);
dom_node_unref(node);
+ ret = NSERROR_NOMEM; /** @todo check this */
goto out_nlist;
}
}
@@ -321,14 +328,12 @@ imagemap_extract(html_content *c)
dom_node_unref(node);
}
- dom_nodelist_unref(nlist);
-
- return true;
out_nlist:
dom_nodelist_unref(nlist);
- return false;
+
+ return ret;
}
/**
diff --git a/render/imagemap.h b/render/imagemap.h
index edbfea08f..d450cda86 100644
--- a/render/imagemap.h
+++ b/render/imagemap.h
@@ -28,7 +28,7 @@ struct hlcache_handle;
void imagemap_destroy(struct html_content *c);
void imagemap_dump(struct html_content *c);
-bool imagemap_extract(struct html_content *c);
+nserror imagemap_extract(struct html_content *c);
nsurl *imagemap_get(struct html_content *c, const char *key,
unsigned long x, unsigned long y,
diff --git a/utils/errors.h b/utils/errors.h
index 546709703..9ad613da6 100644
--- a/utils/errors.h
+++ b/utils/errors.h
@@ -29,6 +29,8 @@
typedef enum {
NSERROR_OK, /**< No error */
+ NSERROR_UNKNOWN, /**< Unknown error - DO *NOT* USE */
+
NSERROR_NOMEM, /**< Memory exhaustion */
NSERROR_NO_FETCH_HANDLER, /**< No fetch handler for URL scheme */
@@ -47,7 +49,19 @@ typedef enum {
NSERROR_NEED_DATA, /**< More data needed */
- NSERROR_BAD_URL /**< More data needed */
+ NSERROR_ENCODING_CHANGE, /**< The character changed */
+
+ NSERROR_BAD_PARAMETER, /**< Bad Parameter */
+
+ NSERROR_INVALID, /**< Invalid data */
+
+ NSERROR_BOX_CONVERT, /**< Box conversion failed */
+
+ NSERROR_STOPPED, /**< Content conversion stopped */
+
+ NSERROR_DOM, /**< DOM call returned error */
+
+ NSERROR_BAD_URL /**< Bad URL */
} nserror;
#endif