summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.sources3
-rw-r--r--render/box_construct.c8
-rw-r--r--render/html.c2
-rw-r--r--render/html_forms.c458
-rw-r--r--render/html_internal.h4
-rw-r--r--render/libdom_binding.c474
6 files changed, 484 insertions, 465 deletions
diff --git a/Makefile.sources b/Makefile.sources
index 3dcec40a3..613d700ea 100644
--- a/Makefile.sources
+++ b/Makefile.sources
@@ -12,7 +12,8 @@ S_FETCHERS := curl.c data.c file.c about.c resource.c
S_CSS := css.c dump.c internal.c select.c utils.c
S_RENDER := box.c box_construct.c box_normalise.c \
- font.c form.c html.c html_interaction.c html_redraw.c \
+ font.c form.c \
+ html.c html_interaction.c html_redraw.c html_forms.c \
libdom_binding.c imagemap.c layout.c list.c search.c table.c \
textinput.c textplain.c
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 <vince@netsurf-browser.org>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#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;
}