summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.sources2
-rw-r--r--css/select.c1
-rw-r--r--javascript/jsapi/document.c6
-rw-r--r--render/box_construct.c27
-rw-r--r--render/html.c195
-rw-r--r--render/html.h13
-rw-r--r--render/html_internal.h6
-rw-r--r--render/html_script.c2
-rw-r--r--render/hubbub_binding.c1325
-rw-r--r--render/libdom_binding.c126
-rw-r--r--render/parser_binding.h63
11 files changed, 138 insertions, 1628 deletions
diff --git a/Makefile.sources b/Makefile.sources
index f76ba0904..9a4d8c59a 100644
--- a/Makefile.sources
+++ b/Makefile.sources
@@ -14,7 +14,7 @@ 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_script.c html_interaction.c html_redraw.c \
- libdom_binding.c imagemap.c layout.c list.c search.c table.c \
+ imagemap.c layout.c list.c search.c table.c \
textinput.c textplain.c
S_UTILS := base64.c filename.c hashtable.c locale.c messages.c nsurl.c \
diff --git a/css/select.c b/css/select.c
index 026aedc7c..1ea818f0e 100644
--- a/css/select.c
+++ b/css/select.c
@@ -28,7 +28,6 @@
#include "css/utils.h"
#include "desktop/gui.h"
#include "desktop/options.h"
-#include "render/parser_binding.h"
#include "utils/log.h"
#include "utils/url.h"
#include "utils/utils.h"
diff --git a/javascript/jsapi/document.c b/javascript/jsapi/document.c
index 7d4ebc543..dfad551d6 100644
--- a/javascript/jsapi/document.c
+++ b/javascript/jsapi/document.c
@@ -56,9 +56,9 @@ static JSBool JSAPI_NATIVE(write, JSContext *cx, uintN argc, jsval *vp)
JSString_to_char(u16_txt, txt, length);
- LOG(("content %p parser %p writing %s",htmlc, htmlc->parser_binding, txt));
- if (htmlc->parser_binding != NULL) {
- dom_hubbub_parser_insert_chunk(htmlc->parser_binding, (uint8_t *)txt, length);
+ LOG(("content %p parser %p writing %s",htmlc, htmlc->parser, txt));
+ if (htmlc->parser != NULL) {
+ dom_hubbub_parser_insert_chunk(htmlc->parser, (uint8_t *)txt, length);
}
JSAPI_SET_RVAL(cx, vp, JSVAL_VOID);
diff --git a/render/box_construct.c b/render/box_construct.c
index c62f4390d..0776a7e86 100644
--- a/render/box_construct.c
+++ b/render/box_construct.c
@@ -146,6 +146,25 @@ static const struct element_entry element_table[] = {
};
#define ELEMENT_TABLE_COUNT (sizeof(element_table) / sizeof(element_table[0]))
+static 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("");
+ 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;
+}
+
/**
* Construct a box tree from an xml tree and stylesheets.
*
@@ -2471,7 +2490,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 = binding_get_control_for_node(content->parser, n);
if (gadget == NULL)
goto no_memory;
box->gadget = gadget;
@@ -2638,7 +2657,7 @@ bool box_button(BOX_SPECIAL_PARAMS)
{
struct form_control *gadget;
- gadget = binding_get_control_for_node(content->parser_binding, n);
+ gadget = binding_get_control_for_node(content->parser, n);
if (!gadget)
return false;
@@ -2666,7 +2685,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 = binding_get_control_for_node(content->parser, n);
if (gadget == NULL)
return false;
@@ -2879,7 +2898,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 = binding_get_control_for_node(content->parser, n);
if (box->gadget == NULL)
return false;
box->gadget->box = box;
diff --git a/render/html.c b/render/html.c
index bb6748a73..015b5b9ae 100644
--- a/render/html.c
+++ b/render/html.c
@@ -28,8 +28,6 @@
#include <strings.h>
#include <stdlib.h>
-#include <dom/dom.h>
-
#include "utils/config.h"
#include "content/content_protected.h"
#include "content/fetch.h"
@@ -191,8 +189,8 @@ static void html_box_convert_done(html_content *c, bool success)
/*imagemap_dump(c);*/
/* Destroy the parser binding */
- binding_destroy_tree(c->parser_binding);
- c->parser_binding = NULL;
+ dom_hubbub_parser_destroy(c->parser);
+ c->parser = NULL;
content_set_ready(&c->base);
@@ -304,10 +302,9 @@ html_create_html_data(html_content *c, const http_parameter *params)
{
lwc_string *charset;
union content_msg_data msg_data;
- binding_error error;
nserror nerror;
- c->parser_binding = NULL;
+ c->parser = NULL;
c->document = NULL;
c->quirks = BINDING_QUIRKS_MODE_NONE;
c->encoding = NULL;
@@ -336,8 +333,10 @@ html_create_html_data(html_content *c, const http_parameter *params)
c->jscontext = NULL;
if (lwc_intern_string("*", SLEN("*"), &c->universal) != lwc_error_ok) {
- error = BINDING_NOMEM;
- goto error;
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
+
+ return NSERROR_NOMEM;
}
selection_prepare(&c->sel, (struct content *)c, true);
@@ -349,60 +348,56 @@ html_create_html_data(html_content *c, const http_parameter *params)
lwc_string_unref(charset);
if (c->encoding == NULL) {
- error = BINDING_NOMEM;
- goto error;
+ lwc_string_unref(c->universal);
+ c->universal = NULL;
+
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
+
+ return NSERROR_NOMEM;
+
}
- c->encoding_source = ENCODING_SOURCE_HEADER;
+ c->encoding_source = DOM_HUBBUB_ENCODING_SOURCE_HEADER;
}
/* Create the parser binding */
- error = binding_create_tree(&c->parser_binding,
- c->encoding,
- nsoption_bool(enable_javascript),
- html_process_script,
- c);
- if (error == BINDING_BADENCODING && c->encoding != NULL) {
+ c->parser = dom_hubbub_parser_create(c->encoding,
+ true,
+ nsoption_bool(enable_javascript),
+ NULL,
+ html_process_script,
+ c);
+ if ((c->parser == NULL) && (c->encoding != NULL)) {
/* Ok, we don't support the declared encoding. Bailing out
* isn't exactly user-friendly, so fall back to autodetect */
talloc_free(c->encoding);
c->encoding = NULL;
- error = binding_create_tree(&c->parser_binding,
- c->encoding,
- nsoption_bool(enable_javascript),
- html_process_script,
- c);
+ c->parser = dom_hubbub_parser_create(c->encoding,
+ true,
+ nsoption_bool(enable_javascript),
+ NULL,
+ html_process_script,
+ c);
- }
- if (error != BINDING_OK)
- goto error;
-
- return NSERROR_OK;
-
-error:
- if (error == BINDING_BADENCODING) {
- LOG(("Bad encoding: %s", c->encoding ? c->encoding : ""));
- msg_data.error = messages_get("ParsingFail");
- nerror = NSERROR_BAD_ENCODING;
- } else {
- msg_data.error = messages_get("NoMemory");
- nerror = NSERROR_NOMEM;
}
- content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
+ if (c->parser == NULL) {
+ nsurl_unref(c->base_url);
+ c->base_url = NULL;
- if (c->universal != NULL) {
lwc_string_unref(c->universal);
c->universal = NULL;
- }
- if (c->base_url != NULL) {
- nsurl_unref(c->base_url);
- c->base_url = NULL;
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
+
+ return NSERROR_NOMEM;
}
- return nerror;
+ return NSERROR_OK;
+
}
/**
@@ -456,14 +451,16 @@ static bool
html_process_data(struct content *c, const char *data, unsigned int size)
{
html_content *html = (html_content *) c;
- binding_error err;
+ dom_hubbub_error error;
const char *encoding;
+ const char *source_data;
+ unsigned long source_size;
- err = binding_parse_chunk(html->parser_binding,
- (const uint8_t *) data, size);
- if (err == BINDING_ENCODINGCHANGE) {
+ 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 (err != BINDING_OK) {
+ } else if (error != DOM_HUBBUB_OK) {
union content_msg_data msg_data;
msg_data.error = messages_get("NoMemory");
@@ -477,9 +474,8 @@ html_process_data(struct content *c, const char *data, unsigned int size)
encoding_change:
/* Retrieve new encoding */
- encoding = binding_get_encoding(
- html->parser_binding,
- &html->encoding_source);
+ encoding = dom_hubbub_parser_get_encoding(html->parser,
+ &html->encoding_source);
if (html->encoding != NULL)
talloc_free(html->encoding);
@@ -494,16 +490,17 @@ encoding_change:
}
/* Destroy binding */
- binding_destroy_tree(html->parser_binding);
- html->parser_binding = NULL;
+ dom_hubbub_parser_destroy(html->parser);
+ html->parser = NULL;
/* Create new binding, using the new encoding */
- err = binding_create_tree(&html->parser_binding,
- html->encoding,
- nsoption_bool(enable_javascript),
- html_process_script,
- html);
- if (err == BINDING_BADENCODING) {
+ html->parser = dom_hubbub_parser_create(html->encoding,
+ 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 */
talloc_free(html->encoding);
@@ -516,37 +513,35 @@ encoding_change:
return false;
}
- err = binding_create_tree(&html->parser_binding,
- html->encoding,
- nsoption_bool(enable_javascript),
- html_process_script,
- html);
- }
+ html->parser = dom_hubbub_parser_create(html->encoding,
+ true,
+ nsoption_bool(enable_javascript),
+ NULL,
+ html_process_script,
+ html);
- if (err != BINDING_OK) {
- union content_msg_data msg_data;
+ if (html->parser == NULL) {
+ union content_msg_data msg_data;
+
+ /** @todo add a message callback function and pass the
+ * parser errors back instead of everything being
+ * OOM
+ */
- if (err == BINDING_BADENCODING) {
- LOG(("Bad encoding: %s", html->encoding
- ? html->encoding : ""));
- msg_data.error = messages_get("ParsingFail");
- } else
msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
- return false;
- }
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ return false;
+ }
- {
- const char *source_data;
- unsigned long source_size;
+ }
- source_data = content__get_source_data(c, &source_size);
+ source_data = content__get_source_data(c, &source_size);
- /* Recurse to 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);
- }
+ /* Recurse to 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);
+
}
@@ -1923,7 +1918,7 @@ html_find_stylesheets_no_memory:
static bool html_convert(struct content *c)
{
html_content *htmlc = (html_content *) c;
- binding_error err;
+ dom_hubbub_error err;
dom_node *html, *head;
union content_msg_data msg_data;
unsigned long size;
@@ -1934,18 +1929,19 @@ static bool html_convert(struct content *c)
/* finish parsing */
content__get_source_data(c, &size);
- err = binding_parse_completed(htmlc->parser_binding);
- if (err != BINDING_OK) {
+ err = dom_hubbub_parser_completed(htmlc->parser);
+ if (err != DOM_HUBBUB_OK) {
union content_msg_data msg_data;
+ /** @todo Improve precessing of errors */
msg_data.error = messages_get("NoMemory");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
return false;
}
- htmlc->document = binding_get_document(htmlc->parser_binding,
- &htmlc->quirks);
+ /** @todo quirks used to be set here too */
+ htmlc->document = dom_hubbub_parser_get_document(htmlc->parser);
if (htmlc->document == NULL) {
LOG(("Parsing failed"));
@@ -1955,9 +1951,9 @@ static bool html_convert(struct content *c)
}
if (htmlc->encoding == NULL) {
- const char *encoding = binding_get_encoding(
- htmlc->parser_binding,
- &htmlc->encoding_source);
+ const char *encoding;
+ encoding = dom_hubbub_parser_get_encoding(htmlc->parser,
+ &htmlc->encoding_source);
htmlc->encoding = talloc_strdup(c, encoding);
if (htmlc->encoding == NULL) {
@@ -2047,7 +2043,7 @@ static bool html_convert(struct content *c)
}
/* Retrieve forms from parser */
- htmlc->forms = binding_get_forms(htmlc->parser_binding);
+ htmlc->forms = NULL; /*binding_get_forms(htmlc->parser);*/
for (f = htmlc->forms; f != NULL; f = f->prev) {
char *action;
url_func_result res;
@@ -2366,13 +2362,14 @@ static void html_destroy(struct content *c)
if (html->base_url)
nsurl_unref(html->base_url);
- if (html->parser_binding != NULL) {
- binding_destroy_tree(html->parser_binding);
- html->parser_binding = NULL;
+ if (html->parser != NULL) {
+ dom_hubbub_parser_destroy(html->parser);
+ html->parser = NULL;
}
- if (html->document != NULL)
- binding_destroy_document(html->document);
+ if (html->document != NULL) {
+ dom_node_unref(html->document);
+ }
/* Free base target */
if (html->base_target != NULL) {
@@ -2943,7 +2940,7 @@ const char *html_get_encoding(hlcache_handle *h)
* \param h Content to retrieve charset from
* \return Pointer to charset, or NULL
*/
-binding_encoding_source html_get_encoding_source(hlcache_handle *h)
+dom_hubbub_encoding_source html_get_encoding_source(hlcache_handle *h)
{
html_content *c = (html_content *) hlcache_handle_get_content(h);
diff --git a/render/html.h b/render/html.h
index 5867bcff2..0aa45d308 100644
--- a/render/html.h
+++ b/render/html.h
@@ -26,11 +26,14 @@
#define _NETSURF_RENDER_HTML_H_
#include <stdbool.h>
+
+#include <dom/dom.h>
+#include <dom/bindings/hubbub/parser.h>
+
#include "content/content_type.h"
#include "css/css.h"
#include "desktop/mouse.h"
#include "desktop/plot_style.h"
-#include "render/parser_binding.h"
#include "desktop/frame_types.h"
struct fetch_multipart_data;
@@ -46,6 +49,12 @@ struct plotters;
struct scrollbar;
struct scrollbar_msg_data;
+typedef enum binding_quirks_mode {
+ BINDING_QUIRKS_MODE_NONE,
+ BINDING_QUIRKS_MODE_LIMITED,
+ BINDING_QUIRKS_MODE_FULL
+} binding_quirks_mode;
+
/**
* Container for stylesheets used by an HTML document
*/
@@ -167,7 +176,7 @@ bool text_redraw(const char *utf8_text, size_t utf8_len,
dom_document *html_get_document(struct hlcache_handle *h);
struct box *html_get_box_tree(struct hlcache_handle *h);
const char *html_get_encoding(struct hlcache_handle *h);
-binding_encoding_source html_get_encoding_source(struct hlcache_handle *h);
+dom_hubbub_encoding_source html_get_encoding_source(struct hlcache_handle *h);
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);
diff --git a/render/html_internal.h b/render/html_internal.h
index acd7a2cdc..89b90c8e2 100644
--- a/render/html_internal.h
+++ b/render/html_internal.h
@@ -31,8 +31,8 @@
typedef struct html_content {
struct content base;
- /** Parser object handle */
- void *parser_binding;
+ dom_hubbub_parser *parser; /**< Parser object handle */
+
/** Document tree */
dom_document *document;
/** Quirkyness of document */
@@ -41,7 +41,7 @@ typedef struct html_content {
/** Encoding of source, NULL if unknown. */
char *encoding;
/** Source of encoding information. */
- binding_encoding_source encoding_source;
+ dom_hubbub_encoding_source encoding_source;
/** Base URL (may be a copy of content->url). */
nsurl *base_url;
diff --git a/render/html_script.c b/render/html_script.c
index f925cfedf..631dcca1e 100644
--- a/render/html_script.c
+++ b/render/html_script.c
@@ -234,7 +234,7 @@ html_process_script(void *ctx, dom_node *node)
}
}
- LOG(("content %p parser %p node %p",c,c->parser_binding, node));
+ LOG(("content %p parser %p node %p",c,c->parser, node));
exc = dom_element_get_attribute(node, html_dom_string_type, &mimetype);
if (exc != DOM_NO_ERR || mimetype == NULL) {
diff --git a/render/hubbub_binding.c b/render/hubbub_binding.c
deleted file mode 100644
index 2f9899fad..000000000
--- a/render/hubbub_binding.c
+++ /dev/null
@@ -1,1325 +0,0 @@
-/*
- * Copyright 2008 Andrew Sidwell <takkaria@netsurf-browser.org>
- * Copyright 2008 John-Mark Bell <jmb@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 <assert.h>
-#include <stdbool.h>
-#include <string.h>
-
-#include <libxml/HTMLparser.h>
-#include <libxml/HTMLtree.h>
-
-#include <hubbub/parser.h>
-#include <hubbub/tree.h>
-
-#include "render/form.h"
-#include "render/parser_binding.h"
-
-#include "utils/config.h"
-#include "utils/log.h"
-#include "utils/talloc.h"
-#include "utils/utils.h"
-
-/**
- * Private data attached to each DOM node
- */
-typedef struct hubbub_private {
- binding_private base;
-
- uint32_t refcnt;
-} hubbub_private;
-
-typedef struct hubbub_ctx {
- hubbub_parser *parser;
-
- htmlDocPtr document;
- bool owns_doc;
-
- binding_quirks_mode quirks;
-
- const char *encoding;
- binding_encoding_source encoding_source;
-
-#define NUM_NAMESPACES (6)
- xmlNsPtr namespaces[NUM_NAMESPACES];
-#undef NUM_NAMESPACES
-
- hubbub_tree_handler tree_handler;
-
- struct form *forms;
-} hubbub_ctx;
-
-static struct {
- const char *prefix;
- const char *url;
-} namespaces[] = {
- { NULL, NULL },
- { NULL, "http://www.w3.org/1999/xhtml" },
- { "math", "http://www.w3.org/1998/Math/MathML" },
- { "svg", "http://www.w3.org/2000/svg" },
- { "xlink", "http://www.w3.org/1999/xlink" },
- /** \todo Oh dear. LibXML2 refuses to create any namespace with a
- * prefix of "xml". That sucks, royally. */
- { "xml", "http://www.w3.org/XML/1998/namespace" },
- { "xmlns", "http://www.w3.org/2000/xmlns/" }
-};
-
-static hubbub_private *create_private(uint32_t refcnt);
-static hubbub_private *copy_private(const hubbub_private *p, uint32_t refcnt);
-static void destroy_private(hubbub_private *p);
-static inline char *c_string_from_hubbub_string(hubbub_ctx *ctx,
- const hubbub_string *str);
-static void create_namespaces(hubbub_ctx *ctx, xmlNode *root);
-static hubbub_error create_comment(void *ctx, const hubbub_string *data,
- void **result);
-static hubbub_error create_doctype(void *ctx, const hubbub_doctype *doctype,
- void **result);
-static hubbub_error create_element(void *ctx, const hubbub_tag *tag,
- void **result);
-static hubbub_error create_text(void *ctx, const hubbub_string *data,
- void **result);
-static hubbub_error ref_node(void *ctx, void *node);
-static hubbub_error unref_node(void *ctx, void *node);
-static hubbub_error append_child(void *ctx, void *parent, void *child,
- void **result);
-static hubbub_error insert_before(void *ctx, void *parent, void *child,
- void *ref_child, void **result);
-static hubbub_error remove_child(void *ctx, void *parent, void *child,
- void **result);
-static hubbub_error clone_node(void *ctx, void *node, bool deep, void **result);
-static hubbub_error reparent_children(void *ctx, void *node, void *new_parent);
-static hubbub_error get_parent(void *ctx, void *node, bool element_only,
- void **result);
-static hubbub_error has_children(void *ctx, void *node, bool *result);
-static hubbub_error form_associate(void *ctx, void *form, void *node);
-static hubbub_error add_attributes(void *ctx, void *node,
- const hubbub_attribute *attributes, uint32_t n_attributes);
-static hubbub_error set_quirks_mode(void *ctx, hubbub_quirks_mode mode);
-static hubbub_error change_encoding(void *ctx, const char *charset);
-
-static struct form *parse_form_element(xmlNode *node, const char *docenc);
-static struct form_control *parse_input_element(xmlNode *node);
-static struct form_control *parse_button_element(xmlNode *node);
-static struct form_control *parse_select_element(xmlNode *node);
-static struct form_control *parse_textarea_element(xmlNode *node);
-
-static hubbub_tree_handler tree_handler = {
- create_comment,
- create_doctype,
- create_element,
- create_text,
- ref_node,
- unref_node,
- append_child,
- insert_before,
- remove_child,
- clone_node,
- reparent_children,
- get_parent,
- has_children,
- form_associate,
- add_attributes,
- set_quirks_mode,
- change_encoding,
- NULL
-};
-
-static void *ns_talloc_based_realloc(void *ptr, size_t len, void *pw)
-{
- /* talloc_realloc_size(pw, ptr, 0) == talloc_free(ptr) */
- return talloc_realloc_size(pw, ptr, len);
-}
-
-binding_error binding_create_tree(void *arena, const char *charset, void **ctx)
-{
- hubbub_ctx *c;
- hubbub_parser_optparams params;
- uint32_t i;
- hubbub_error error;
-
- c = malloc(sizeof(hubbub_ctx));
- if (c == NULL)
- return BINDING_NOMEM;
-
- c->parser = NULL;
- c->encoding = charset;
- c->encoding_source = charset != NULL ? ENCODING_SOURCE_HEADER
- : ENCODING_SOURCE_DETECTED;
- c->document = NULL;
- c->owns_doc = true;
- c->quirks = BINDING_QUIRKS_MODE_NONE;
- c->forms = NULL;
-
- error = hubbub_parser_create(charset, true, ns_talloc_based_realloc,
- arena, &c->parser);
- if (error != HUBBUB_OK) {
- free(c);
- if (error == HUBBUB_BADENCODING)
- return BINDING_BADENCODING;
- else
- return BINDING_NOMEM; /* Assume OOM */
- }
-
- c->document = htmlNewDocNoDtD(NULL, NULL);
- if (c->document == NULL) {
- hubbub_parser_destroy(c->parser);
- free(c);
- return BINDING_NOMEM;
- }
- c->document->_private = create_private(0);
- if (c->document->_private == NULL) {
- xmlFreeDoc(c->document);
- hubbub_parser_destroy(c->parser);
- free(c);
- return BINDING_NOMEM;
- }
-
- for (i = 0; i < sizeof(c->namespaces) / sizeof(c->namespaces[0]); i++) {
- c->namespaces[i] = NULL;
- }
-
- c->tree_handler = tree_handler;
- c->tree_handler.ctx = (void *) c;
-
- params.tree_handler = &c->tree_handler;
- hubbub_parser_setopt(c->parser, HUBBUB_PARSER_TREE_HANDLER, &params);
-
- ref_node(c, c->document);
- params.document_node = c->document;
- hubbub_parser_setopt(c->parser, HUBBUB_PARSER_DOCUMENT_NODE, &params);
-
- *ctx = (void *) c;
-
- return BINDING_OK;
-}
-
-binding_error binding_destroy_tree(void *ctx)
-{
- hubbub_ctx *c = (hubbub_ctx *) ctx;
-
- if (ctx == NULL)
- return BINDING_OK;
-
- if (c->parser != NULL)
- hubbub_parser_destroy(c->parser);
-
- if (c->owns_doc)
- binding_destroy_document(c->document);
-
- c->parser = NULL;
- c->encoding = NULL;
- c->document = NULL;
-
- free(c);
-
- return BINDING_OK;
-}
-
-binding_error binding_parse_chunk(void *ctx, const uint8_t *data, size_t len)
-{
- hubbub_ctx *c = (hubbub_ctx *) ctx;
- hubbub_error err;
-
- err = hubbub_parser_parse_chunk(c->parser, (uint8_t *) data, len);
- if (err == HUBBUB_ENCODINGCHANGE)
- return BINDING_ENCODINGCHANGE;
-
- return err == HUBBUB_NOMEM ? BINDING_NOMEM : BINDING_OK;
-}
-
-binding_error binding_parse_completed(void *ctx)
-{
- hubbub_ctx *c = (hubbub_ctx *) ctx;
- hubbub_error error;
-
- error = hubbub_parser_completed(c->parser);
-
- return error == HUBBUB_NOMEM ? BINDING_NOMEM : BINDING_OK;
-}
-
-const char *binding_get_encoding(void *ctx, binding_encoding_source *source)
-{
- hubbub_ctx *c = (hubbub_ctx *) ctx;
-
- *source = c->encoding_source;
-
- return c->encoding != NULL ? c->encoding : "Windows-1252";
-}
-
-xmlDocPtr binding_get_document(void *ctx, binding_quirks_mode *quirks)
-{
- hubbub_ctx *c = (hubbub_ctx *) ctx;
- xmlDocPtr doc = c->document;
-
- c->owns_doc = false;
-
- *quirks = c->quirks;
-
- return doc;
-}
-
-struct form *binding_get_forms(void *ctx)
-{
- hubbub_ctx *c = (hubbub_ctx *) ctx;
-
- return c->forms;
-}
-
-struct form_control *binding_get_control_for_node(void *ctx, xmlNodePtr node)
-{
- hubbub_ctx *c = (hubbub_ctx *) ctx;
- struct form *f;
- struct form_control *ctl = NULL;
-
- for (f = c->forms; f != NULL; f = f->prev) {
- for (ctl = f->controls; ctl != NULL; ctl = ctl->next) {
- if (ctl->node == node)
- return ctl;
- }
- }
-
- /* No control found. This implies that it's not associated
- * with any form. In this case, we create a control for it
- * on the fly. */
- if (strcasecmp((const char *) node->name, "input") == 0) {
- ctl = parse_input_element(node);
- } else if (strcasecmp((const char *) node->name, "button") == 0) {
- ctl = parse_button_element(node);
- } else if (strcasecmp((const char *) node->name, "select") == 0) {
- ctl = parse_select_element(node);
- } else if (strcasecmp((const char *) node->name, "textarea") == 0) {
- ctl = parse_textarea_element(node);
- }
-
- return ctl;
-}
-
-void binding_destroy_document(xmlDocPtr doc)
-{
- xmlNode *n = (xmlNode *) doc;
-
- while (n != NULL) {
- destroy_private(n->_private);
-
- if (n->children != NULL) {
- n = n->children;
- } else if (n->next != NULL) {
- n = n->next;
- } else {
- while (n->parent != NULL && n->parent->next == NULL)
- n = n->parent;
-
- if (n->parent != NULL)
- n = n->parent->next;
- else
- n = NULL;
- }
- }
-
- xmlFreeDoc(doc);
-}
-
-/*****************************************************************************/
-
-hubbub_private *create_private(uint32_t refcnt)
-{
- hubbub_private *pvt = calloc(1, sizeof(*pvt));
-
- if (pvt != NULL)
- pvt->refcnt = refcnt;
-
- return pvt;
-}
-
-hubbub_private *copy_private(const hubbub_private *p, uint32_t refcnt)
-{
- hubbub_private *pvt = calloc(1, sizeof(*pvt));
-
- if (pvt != NULL) {
- pvt->refcnt = refcnt;
-
- if (p->base.nclasses > 0) {
- pvt->base.classes =
- malloc(p->base.nclasses * sizeof(lwc_string *));
- if (pvt->base.classes == NULL) {
- free(pvt);
- return NULL;
- }
-
- while (pvt->base.nclasses < p->base.nclasses) {
- pvt->base.classes[pvt->base.nclasses] =
- lwc_string_ref(p->base.classes[
- pvt->base.nclasses]);
- pvt->base.nclasses++;
- }
- }
-
- if (p->base.localname != NULL)
- pvt->base.localname = lwc_string_ref(p->base.localname);
-
- if (p->base.id != NULL)
- pvt->base.id = lwc_string_ref(p->base.id);
- }
-
- return pvt;
-}
-
-void destroy_private(hubbub_private *p)
-{
- if (p->base.localname != NULL)
- lwc_string_unref(p->base.localname);
-
- if (p->base.id != NULL)
- lwc_string_unref(p->base.id);
-
- while (p->base.nclasses > 0)
- lwc_string_unref(p->base.classes[--p->base.nclasses]);
-
- if (p->base.classes != NULL)
- free(p->base.classes);
-
- free(p);
-}
-
-char *c_string_from_hubbub_string(hubbub_ctx *ctx, const hubbub_string *str)
-{
- return strndup((const char *) str->ptr, (int) str->len);
-}
-
-void create_namespaces(hubbub_ctx *ctx, xmlNode *root)
-{
- uint32_t i;
-
- for (i = 1; i < sizeof(namespaces) / sizeof(namespaces[0]); i++) {
- ctx->namespaces[i - 1] = xmlNewNs(root,
- BAD_CAST namespaces[i].url,
- BAD_CAST namespaces[i].prefix);
-
- if (ctx->namespaces[i - 1] == NULL) {
- LOG(("Failed creating namespace %s\n",
- namespaces[i].prefix));
- }
- }
-}
-
-hubbub_error create_comment(void *ctx, const hubbub_string *data, void **result)
-{
- hubbub_ctx *c = (hubbub_ctx *) ctx;
- char *content;
- xmlNodePtr n;
-
- content = c_string_from_hubbub_string(c, data);
- if (content == NULL)
- return HUBBUB_NOMEM;
-
- n = xmlNewDocComment(c->document, BAD_CAST content);
- if (n == NULL) {
- free(content);
- return HUBBUB_NOMEM;
- }
- n->_private = create_private(1);
- if (n->_private == NULL) {
- xmlFreeNode(n);
- free(content);
- return HUBBUB_NOMEM;
- }
-
- free(content);
-
- *result = (void *) n;
-
- return HUBBUB_OK;
-}
-
-hubbub_error create_doctype(void *ctx, const hubbub_doctype *doctype,
- void **result)
-{
- hubbub_ctx *c = (hubbub_ctx *) ctx;
- char *name, *public = NULL, *system = NULL;
- xmlDtdPtr n;
-
- name = c_string_from_hubbub_string(c, &doctype->name);
- if (name == NULL)
- return HUBBUB_NOMEM;
-
- if (!doctype->public_missing) {
- public = c_string_from_hubbub_string(c, &doctype->public_id);
- if (public == NULL) {
- free(name);
- return HUBBUB_NOMEM;
- }
- }
-
- if (!doctype->system_missing) {
- system = c_string_from_hubbub_string(c, &doctype->system_id);
- if (system == NULL) {
- free(public);
- free(name);
- return HUBBUB_NOMEM;
- }
- }
-
- n = xmlNewDtd(c->document, BAD_CAST name,
- BAD_CAST (public ? public : ""),
- BAD_CAST (system ? system : ""));
- if (n == NULL) {
- free(system);
- free(public);
- free(name);
- return HUBBUB_NOMEM;
- }
- n->_private = create_private(1);
- if (n->_private == NULL) {
- xmlFreeDtd(n);
- free(system);
- free(public);
- free(name);
- return HUBBUB_NOMEM;
- }
-
- *result = (void *) n;
-
- free(system);
- free(public);
- free(name);
-
- return HUBBUB_OK;
-}
-
-hubbub_error create_element(void *ctx, const hubbub_tag *tag, void **result)
-{
- hubbub_ctx *c = (hubbub_ctx *) ctx;
- lwc_string *iname;
- xmlNodePtr n;
-
- if (lwc_intern_string((const char *) tag->name.ptr, tag->name.len,
- &iname) != lwc_error_ok) {
- return HUBBUB_NOMEM;
- }
-
- if (c->namespaces[0] != NULL) {
- n = xmlNewDocNode(c->document, c->namespaces[tag->ns - 1],
- BAD_CAST lwc_string_data(iname), NULL);
- } else {
- n = xmlNewDocNode(c->document, NULL,
- BAD_CAST lwc_string_data(iname), NULL);
-
- /* We're creating the root node of the document. Therefore,
- * create the namespaces and set this node's namespace */
- if (n != NULL && c->namespaces[0] == NULL) {
- create_namespaces(c, (void *) n);
-
- xmlSetNs(n, c->namespaces[tag->ns - 1]);
- }
- }
- if (n == NULL) {
- lwc_string_unref(iname);
- return HUBBUB_NOMEM;
- }
- n->_private = create_private(1);
- if (n->_private == NULL) {
- xmlFreeNode(n);
- lwc_string_unref(iname);
- return HUBBUB_NOMEM;
- }
-
- if (tag->n_attributes > 0 && add_attributes(ctx, (void *) n,
- tag->attributes, tag->n_attributes) != HUBBUB_OK) {
- destroy_private(n->_private);
- xmlFreeNode(n);
- lwc_string_unref(iname);
- return HUBBUB_NOMEM;
- }
-
- if (lwc_string_length(iname) == SLEN("form") &&
- strcasecmp(lwc_string_data(iname), "form") == 0) {
- struct form *form = parse_form_element(n, c->encoding);
-
- /* Memory exhaustion */
- if (form == NULL) {
- destroy_private(n->_private);
- xmlFreeNode(n);
- lwc_string_unref(iname);
- return HUBBUB_NOMEM;
- }
-
- /* Insert into list */
- form->prev = c->forms;
- c->forms = form;
- }
-
- ((binding_private *) n->_private)->localname = iname;
-
- *result = (void *) n;
-
- return HUBBUB_OK;
-}
-
-hubbub_error create_text(void *ctx, const hubbub_string *data, void **result)
-{
- hubbub_ctx *c = (hubbub_ctx *) ctx;
- xmlNodePtr n;
-
- n = xmlNewDocTextLen(c->document, BAD_CAST data->ptr, (int) data->len);
- if (n == NULL) {
- return HUBBUB_NOMEM;
- }
- n->_private = create_private(1);
- if (n->_private == NULL) {
- xmlFreeNode(n);
- return HUBBUB_NOMEM;
- }
-
- *result = (void *) n;
-
- return HUBBUB_OK;
-}
-
-hubbub_error ref_node(void *ctx, void *node)
-{
- hubbub_ctx *c = (hubbub_ctx *) ctx;
- hubbub_private *pvt;
-
- if (node == c->document) {
- xmlDoc *n = (xmlDoc *) node;
- pvt = n->_private;
-
- pvt->refcnt++;
- } else {
- xmlNode *n = (xmlNode *) node;
- pvt = n->_private;
-
- pvt->refcnt++;
- }
-
- return HUBBUB_OK;
-}
-
-hubbub_error unref_node(void *ctx, void *node)
-{
- hubbub_ctx *c = (hubbub_ctx *) ctx;
- hubbub_private *pvt;
-
- if (node == c->document) {
- xmlDoc *n = (xmlDoc *) node;
- pvt = n->_private;
-
- assert(pvt->refcnt != 0 && "Node has refcount of zero");
-
- pvt->refcnt--;
- } else {
- xmlNode *n = (xmlNode *) node;
- pvt = n->_private;
-
- assert(pvt->refcnt != 0 && "Node has refcount of zero");
-
- pvt->refcnt--;
-
- if (pvt->refcnt == 0 && n->parent == NULL) {
- destroy_private(pvt);
- xmlFreeNode(n);
- }
- }
-
- return HUBBUB_OK;
-}
-
-hubbub_error append_child(void *ctx, void *parent, void *child, void **result)
-{
- xmlNode *chld = (xmlNode *) child;
- xmlNode *p = (xmlNode *) parent;
-
- /** \todo Text node merging logic as per
- * http://www.whatwg.org/specs/web-apps/current-work/multipage/ \
- * tree-construction.html#insert-a-character
- *
- * Doesn't actually matter for us until we have scripting. Thus,
- * this is something which can wait until libdom.
- */
- if (chld->type == XML_TEXT_NODE && p->last != NULL &&
- p->last->type == XML_TEXT_NODE) {
- /* Need to clone the child, as libxml will free it if it
- * merges the content with a pre-existing text node. */
- chld = xmlCopyNode(chld, 0);
- if (chld == NULL)
- return HUBBUB_NOMEM;
-
- *result = xmlAddChild(p, chld);
-
- assert(*result != (void *) chld);
- } else {
- *result = xmlAddChild(p, chld);
- }
-
- if (*result == NULL)
- return HUBBUB_NOMEM;
-
- ref_node(ctx, *result);
-
- return HUBBUB_OK;
-}
-
-hubbub_error insert_before(void *ctx, void *parent, void *child,
- void *ref_child, void **result)
-{
- xmlNode *chld = (xmlNode *) child;
- xmlNode *ref = (xmlNode *) ref_child;
-
- if (chld->type == XML_TEXT_NODE && ref->prev != NULL &&
- ref->prev->type == XML_TEXT_NODE) {
- /* Clone text node, as it'll be freed by libxml */
- chld = xmlCopyNode(chld, 0);
- if (chld == NULL)
- return HUBBUB_NOMEM;
-
- *result = xmlAddNextSibling(ref->prev, chld);
-
- assert(*result != (void *) chld);
- } else {
- *result = xmlAddPrevSibling(ref, chld);
- }
-
- if (*result == NULL)
- return HUBBUB_NOMEM;
-
- ref_node(ctx, *result);
-
- return HUBBUB_OK;
-}
-
-hubbub_error remove_child(void *ctx, void *parent, void *child, void **result)
-{
- xmlNode *chld = (xmlNode *) child;
-
- xmlUnlinkNode(chld);
-
- *result = child;
-
- ref_node(ctx, *result);
-
- return HUBBUB_OK;
-}
-
-hubbub_error clone_node(void *ctx, void *node, bool deep, void **result)
-{
- xmlNode *n = (xmlNode *) node;
- xmlNode *clonedtree;
-
- /* Shallow clone node */
- clonedtree = xmlCopyNode(n, 2);
- if (clonedtree == NULL)
- return HUBBUB_NOMEM;
-
- clonedtree->_private = copy_private(n->_private, 1);
- if (clonedtree->_private == NULL) {
- xmlFreeNode(clonedtree);
- return HUBBUB_NOMEM;
- }
-
- /* Iteratively clone children too, if required */
- if (deep && n->children != NULL) {
- xmlNode *parent = clonedtree, *copy;
-
- n = n->children;
-
- while (n != node) {
- copy = xmlCopyNode(n, 2);
- if (copy == NULL)
- goto error;
-
- copy->_private = copy_private(n->_private, 0);
- if (copy->_private == NULL) {
- xmlFreeNode(copy);
- goto error;
- }
-
- xmlAddChild(parent, copy);
-
- if (n->children != NULL) {
- parent = copy;
- n = n->children;
- } else if (n->next != NULL) {
- n = n->next;
- } else {
- while (n->parent != node &&
- n->parent->next == NULL) {
- parent = parent->parent;
- n = n->parent;
- }
-
- if (n->parent != node) {
- parent = parent->parent;
- n = n->parent->next;
- } else
- n = node;
- }
- }
- }
-
- *result = clonedtree;
-
- return HUBBUB_OK;
-
-error:
- n = clonedtree;
-
- while (n != NULL) {
- destroy_private(n->_private);
-
- if (n->children != NULL) {
- n = n->children;
- } else if (n->next != NULL) {
- n = n->next;
- } else {
- while (n->parent != NULL && n->parent->next == NULL) {
- n = n->parent;
- }
-
- if (n->parent != NULL)
- n = n->parent->next;
- else
- n = NULL;
- }
- }
-
- xmlFreeNode(clonedtree);
-
- return HUBBUB_NOMEM;
-}
-
-hubbub_error reparent_children(void *ctx, void *node, void *new_parent)
-{
- xmlNode *n = (xmlNode *) node;
- xmlNode *p = (xmlNode *) new_parent;
- xmlNode *child;
-
- for (child = n->children; child != NULL; ) {
- xmlNode *next = child->next;
-
- xmlUnlinkNode(child);
-
- if (xmlAddChild(p, child) == NULL)
- return HUBBUB_NOMEM;
-
- child = next;
- }
-
- return HUBBUB_OK;
-}
-
-hubbub_error get_parent(void *ctx, void *node, bool element_only, void **result)
-{
- xmlNode *n = (xmlNode *) node;
-
- *result = (void *) n->parent;
-
- if (*result != NULL && element_only &&
- ((xmlNode *) *result)->type != XML_ELEMENT_NODE) {
- *result = NULL;
- }
-
- if (*result != NULL)
- ref_node(ctx, *result);
-
- return HUBBUB_OK;
-}
-
-hubbub_error has_children(void *ctx, void *node, bool *result)
-{
- xmlNode *n = (xmlNode *) node;
-
- *result = n->children != NULL;
-
- return HUBBUB_OK;
-}
-
-hubbub_error form_associate(void *ctx, void *form, void *node)
-{
- hubbub_ctx *c = (hubbub_ctx *) ctx;
- xmlNode *n = (xmlNode *) node;
- struct form *f;
- struct form_control *control = NULL;
- xmlChar *id = NULL;
-
- /* Find form object to associate with:
- *
- * 1) If node possesses an @form, use the form with a matching @id
- * 2) Otherwise, use the form provided
- */
- id = xmlGetProp(n, (const xmlChar *) "form");
- for (f = c->forms; f != NULL; f = f->prev) {
- if (id == NULL && f->node == form) {
- break;
- } else if (id != NULL) {
- xmlNode *fn = (xmlNode *) f->node;
- xmlChar *fid = xmlGetProp(fn, (const xmlChar *) "id");
-
- if (fid != NULL && strcmp((char *) id,
- (char *) fid) == 0) {
- xmlFree(fid);
- break;
- } else if (fid != NULL) {
- xmlFree(fid);
- }
- }
- }
- if (id != NULL)
- xmlFree(id);
-
- /* None found -- give up */
- if (f == NULL)
- return HUBBUB_OK;
-
- /* Will be one of: button, fieldset, input, label,
- * output, select, textarea.
- *
- * We ignore fieldset, label and output.
- */
- if (strcasecmp((const char *) n->name, "input") == 0) {
- control = parse_input_element(n);
- } else if (strcasecmp((const char *) n->name, "button") == 0) {
- control = parse_button_element(n);
- } else if (strcasecmp((const char *) n->name, "select") == 0) {
- control = parse_select_element(n);
- } else if (strcasecmp((const char *) n->name, "textarea") == 0) {
- control = parse_textarea_element(n);
- } else
- return HUBBUB_OK;
-
- /* Memory exhaustion */
- if (control == NULL)
- return HUBBUB_NOMEM;
-
- /* Add the control to the form */
- form_add_control(f, control);
-
- return HUBBUB_OK;
-}
-
-static hubbub_error parse_class_attr(lwc_string *value,
- lwc_string ***classes, uint32_t *nclasses)
-{
- const char *pv;
- lwc_string **cls = NULL;
- uint32_t count = 0;
-
- /* Count number of classes */
- for (pv = lwc_string_data(value); *pv != '\0'; ) {
- if (*pv != ' ') {
- while (*pv != ' ' && *pv != '\0')
- pv++;
- count++;
- } else {
- while (*pv == ' ')
- pv++;
- }
- }
-
- /* If there are some, unpack them */
- if (count > 0) {
- cls = malloc(count * sizeof(lwc_string *));
- if (cls == NULL)
- return HUBBUB_NOMEM;
-
- for (pv = lwc_string_data(value), count = 0; *pv != '\0'; ) {
- if (*pv != ' ') {
- const char *s = pv;
- while (*pv != ' ' && *pv != '\0')
- pv++;
- if (lwc_intern_string(s, pv - s,
- &cls[count]) != lwc_error_ok)
- goto error;
- count++;
- } else {
- while (*pv == ' ')
- pv++;
- }
- }
- }
-
- *classes = cls;
- *nclasses = count;
-
- return HUBBUB_OK;
-error:
- while (count > 0)
- lwc_string_unref(cls[--count]);
-
- free(cls);
-
- return HUBBUB_NOMEM;
-}
-
-hubbub_error add_attributes(void *ctx, void *node,
- const hubbub_attribute *attributes, uint32_t n_attributes)
-{
- hubbub_ctx *c = (hubbub_ctx *) ctx;
- xmlNode *n = (xmlNode *) node;
- binding_private *p = n->_private;
- uint32_t attr;
-
- for (attr = 0; attr < n_attributes; attr++) {
- xmlAttr *prop;
- lwc_string *name, *value;
-
- if (lwc_intern_string((const char *) attributes[attr].name.ptr,
- attributes[attr].name.len,
- &name) != lwc_error_ok)
- return HUBBUB_NOMEM;
-
- if (lwc_intern_string((const char *) attributes[attr].value.ptr,
- attributes[attr].value.len,
- &value) != lwc_error_ok) {
- lwc_string_unref(name);
- return HUBBUB_NOMEM;
- }
-
- if (attributes[attr].ns != HUBBUB_NS_NULL &&
- c->namespaces[0] != NULL) {
- prop = xmlNewNsProp(n,
- c->namespaces[attributes[attr].ns - 1],
- BAD_CAST lwc_string_data(name),
- BAD_CAST lwc_string_data(value));
- } else {
- prop = xmlNewProp(n, BAD_CAST lwc_string_data(name),
- BAD_CAST lwc_string_data(value));
- }
-
- /* Handle @id / @class */
- if (p->id == NULL && lwc_string_length(name) == SLEN("id") &&
- strcasecmp(lwc_string_data(name), "id") == 0) {
- p->id = lwc_string_ref(value);
- } else if (p->nclasses == 0 &&
- lwc_string_length(name) == SLEN("class") &&
- strcasecmp(lwc_string_data(name),
- "class") == 0) {
- hubbub_error error;
-
- error = parse_class_attr(value, &p->classes,
- &p->nclasses);
- if (error != HUBBUB_OK) {
- lwc_string_unref(value);
- lwc_string_unref(name);
- return error;
- }
- }
-
- lwc_string_unref(value);
- lwc_string_unref(name);
-
- if (prop == NULL) {
- return HUBBUB_NOMEM;
- }
- }
-
- return HUBBUB_OK;
-}
-
-hubbub_error set_quirks_mode(void *ctx, hubbub_quirks_mode mode)
-{
- hubbub_ctx *c = (hubbub_ctx *) ctx;
-
- switch (mode) {
- case HUBBUB_QUIRKS_MODE_NONE:
- c->quirks = BINDING_QUIRKS_MODE_NONE;
- break;
- case HUBBUB_QUIRKS_MODE_LIMITED:
- c->quirks = BINDING_QUIRKS_MODE_LIMITED;
- break;
- case HUBBUB_QUIRKS_MODE_FULL:
- c->quirks = BINDING_QUIRKS_MODE_FULL;
- break;
- }
-
- return HUBBUB_OK;
-}
-
-hubbub_error change_encoding(void *ctx, const char *charset)
-{
- hubbub_ctx *c = (hubbub_ctx *) ctx;
- uint32_t source;
- const char *name;
-
- /* If we have an encoding here, it means we are *certain* */
- if (c->encoding != NULL) {
- return HUBBUB_OK;
- }
-
- /* Find the confidence otherwise (can only be from a BOM) */
- name = hubbub_parser_read_charset(c->parser, &source);
-
- if (source == HUBBUB_CHARSET_CONFIDENT) {
- c->encoding_source = ENCODING_SOURCE_DETECTED;
- c->encoding = (char *) charset;
- return HUBBUB_OK;
- }
-
- /* So here we have something of confidence tentative... */
- /* http://www.whatwg.org/specs/web-apps/current-work/#change */
-
- /* 2. "If the new encoding is identical or equivalent to the encoding
- * that is already being used to interpret the input stream, then set
- * the confidence to confident and abort these steps." */
-
- /* Whatever happens, the encoding should be set here; either for
- * reprocessing with a different charset, or for confirming that the
- * charset is in fact correct */
- c->encoding = charset;
- c->encoding_source = ENCODING_SOURCE_META;
-
- /* Equal encodings will have the same string pointers */
- return (charset == name) ? HUBBUB_OK : HUBBUB_ENCODINGCHANGE;
-}
-
-struct form *parse_form_element(xmlNode *node, const char *docenc)
-{
- struct form *form;
- form_method method;
- xmlChar *action, *meth, *charset, *target;
-
- action = xmlGetProp(node, (const xmlChar *) "action");
- charset = xmlGetProp(node, (const xmlChar *) "accept-charset");
- target = xmlGetProp(node, (const xmlChar *) "target");
-
- method = method_GET;
- meth = xmlGetProp(node, (const xmlChar *) "method");
- if (meth != NULL) {
- if (strcasecmp((char *) meth, "post") == 0) {
- xmlChar *enctype;
-
- method = method_POST_URLENC;
-
- enctype = xmlGetProp(node, (const xmlChar *) "enctype");
- if (enctype != NULL) {
- if (strcasecmp((char *) enctype,
- "multipart/form-data") == 0)
- method = method_POST_MULTIPART;
-
- xmlFree(enctype);
- }
- }
- xmlFree(meth);
- }
-
- form = form_new(node, (char *) action, (char *) target, method,
- (char *) charset, docenc);
-
- if (target != NULL)
- xmlFree(target);
- if (charset != NULL)
- xmlFree(charset);
- if (action != NULL)
- xmlFree(action);
-
- return form;
-}
-
-struct form_control *parse_input_element(xmlNode *node)
-{
- struct form_control *control = NULL;
- xmlChar *type = xmlGetProp(node, (const xmlChar *) "type");
- xmlChar *name;
-
- if (type != NULL && strcasecmp((char *) type, "password") == 0) {
- control = form_new_control(node, GADGET_PASSWORD);
- } else if (type != NULL && strcasecmp((char *) type, "file") == 0) {
- control = form_new_control(node, GADGET_FILE);
- } else if (type != NULL && strcasecmp((char *) type, "hidden") == 0) {
- control = form_new_control(node, GADGET_HIDDEN);
- } else if (type != NULL && strcasecmp((char *) type, "checkbox") == 0) {
- control = form_new_control(node, GADGET_CHECKBOX);
- } else if (type != NULL && strcasecmp((char *) type, "radio") == 0) {
- control = form_new_control(node, GADGET_RADIO);
- } else if (type != NULL && strcasecmp((char *) type, "submit") == 0) {
- control = form_new_control(node, GADGET_SUBMIT);
- } else if (type != NULL && strcasecmp((char *) type, "reset") == 0) {
- control = form_new_control(node, GADGET_RESET);
- } else if (type != NULL && strcasecmp((char *) type, "button") == 0) {
- control = form_new_control(node, GADGET_BUTTON);
- } else if (type != NULL && strcasecmp((char *) type, "image") == 0) {
- control = form_new_control(node, GADGET_IMAGE);
- } else {
- control = form_new_control(node, GADGET_TEXTBOX);
- }
-
- xmlFree(type);
-
- if (control == NULL)
- return NULL;
-
- if (control->type == GADGET_CHECKBOX || control->type == GADGET_RADIO) {
- control->selected =
- xmlHasProp(node, (const xmlChar *) "checked") != NULL;
- }
-
- if (control->type == GADGET_PASSWORD ||
- control->type == GADGET_TEXTBOX) {
- xmlChar *len = xmlGetProp(node, (const xmlChar *) "maxlength");
- if (len != NULL) {
- if (len[0] != '\0')
- control->maxlength = atoi((char *) len);
- xmlFree(len);
- }
- }
-
- if (control->type != GADGET_FILE && control->type != GADGET_IMAGE) {
- xmlChar *value = xmlGetProp(node, (const xmlChar *) "value");
- if (value != NULL) {
- control->value = strdup((char *) value);
-
- xmlFree(value);
-
- if (control->value == NULL) {
- form_free_control(control);
- return NULL;
- }
-
- 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);
- return NULL;
- }
-
- control->length = 0;
- }
-
- control->initial_value = strdup(control->value);
- if (control->initial_value == NULL) {
- form_free_control(control);
- return NULL;
- }
- }
- }
-
- name = xmlGetProp(node, (const xmlChar *) "name");
- if (name != NULL) {
- control->name = strdup((char *) name);
-
- xmlFree(name);
-
- if (control->name == NULL) {
- form_free_control(control);
- return NULL;
- }
- }
-
- return control;
-}
-
-struct form_control *parse_button_element(xmlNode *node)
-{
- struct form_control *control;
- xmlChar *type = xmlGetProp(node, (const xmlChar *) "type");
- xmlChar *name;
- xmlChar *value;
-
- if (type == NULL || strcasecmp((char *) type, "submit") == 0) {
- control = form_new_control(node, GADGET_SUBMIT);
- } else if (strcasecmp((char *) type, "reset") == 0) {
- control = form_new_control(node, GADGET_RESET);
- } else {
- control = form_new_control(node, GADGET_BUTTON);
- }
-
- xmlFree(type);
-
- if (control == NULL)
- return NULL;
-
- value = xmlGetProp(node, (const xmlChar *) "value");
- if (value != NULL) {
- control->value = strdup((char *) value);
-
- xmlFree(value);
-
- if (control->value == NULL) {
- form_free_control(control);
- return NULL;
- }
- }
-
- name = xmlGetProp(node, (const xmlChar *) "name");
- if (name != NULL) {
- control->name = strdup((char *) name);
-
- xmlFree(name);
-
- if (control->name == NULL) {
- form_free_control(control);
- return NULL;
- }
- }
-
- return control;
-}
-
-struct form_control *parse_select_element(xmlNode *node)
-{
- struct form_control *control = form_new_control(node, GADGET_SELECT);
- xmlChar *name;
-
- if (control == NULL)
- return NULL;
-
- control->data.select.multiple =
- xmlHasProp(node, (const xmlChar *) "multiple") != NULL;
-
- name = xmlGetProp(node, (const xmlChar *) "name");
- if (name != NULL) {
- control->name = strdup((char *) name);
-
- xmlFree(name);
-
- if (control->name == NULL) {
- form_free_control(control);
- return NULL;
- }
- }
-
- return control;
-}
-
-struct form_control *parse_textarea_element(xmlNode *node)
-{
- struct form_control *control = form_new_control(node, GADGET_TEXTAREA);
- xmlChar *name;
-
- if (control == NULL)
- return NULL;
-
- name = xmlGetProp(node, (const xmlChar *) "name");
- if (name != NULL) {
- control->name = strdup((char *) name);
-
- xmlFree(name);
-
- if (control->name == NULL) {
- form_free_control(control);
- return NULL;
- }
- }
-
- return control;
-}
-
diff --git a/render/libdom_binding.c b/render/libdom_binding.c
deleted file mode 100644
index 9ae76469c..000000000
--- a/render/libdom_binding.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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 <dom/dom.h>
-#include <dom/bindings/hubbub/parser.h>
-
-#include "render/form.h"
-#include "render/parser_binding.h"
-
-#include "utils/log.h"
-
-binding_error binding_create_tree(void **ctx, const char *charset, bool enable_script, dom_script script, void *context)
-{
- dom_hubbub_parser *parser = NULL;
-
- 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;
- return BINDING_OK;
-}
-
-binding_error binding_destroy_tree(void *ctx)
-{
- dom_hubbub_parser_destroy(ctx);
- return BINDING_OK;
-}
-
-binding_error binding_parse_chunk(void *ctx, const uint8_t *data, size_t len)
-{
- dom_hubbub_error error;
- 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) {
- return BINDING_NOMEM;
- }
- return BINDING_OK;
-}
-
-binding_error binding_parse_completed(void *ctx)
-{
- dom_hubbub_error error;
- 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)
-{
- dom_hubbub_encoding_source hubbub_src;
- const char *encoding;
-
- encoding = dom_hubbub_parser_get_encoding(ctx, &hubbub_src);
-
- switch (hubbub_src) {
- case DOM_HUBBUB_ENCODING_SOURCE_HEADER:
- *source = ENCODING_SOURCE_HEADER;
- break;
-
- case DOM_HUBBUB_ENCODING_SOURCE_DETECTED:
- *source = ENCODING_SOURCE_DETECTED;
- break;
-
- case DOM_HUBBUB_ENCODING_SOURCE_META:
- *source = ENCODING_SOURCE_META;
- break;
- }
-
- return encoding;
-}
-
-dom_document *binding_get_document(void *ctx, binding_quirks_mode *quirks)
-{
- return dom_hubbub_parser_get_document(ctx);
-}
-
-struct form *binding_get_forms(void *ctx)
-{
- return NULL;
-}
-
-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("");
- 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;
-}
-
-void binding_destroy_document(dom_document *doc)
-{
- dom_node_unref(doc);
-}
-
-
diff --git a/render/parser_binding.h b/render/parser_binding.h
deleted file mode 100644
index cf3497867..000000000
--- a/render/parser_binding.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2008 John-Mark Bell <jmb@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/>.
- */
-
-#ifndef _NETSURF_RENDER_PARSER_BINDING_H_
-#define _NETSURF_RENDER_PARSER_BINDING_H_
-
-#include <dom/dom.h>
-#include <dom/bindings/hubbub/parser.h>
-
-struct box;
-struct form;
-struct form_control;
-
-typedef enum binding_error {
- BINDING_OK,
- BINDING_NOMEM,
- BINDING_BADENCODING,
- BINDING_ENCODINGCHANGE
-} binding_error;
-
-typedef enum binding_encoding_source {
- ENCODING_SOURCE_HEADER,
- ENCODING_SOURCE_DETECTED,
- ENCODING_SOURCE_META
-} binding_encoding_source;
-
-typedef enum binding_quirks_mode {
- BINDING_QUIRKS_MODE_NONE,
- BINDING_QUIRKS_MODE_LIMITED,
- BINDING_QUIRKS_MODE_FULL
-} binding_quirks_mode;
-
-binding_error binding_create_tree(void **ctx, const char *charset, bool enable_script, dom_script script, void *context);
-binding_error binding_destroy_tree(void *ctx);
-
-binding_error binding_parse_chunk(void *ctx, const uint8_t *data, size_t len);
-binding_error binding_parse_completed(void *ctx);
-
-const char *binding_get_encoding(void *ctx, binding_encoding_source *source);
-dom_document *binding_get_document(void *ctx, binding_quirks_mode *quirks);
-
-struct form *binding_get_forms(void *ctx);
-struct form_control *binding_get_control_for_node(void *ctx, dom_node *node);
-
-void binding_destroy_document(dom_document *doc);
-
-#endif
-