mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-14 00:07:25 +03:00
449 lines
11 KiB
Plaintext
449 lines
11 KiB
Plaintext
/* document binding for browser using duktape and libdom
|
|
*
|
|
* Copyright 2015 Vincent Sanders <vince@netsurf-browser.org>
|
|
*
|
|
* 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 "html/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();
|