mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-23 04:26:50 +03:00
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>
This commit is contained in:
parent
310247ef82
commit
2325062ff1
@ -11,6 +11,7 @@
|
|||||||
class Element {
|
class Element {
|
||||||
prologue %{
|
prologue %{
|
||||||
#include <utils/corestrings.h>
|
#include <utils/corestrings.h>
|
||||||
|
#include <dom/bindings/hubbub/parser.h>
|
||||||
%};
|
%};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -391,3 +392,125 @@ setter Element::className ()
|
|||||||
return 0;
|
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;
|
||||||
|
%}
|
||||||
|
Loading…
Reference in New Issue
Block a user