From 6ab102c3b10b2c5934497b06978e25c656c6e19a Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sat, 14 Jul 2012 11:16:37 -0600 Subject: Rework form acessors to deal with binding changes --- render/box_construct.c | 8 +- render/html.c | 2 +- render/html_forms.c | 458 ++++++++++++++++++++++++++++++++++++++++++++++ render/html_internal.h | 4 + render/libdom_binding.c | 474 ++---------------------------------------------- 5 files changed, 482 insertions(+), 464 deletions(-) create mode 100644 render/html_forms.c (limited to 'render') diff --git a/render/box_construct.c b/render/box_construct.c index b860795b5..c09563d89 100644 --- a/render/box_construct.c +++ b/render/box_construct.c @@ -2471,7 +2471,7 @@ bool box_input(BOX_SPECIAL_PARAMS) dom_element_get_attribute(n, kstr_type, &type); - gadget = binding_get_control_for_node(content->parser_binding, n); + gadget = html_forms_get_control_for_node(content->forms, n); if (gadget == NULL) goto no_memory; box->gadget = gadget; @@ -2638,7 +2638,7 @@ bool box_button(BOX_SPECIAL_PARAMS) { struct form_control *gadget; - gadget = binding_get_control_for_node(content->parser_binding, n); + gadget = html_forms_get_control_for_node(content->forms, n); if (!gadget) return false; @@ -2666,7 +2666,7 @@ bool box_select(BOX_SPECIAL_PARAMS) dom_node *next, *next2; dom_exception err; - gadget = binding_get_control_for_node(content->parser_binding, n); + gadget = html_forms_get_control_for_node(content->forms, n); if (gadget == NULL) return false; @@ -2879,7 +2879,7 @@ bool box_textarea(BOX_SPECIAL_PARAMS) size_t len; box->type = BOX_INLINE_BLOCK; - box->gadget = binding_get_control_for_node(content->parser_binding, n); + box->gadget = html_forms_get_control_for_node(content->forms, n); if (box->gadget == NULL) return false; box->gadget->box = box; diff --git a/render/html.c b/render/html.c index 495cd7dab..996bfc3a5 100644 --- a/render/html.c +++ b/render/html.c @@ -2348,7 +2348,7 @@ static bool html_convert(struct content *c) } /* Retrieve forms from parser */ - htmlc->forms = binding_get_forms(htmlc->parser_binding); + htmlc->forms = html_forms_get_forms(htmlc->encoding, htmlc->document); for (f = htmlc->forms; f != NULL; f = f->prev) { char *action; url_func_result res; diff --git a/render/html_forms.c b/render/html_forms.c new file mode 100644 index 000000000..626fe4c0e --- /dev/null +++ b/render/html_forms.c @@ -0,0 +1,458 @@ +/* + * Copyright 2011 Vincent Sanders + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "render/form.h" +#include "render/html_internal.h" + +#include "utils/log.h" + +/** + * process form element from dom + */ +static struct form * +parse_form_element(const char *docenc, 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; + + /* 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; + } + } + } + } + + /* 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; +} + +/* documented in html_internal.h */ +struct form *html_forms_get_forms(const char *docenc, dom_html_document *doc) +{ + 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(docenc, 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; +} + +static struct form * +find_form(struct form *forms, dom_html_form_element *form) +{ + while (forms != NULL) { + if (forms->node == form) + break; + forms = forms->prev; + } + + return forms; +} + +static struct form_control * +parse_button_element(struct form *forms, dom_html_button_element *button) +{ + struct form_control *control = NULL; + dom_exception err; + dom_html_form_element *form = NULL; + dom_string *ds_type = NULL; + dom_string *ds_value = NULL; + dom_string *ds_name = NULL; + char *type = NULL; + + err = dom_html_button_element_get_form(button, &form); + if (err != DOM_NO_ERR) + goto out; + + err = dom_html_button_element_get_type(button, &ds_type); + if (err != DOM_NO_ERR) + goto out; + + if (ds_type == NULL) { + control = form_new_control(button, GADGET_SUBMIT); + } else { + type = strndup(dom_string_data(ds_type), + dom_string_byte_length(ds_type)); + if (strcasecmp(type, "submit") == 0) { + control = form_new_control(button, GADGET_SUBMIT); + } else if (strcasecmp(type, "reset") == 0) { + control = form_new_control(button, GADGET_RESET); + } else { + control = form_new_control(button, GADGET_BUTTON); + } + } + + if (control == NULL) + goto out; + + err = dom_html_button_element_get_value(button, &ds_value); + if (err != DOM_NO_ERR) + goto out; + err = dom_html_button_element_get_name(button, &ds_name); + if (err != DOM_NO_ERR) + goto out; + + if (ds_value != NULL) { + control->value = strndup( + dom_string_data(ds_value), + dom_string_byte_length(ds_value)); + + if (control->value == NULL) { + form_free_control(control); + control = NULL; + goto out; + } + } + + if (ds_name != NULL) { + control->name = strndup( + dom_string_data(ds_name), + dom_string_byte_length(ds_name)); + + if (control->name == NULL) { + form_free_control(control); + control = NULL; + goto out; + } + } + + if (form != NULL && control != NULL) + form_add_control(find_form(forms, form), control); + +out: + if (form != NULL) + dom_node_unref(form); + if (ds_type != NULL) + dom_string_unref(ds_type); + if (ds_value != NULL) + dom_string_unref(ds_value); + if (ds_name != NULL) + dom_string_unref(ds_name); + if (type == NULL) + free(type); + + return control; +} + +static struct form_control * +parse_input_element(struct form *forms, dom_html_input_element *input) +{ + struct form_control *control; + dom_html_form_element *form = NULL; + dom_string *ds_type = NULL; + dom_string *ds_name = NULL; + dom_string *ds_value = NULL; + + char *type = NULL; + char *name = NULL; + + if (dom_html_input_element_get_form(input, &form) != DOM_NO_ERR) + goto out; + + if (dom_html_input_element_get_type(input, &ds_type) != DOM_NO_ERR) + goto out; + + if (ds_type != NULL) + type = strndup(dom_string_data(ds_type), + dom_string_byte_length(ds_type)); + + if (dom_html_input_element_get_name(input, &ds_name) != DOM_NO_ERR) + goto out; + + if (ds_name != NULL) + name = strndup(dom_string_data(ds_name), + dom_string_byte_length(ds_name)); + + if (type != NULL && strcasecmp(type, "password") == 0) { + control = form_new_control(input, GADGET_PASSWORD); + } else if (type != NULL && strcasecmp(type, "file") == 0) { + control = form_new_control(input, GADGET_FILE); + } else if (type != NULL && strcasecmp(type, "hidden") == 0) { + control = form_new_control(input, GADGET_HIDDEN); + } else if (type != NULL && strcasecmp(type, "checkbox") == 0) { + control = form_new_control(input, GADGET_CHECKBOX); + } else if (type != NULL && strcasecmp(type, "radio") == 0) { + control = form_new_control(input, GADGET_RADIO); + } else if (type != NULL && strcasecmp(type, "submit") == 0) { + control = form_new_control(input, GADGET_SUBMIT); + } else if (type != NULL && strcasecmp(type, "reset") == 0) { + control = form_new_control(input, GADGET_RESET); + } else if (type != NULL && strcasecmp(type, "button") == 0) { + control = form_new_control(input, GADGET_BUTTON); + } else if (type != NULL && strcasecmp(type, "image") == 0) { + control = form_new_control(input, GADGET_IMAGE); + } else { + control = form_new_control(input, GADGET_TEXTBOX); + } + + if (control == NULL) + goto out; + + if (name != NULL) { + /* Hand the name string over */ + control->name = name; + name = NULL; + } + + if (control->type == GADGET_CHECKBOX || control->type == GADGET_RADIO) { + bool selected; + if (dom_html_input_element_get_checked( + input, &selected) == DOM_NO_ERR) { + control->selected = selected; + } + } + + if (control->type == GADGET_PASSWORD || + control->type == GADGET_TEXTBOX) { + unsigned long maxlength; + if (dom_html_input_element_get_max_length( + input, &maxlength) == DOM_NO_ERR) { + control->maxlength = maxlength; + } + } + + if (control->type != GADGET_FILE && control->type != GADGET_IMAGE) { + if (dom_html_input_element_get_value( + input, &ds_value) == DOM_NO_ERR) { + if (ds_value != NULL) { + control->value = strndup( + dom_string_data(ds_value), + dom_string_byte_length(ds_value)); + if (control->value == NULL) { + form_free_control(control); + control = NULL; + goto out; + } + control->length = strlen(control->value); + } + } + + if (control->type == GADGET_TEXTBOX || + control->type == GADGET_PASSWORD) { + if (control->value == NULL) { + control->value = strdup(""); + if (control->value == NULL) { + form_free_control(control); + control = NULL; + goto out; + } + + control->length = 0; + } + + control->initial_value = strdup(control->value); + if (control->initial_value == NULL) { + form_free_control(control); + control = NULL; + goto out; + } + } + } + + if (form != NULL && control != NULL) + form_add_control(find_form(forms, form), control); + +out: + if (form != NULL) + dom_node_unref(form); + if (ds_type != NULL) + dom_string_unref(ds_type); + if (ds_name != NULL) + dom_string_unref(ds_name); + if (ds_value != NULL) + dom_string_unref(ds_value); + + if (type != NULL) + free(type); + if (name != NULL) + free(name); + + return control; +} + +static struct form_control * +invent_fake_gadget(dom_node *node) +{ + struct form_control *ctl = form_new_control(node, GADGET_HIDDEN); + if (ctl != NULL) { + ctl->value = strdup(""); + ctl->initial_value = strdup(""); + ctl->name = strdup("foo"); + + if (ctl->value == NULL || ctl->initial_value == NULL || + ctl->name == NULL) { + form_free_control(ctl); + ctl = NULL; + } + } + return ctl; +} + +/* documented in html_internal.h */ +struct form_control *html_forms_get_control_for_node(struct form *forms, dom_node *node) +{ + struct form *f; + struct form_control *ctl = NULL; + dom_exception err; + dom_string *ds_name = NULL; + char *node_name = NULL; + + if (forms == NULL) + return NULL; + + /* Step one, see if we already have a control */ + for (f = forms; f != NULL; f = f->prev) { + for (ctl = f->controls; ctl != NULL; ctl = ctl->next) { + if (ctl->node == node) + return ctl; + } + } + + /* Step two, extract the node's name so we can construct a gadget. */ + err = dom_element_get_tag_name(node, &ds_name); + if (err == DOM_NO_ERR && ds_name != NULL) { + node_name = strndup(dom_string_data(ds_name), + dom_string_byte_length(ds_name)); + } + + /* Step three, attempt to work out what gadget to make */ + + if (node_name && strcasecmp(node_name, "button") == 0) + ctl = parse_button_element(forms, + (dom_html_button_element *) node); + else if (node_name && strcasecmp(node_name, "input") == 0) + ctl = parse_input_element(forms, + (dom_html_input_element *) node); + + /* If all else fails, fake gadget time */ + if (ctl == NULL) + ctl = invent_fake_gadget(node); + + if (ds_name != NULL) + dom_string_unref(ds_name); + if (node_name != NULL) + free(node_name); + return ctl; +} + diff --git a/render/html_internal.h b/render/html_internal.h index da3d686bd..d5e1f05f3 100644 --- a/render/html_internal.h +++ b/render/html_internal.h @@ -140,6 +140,10 @@ void html_mouse_action(struct content *c, struct browser_window *bw, void html_overflow_scroll_callback(void *client_data, struct scrollbar_msg_data *scrollbar_data); +/* in render/html_forms.c */ +struct form *html_forms_get_forms(const char *docenc, dom_html_document *doc); +struct form_control *html_forms_get_control_for_node(struct form *forms, dom_node *node); + /* Useful dom_string pointers */ struct dom_string; diff --git a/render/libdom_binding.c b/render/libdom_binding.c index 638fa6fce..9ae76469c 100644 --- a/render/libdom_binding.c +++ b/render/libdom_binding.c @@ -24,46 +24,29 @@ #include "utils/log.h" -typedef struct binding_ctx { - dom_hubbub_parser *parser; - dom_document *extracted; - struct form *forms; -} 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; - } - bctx->parser = parser; - *ctx = bctx; + if (parser == NULL) { + LOG(("Can't create Hubbub Parser\n")); + return BINDING_NOMEM; + } + *ctx = parser; return BINDING_OK; } binding_error binding_destroy_tree(void *ctx) { - struct binding_ctx *bctx = ctx; - dom_hubbub_parser_destroy(bctx->parser); - free(bctx); + dom_hubbub_parser_destroy(ctx); 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(bctx->parser, data, len); + error = dom_hubbub_parser_parse_chunk(ctx, data, len); if (error == (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_ENCODINGCHANGE)) { return BINDING_ENCODINGCHANGE; } else if (error != DOM_HUBBUB_OK) { @@ -74,22 +57,20 @@ 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(bctx->parser); - if (error != DOM_HUBBUB_OK) { + error = dom_hubbub_parser_completed(ctx); + if (error != DOM_HUBBUB_OK) { return BINDING_NOMEM; - } + } return BINDING_OK; } 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(bctx->parser, &hubbub_src); + encoding = dom_hubbub_parser_get_encoding(ctx, &hubbub_src); switch (hubbub_src) { case DOM_HUBBUB_ENCODING_SOURCE_HEADER: @@ -110,396 +91,17 @@ const char *binding_get_encoding(void *ctx, binding_encoding_source *source) dom_document *binding_get_document(void *ctx, binding_quirks_mode *quirks) { - 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; + return dom_hubbub_parser_get_document(ctx); } struct form *binding_get_forms(void *ctx) { - 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 (bctx->forms != NULL) - return bctx->forms; - - 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); - - bctx->forms = ret; - - return ret; -} - -static struct form * -find_form(struct form *forms, dom_html_form_element *form) -{ - while (forms != NULL) { - if (forms->node == form) - break; - forms = forms->prev; - } - - return forms; + return NULL; } -static struct form_control * -parse_button_element(struct form *forms, dom_html_button_element *button) -{ - struct form_control *control = NULL; - dom_exception err; - dom_html_form_element *form = NULL; - dom_string *ds_type = NULL; - dom_string *ds_value = NULL; - dom_string *ds_name = NULL; - char *type = NULL; - - err = dom_html_button_element_get_form(button, &form); - if (err != DOM_NO_ERR) - goto out; - - err = dom_html_button_element_get_type(button, &ds_type); - if (err != DOM_NO_ERR) - goto out; - - if (ds_type == NULL) { - control = form_new_control(button, GADGET_SUBMIT); - } else { - type = strndup(dom_string_data(ds_type), - dom_string_byte_length(ds_type)); - if (strcasecmp(type, "submit") == 0) { - control = form_new_control(button, GADGET_SUBMIT); - } else if (strcasecmp(type, "reset") == 0) { - control = form_new_control(button, GADGET_RESET); - } else { - control = form_new_control(button, GADGET_BUTTON); - } - } - - if (control == NULL) - goto out; - - err = dom_html_button_element_get_value(button, &ds_value); - if (err != DOM_NO_ERR) - goto out; - err = dom_html_button_element_get_name(button, &ds_name); - if (err != DOM_NO_ERR) - goto out; - - if (ds_value != NULL) { - control->value = strndup( - dom_string_data(ds_value), - dom_string_byte_length(ds_value)); - - if (control->value == NULL) { - form_free_control(control); - control = NULL; - goto out; - } - } - - if (ds_name != NULL) { - control->name = strndup( - dom_string_data(ds_name), - dom_string_byte_length(ds_name)); - - if (control->name == NULL) { - form_free_control(control); - control = NULL; - goto out; - } - } - - if (form != NULL && control != NULL) - form_add_control(find_form(forms, form), control); - -out: - if (form != NULL) - dom_node_unref(form); - if (ds_type != NULL) - dom_string_unref(ds_type); - if (ds_value != NULL) - dom_string_unref(ds_value); - if (ds_name != NULL) - dom_string_unref(ds_name); - if (type == NULL) - free(type); - - return control; -} - -static struct form_control * -parse_input_element(struct form *forms, dom_html_input_element *input) -{ - struct form_control *control; - dom_html_form_element *form = NULL; - dom_string *ds_type = NULL; - dom_string *ds_name = NULL; - dom_string *ds_value = NULL; - - char *type = NULL; - char *name = NULL; - - if (dom_html_input_element_get_form(input, &form) != DOM_NO_ERR) - goto out; - - if (dom_html_input_element_get_type(input, &ds_type) != DOM_NO_ERR) - goto out; - - if (ds_type != NULL) - type = strndup(dom_string_data(ds_type), - dom_string_byte_length(ds_type)); - - if (dom_html_input_element_get_name(input, &ds_name) != DOM_NO_ERR) - goto out; - - if (ds_name != NULL) - name = strndup(dom_string_data(ds_name), - dom_string_byte_length(ds_name)); - - if (type != NULL && strcasecmp(type, "password") == 0) { - control = form_new_control(input, GADGET_PASSWORD); - } else if (type != NULL && strcasecmp(type, "file") == 0) { - control = form_new_control(input, GADGET_FILE); - } else if (type != NULL && strcasecmp(type, "hidden") == 0) { - control = form_new_control(input, GADGET_HIDDEN); - } else if (type != NULL && strcasecmp(type, "checkbox") == 0) { - control = form_new_control(input, GADGET_CHECKBOX); - } else if (type != NULL && strcasecmp(type, "radio") == 0) { - control = form_new_control(input, GADGET_RADIO); - } else if (type != NULL && strcasecmp(type, "submit") == 0) { - control = form_new_control(input, GADGET_SUBMIT); - } else if (type != NULL && strcasecmp(type, "reset") == 0) { - control = form_new_control(input, GADGET_RESET); - } else if (type != NULL && strcasecmp(type, "button") == 0) { - control = form_new_control(input, GADGET_BUTTON); - } else if (type != NULL && strcasecmp(type, "image") == 0) { - control = form_new_control(input, GADGET_IMAGE); - } else { - control = form_new_control(input, GADGET_TEXTBOX); - } - - if (control == NULL) - goto out; - - if (name != NULL) { - /* Hand the name string over */ - control->name = name; - name = NULL; - } - - if (control->type == GADGET_CHECKBOX || control->type == GADGET_RADIO) { - bool selected; - if (dom_html_input_element_get_checked( - input, &selected) == DOM_NO_ERR) { - control->selected = selected; - } - } - - if (control->type == GADGET_PASSWORD || - control->type == GADGET_TEXTBOX) { - unsigned long maxlength; - if (dom_html_input_element_get_max_length( - input, &maxlength) == DOM_NO_ERR) { - control->maxlength = maxlength; - } - } - - if (control->type != GADGET_FILE && control->type != GADGET_IMAGE) { - if (dom_html_input_element_get_value( - input, &ds_value) == DOM_NO_ERR) { - if (ds_value != NULL) { - control->value = strndup( - dom_string_data(ds_value), - dom_string_byte_length(ds_value)); - if (control->value == NULL) { - form_free_control(control); - control = NULL; - goto out; - } - control->length = strlen(control->value); - } - } - - if (control->type == GADGET_TEXTBOX || - control->type == GADGET_PASSWORD) { - if (control->value == NULL) { - control->value = strdup(""); - if (control->value == NULL) { - form_free_control(control); - control = NULL; - goto out; - } - - control->length = 0; - } - - control->initial_value = strdup(control->value); - if (control->initial_value == NULL) { - form_free_control(control); - control = NULL; - goto out; - } - } - } - - if (form != NULL && control != NULL) - form_add_control(find_form(forms, form), control); - -out: - if (form != NULL) - dom_node_unref(form); - if (ds_type != NULL) - dom_string_unref(ds_type); - if (ds_name != NULL) - dom_string_unref(ds_name); - if (ds_value != NULL) - dom_string_unref(ds_value); - - if (type != NULL) - free(type); - if (name != NULL) - free(name); - - return control; -} - -static struct form_control * -invent_fake_gadget(dom_node *node) +struct form_control *binding_get_control_for_node(void *ctx, dom_node *node) { + /** \todo implement properly */ struct form_control *ctl = form_new_control(node, GADGET_HIDDEN); if (ctl != NULL) { ctl->value = strdup(""); @@ -512,53 +114,7 @@ invent_fake_gadget(dom_node *node) ctl = NULL; } } - return ctl; -} - -struct form_control *binding_get_control_for_node(void *ctx, dom_node *node) -{ - struct form *f; - struct form_control *ctl = NULL; - dom_exception err; - dom_string *ds_name = NULL; - char *node_name = NULL; - binding_ctx *bctx = ctx; - - if (bctx->forms == NULL) - return NULL; - - /* Step one, see if we already have a control */ - for (f = bctx->forms; f != NULL; f = f->prev) { - for (ctl = f->controls; ctl != NULL; ctl = ctl->next) { - if (ctl->node == node) - return ctl; - } - } - - /* Step two, extract the node's name so we can construct a gadget. */ - err = dom_element_get_tag_name(node, &ds_name); - if (err == DOM_NO_ERR && ds_name != NULL) { - node_name = strndup(dom_string_data(ds_name), - dom_string_byte_length(ds_name)); - } - - /* Step three, attempt to work out what gadget to make */ - - if (node_name && strcasecmp(node_name, "button") == 0) - ctl = parse_button_element(bctx->forms, - (dom_html_button_element *) node); - else if (node_name && strcasecmp(node_name, "input") == 0) - ctl = parse_input_element(bctx->forms, - (dom_html_input_element *) node); - - /* If all else fails, fake gadget time */ - if (ctl == NULL) - ctl = invent_fake_gadget(node); - if (ds_name != NULL) - dom_string_unref(ds_name); - if (node_name != NULL) - free(node_name); return ctl; } -- cgit v1.2.3