Binding: Construct forms objects for a document
This commit is contained in:
parent
ea5a8ed771
commit
dc9100ba7c
|
@ -24,29 +24,45 @@
|
|||
|
||||
#include "utils/log.h"
|
||||
|
||||
typedef struct binding_ctx {
|
||||
dom_hubbub_parser *parser;
|
||||
dom_document *extracted;
|
||||
} binding_ctx;
|
||||
|
||||
binding_error binding_create_tree(void **ctx, const char *charset, bool enable_script, dom_script script, void *context)
|
||||
{
|
||||
dom_hubbub_parser *parser = NULL;
|
||||
binding_ctx *bctx = NULL;
|
||||
|
||||
bctx = calloc(sizeof(*bctx), 1);
|
||||
if (bctx == NULL) {
|
||||
LOG(("Can't allocate memory for binding context"));
|
||||
return BINDING_NOMEM;
|
||||
}
|
||||
|
||||
parser = dom_hubbub_parser_create(charset, true, enable_script, NULL, script, context);
|
||||
if (parser == NULL) {
|
||||
LOG(("Can't create Hubbub Parser\n"));
|
||||
return BINDING_NOMEM;
|
||||
}
|
||||
*ctx = parser;
|
||||
bctx->parser = parser;
|
||||
*ctx = bctx;
|
||||
return BINDING_OK;
|
||||
}
|
||||
|
||||
binding_error binding_destroy_tree(void *ctx)
|
||||
{
|
||||
dom_hubbub_parser_destroy(ctx);
|
||||
struct binding_ctx *bctx = ctx;
|
||||
dom_hubbub_parser_destroy(bctx->parser);
|
||||
free(bctx);
|
||||
return BINDING_OK;
|
||||
}
|
||||
|
||||
binding_error binding_parse_chunk(void *ctx, const uint8_t *data, size_t len)
|
||||
{
|
||||
struct binding_ctx *bctx = ctx;
|
||||
dom_hubbub_error error;
|
||||
error = dom_hubbub_parser_parse_chunk(ctx, data, len);
|
||||
error = dom_hubbub_parser_parse_chunk(bctx->parser, data, len);
|
||||
if (error == (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_ENCODINGCHANGE)) {
|
||||
return BINDING_ENCODINGCHANGE;
|
||||
} else if (error != DOM_HUBBUB_OK) {
|
||||
|
@ -57,8 +73,9 @@ binding_error binding_parse_chunk(void *ctx, const uint8_t *data, size_t len)
|
|||
|
||||
binding_error binding_parse_completed(void *ctx)
|
||||
{
|
||||
struct binding_ctx *bctx = ctx;
|
||||
dom_hubbub_error error;
|
||||
error = dom_hubbub_parser_completed(ctx);
|
||||
error = dom_hubbub_parser_completed(bctx->parser);
|
||||
if (error != DOM_HUBBUB_OK) {
|
||||
return BINDING_NOMEM;
|
||||
}
|
||||
|
@ -67,10 +84,11 @@ binding_error binding_parse_completed(void *ctx)
|
|||
|
||||
const char *binding_get_encoding(void *ctx, binding_encoding_source *source)
|
||||
{
|
||||
struct binding_ctx *bctx = ctx;
|
||||
dom_hubbub_encoding_source hubbub_src;
|
||||
const char *encoding;
|
||||
|
||||
encoding = dom_hubbub_parser_get_encoding(ctx, &hubbub_src);
|
||||
encoding = dom_hubbub_parser_get_encoding(bctx->parser, &hubbub_src);
|
||||
|
||||
switch (hubbub_src) {
|
||||
case DOM_HUBBUB_ENCODING_SOURCE_HEADER:
|
||||
|
@ -91,12 +109,153 @@ const char *binding_get_encoding(void *ctx, binding_encoding_source *source)
|
|||
|
||||
dom_document *binding_get_document(void *ctx, binding_quirks_mode *quirks)
|
||||
{
|
||||
return dom_hubbub_parser_get_document(ctx);
|
||||
struct binding_ctx *bctx = ctx;
|
||||
if (bctx->extracted == NULL)
|
||||
bctx->extracted = dom_hubbub_parser_get_document(bctx->parser);
|
||||
return bctx->extracted;
|
||||
}
|
||||
|
||||
static struct form *
|
||||
parse_form_element(dom_hubbub_parser *parser, dom_node *node)
|
||||
{
|
||||
dom_string *ds_action = NULL;
|
||||
dom_string *ds_charset = NULL;
|
||||
dom_string *ds_target = NULL;
|
||||
dom_string *ds_method = NULL;
|
||||
dom_string *ds_enctype = NULL;
|
||||
char *action = NULL, *charset = NULL, *target = NULL;
|
||||
form_method method;
|
||||
dom_html_form_element *formele = (dom_html_form_element *)(node);
|
||||
struct form * ret = NULL;
|
||||
const char *docenc;
|
||||
|
||||
/* Retrieve the attributes from the node */
|
||||
if (dom_html_form_element_get_action(formele, &ds_action) != DOM_NO_ERR)
|
||||
goto out;
|
||||
|
||||
if (dom_html_form_element_get_accept_charset(formele, &ds_charset) != DOM_NO_ERR)
|
||||
goto out;
|
||||
|
||||
if (dom_html_form_element_get_target(formele, &ds_target) != DOM_NO_ERR)
|
||||
goto out;
|
||||
|
||||
if (dom_html_form_element_get_method(formele, &ds_method) != DOM_NO_ERR)
|
||||
goto out;
|
||||
|
||||
if (dom_html_form_element_get_enctype(formele, &ds_enctype) != DOM_NO_ERR)
|
||||
goto out;
|
||||
|
||||
/* Extract the plain attributes ready for use. We have to do this
|
||||
* because we cannot guarantee that the dom_strings are NULL terminated
|
||||
* and thus we copy them.
|
||||
*/
|
||||
if (ds_action != NULL)
|
||||
action = strndup(dom_string_data(ds_action),
|
||||
dom_string_byte_length(ds_action));
|
||||
|
||||
if (ds_charset != NULL)
|
||||
charset = strndup(dom_string_data(ds_charset),
|
||||
dom_string_byte_length(ds_charset));
|
||||
|
||||
if (ds_target != NULL)
|
||||
target = strndup(dom_string_data(ds_target),
|
||||
dom_string_byte_length(ds_target));
|
||||
|
||||
/* Determine the method */
|
||||
method = method_GET;
|
||||
if (ds_method != NULL) {
|
||||
if (strncasecmp("post", dom_string_data(ds_method),
|
||||
dom_string_byte_length(ds_method)) == 0) {
|
||||
method = method_POST_URLENC;
|
||||
if (ds_enctype != NULL) {
|
||||
if (strncasecmp("multipart/form-data",
|
||||
dom_string_data(ds_enctype),
|
||||
dom_string_byte_length(ds_enctype)) == 0) {
|
||||
method = method_POST_MULTIPART;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Retrieve the document encoding */
|
||||
{
|
||||
dom_hubbub_encoding_source hubbub_src;
|
||||
docenc = dom_hubbub_parser_get_encoding(parser, &hubbub_src);
|
||||
}
|
||||
|
||||
/* Construct the form object */
|
||||
ret = form_new(node, action, target, method, charset, docenc);
|
||||
|
||||
out:
|
||||
if (ds_action != NULL)
|
||||
dom_string_unref(ds_action);
|
||||
if (ds_charset != NULL)
|
||||
dom_string_unref(ds_charset);
|
||||
if (ds_target != NULL)
|
||||
dom_string_unref(ds_target);
|
||||
if (ds_method != NULL)
|
||||
dom_string_unref(ds_method);
|
||||
if (ds_enctype != NULL)
|
||||
dom_string_unref(ds_enctype);
|
||||
if (action != NULL)
|
||||
free(action);
|
||||
if (charset != NULL)
|
||||
free(charset);
|
||||
if (target != NULL)
|
||||
free(charset);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct form *binding_get_forms(void *ctx)
|
||||
{
|
||||
return NULL;
|
||||
binding_ctx *bctx = ctx;
|
||||
binding_quirks_mode ignored;
|
||||
dom_html_document *doc =
|
||||
(dom_html_document *)binding_get_document(ctx, &ignored);
|
||||
dom_html_collection *forms;
|
||||
struct form *ret = NULL, *newf;
|
||||
dom_node *node;
|
||||
unsigned long nforms, n;
|
||||
|
||||
if (doc == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Attempt to build a set of all the forms */
|
||||
if (dom_html_document_get_forms(doc, &forms) != DOM_NO_ERR)
|
||||
return NULL;
|
||||
|
||||
/* Count the number of forms so we can iterate */
|
||||
if (dom_html_collection_get_length(forms, &nforms) != DOM_NO_ERR)
|
||||
goto out;
|
||||
|
||||
/* Iterate the forms collection, making form structs for returning */
|
||||
for (n = 0; n < nforms; ++n) {
|
||||
if (dom_html_collection_item(forms, n, &node) != DOM_NO_ERR) {
|
||||
goto out;
|
||||
}
|
||||
newf = parse_form_element(bctx->parser, node);
|
||||
dom_node_unref(node);
|
||||
if (newf == NULL) {
|
||||
goto err;
|
||||
}
|
||||
newf->prev = ret;
|
||||
ret = newf;
|
||||
}
|
||||
|
||||
/* All went well */
|
||||
goto out;
|
||||
err:
|
||||
while (ret != NULL) {
|
||||
struct form *prev = ret->prev;
|
||||
/* Destroy ret */
|
||||
free(ret);
|
||||
ret = prev;
|
||||
}
|
||||
out:
|
||||
/* Finished with the collection, return it */
|
||||
dom_html_collection_unref(forms);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct form_control *binding_get_control_for_node(void *ctx, dom_node *node)
|
||||
|
|
Loading…
Reference in New Issue