summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2020-02-21 18:02:57 +0000
committerDaniel Silverstone <dsilvers@digital-scurf.org>2020-02-21 18:02:57 +0000
commit2325062ff1429ab9a19ff2db251fa13b0799a276 (patch)
treeee1516d10c3fe6a33dc453e6b378a43a9724931c
parent310247ef82a99512d7f3302b149a1bae0736b34f (diff)
downloadnetsurf-2325062ff1429ab9a19ff2db251fa13b0799a276.tar.gz
netsurf-2325062ff1429ab9a19ff2db251fa13b0799a276.tar.bz2
Element: support innerHTML
To get us further along the JavaScript pathway, support the getter and setter for innerHTML. The getter always returns an empty string for now, but the setter works. Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
-rw-r--r--content/handlers/javascript/duktape/Element.bnd123
1 files changed, 123 insertions, 0 deletions
diff --git a/content/handlers/javascript/duktape/Element.bnd b/content/handlers/javascript/duktape/Element.bnd
index 6702342e1..35157d5cd 100644
--- a/content/handlers/javascript/duktape/Element.bnd
+++ b/content/handlers/javascript/duktape/Element.bnd
@@ -11,6 +11,7 @@
class Element {
prologue %{
#include <utils/corestrings.h>
+#include <dom/bindings/hubbub/parser.h>
%};
};
@@ -391,3 +392,125 @@ setter Element::className ()
return 0;
%}
+getter Element::innerHTML()
+%{
+ duk_push_lstring(ctx, "", 0);
+ return 1;
+%}
+
+setter Element::innerHTML()
+%{
+ duk_size_t size;
+ const char *s = duk_safe_to_lstring(ctx, 0, &size);
+ dom_hubbub_parser_params parse_params;
+ dom_hubbub_error error;
+ dom_hubbub_parser *parser = NULL;
+ struct dom_document *doc = NULL;
+ struct dom_document_fragment *fragment = NULL;
+ dom_exception exc;
+ struct dom_node *child = NULL, *html = NULL, *body = NULL;
+ struct dom_nodelist *bodies = NULL;
+
+ exc = dom_node_get_owner_document(priv->parent.node, &doc);
+ if (exc != DOM_NO_ERR) goto out;
+
+ parse_params.enc = "UTF-8";
+ parse_params.fix_enc = true;
+ parse_params.enable_script = false;
+ parse_params.msg = NULL;
+ parse_params.script = NULL;
+ parse_params.ctx = NULL;
+ parse_params.daf = NULL;
+
+ error = dom_hubbub_fragment_parser_create(&parse_params,
+ doc,
+ &parser,
+ &fragment);
+ if (error != DOM_HUBBUB_OK) {
+ NSLOG(netsurf, ERROR, "Unable to create fragment parser!");
+ goto out;
+ }
+
+ error = dom_hubbub_parser_parse_chunk(parser, (const uint8_t*)s, size);
+ if (error != DOM_HUBBUB_OK) {
+ NSLOG(netsurf, ERROR, "Unable to parse HTML chunk");
+ goto out;
+ }
+ error = dom_hubbub_parser_completed(parser);
+ if (error != DOM_HUBBUB_OK) {
+ NSLOG(netsurf, ERROR, "Unable to complete parser");
+ goto out;
+ }
+
+ /* Parse is finished, transfer contents of fragment into node */
+
+ /* 1. empty this node */
+ exc = dom_node_get_first_child(priv->parent.node, &child);
+ if (exc != DOM_NO_ERR) goto out;
+ while (child != NULL) {
+ struct dom_node *cref;
+ exc = dom_node_remove_child(priv->parent.node, child, &cref);
+ if (exc != DOM_NO_ERR) goto out;
+ dom_node_unref(child);
+ child = NULL;
+ dom_node_unref(cref);
+ exc = dom_node_get_first_child(priv->parent.node, &child);
+ if (exc != DOM_NO_ERR) goto out;
+ }
+
+ /* 2. the first child in the fragment will be an HTML element
+ * because that's how hubbub works, walk through that to the body
+ * element hubbub will have created, we want to migrate that element's
+ * children into ourself.
+ */
+ exc = dom_node_get_first_child(fragment, &html);
+ if (exc != DOM_NO_ERR) goto out;
+
+ /* We can then ask that HTML element to give us its body */
+ exc = dom_element_get_elements_by_tag_name(html, corestring_dom_BODY, &bodies);
+ if (exc != DOM_NO_ERR) goto out;
+
+ /* And now we can get the body which will be the zeroth body */
+ exc = dom_nodelist_item(bodies, 0, &body);
+ if (exc != DOM_NO_ERR) goto out;
+
+ /* 3. Migrate the children */
+ exc = dom_node_get_first_child(body, &child);
+ if (exc != DOM_NO_ERR) goto out;
+ while (child != NULL) {
+ struct dom_node *cref;
+ exc = dom_node_remove_child(body, child, &cref);
+ if (exc != DOM_NO_ERR) goto out;
+ dom_node_unref(cref);
+ exc = dom_node_append_child(priv->parent.node, child, &cref);
+ if (exc != DOM_NO_ERR) goto out;
+ dom_node_unref(cref);
+ dom_node_unref(child);
+ child = NULL;
+ exc = dom_node_get_first_child(body, &child);
+ if (exc != DOM_NO_ERR) goto out;
+ }
+out:
+ if (parser != NULL) {
+ dom_hubbub_parser_destroy(parser);
+ }
+ if (doc != NULL) {
+ dom_node_unref(doc);
+ }
+ if (fragment != NULL) {
+ dom_node_unref(fragment);
+ }
+ if (child != NULL) {
+ dom_node_unref(child);
+ }
+ if (html != NULL) {
+ dom_node_unref(html);
+ }
+ if (bodies != NULL) {
+ dom_nodelist_unref(bodies);
+ }
+ if (body != NULL) {
+ dom_node_unref(body);
+ }
+ return 0;
+%}