Gitweb links: ...log http://git.netsurf-browser.org/netsurf.git/shortlog/d63ed30a815d700b1a6889b9fec58e60561f506f ...commit http://git.netsurf-browser.org/netsurf.git/commit/d63ed30a815d700b1a6889b9fec58e60561f506f ...tree http://git.netsurf-browser.org/netsurf.git/tree/d63ed30a815d700b1a6889b9fec58e60561f506f
The branch, vince/script-async has been created at d63ed30a815d700b1a6889b9fec58e60561f506f (commit) - Log ----------------------------------------------------------------- commitdiff http://git.netsurf-browser.org/netsurf.git/commitdiff/d63ed30a815d700b1a6889b9fec58e60561f506f commit d63ed30a815d700b1a6889b9fec58e60561f506f Author: Vincent Sanders <vi...@netsurf-browser.org> Commit: Vincent Sanders <vi...@netsurf-browser.org> current wip on adding syncronous interpretation diff --git a/render/html_script.c b/render/html_script.c index e3075f6..379fb39 100644 --- a/render/html_script.c +++ b/render/html_script.c @@ -227,7 +227,25 @@ exec_src_script(html_content *c, struct html_script *nscript; union content_msg_data msg_data; - //exc = dom_element_has_attribute(node, html_dom_string_async, &async); + /* there are three ways to precess the script tag at this point: + + * Syncronously pause the parent parse and continue after + * the script has downloaded and executed. (default) + * Defered Start the script downloading and execute it when + * the page has completed parsing + * Async Start the script downloading and execute it when it + * becomes available. + */ + + /* we interpret the presence of the async and defer attribute + * as true and ignore its value, technically only the empty + * value or the attribute name itself are valid. However + * various browsers interpret this in various ways the most + * compatible approach is to be liberal and accept any + * value + */ + exc = dom_element_has_attribute(node, html_dom_string_async, &async); + exc = dom_element_has_attribute(node, html_dom_string_async, &defer); nscript = html_process_new_script(c, HTML_SCRIPT_SYNC); if (nscript == NULL) { commitdiff http://git.netsurf-browser.org/netsurf.git/commitdiff/0b493a680b374b18669881353979198a5f83ec38 commit 0b493a680b374b18669881353979198a5f83ec38 Author: Vincent Sanders <vi...@netsurf-browser.org> Commit: Vincent Sanders <vi...@netsurf-browser.org> rename and extend script enum to represent the four types we require diff --git a/render/html.c b/render/html.c index 759c244..2367529 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); diff --git a/render/html.h b/render/html.h index 64548f8..dcbc1a3 100644 --- a/render/html.h +++ b/render/html.h @@ -66,10 +66,13 @@ struct html_stylesheet { */ struct html_script { /** Type of script */ - enum html_script_type { HTML_SCRIPT_EXTERNAL, HTML_SCRIPT_INTERNAL } type; + enum html_script_type { HTML_SCRIPT_INLINE, + HTML_SCRIPT_SYNC, + HTML_SCRIPT_DEFER, + HTML_SCRIPT_ASYNC } type; union { - struct hlcache_handle *external; - struct dom_string *internal; + struct hlcache_handle *handle; + struct dom_string *string; } data; /**< Script data */ struct dom_string *mimetype; struct dom_string *encoding; @@ -175,9 +178,9 @@ struct content_html_frames *html_get_frameset(struct hlcache_handle *h); struct content_html_iframe *html_get_iframe(struct hlcache_handle *h); nsurl *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, +struct html_stylesheet *html_get_stylesheets(struct hlcache_handle *h, unsigned int *n); -struct content_html_object *html_get_objects(struct hlcache_handle *h, +struct content_html_object *html_get_objects(struct hlcache_handle *h, unsigned int *n); bool html_get_id_offset(struct hlcache_handle *h, lwc_string *frag_id, int *x, int *y); diff --git a/render/html_internal.h b/render/html_internal.h index ad032f7..3eabe1c 100644 --- a/render/html_internal.h +++ b/render/html_internal.h @@ -149,6 +149,7 @@ void html_overflow_scroll_callback(void *client_data, /* in render/html_script.c */ dom_hubbub_error html_process_script(void *ctx, dom_node *node); +void html_free_scripts(html_content *html); /* in render/html_forms.c */ struct form *html_forms_get_forms(const char *docenc, dom_html_document *doc); diff --git a/render/html_script.c b/render/html_script.c index fb51256..e3075f6 100644 --- a/render/html_script.c +++ b/render/html_script.c @@ -69,32 +69,32 @@ static bool html_scripts_exec(html_content *c) continue; } - assert((s->type == HTML_SCRIPT_EXTERNAL) || - (s->type == HTML_SCRIPT_INTERNAL)); + assert((s->type == HTML_SCRIPT_SYNC) || + (s->type == HTML_SCRIPT_INLINE)); - if (s->type == HTML_SCRIPT_EXTERNAL) { + if (s->type == HTML_SCRIPT_SYNC) { /* ensure script content is present */ - if (s->data.external == NULL) + if (s->data.handle == NULL) continue; /* ensure script content fetch status is not an error */ - if (content_get_status(s->data.external) == + if (content_get_status(s->data.handle) == CONTENT_STATUS_ERROR) continue; /* ensure script handler for content type */ script_handler = select_script_handler( - content_get_type(s->data.external)); + content_get_type(s->data.handle)); if (script_handler == NULL) continue; /* unsupported type */ - if (content_get_status(s->data.external) == + if (content_get_status(s->data.handle) == CONTENT_STATUS_DONE) { /* external script is now available */ const char *data; unsigned long size; data = content_get_source_data( - s->data.external, &size ); + s->data.handle, &size ); script_handler(c->jscontext, data, size); s->already_started = true; @@ -158,8 +158,7 @@ convert_script_async_cb(hlcache_handle *script, /* Find script */ for (i = 0, s = parent->scripts; i != parent->scripts_count; i++, s++) { - if (s->type == HTML_SCRIPT_EXTERNAL && - s->data.external == script) + if (s->type == HTML_SCRIPT_ASYNC && s->data.handle == script) break; } @@ -187,7 +186,7 @@ convert_script_async_cb(hlcache_handle *script, nsurl_access(hlcache_handle_get_url(script)), event->data.error)); hlcache_handle_release(script); - s->data.external = NULL; + s->data.handle = NULL; parent->base.active--; LOG(("%d fetches active", parent->base.active)); content_add_error(&parent->base, "?", 0); @@ -213,13 +212,13 @@ convert_script_async_cb(hlcache_handle *script, return NSERROR_OK; } -/** - * process a script with a src tag +/** + * process a script with a src tag */ static dom_hubbub_error -exec_src_script(html_content *c, - dom_node *node, - dom_string *mimetype, +exec_src_script(html_content *c, + dom_node *node, + dom_string *mimetype, dom_string *src) { nserror ns_error; @@ -230,7 +229,7 @@ exec_src_script(html_content *c, //exc = dom_element_has_attribute(node, html_dom_string_async, &async); - nscript = html_process_new_script(c, HTML_STYLESHEET_EXTERNAL); + nscript = html_process_new_script(c, HTML_SCRIPT_SYNC); if (nscript == NULL) { dom_string_unref(mimetype); goto html_process_script_no_memory; @@ -258,7 +257,7 @@ exec_src_script(html_content *c, c, &child, CONTENT_SCRIPT, - &nscript->data.external); + &nscript->data.handle); nsurl_unref(joined); @@ -297,7 +296,7 @@ exec_inline_script(html_content *c, dom_node *node, dom_string *mimetype) return DOM_HUBBUB_OK; /* no contents, skip */ } - nscript = html_process_new_script(c, HTML_STYLESHEET_INTERNAL); + nscript = html_process_new_script(c, HTML_SCRIPT_INLINE); if (nscript == NULL) { dom_string_unref(mimetype); dom_string_unref(script); @@ -308,7 +307,7 @@ exec_inline_script(html_content *c, dom_node *node, dom_string *mimetype) } - nscript->data.internal = script; + nscript->data.string = script; nscript->mimetype = mimetype; nscript->already_started = true; @@ -328,7 +327,7 @@ exec_inline_script(html_content *c, dom_node *node, dom_string *mimetype) } -/** +/** * process script node parser callback * * @@ -354,7 +353,7 @@ html_process_script(void *ctx, dom_node *node) } } - LOG(("content %p parser %p node %p",c,c->parser, node)); + LOG(("content %p parser %p node %p", c, c->parser, node)); exc = dom_element_get_attribute(node, corestring_dom_type, &mimetype); if (exc != DOM_NO_ERR || mimetype == NULL) { @@ -371,3 +370,27 @@ html_process_script(void *ctx, dom_node *node) return err; } + +void html_free_scripts(html_content *html) +{ + unsigned int i; + + 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_INLINE) && + (html->scripts[i].data.string != NULL)) { + + dom_string_unref(html->scripts[i].data.string); + + } else if ((html->scripts[i].type == HTML_SCRIPT_SYNC) && + (html->scripts[i].data.handle != NULL)) { + + hlcache_handle_release(html->scripts[i].data.handle); + + } + } + free(html->scripts); +} commitdiff http://git.netsurf-browser.org/netsurf.git/commitdiff/70d70b2878804b02a043fd08c2cdc705d1611e5e commit 70d70b2878804b02a043fd08c2cdc705d1611e5e Author: Vincent Sanders <vi...@netsurf-browser.org> Commit: Vincent Sanders <vi...@netsurf-browser.org> split up the script processing diff --git a/render/html_script.c b/render/html_script.c index 5fd8c8a..fb51256 100644 --- a/render/html_script.c +++ b/render/html_script.c @@ -144,11 +144,11 @@ html_process_new_script(html_content *c, enum html_script_type type) } /** - * Callback for fetchcache() for linked stylesheets. + * Callback for asyncronous scripts */ static nserror -html_convert_script_callback(hlcache_handle *script, +convert_script_async_cb(hlcache_handle *script, const hlcache_event *event, void *pw) { @@ -213,7 +213,123 @@ html_convert_script_callback(hlcache_handle *script, return NSERROR_OK; } -/** process script node +/** + * process a script with a src tag + */ +static dom_hubbub_error +exec_src_script(html_content *c, + dom_node *node, + dom_string *mimetype, + dom_string *src) +{ + nserror ns_error; + nsurl *joined; + hlcache_child_context child; + struct html_script *nscript; + union content_msg_data msg_data; + + //exc = dom_element_has_attribute(node, html_dom_string_async, &async); + + nscript = html_process_new_script(c, HTML_STYLESHEET_EXTERNAL); + if (nscript == NULL) { + dom_string_unref(mimetype); + goto html_process_script_no_memory; + } + + /* charset (encoding) */ + ns_error = nsurl_join(c->base_url, dom_string_data(src), &joined); + if (ns_error != NSERROR_OK) { + dom_string_unref(mimetype); + goto html_process_script_no_memory; + } + + nscript->mimetype = mimetype; /* keep reference to mimetype */ + + LOG(("script %i '%s'", c->scripts_count, nsurl_access(joined))); + + child.charset = c->encoding; + child.quirks = c->base.quirks; + + ns_error = hlcache_handle_retrieve(joined, + 0, + content_get_url(&c->base), + NULL, + convert_script_async_cb, + c, + &child, + CONTENT_SCRIPT, + &nscript->data.external); + + nsurl_unref(joined); + + if (ns_error != NSERROR_OK) { + goto html_process_script_no_memory; + } + + c->base.active++; /* ensure base content knows the fetch is active */ + LOG(("%d fetches active", c->base.active)); + + html_scripts_exec(c); + + return DOM_HUBBUB_OK; + + +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 +exec_inline_script(html_content *c, dom_node *node, dom_string *mimetype) +{ + union content_msg_data msg_data; + dom_string *script; + dom_exception exc; /* returned by libdom functions */ + struct lwc_string_s *lwcmimetype; + script_handler_t *script_handler; + struct html_script *nscript; + + /* does not appear to be a src so script is inline content */ + exc = dom_node_get_text_content(node, &script); + if ((exc != DOM_NO_ERR) || (script == NULL)) { + dom_string_unref(mimetype); + return DOM_HUBBUB_OK; /* no contents, skip */ + } + + nscript = html_process_new_script(c, HTML_STYLESHEET_INTERNAL); + if (nscript == NULL) { + dom_string_unref(mimetype); + dom_string_unref(script); + + msg_data.error = messages_get("NoMemory"); + content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); + return DOM_HUBBUB_NOMEM; + + } + + nscript->data.internal = script; + nscript->mimetype = mimetype; + nscript->already_started = true; + + /* charset (encoding) */ + + /* ensure script handler for content type */ + dom_string_intern(mimetype, &lwcmimetype); + script_handler = select_script_handler(content_factory_type_from_mime_type(lwcmimetype)); + lwc_string_unref(lwcmimetype); + + if (script_handler != NULL) { + script_handler(c->jscontext, + dom_string_data(script), + dom_string_byte_length(script)); + } + return DOM_HUBBUB_OK; +} + + +/** + * process script node parser callback * * */ @@ -222,9 +338,8 @@ html_process_script(void *ctx, dom_node *node) { html_content *c = (html_content *)ctx; dom_exception exc; /* returned by libdom functions */ - dom_string *src, *script, *mimetype; - struct html_script *nscript; - union content_msg_data msg_data; + dom_string *src, *mimetype; + dom_hubbub_error err = DOM_HUBBUB_OK; /* ensure javascript context is available */ if (c->jscontext == NULL) { @@ -248,97 +363,11 @@ html_process_script(void *ctx, dom_node *node) exc = dom_element_get_attribute(node, corestring_dom_src, &src); if (exc != DOM_NO_ERR || src == NULL) { - struct lwc_string_s *lwcmimetype; - script_handler_t *script_handler; - - /* does not appear to be a src so script is inline content */ - exc = dom_node_get_text_content(node, &script); - if ((exc != DOM_NO_ERR) || (script == NULL)) { - dom_string_unref(mimetype); - return DOM_HUBBUB_OK; /* no contents, skip */ - } - - nscript = html_process_new_script(c, HTML_STYLESHEET_INTERNAL); - if (nscript == NULL) { - dom_string_unref(mimetype); - dom_string_unref(script); - goto html_process_script_no_memory; - } - - nscript->data.internal = script; - nscript->mimetype = mimetype; - nscript->already_started = true; - - /* charset (encoding) */ - - /* ensure script handler for content type */ - dom_string_intern(mimetype, &lwcmimetype); - script_handler = select_script_handler(content_factory_type_from_mime_type(lwcmimetype)); - lwc_string_unref(lwcmimetype); - - if (script_handler != NULL) { - script_handler(c->jscontext, - dom_string_data(script), - dom_string_byte_length(script)); - } - - + err = exec_inline_script(c, node, mimetype); } else { - /* script with a src tag */ - nserror ns_error; - nsurl *joined; - hlcache_child_context child; - - - nscript = html_process_new_script(c, HTML_STYLESHEET_EXTERNAL); - if (nscript == NULL) { - dom_string_unref(src); - dom_string_unref(mimetype); - goto html_process_script_no_memory; - } - - /* charset (encoding) */ - - ns_error = nsurl_join(c->base_url, dom_string_data(src), &joined); + err = exec_src_script(c, node, mimetype, src); dom_string_unref(src); - if (ns_error != NSERROR_OK) { - dom_string_unref(mimetype); - goto html_process_script_no_memory; - } - - nscript->mimetype = mimetype; /* keep reference to mimetype */ - - LOG(("script %i '%s'", c->scripts_count, nsurl_access(joined))); - - child.charset = c->encoding; - child.quirks = c->base.quirks; - - ns_error = hlcache_handle_retrieve(joined, - 0, - content_get_url(&c->base), - NULL, - html_convert_script_callback, - c, - &child, - CONTENT_SCRIPT, - &nscript->data.external); - - nsurl_unref(joined); - - if (ns_error != NSERROR_OK) { - goto html_process_script_no_memory; - } - - c->base.active++; /* ensure base content knows the fetch is active */ - LOG(("%d fetches active", c->base.active)); - } - html_scripts_exec(c); - - return DOM_HUBBUB_OK; -html_process_script_no_memory: - msg_data.error = messages_get("NoMemory"); - content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); - return DOM_HUBBUB_NOMEM; + return err; } ----------------------------------------------------------------------- -- NetSurf Browser _______________________________________________ netsurf-commits mailing list netsurf-commits@netsurf-browser.org http://vlists.pepperfish.net/cgi-bin/mailman/listinfo/netsurf-commits-netsurf-browser.org