From 06608c1bf0b1046520e184fdc063c83ead2184af Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Fri, 27 Jul 2012 13:53:14 +0100 Subject: extend script enumeration to include asyncronous and deferred scripts --- render/html.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'render/html.c') diff --git a/render/html.c b/render/html.c index 759c24433..236752942 100644 --- a/render/html.c +++ b/render/html.c @@ -2433,21 +2433,7 @@ static void html_destroy(struct content *c) } /* Free scripts */ - for (i = 0; i != html->scripts_count; i++) { - if (html->scripts[i].mimetype != NULL) { - dom_string_unref(html->scripts[i].mimetype); - } - if (html->scripts[i].type == HTML_SCRIPT_EXTERNAL && - html->scripts[i].data.external != NULL) { - hlcache_handle_release( - html->scripts[i].data.external); - } else if (html->scripts[i].type == - HTML_SCRIPT_INTERNAL && - html->scripts[i].data.internal != NULL) { - dom_string_unref(html->scripts[i].data.internal); - } - } - free(html->scripts); + html_free_scripts(html); /* Free objects */ html_destroy_objects(html); -- cgit v1.2.3 From b0a41606ffe3b2cff04c68e0ae0aec96816cb857 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Mon, 30 Jul 2012 15:17:57 +0100 Subject: 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(-) (limited to 'render/html.c') 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 -- cgit v1.2.3 From 4182685d1e90e082407a8e40a0b1db76cf9fbea2 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Mon, 30 Jul 2012 18:18:11 +0100 Subject: fix parse completion - working syncronous scripts --- render/html.c | 61 ++++++++++++++++++++++++++++++++++---------------- render/html_internal.h | 12 ++++++++-- render/html_script.c | 36 ++++++++++++++++------------- 3 files changed, 72 insertions(+), 37 deletions(-) (limited to 'render/html.c') diff --git a/render/html.c b/render/html.c index 95f7553a0..4263a064d 100644 --- a/render/html.c +++ b/render/html.c @@ -301,6 +301,8 @@ html_create_html_data(html_content *c, const http_parameter *params) c->scripts = NULL; c->jscontext = NULL; + c->base.active = 1; /* The html content itself is active */ + if (lwc_intern_string("*", SLEN("*"), &c->universal) != lwc_error_ok) { msg_data.error = messages_get("NoMemory"); content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); @@ -1933,24 +1935,39 @@ html_find_stylesheets_no_memory: static bool html_convert(struct content *c) { html_content *htmlc = (html_content *) c; - dom_hubbub_error err; + + htmlc->base.active--; /* the html fetch is no longer active */ + LOG(("%d fetches active", htmlc->base.active)); + + + /* if there are no active fetches in progress no scripts are + * being fetched or they completed already. + */ + if (htmlc->base.active == 0) { + return html_begin_conversion(htmlc); + } + return true; + +} + +bool +html_begin_conversion(html_content *htmlc) +{ dom_node *html, *head; union content_msg_data msg_data; - unsigned long size; struct form *f; dom_exception exc; /* returned by libdom functions */ dom_string *node_name = NULL; + dom_hubbub_error error; - /* finish parsing */ - content__get_source_data(c, &size); - - err = dom_hubbub_parser_completed(htmlc->parser); - if (err != DOM_HUBBUB_OK) { + /* complete parsing */ + error = dom_hubbub_parser_completed(htmlc->parser); + if (error != DOM_HUBBUB_OK) { union content_msg_data msg_data; /** @todo Improve processing of errors */ msg_data.error = messages_get("NoMemory"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + content_broadcast(&htmlc->base, CONTENT_MSG_ERROR, msg_data); return false; } @@ -1960,7 +1977,7 @@ static bool html_convert(struct content *c) if (htmlc->document == NULL) { LOG(("Parsing failed")); msg_data.error = messages_get("ParsingFail"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + content_broadcast(&htmlc->base, CONTENT_MSG_ERROR, msg_data); return false; } @@ -1977,10 +1994,10 @@ static bool html_convert(struct content *c) encoding = dom_hubbub_parser_get_encoding(htmlc->parser, &htmlc->encoding_source); - htmlc->encoding = talloc_strdup(c, encoding); + htmlc->encoding = talloc_strdup(&htmlc->base, encoding); if (htmlc->encoding == NULL) { msg_data.error = messages_get("NoMemory"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + content_broadcast(&htmlc->base, CONTENT_MSG_ERROR, msg_data); return false; } } @@ -1988,7 +2005,7 @@ static bool html_convert(struct content *c) /* Give up processing if we've been aborted */ if (htmlc->aborted) { msg_data.error = messages_get("Stopped"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + content_broadcast(&htmlc->base, CONTENT_MSG_ERROR, msg_data); return false; } @@ -1997,7 +2014,7 @@ static bool html_convert(struct content *c) if ((exc != DOM_NO_ERR) || (html == NULL)) { LOG(("error retrieving html element from dom")); msg_data.error = messages_get("ParsingFail"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + content_broadcast(&htmlc->base, CONTENT_MSG_ERROR, msg_data); return false; } @@ -2008,7 +2025,7 @@ static bool html_convert(struct content *c) corestring_lwc_html))) { LOG(("root element not html")); msg_data.error = messages_get("ParsingFail"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + content_broadcast(&htmlc->base, CONTENT_MSG_ERROR, msg_data); dom_node_unref(html); return false; } @@ -2057,7 +2074,7 @@ static bool html_convert(struct content *c) if (head != NULL) { if (html_head(htmlc, head) == false) { msg_data.error = messages_get("NoMemory"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + content_broadcast(&htmlc->base, CONTENT_MSG_ERROR, msg_data); dom_node_unref(html); dom_node_unref(head); return false; @@ -2081,7 +2098,7 @@ static bool html_convert(struct content *c) /* Make all actions absolute */ if (f->action == NULL || f->action[0] == '\0') { /* HTML5 4.10.22.3 step 11 */ - res = url_join(nsurl_access(content_get_url(c)), + res = url_join(nsurl_access(content_get_url(&htmlc->base)), nsurl_access(htmlc->base_url), &action); } else { res = url_join(f->action, nsurl_access(htmlc->base_url), @@ -2090,7 +2107,7 @@ static bool html_convert(struct content *c) if (res != URL_FUNC_OK) { msg_data.error = messages_get("NoMemory"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + content_broadcast(&htmlc->base, CONTENT_MSG_ERROR, msg_data); dom_node_unref(html); dom_node_unref(head); return false; @@ -2104,8 +2121,9 @@ static bool html_convert(struct content *c) f->document_charset = strdup(htmlc->encoding); if (f->document_charset == NULL) { msg_data.error = messages_get("NoMemory"); - content_broadcast(c, CONTENT_MSG_ERROR, - msg_data); + content_broadcast(&htmlc->base, + CONTENT_MSG_ERROR, + msg_data); dom_node_unref(html); dom_node_unref(head); return false; @@ -2122,6 +2140,11 @@ static bool html_convert(struct content *c) } dom_node_unref(html); + + if (htmlc->base.active == 0) { + html_finish_conversion(htmlc); + } + return true; } diff --git a/render/html_internal.h b/render/html_internal.h index 3eabe1cc6..0f20cc1c3 100644 --- a/render/html_internal.h +++ b/render/html_internal.h @@ -127,12 +127,20 @@ void html__redraw_a_box(struct content *c, struct box *box); struct browser_window *html_get_browser_window(struct content *c); struct search_context *html_get_search(struct content *c); void html_set_search(struct content *c, struct search_context *s); + /** * Complete conversion of an HTML document * - * \param c Content to convert + * \param htmlc Content to convert + */ +void html_finish_conversion(html_content *htmlc); + +/** + * Begin conversion of an HTML document + * + * \param htmlc Content to convert */ -void html_finish_conversion(html_content *c); +bool html_begin_conversion(html_content *htmlc); /* in render/html_redraw.c */ bool html_redraw(struct content *c, struct content_redraw_data *data, diff --git a/render/html_script.c b/render/html_script.c index 1e2c1b37d..7222f80e2 100644 --- a/render/html_script.c +++ b/render/html_script.c @@ -180,8 +180,8 @@ convert_script_async_cb(hlcache_handle *script, parent->base.active--; LOG(("%d fetches active", parent->base.active)); - /* script finished loading so try and continue execution */ - html_scripts_exec(parent); + + break; case CONTENT_MSG_ERROR: @@ -194,9 +194,6 @@ convert_script_async_cb(hlcache_handle *script, LOG(("%d fetches active", parent->base.active)); content_add_error(&parent->base, "?", 0); - /* script failed loading so try and continue execution */ - html_scripts_exec(parent); - break; case CONTENT_MSG_STATUS: @@ -209,9 +206,6 @@ convert_script_async_cb(hlcache_handle *script, assert(0); } - if (parent->base.active == 0) - html_finish_conversion(parent); - return NSERROR_OK; } @@ -248,8 +242,6 @@ convert_script_defer_cb(hlcache_handle *script, parent->base.active--; LOG(("%d fetches active", parent->base.active)); - /* script finished loading so try and continue execution */ - html_scripts_exec(parent); break; case CONTENT_MSG_ERROR: @@ -262,9 +254,6 @@ convert_script_defer_cb(hlcache_handle *script, LOG(("%d fetches active", parent->base.active)); content_add_error(&parent->base, "?", 0); - /* script failed loading so try and continue execution */ - html_scripts_exec(parent); - break; case CONTENT_MSG_STATUS: @@ -277,8 +266,12 @@ convert_script_defer_cb(hlcache_handle *script, assert(0); } - if (parent->base.active == 0) - html_finish_conversion(parent); + /* if there are no active fetches remaining begin post parse + * conversion + */ + if (parent->base.active == 0) { + html_begin_conversion(parent); + } return NSERROR_OK; } @@ -295,6 +288,7 @@ convert_script_sync_cb(hlcache_handle *script, unsigned int i; struct html_script *s; script_handler_t *script_handler; + dom_hubbub_error err; /* Find script */ for (i = 0, s = parent->scripts; i != parent->scripts_count; i++, s++) { @@ -330,7 +324,10 @@ convert_script_sync_cb(hlcache_handle *script, } /* continue parse */ - dom_hubbub_parser_pause(parent->parser, false); + err = dom_hubbub_parser_pause(parent->parser, false); + if (err != DOM_HUBBUB_OK) { + LOG(("unpause returned 0x%x", err)); + } break; @@ -360,6 +357,13 @@ convert_script_sync_cb(hlcache_handle *script, assert(0); } + /* if there are no active fetches remaining begin post parse + * conversion + */ + if (parent->base.active == 0) { + html_begin_conversion(parent); + } + return NSERROR_OK; } -- cgit v1.2.3