extend html data processing to deal with paused parse

This commit is contained in:
Vincent Sanders 2012-07-30 15:17:57 +01:00 committed by Vincent Sanders
parent db76dd3b1a
commit b0a41606ff
2 changed files with 72 additions and 47 deletions

View File

@ -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);

View File

@ -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