/* document binding for browser using duktape and libdom * * Copyright 2015 Vincent Sanders * * This file is part of NetSurf, http://www.netsurf-browser.org/ * * Released under the terms of the MIT License, * http://www.opensource.org/licenses/mit-license */ prologue Document() %{ #include "utils/corestrings.h" #include "utils/libdom.h" #include "utils/utils.h" #include "content/hlcache.h" #include "render/html_internal.h" #include "content/urldb.h" #define HANDLER_MAGIC MAGIC(HANDLER_MAP) %} init Document(struct dom_document *document::node); method Document::write() %{ struct html_content *htmlc; duk_size_t text_len; dom_exception err; const char *text; for (int i = 0; i < duk_get_top(ctx); ++i) { duk_safe_to_string(ctx, i); } duk_concat(ctx, duk_get_top(ctx)); text = duk_safe_to_lstring(ctx, 0, &text_len); JS_LOG("Writing %*s", (int)text_len, text); err = dom_node_get_user_data(priv->parent.node, corestring_dom___ns_key_html_content_data, &htmlc); if ((err != DOM_NO_ERR) || (htmlc == NULL)) { NSLOG(netsurf, INFO, "error getting htmlc. parent node:%p htmlc:%p", priv->parent.node, htmlc); return 0; } else if (htmlc->parser == NULL) { NSLOG(netsurf, INFO, "error; no parser for htmlc: %p", htmlc); return 0; } dom_hubbub_parser_insert_chunk(htmlc->parser, (uint8_t *)text, text_len); return 0; %} method Document::writeln() %{ const char nl[] = "\n"; struct html_content *htmlc; duk_size_t text_len; const char *text; dom_exception err; for (int i = 0; i < duk_get_top(ctx); ++i) { duk_safe_to_string(ctx, i); } duk_concat(ctx, duk_get_top(ctx)); text = duk_safe_to_lstring(ctx, 0, &text_len); JS_LOG("Writeln %*s", (int)text_len, text); err = dom_node_get_user_data(priv->parent.node, corestring_dom___ns_key_html_content_data, &htmlc); if ((err != DOM_NO_ERR) || (htmlc == NULL)) { NSLOG(netsurf, INFO, "error getting htmlc. parent node:%p htmlc:%p", priv->parent.node, htmlc); return 0; } else if (htmlc->parser == NULL) { NSLOG(netsurf, INFO, "error; no parser for htmlc: %p", htmlc); return 0; } dom_hubbub_parser_insert_chunk(htmlc->parser, (uint8_t *)text, text_len); dom_hubbub_parser_insert_chunk(htmlc->parser, (uint8_t *)nl, SLEN(nl)); return 0; %} method Document::createTextNode() %{ dom_node *newnode; dom_exception err; duk_size_t text_len; const char *text = duk_safe_to_lstring(ctx, 0, &text_len); dom_string *text_str; err = dom_string_create((const uint8_t*)text, text_len, &text_str); if (err != DOM_NO_ERR) return 0; /* coerced to undefined */ err = dom_document_create_text_node(priv->parent.node, text_str, &newnode); if (err != DOM_NO_ERR) { dom_string_unref(text_str); return 0; /* coerced to undefined */ } dom_string_unref(text_str); dukky_push_node(ctx, newnode); dom_node_unref(newnode); return 1; %} method Document::createElement() %{ dom_node *newnode; dom_exception err; duk_size_t text_len; const char *text = duk_safe_to_lstring(ctx, 0, &text_len); dom_string *text_str; err = dom_string_create((const uint8_t*)text, text_len, &text_str); if (err != DOM_NO_ERR) return 0; /* coerced to undefined */ err = dom_document_create_element_ns(priv->parent.node, corestring_dom_html_namespace, text_str, &newnode); if (err != DOM_NO_ERR) { dom_string_unref(text_str); return 0; /* coerced to undefined */ } dom_string_unref(text_str); dukky_push_node(ctx, newnode); dom_node_unref(newnode); return 1; %} getter Document::head() %{ struct dom_nodelist *nodes; struct dom_node *retnode; dom_exception err; err = dom_document_get_elements_by_tag_name(priv->parent.node, corestring_dom_HEAD, &nodes); if (err != DOM_NO_ERR) return 0; /* coerced to undefined */ err = dom_nodelist_item(nodes, 0, &retnode); if (err != DOM_NO_ERR) { dom_nodelist_unref(nodes); return 0; /* coerced to undefined */ } dom_nodelist_unref(nodes); if (retnode == NULL) return 0; /* coerced to undefined */ dukky_push_node(ctx, retnode); dom_node_unref(retnode); return 1; %} getter Document::body() %{ struct dom_nodelist *nodes; struct dom_node *retnode; dom_exception err; err = dom_document_get_elements_by_tag_name(priv->parent.node, corestring_dom_BODY, &nodes); if (err != DOM_NO_ERR) { return 0; /* coerced to undefined */ } err = dom_nodelist_item(nodes, 0, &retnode); if (err != DOM_NO_ERR) { dom_nodelist_unref(nodes); return 0; /* coerced to undefined */ } dom_nodelist_unref(nodes); if (retnode != NULL) { dukky_push_node(ctx, retnode); dom_node_unref(retnode); return 1; } return 0; /* coerced to undefined */ %} getter Document::location() %{ /* retrieve the location object from the root object (window) */ duk_push_global_object(ctx); duk_get_prop_string(ctx, -1, "location"); if (duk_is_undefined(ctx, -1)) { duk_pop(ctx); return 0; } return 1; %} method Document::getElementById() %{ dom_string *elementId_dom; dom_element *element; dom_exception exc; duk_size_t text_len; const char *text = duk_safe_to_lstring(ctx, 0, &text_len); exc = dom_string_create((uint8_t*)text, text_len, &elementId_dom); if (exc != DOM_NO_ERR) { return 0; } exc = dom_document_get_element_by_id(((node_private_t *)priv)->node, elementId_dom, &element); dom_string_unref(elementId_dom); if (exc != DOM_NO_ERR) { return 0; } if (element != NULL) { dukky_push_node(ctx, (dom_node *)element); dom_node_unref(element); return 1; } return 0; %} getter Document::documentElement() %{ dom_exception exc; dom_element *element; exc = dom_document_get_document_element(((node_private_t *)priv)->node, &element); if (exc != DOM_NO_ERR) { return 0; } if (element == NULL) { return 0; } dukky_push_node(ctx, (dom_node *)element); dom_node_unref(element); return 1; %} method Document::getElementsByTagName() %{ dom_nodelist *nodes; dom_exception err; duk_size_t text_len; const char *text = duk_safe_to_lstring(ctx, 0, &text_len); dom_string *tag; err = dom_string_create((uint8_t*)text, text_len, &tag); if (err != DOM_NO_ERR) return 0; /* coerced to undefined */ err = dom_document_get_elements_by_tag_name(((node_private_t *)priv)->node, tag, &nodes); dom_string_unref(tag); if (err != DOM_NO_ERR) return 0; /* coerced to undefined */ if (nodes == NULL) return 0; /* coerced to undefined */ duk_push_pointer(ctx, nodes); dukky_create_object(ctx, PROTO_NAME(NODELIST), 1); dom_nodelist_unref(nodes); return 1; %} getter Document::cookie() %{ char *cookie_str; struct html_content *htmlc; dom_exception err; err = dom_node_get_user_data(priv->parent.node, corestring_dom___ns_key_html_content_data, &htmlc); if ((err == DOM_NO_ERR) && (htmlc != NULL)) { cookie_str = urldb_get_cookie(llcache_handle_get_url(htmlc->base.llcache), false); if (cookie_str != NULL) { duk_push_string(ctx, cookie_str); free(cookie_str); return 1; } } else { NSLOG(netsurf, INFO, "error getting htmlc. parent node:%p htmlc:%p", priv->parent.node, htmlc); } return 0; %} getter Document::onabort(); setter Document::onabort(); getter Document::onautocompleteerror(); setter Document::onautocompleteerror(); getter Document::onautocomplete(); setter Document::onautocomplete(); getter Document::onblur(); setter Document::onblur(); getter Document::oncancel(); setter Document::oncancel(); getter Document::oncanplaythrough(); setter Document::oncanplaythrough(); getter Document::oncanplay(); setter Document::oncanplay(); getter Document::onchange(); setter Document::onchange(); getter Document::onclick(); setter Document::onclick(); getter Document::onclose(); setter Document::onclose(); getter Document::oncontextmenu(); setter Document::oncontextmenu(); getter Document::oncuechange(); setter Document::oncuechange(); getter Document::ondblclick(); setter Document::ondblclick(); getter Document::ondragend(); setter Document::ondragend(); getter Document::ondragenter(); setter Document::ondragenter(); getter Document::ondragexit(); setter Document::ondragexit(); getter Document::ondragleave(); setter Document::ondragleave(); getter Document::ondragover(); setter Document::ondragover(); getter Document::ondragstart(); setter Document::ondragstart(); getter Document::ondrag(); setter Document::ondrag(); getter Document::ondrop(); setter Document::ondrop(); getter Document::ondurationchange(); setter Document::ondurationchange(); getter Document::onemptied(); setter Document::onemptied(); getter Document::onended(); setter Document::onended(); getter Document::onfocus(); setter Document::onfocus(); getter Document::oninput(); setter Document::oninput(); getter Document::oninvalid(); setter Document::oninvalid(); getter Document::onkeydown(); setter Document::onkeydown(); getter Document::onkeypress(); setter Document::onkeypress(); getter Document::onkeyup(); setter Document::onkeyup(); getter Document::onloadeddata(); setter Document::onloadeddata(); getter Document::onloadedmetadata(); setter Document::onloadedmetadata(); getter Document::onloadstart(); setter Document::onloadstart(); getter Document::onload(); setter Document::onload(); getter Document::onmousedown(); setter Document::onmousedown(); getter Document::onmouseenter(); setter Document::onmouseenter(); getter Document::onmouseleave(); setter Document::onmouseleave(); getter Document::onmousemove(); setter Document::onmousemove(); getter Document::onmouseout(); setter Document::onmouseout(); getter Document::onmouseover(); setter Document::onmouseover(); getter Document::onmouseup(); setter Document::onmouseup(); getter Document::onpause(); setter Document::onpause(); getter Document::onplaying(); setter Document::onplaying(); getter Document::onplay(); setter Document::onplay(); getter Document::onprogress(); setter Document::onprogress(); getter Document::onratechange(); setter Document::onratechange(); getter Document::onreadystatechange(); setter Document::onreadystatechange(); getter Document::onreset(); setter Document::onreset(); getter Document::onresize(); setter Document::onresize(); getter Document::onscroll(); setter Document::onscroll(); getter Document::onseeked(); setter Document::onseeked(); getter Document::onseeking(); setter Document::onseeking(); getter Document::onselect(); setter Document::onselect(); getter Document::onshow(); setter Document::onshow(); getter Document::onsort(); setter Document::onsort(); getter Document::onstalled(); setter Document::onstalled(); getter Document::onsubmit(); setter Document::onsubmit(); getter Document::onsuspend(); setter Document::onsuspend(); getter Document::ontimeupdate(); setter Document::ontimeupdate(); getter Document::ontoggle(); setter Document::ontoggle(); getter Document::onvolumechange(); setter Document::onvolumechange(); getter Document::onwaiting(); setter Document::onwaiting(); getter Document::onwheel(); setter Document::onwheel();