From b0a41606ffe3b2cff04c68e0ae0aec96816cb857 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Mon, 30 Jul 2012 15:17:57 +0100 Subject: [PATCH] extend html data processing to deal with paused parse --- render/html.c | 82 ++++++++++++++++++++++++++++---------------- render/html_script.c | 37 +++++++++++--------- 2 files changed, 72 insertions(+), 47 deletions(-) diff --git a/render/html.c b/render/html.c index 236752942..95f7553a0 100644 --- a/render/html.c +++ b/render/html.c @@ -412,12 +412,10 @@ html_create(const content_handler *handler, -/** - * Process data for CONTENT_HTML. - */ - static bool -html_process_data(struct content *c, const char *data, unsigned int size) +html_process_encoding_change(struct content *c, + const char *data, + unsigned int size) { html_content *html = (html_content *) c; dom_hubbub_error error; @@ -425,23 +423,6 @@ html_process_data(struct content *c, const char *data, unsigned int size) const char *source_data; unsigned long source_size; - error = dom_hubbub_parser_parse_chunk(html->parser, (const uint8_t *) data, size); - - if (error == (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_ENCODINGCHANGE)) { - goto encoding_change; - } else if (error != DOM_HUBBUB_OK) { - union content_msg_data msg_data; - - msg_data.error = messages_get("NoMemory"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - - return false; - } - - return true; - -encoding_change: - /* Retrieve new encoding */ encoding = dom_hubbub_parser_get_encoding(html->parser, &html->encoding_source); @@ -464,11 +445,11 @@ encoding_change: /* Create new binding, using the new encoding */ html->parser = dom_hubbub_parser_create(html->encoding, - true, - nsoption_bool(enable_javascript), - NULL, - html_process_script, - html); + true, + nsoption_bool(enable_javascript), + NULL, + html_process_script, + html); if (html->parser == NULL) { /* Ok, we don't support the declared encoding. Bailing out * isn't exactly user-friendly, so fall back to Windows-1252 */ @@ -506,10 +487,50 @@ encoding_change: source_data = content__get_source_data(c, &source_size); - /* Recurse to reprocess all the data. This is safe because + /* Reprocess all the 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, source_data, source_size); + 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; + } + + union content_msg_data msg_data; + + msg_data.error = messages_get("NoMemory"); + content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + + return false; + +} + +/** + * Process data for CONTENT_HTML. + */ + +static bool +html_process_data(struct content *c, const char *data, unsigned int size) +{ + html_content *html = (html_content *) c; + dom_hubbub_error error; + union content_msg_data msg_data; + + error = dom_hubbub_parser_parse_chunk(html->parser, (const uint8_t *) data, size); + + 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); + } + + /** @todo better error handling and reporting */ + msg_data.error = messages_get("NoMemory"); + content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + + return false; } @@ -1927,7 +1948,7 @@ static bool html_convert(struct content *c) if (err != DOM_HUBBUB_OK) { union content_msg_data msg_data; - /** @todo Improve precessing of errors */ + /** @todo Improve processing of errors */ msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); @@ -2093,6 +2114,7 @@ static bool html_convert(struct content *c) } dom_node_unref(head); + /* get stylesheets */ if (html_find_stylesheets(htmlc, html) == false) { dom_node_unref(html); diff --git a/render/html_script.c b/render/html_script.c index 932efa4e8..1e2c1b37d 100644 --- a/render/html_script.c +++ b/render/html_script.c @@ -294,10 +294,11 @@ convert_script_sync_cb(hlcache_handle *script, html_content *parent = pw; unsigned int i; struct html_script *s; + script_handler_t *script_handler; /* Find script */ for (i = 0, s = parent->scripts; i != parent->scripts_count; i++, s++) { - if (s->type == HTML_SCRIPT_ASYNC && s->data.handle == script) + if (s->type == HTML_SCRIPT_SYNC && s->data.handle == script) break; } @@ -318,16 +319,19 @@ convert_script_sync_cb(hlcache_handle *script, s->already_started = true; - script_handler = select_script_handler( - content_get_type(s->data.handle)); + /* attempt to execute script */ + script_handler = select_script_handler(content_get_type(s->data.handle)); if (script_handler != NULL) { - /* script fetch is done and supported type */ - + /* script has a handler */ const char *data; unsigned long size; data = content_get_source_data(s->data.handle, &size ); - script_handler(c->jscontext, data, size); + script_handler(parent->jscontext, data, size); } + + /* continue parse */ + dom_hubbub_parser_pause(parent->parser, false); + break; case CONTENT_MSG_ERROR: @@ -338,6 +342,7 @@ convert_script_sync_cb(hlcache_handle *script, hlcache_handle_release(script); s->data.handle = NULL; parent->base.active--; + LOG(("%d fetches active", parent->base.active)); content_add_error(&parent->base, "?", 0); @@ -355,9 +360,6 @@ convert_script_sync_cb(hlcache_handle *script, assert(0); } - if (parent->base.active == 0) - html_finish_conversion(parent); - return NSERROR_OK; } @@ -385,8 +387,11 @@ exec_src_script(html_content *c, /* src url */ ns_error = nsurl_join(c->base_url, dom_string_data(src), &joined); if (ns_error != NSERROR_OK) { - goto html_process_script_no_memory; + msg_data.error = messages_get("NoMemory"); + content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); + return DOM_HUBBUB_NOMEM; } + LOG(("script %i '%s'", c->scripts_count, nsurl_access(joined))); /* there are three ways to process the script tag at this point: @@ -438,7 +443,9 @@ exec_src_script(html_content *c, nscript = html_process_new_script(c, mimetype, script_type); if (nscript == NULL) { nsurl_unref(joined); - goto html_process_script_no_memory; + msg_data.error = messages_get("NoMemory"); + content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); + return DOM_HUBBUB_NOMEM; } /* set up child fetch encoding and quirks */ @@ -469,6 +476,7 @@ exec_src_script(html_content *c, /* update base content active fetch count */ c->base.active++; LOG(("%d fetches active", c->base.active)); + switch (script_type) { case HTML_SCRIPT_SYNC: ret = DOM_HUBBUB_PAUSED; @@ -480,16 +488,11 @@ exec_src_script(html_content *c, break; default: - assert(true); + assert(0); } } return ret; - -html_process_script_no_memory: - msg_data.error = messages_get("NoMemory"); - content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); - return DOM_HUBBUB_NOMEM; } static dom_hubbub_error