1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00

[mujs] checkpoint

Code at least is compilable.
This commit is contained in:
Witold Filipczyk 2022-08-15 21:21:19 +02:00
parent 5f79e6e91c
commit 00db3c9d76
24 changed files with 7292 additions and 1 deletions

View File

@ -26,8 +26,11 @@
#include "ecmascript/ecmascript.h"
#include "ecmascript/mujs.h"
#include "ecmascript/mujs/console.h"
#include "ecmascript/mujs/document.h"
#include "ecmascript/mujs/element.h"
#include "ecmascript/mujs/history.h"
#include "ecmascript/mujs/localstorage.h"
#include "ecmascript/mujs/location.h"
#include "ecmascript/mujs/navigator.h"
#include "ecmascript/mujs/screen.h"
#include "ecmascript/mujs/unibar.h"
@ -89,6 +92,9 @@ mujs_get_interpreter(struct ecmascript_interpreter *interpreter)
mjs_history_init(J);
mjs_console_init(J);
mjs_localstorage_init(J);
mjs_element_init(J);
mjs_document_init(J);
mjs_location_init(J);
return J;
#if 0

View File

@ -0,0 +1,136 @@
/* The MuJS attr object implementation. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "elinks.h"
#include "bfu/dialog.h"
#include "cache/cache.h"
#include "cookies/cookies.h"
#include "dialogs/menu.h"
#include "dialogs/status.h"
#include "document/html/frames.h"
#include "document/document.h"
#include "document/forms.h"
#include "document/view.h"
#include "ecmascript/ecmascript.h"
#include "ecmascript/mujs.h"
#include "ecmascript/mujs/attr.h"
#include "intl/libintl.h"
#include "main/select.h"
#include "osdep/newwin.h"
#include "osdep/sysname.h"
#include "protocol/http/http.h"
#include "protocol/uri.h"
#include "session/history.h"
#include "session/location.h"
#include "session/session.h"
#include "session/task.h"
#include "terminal/tab.h"
#include "terminal/terminal.h"
#include "util/conv.h"
#include "util/memory.h"
#include "util/string.h"
#include "viewer/text/draw.h"
#include "viewer/text/form.h"
#include "viewer/text/link.h"
#include "viewer/text/vs.h"
#include <libxml/tree.h>
#include <libxml/HTMLparser.h>
#include <libxml++/libxml++.h>
#include <libxml++/attributenode.h>
#include <libxml++/parsers/domparser.h>
#include <iostream>
#include <algorithm>
#include <string>
static void
mjs_attr_get_property_name(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
xmlpp::AttributeNode *attr = static_cast<xmlpp::AttributeNode *>(js_touserdata(J, 0, "attr"));
if (!attr) {
js_pushnull(J);
return;
}
xmlpp::ustring v = attr->get_name();
js_pushstring(J, v.c_str());
}
static void
mjs_attr_get_property_value(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
xmlpp::AttributeNode *attr = static_cast<xmlpp::AttributeNode *>(js_touserdata(J, 0, "attr"));
if (!attr) {
js_pushnull(J);
return;
}
xmlpp::ustring v = attr->get_value();
js_pushstring(J, v.c_str());
}
static void
mjs_attr_toString(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
js_pushstring(J, "[attr object]");
}
static std::map<void *, void *> map_attrs;
static
void mjs_attr_finalizer(js_State *J, void *node)
{
map_attrs.erase(node);
}
void
mjs_push_attr(js_State *J, void *node)
{
js_newobject(J);
{
js_newuserdata(J, "attr", node, mjs_attr_finalizer);
addmethod(J, "toString", mjs_attr_toString, 0);
addproperty(J, "name", mjs_attr_get_property_name, NULL);
addproperty(J, "value", mjs_attr_get_property_value, NULL);
}
}

View File

@ -0,0 +1,8 @@
#ifndef EL__ECMASCRIPT_MUJS_ATTR_H
#define EL__ECMASCRIPT_MUJS_ATTR_H
#include <mujs.h>
void mjs_push_attr(js_State *J, void *node);
#endif

View File

@ -0,0 +1,238 @@
/* The MuJS attributes object implementation. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "elinks.h"
#include "bfu/dialog.h"
#include "cache/cache.h"
#include "cookies/cookies.h"
#include "dialogs/menu.h"
#include "dialogs/status.h"
#include "document/html/frames.h"
#include "document/document.h"
#include "document/forms.h"
#include "document/view.h"
#include "ecmascript/ecmascript.h"
#include "ecmascript/mujs.h"
#include "ecmascript/mujs/attr.h"
#include "ecmascript/mujs/attributes.h"
#include "intl/libintl.h"
#include "main/select.h"
#include "osdep/newwin.h"
#include "osdep/sysname.h"
#include "protocol/http/http.h"
#include "protocol/uri.h"
#include "session/history.h"
#include "session/location.h"
#include "session/session.h"
#include "session/task.h"
#include "terminal/tab.h"
#include "terminal/terminal.h"
#include "util/conv.h"
#include "util/memory.h"
#include "util/string.h"
#include "viewer/text/draw.h"
#include "viewer/text/form.h"
#include "viewer/text/link.h"
#include "viewer/text/vs.h"
#include <libxml/tree.h>
#include <libxml/HTMLparser.h>
#include <libxml++/libxml++.h>
#include <libxml++/attributenode.h>
#include <libxml++/parsers/domparser.h>
#include <iostream>
#include <algorithm>
#include <string>
static std::map<void *, void *> map_attributes;
static std::map<void *, void *> map_rev_attributes;
static void
mjs_attributes_set_items(js_State *J, void *node)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
assert(interpreter);
xmlpp::Element::AttributeList *al = static_cast<xmlpp::Element::AttributeList *>(node);
if (!al) {
return;
}
auto it = al->begin();
auto end = al->end();
int i = 0;
for (;it != end; ++it, ++i) {
xmlpp::Attribute *attr = *it;
if (!attr) {
continue;
}
// TODO Check it
mjs_push_attr(J, attr);
js_dup(J);
js_setindex(J, -2, i);
xmlpp::ustring name = attr->get_name();
if (name != "" && name != "item" && name != "namedItem") {
js_setproperty(J, -2, name.c_str());
}
js_pop(J, 1);
}
}
static void
mjs_attributes_get_property_length(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
xmlpp::Element::AttributeList *al = static_cast<xmlpp::Element::AttributeList *>(js_touserdata(J, 0, "attribute"));
if (!al) {
js_pushnumber(J, 0);
return;
}
js_pushnumber(J, al->size());
}
static void
mjs_push_attributes_item2(js_State *J, int idx)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
xmlpp::Element::AttributeList *al = static_cast<xmlpp::Element::AttributeList *>(js_touserdata(J, 0, "attribute"));
if (!al) {
js_pushundefined(J);
return;
}
auto it = al->begin();
auto end = al->end();
int i = 0;
for (;it != end; it++, i++) {
if (i != idx) {
continue;
}
xmlpp::Attribute *attr = *it;
mjs_push_attr(J, attr);
return;
}
js_pushundefined(J);
}
static void
mjs_attributes_item(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
int index = js_toint32(J, 1);
mjs_push_attributes_item2(J, index);
}
static void
mjs_push_attributes_namedItem2(js_State *J, const char *str)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
xmlpp::Element::AttributeList *al = static_cast<xmlpp::Element::AttributeList *>(js_touserdata(J, 0, "attribute"));
if (!al) {
js_pushundefined(J);
return;
}
xmlpp::ustring name = str;
auto it = al->begin();
auto end = al->end();
for (; it != end; ++it) {
auto attr = dynamic_cast<xmlpp::AttributeNode*>(*it);
if (!attr) {
continue;
}
if (name == attr->get_name()) {
mjs_push_attr(J, attr);
return;
}
}
js_pushundefined(J);
}
static void
mjs_attributes_getNamedItem(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
const char *str = js_tostring(J, 1);
mjs_push_attributes_namedItem2(J, str);
}
static void
mjs_attributes_toString(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
js_pushstring(J, "[attributes object]");
}
static void
mjs_attributes_finalizer(js_State *J, void *node)
{
map_attributes.erase(node);
}
void
mjs_push_attributes(js_State *J, void *node)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
js_newobject(J);
{
js_newuserdata(J, "attribute", node, mjs_attributes_finalizer);
addmethod(J, "item", mjs_attributes_item, 1);
addmethod(J, "getNamedItem", mjs_attributes_getNamedItem, 1);
addmethod(J, "toString", mjs_attributes_toString, 0);
addproperty(J, "length", mjs_attributes_get_property_length, NULL);
mjs_attributes_set_items(J, node);
}
map_attributes[node] = node;
}

View File

@ -0,0 +1,8 @@
#ifndef EL__ECMASCRIPT_MUJS_ATTRIBUTES_H
#define EL__ECMASCRIPT_MUJS_ATTRIBUTES_H
#include <mujs.h>
void mjs_push_attributes(js_State *J, void *node);
#endif

View File

@ -0,0 +1,231 @@
/* The MuJS html collection object implementation. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "elinks.h"
#include "bfu/dialog.h"
#include "cache/cache.h"
#include "cookies/cookies.h"
#include "dialogs/menu.h"
#include "dialogs/status.h"
#include "document/html/frames.h"
#include "document/document.h"
#include "document/forms.h"
#include "document/view.h"
#include "ecmascript/ecmascript.h"
#include "ecmascript/mujs.h"
#include "ecmascript/mujs/collection.h"
#include "ecmascript/mujs/element.h"
#include "intl/libintl.h"
#include "main/select.h"
#include "osdep/newwin.h"
#include "osdep/sysname.h"
#include "protocol/http/http.h"
#include "protocol/uri.h"
#include "session/history.h"
#include "session/location.h"
#include "session/session.h"
#include "session/task.h"
#include "terminal/tab.h"
#include "terminal/terminal.h"
#include "util/conv.h"
#include "util/memory.h"
#include "util/string.h"
#include "viewer/text/draw.h"
#include "viewer/text/form.h"
#include "viewer/text/link.h"
#include "viewer/text/vs.h"
#include <libxml/tree.h>
#include <libxml/HTMLparser.h>
#include <libxml++/libxml++.h>
#include <libxml++/attributenode.h>
#include <libxml++/parsers/domparser.h>
#include <iostream>
#include <algorithm>
#include <map>
#include <string>
static std::map<void *, void *> map_collections;
static std::map<void *, void *> map_rev_collections;
static void
mjs_htmlCollection_get_property_length(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
xmlpp::Node::NodeSet *ns = static_cast<xmlpp::Node::NodeSet *>(js_touserdata(J, 0, "collection"));
if (!ns) {
js_pushnumber(J, 0);
return;
}
js_pushnumber(J, ns->size());
}
static void
mjs_push_htmlCollection_item2(js_State *J, int idx)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
xmlpp::Node::NodeSet *ns = static_cast<xmlpp::Node::NodeSet *>(js_touserdata(J, 0, "collection"));
if (!ns) {
js_pushundefined(J);
return;
}
xmlpp::Element *element;
try {
element = dynamic_cast<xmlpp::Element *>(ns->at(idx));
} catch (std::out_of_range &e) {
js_pushundefined(J);
return;
}
if (!element) {
js_pushundefined(J);
return;
}
mjs_push_element(J, element);
}
static void
mjs_htmlCollection_item(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
int index = js_toint32(J, 1);
mjs_push_htmlCollection_item2(J, index);
}
static void
mjs_push_htmlCollection_namedItem2(js_State *J, const char *str)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
xmlpp::Node::NodeSet *ns = static_cast<xmlpp::Node::NodeSet *>(js_touserdata(J, 0, "collection"));
if (!ns) {
js_pushundefined(J);
return;
}
xmlpp::ustring name = str;
auto it = ns->begin();
auto end = ns->end();
for (; it != end; ++it) {
auto element = dynamic_cast<xmlpp::Element*>(*it);
if (!element) {
continue;
}
if (name == element->get_attribute_value("id")
|| name == element->get_attribute_value("name")) {
mjs_push_element(J, element);
return;
}
}
js_pushundefined(J);
}
static void
mjs_htmlCollection_namedItem(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
const char *str = js_tostring(J, 1);
mjs_push_htmlCollection_namedItem2(J, str);
}
static void
mjs_htmlCollection_set_items(js_State *J, void *node)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
int counter = 0;
xmlpp::Node::NodeSet *ns = static_cast<xmlpp::Node::NodeSet *>(js_touserdata(J, 0, "collection"));
if (!ns) {
return;
}
xmlpp::Element *element;
while (1) {
try {
element = dynamic_cast<xmlpp::Element *>(ns->at(counter));
} catch (std::out_of_range &e) { return;}
if (!element) {
return;
}
mjs_push_element(J, element);
js_dup(J);
js_setindex(J, -2, counter);
xmlpp::ustring name = element->get_attribute_value("id");
if (name == "") {
name = element->get_attribute_value("name");
}
if (name != "" && name != "item" && name != "namedItem") {
js_setproperty(J, -2, name.c_str());
}
js_pop(J, 1);
counter++;
}
}
static void
mjs_htmlCollection_toString(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
js_pushstring(J, "[htmlCollection object]");
}
static void
mjs_htmlCollection_finalizer(js_State *J, void *node)
{
map_collections.erase(node);
}
void
mjs_push_collection(js_State *J, void *node)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
js_newobject(J);
{
js_newuserdata(J, "collection", node, mjs_htmlCollection_finalizer);
addmethod(J, "item", mjs_htmlCollection_item, 1);
addmethod(J, "namedItem", mjs_htmlCollection_namedItem, 1);
addmethod(J, "toString", mjs_htmlCollection_toString, 0);
addproperty(J, "length", mjs_htmlCollection_get_property_length, NULL);
mjs_htmlCollection_set_items(J, node);
}
map_collections[node] = node;
}

View File

@ -0,0 +1,8 @@
#ifndef EL__ECMASCRIPT_MUJS_COLLECTION_H
#define EL__ECMASCRIPT_MUJS_COLLECTION_H
#include <mujs.h>
void mjs_push_collection(js_State *J, void *node);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
#ifndef EL__ECMASCRIPT_MUJS_DOCUMENT_H
#define EL__ECMASCRIPT_MUJS_DOCUMENT_H
#include <mujs.h>
void mjs_push_document(js_State *J, void *doc);
int mjs_document_init(js_State *J);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
#ifndef EL__ECMASCRIPT_MUJS_ELEMENT_H
#define EL__ECMASCRIPT_MUJS_ELEMENT_H
#include <mujs.h>
int mjs_element_init(js_State *J);
void mjs_push_element(js_State *J, void *node);
void walk_tree(struct string *buf, void *nod, bool start = true, bool toSortAttrs = false);
#endif

View File

@ -0,0 +1,842 @@
/* The MuJS form object implementation. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "elinks.h"
#include "bfu/dialog.h"
#include "cache/cache.h"
#include "cookies/cookies.h"
#include "dialogs/menu.h"
#include "dialogs/status.h"
#include "document/html/frames.h"
#include "document/document.h"
#include "document/forms.h"
#include "document/view.h"
#include "ecmascript/ecmascript.h"
#include "ecmascript/mujs.h"
#include "ecmascript/mujs/document.h"
#include "ecmascript/mujs/form.h"
#include "ecmascript/mujs/forms.h"
#include "ecmascript/mujs/input.h"
#include "ecmascript/mujs/window.h"
#include "intl/libintl.h"
#include "main/select.h"
#include "osdep/newwin.h"
#include "osdep/sysname.h"
#include "protocol/http/http.h"
#include "protocol/uri.h"
#include "session/history.h"
#include "session/location.h"
#include "session/session.h"
#include "session/task.h"
#include "terminal/tab.h"
#include "terminal/terminal.h"
#include "util/conv.h"
#include "util/memory.h"
#include "util/string.h"
#include "viewer/text/draw.h"
#include "viewer/text/form.h"
#include "viewer/text/link.h"
#include "viewer/text/vs.h"
#include <libxml++/libxml++.h>
#include <map>
static std::map<struct form_view *, void *> map_form_elements;
static std::map<void *, struct form_view *> map_elements_form;
static std::map<struct form *, void *> map_form;
static std::map<void *, struct form *> map_rev_form;
//void mjs_push_form_object(js_State *J, struct form *form);
static void
mjs_push_form_control_object(js_State *J,
enum form_type type, struct form_state *fs)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
switch (type) {
case FC_TEXT:
case FC_PASSWORD:
case FC_FILE:
case FC_CHECKBOX:
case FC_RADIO:
case FC_SUBMIT:
case FC_IMAGE:
case FC_RESET:
case FC_BUTTON:
case FC_HIDDEN:
case FC_SELECT:
mjs_push_input_object(J, fs);
return;
case FC_TEXTAREA:
/* TODO */
js_pushnull(J);
return;
default:
INTERNAL("Weird fc->type %d", type);
js_pushnull(J);
return;
}
}
static void
mjs_form_set_items(js_State *J, void *node)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct document_view *doc_view;
struct document *document;
struct form_view *form_view;
struct form *form;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
vs = interpreter->vs;
doc_view = vs->doc_view;
document = doc_view->document;
form_view = (struct form_view *)node;
if (!form_view) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
return; /* detached */
}
form = find_form_by_form_view(document, form_view);
int counter = 0;
struct el_form_control *fc;
foreach (fc, form->items) {
struct form_state *fs = find_form_state(doc_view, fc);
if (!fs) {
continue;
}
mjs_push_form_control_object(J, fc->type, fs);
js_dup(J);
js_setindex(J, 0, counter);
if (fc->id && strcmp(fc->id, "item") && strcmp(fc->id, "namedItem")) {
js_setproperty(J, 0, fc->id);
} else if (fc->name && strcmp(fc->name, "item") && strcmp(fc->name, "namedItem")) {
js_setproperty(J, 0, fc->name);
} else {
js_pop(J, 1);
}
counter++;
}
}
static void
mjs_form_set_items2(js_State *J, void *node)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct document_view *doc_view;
struct form *form;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
vs = interpreter->vs;
doc_view = vs->doc_view;
form = (struct form *)node;
int counter = 0;
struct el_form_control *fc;
foreach (fc, form->items) {
struct form_state *fs = find_form_state(doc_view, fc);
if (!fs) {
continue;
}
mjs_push_form_control_object(J, fc->type, fs);
js_dup(J);
js_setindex(J, 0, counter);
if (fc->id && strcmp(fc->id, "item") && strcmp(fc->id, "namedItem")) {
js_setproperty(J, 0, fc->id);
} else if (fc->name && strcmp(fc->name, "item") && strcmp(fc->name, "namedItem")) {
js_setproperty(J, 0, fc->name);
} else {
js_pop(J, 1);
}
counter++;
}
}
static void
mjs_form_elements_get_property_length(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct document_view *doc_view;
struct document *document;
struct form_view *form_view;
struct form *form;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushundefined(J);
return;
}
doc_view = vs->doc_view;
document = doc_view->document;
form_view = (struct form_view *)js_touserdata(J, 0, "form_view");
if (!form_view) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushundefined(J);
return; /* detached */
}
form = find_form_by_form_view(document, form_view);
js_pushnumber(J, list_size(&form->items));
}
static void
mjs_form_elements_item2(js_State *J, int index)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct document_view *doc_view;
struct document *document;
struct form_view *form_view;
struct form *form;
struct el_form_control *fc;
int counter = -1;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
vs = interpreter->vs;
doc_view = vs->doc_view;
document = doc_view->document;
form_view = (struct form_view *)js_touserdata(J, 0, "form_view");
if (!form_view) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return; /* detached */
}
form = find_form_by_form_view(document, form_view);
foreach (fc, form->items) {
counter++;
if (counter == index) {
struct form_state *fs = find_form_state(doc_view, fc);
if (fs) {
mjs_push_form_control_object(J, fc->type, fs);
return;
}
}
}
js_pushundefined(J);
}
/* @form_elements_funcs{"item"} */
static void
mjs_form_elements_item(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
int index = js_toint32(J, 1);
mjs_form_elements_item2(J, index);
}
static void
mjs_form_elements_namedItem2(js_State *J, const char *string)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct document_view *doc_view;
struct document *document;
struct form_view *form_view;
struct form *form;
struct el_form_control *fc;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
if (!*string) {
js_pushundefined(J);
return;
}
vs = interpreter->vs;
doc_view = vs->doc_view;
document = doc_view->document;
form_view = (struct form_view *)js_touserdata(J, 0, "form_view");
if (!form_view) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return; /* detached */
}
form = find_form_by_form_view(document, form_view);
foreach (fc, form->items) {
if ((fc->id && !c_strcasecmp(string, fc->id))
|| (fc->name && !c_strcasecmp(string, fc->name))) {
struct form_state *fs = find_form_state(doc_view, fc);
if (fs) {
mjs_push_form_control_object(J, fc->type, fs);
return;
}
}
}
js_pushundefined(J);
}
/* @form_elements_funcs{"namedItem"} */
static void
mjs_form_elements_namedItem(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
const char *str = js_tostring(J, 1);
if (!str) {
js_pushnull(J);
return;
}
mjs_form_elements_namedItem2(J, str);
}
static void
mjs_form_elements_toString(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
js_pushstring(J, "[form elements object]");
}
static void
mjs_form_get_property_action(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct form *form;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushundefined(J);
return;
}
form = (struct form *)js_touserdata(J, 0, "form");
assert(form);
js_pushstring(J, form->action);
}
static void
mjs_form_set_property_action(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct form *form;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushundefined(J);
return;
}
form = (struct form *)js_touserdata(J, 0, "form");
assert(form);
const char *str = js_tostring(J, 1);
char *string;
if (!str) {
js_pushnull(J);
return;
}
string = stracpy(str);
if (form->action) {
ecmascript_set_action(&form->action, string);
} else {
mem_free_set(&form->action, string);
}
js_pushundefined(J);
}
#if 0
void
mjs_detach_form_view(struct form_view *fv)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
JSValue jsform = fv->ecmascript_obj;
if (!JS_IsNull(jsform)) {
map_form_elements.erase(fv);
setOpaque(jsform, nullptr);
fv->ecmascript_obj = JS_NULL;
}
}
#endif
static void
mjs_elements_finalizer(js_State *J, void *node)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct form_view *fv = (struct form_view *)node;
map_form_elements.erase(fv);
}
void
mjs_push_form_elements(js_State *J, struct form_view *fv)
{
js_newobject(J);
{
js_newuserdata(J, "form_view", fv, mjs_elements_finalizer);
addmethod(J, "item", mjs_form_elements_item, 1);
addmethod(J, "namedItem", mjs_form_elements_namedItem, 1);
addmethod(J, "toString", mjs_form_elements_toString, 0);
addproperty(J, "length", mjs_form_elements_get_property_length, NULL);
mjs_form_set_items(J, fv);
}
map_form_elements[fv] = fv;
}
static void
mjs_form_get_property_elements(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
struct form *form = (struct form *)js_touserdata(J, 0, "form");
assert(form);
struct form_view *fv = NULL;
bool found = false;
foreach (fv, vs->forms) {
if (form->form_num == fv->form_num) {
found = true;
break;
}
}
if (!found || !fv) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return; /* detached */
}
mjs_push_form_elements(J, fv);
}
static void
mjs_form_get_property_encoding(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct form *form;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
form = (struct form *)js_touserdata(J, 0, "form");
assert(form);
switch (form->method) {
case FORM_METHOD_GET:
case FORM_METHOD_POST:
js_pushstring(J, "application/x-www-form-urlencoded");
return;
case FORM_METHOD_POST_MP:
js_pushstring(J, "multipart/form-data");
return;
case FORM_METHOD_POST_TEXT_PLAIN:
js_pushstring(J, "text/plain");
return;
}
js_pushundefined(J);
}
/* @form_class.setProperty */
static void
mjs_form_set_property_encoding(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct form *form;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushundefined(J);
return;
}
form = (struct form *)js_touserdata(J, 0, "form");
assert(form);
const char *str = js_tostring(J, 1);
if (!str) {
js_pushnull(J);
return;
}
if (!c_strcasecmp(str, "application/x-www-form-urlencoded")) {
form->method = form->method == FORM_METHOD_GET ? FORM_METHOD_GET
: FORM_METHOD_POST;
} else if (!c_strcasecmp(str, "multipart/form-data")) {
form->method = FORM_METHOD_POST_MP;
} else if (!c_strcasecmp(str, "text/plain")) {
form->method = FORM_METHOD_POST_TEXT_PLAIN;
}
js_pushundefined(J);
}
static void
mjs_form_get_property_length(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct form *form;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushundefined(J);
return;
}
form = (struct form *)js_touserdata(J, 0, "form");
assert(form);
js_pushnumber(J, list_size(&form->items));
}
static void
mjs_form_get_property_method(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct form *form;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushundefined(J);
return;
}
form = (struct form *)js_touserdata(J, 0, "form");
assert(form);
switch (form->method) {
case FORM_METHOD_GET:
js_pushstring(J, "GET");
return;
case FORM_METHOD_POST:
case FORM_METHOD_POST_MP:
case FORM_METHOD_POST_TEXT_PLAIN:
js_pushstring(J, "POST");
return;
}
js_pushundefined(J);
}
/* @form_class.setProperty */
static void
mjs_form_set_property_method(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct form *form;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushundefined(J);
return;
}
form = (struct form *)js_touserdata(J, 0, "form");
assert(form);
const char *str = js_tostring(J, 1);
if (!str) {
js_pushnull(J);
return;
}
if (!c_strcasecmp(str, "GET")) {
form->method = FORM_METHOD_GET;
} else if (!c_strcasecmp(str, "POST")) {
form->method = FORM_METHOD_POST;
}
js_pushundefined(J);
}
static void
mjs_form_get_property_name(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct form *form;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushundefined(J);
return;
}
form = (struct form *)js_touserdata(J, 0, "form");
assert(form);
js_pushstring(J, form->name);
}
/* @form_class.setProperty */
static void
mjs_form_set_property_name(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct form *form;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushundefined(J);
return;
}
form = (struct form *)js_touserdata(J, 0, "form");
assert(form);
const char *str = js_tostring(J, 1);
if (!str) {
js_pushnull(J);
return;
}
mem_free_set(&form->name, stracpy(str));
js_pushundefined(J);
}
static void
mjs_form_get_property_target(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct form *form;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushundefined(J);
return;
}
form = (struct form *)js_touserdata(J, 0, "form");
assert(form);
js_pushstring(J, form->target);
}
static void
mjs_form_set_property_target(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct form *form;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushundefined(J);
return;
}
form = (struct form *)js_touserdata(J, 0, "form");
assert(form);
const char *str = js_tostring(J, 1);
if (!str) {
js_pushnull(J);
return;
}
mem_free_set(&form->target, stracpy(str));
js_pushundefined(J);
}
/* @form_funcs{"reset"} */
static void
mjs_form_reset(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct document_view *doc_view;
struct form *form;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
vs = interpreter->vs;
doc_view = vs->doc_view;
form = (struct form *)js_touserdata(J, 0, "form");
assert(form);
do_reset_form(doc_view, form);
draw_forms(doc_view->session->tab->term, doc_view);
js_pushundefined(J);
}
/* @form_funcs{"submit"} */
static void
mjs_form_submit(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct document_view *doc_view;
struct session *ses;
struct form *form;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
vs = interpreter->vs;
doc_view = vs->doc_view;
ses = doc_view->session;
form = (struct form *)js_touserdata(J, 0, "form");
assert(form);
submit_given_form(ses, doc_view, form, 0);
js_pushundefined(J);
}
static void
mjs_form_toString(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
js_pushstring(J, "[form object]");
}
static
void mjs_form_finalizer(js_State *J, void *node)
{
struct form *form = (struct form *)node;
map_form.erase(form);
}
void
mjs_push_form_object(js_State *J, struct form *form)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
js_newobject(J);
{
js_newuserdata(J, "form", form, mjs_form_finalizer);
addmethod(J, "reset", mjs_form_reset, 0);
addmethod(J, "submit", mjs_form_submit, 0);
addmethod(J, "toString", mjs_form_toString, 0);
addproperty(J, "action", mjs_form_get_property_action, mjs_form_set_property_action);
addproperty(J, "elements", mjs_form_get_property_elements, NULL);
addproperty(J, "encoding", mjs_form_get_property_encoding, mjs_form_set_property_encoding);
addproperty(J, "length", mjs_form_get_property_length, NULL);
addproperty(J, "method", mjs_form_get_property_method, mjs_form_set_property_method);
addproperty(J, "name", mjs_form_get_property_name, mjs_form_set_property_name);
addproperty(J, "target", mjs_form_get_property_target, mjs_form_set_property_target);
mjs_form_set_items2(J, form);
}
map_form[form] = form;
}

View File

@ -0,0 +1,10 @@
#ifndef EL__ECMASCRIPT_MUJS_FORM_H
#define EL__ECMASCRIPT_MUJS_FORM_H
#include <mujs.h>
struct form;
void mjs_push_form_object(js_State *J, struct form *form);
#endif

View File

@ -0,0 +1,223 @@
/* The MuJS forms implementation. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "elinks.h"
#include "bfu/dialog.h"
#include "cache/cache.h"
#include "cookies/cookies.h"
#include "dialogs/menu.h"
#include "dialogs/status.h"
#include "document/html/frames.h"
#include "document/document.h"
#include "document/forms.h"
#include "document/view.h"
#include "ecmascript/ecmascript.h"
#include "ecmascript/mujs.h"
#include "ecmascript/mujs/document.h"
#include "ecmascript/mujs/form.h"
#include "ecmascript/mujs/forms.h"
#include "ecmascript/mujs/input.h"
#include "ecmascript/mujs/window.h"
#include "intl/libintl.h"
#include "main/select.h"
#include "osdep/newwin.h"
#include "osdep/sysname.h"
#include "protocol/http/http.h"
#include "protocol/uri.h"
#include "session/history.h"
#include "session/location.h"
#include "session/session.h"
#include "session/task.h"
#include "terminal/tab.h"
#include "terminal/terminal.h"
#include "util/conv.h"
#include "util/memory.h"
#include "util/string.h"
#include "viewer/text/draw.h"
#include "viewer/text/form.h"
#include "viewer/text/link.h"
#include "viewer/text/vs.h"
#include <libxml++/libxml++.h>
#include <map>
static std::map<void *, void *> map_forms;
static std::map<void *, void *> map_rev_forms;
/* Find the form whose name is @name, which should normally be a
* string (but might not be). */
static void
mjs_find_form_by_name(js_State *J,
struct document_view *doc_view,
const char *string)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct form *form;
if (!*string) {
js_pushnull(J);
return;
}
foreach (form, doc_view->document->forms) {
if (form->name && !c_strcasecmp(string, form->name)) {
mjs_push_form_object(J, form);
return;
}
}
js_pushnull(J);
}
static void
mjs_forms_set_items(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct document_view *doc_view;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
vs = interpreter->vs;
doc_view = vs->doc_view;
struct document *document = doc_view->document;
int counter = 0;
struct form_view *fv;
foreach (fv, vs->forms) {
struct form *form = find_form_by_form_view(document, fv);
mjs_push_form_object(J, form);
js_dup(J);
js_setindex(J, 0, counter);
if (form->name && strcmp(form->name, "item") && strcmp(form->name, "namedItem")) {
js_setproperty(J, 0, form->name);
} else {
js_pop(J, 1);
}
counter++;
}
}
static void
mjs_forms_get_property_length(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushundefined(J);
return;
}
struct document_view *doc_view = vs->doc_view;
struct document *document = doc_view->document;
js_pushnumber(J, list_size(&document->forms));
}
static void
mjs_forms_item2(js_State *J, int index)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct view_state *vs;
struct form_view *fv;
int counter = -1;
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
vs = interpreter->vs;
struct document_view *doc_view = vs->doc_view;
struct document *document = doc_view->document;
foreach (fv, vs->forms) {
counter++;
if (counter == index) {
struct form *form = find_form_by_form_view(document, fv);
mjs_push_form_object(J, form);
return;
}
}
js_pushundefined(J);
}
/* @forms_funcs{"item"} */
static void
mjs_forms_item(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
int index = js_toint32(J, 1);;
mjs_forms_item2(J, index);
}
/* @forms_funcs{"namedItem"} */
static void
mjs_forms_namedItem(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
struct document_view *doc_view = vs->doc_view;
const char *str = js_tostring(J, 1);;
if (!str) {
js_pushnull(J);
return;
}
mjs_find_form_by_name(J, doc_view, str);
}
static void
mjs_forms_toString(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
js_pushstring(J, "[forms object]");
}
void
mjs_push_forms(js_State *J, void *node)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
js_newobject(J);
{
js_newuserdata(J, "forms", node, NULL);
addmethod(J, "item", mjs_forms_item, 1);
addmethod(J, "namedItem", mjs_forms_namedItem, 1);
addmethod(J, "toString", mjs_forms_toString, 0);
addproperty(J, "length", mjs_forms_get_property_length, NULL);
mjs_forms_set_items(J);
}
map_forms[node] = node;
}

View File

@ -0,0 +1,11 @@
#ifndef EL__ECMASCRIPT_MUJS_FORMS_H
#define EL__ECMASCRIPT_MUJS_FORMS_H
#include <mujs.h>
struct form;
void mjs_push_form_object(js_State *J, struct form *form);
void mjs_push_forms(js_State *J, void *node);
#endif

View File

@ -0,0 +1,75 @@
/* The MuJS domimplementation object. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "elinks.h"
#include "ecmascript/ecmascript.h"
#include "ecmascript/mujs.h"
#include "ecmascript/mujs/document.h"
#include "ecmascript/mujs/implementation.h"
#include "util/conv.h"
#include <libxml/HTMLparser.h>
#include <libxml++/libxml++.h>
static void
mjs_implementation_createHTMLDocument(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
const char *title = js_tostring(J, 1);
if (!title) {
js_pushnull(J);
return;
}
struct string str;
if (!init_string(&str)) {
js_pushnull(J);
return;
}
add_to_string(&str, "<!doctype html>\n<html><head><title>");
add_to_string(&str, title);
add_to_string(&str, "</title></head><body></body></html>");
// Parse HTML and create a DOM tree
xmlDoc* doc = htmlReadDoc((xmlChar*)str.source, NULL, "utf-8",
HTML_PARSE_RECOVER | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING);
// Encapsulate raw libxml document in a libxml++ wrapper
xmlpp::Document *docu = new(std::nothrow) xmlpp::Document(doc);
done_string(&str);
mjs_push_document(J, docu);
}
static void
mjs_implementation_toString(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
js_pushstring(J, "[implementation object]");
}
void
mjs_push_implementation(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
js_newobject(J);
{
addmethod(J, "createHTMLDocument", mjs_implementation_createHTMLDocument, 1);
addmethod(J, "toString", mjs_implementation_toString, 0);
}
}

View File

@ -0,0 +1,11 @@
#ifndef EL__ECMASCRIPT_MUJS_IMPLEMENTATION_H
#define EL__ECMASCRIPT_MUJS_IMPLEMENTATION_H
#include <mujs.h>
void mjs_push_implementation(js_State *J);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
#ifndef EL__ECMASCRIPT_MUJS_INPUT_H
#define EL__ECMASCRIPT_MUJS_INPUT_H
#include <mujs.h>
struct form_state;
void mjs_push_input_object(js_State *J, struct form_state *fs);
#endif

View File

@ -0,0 +1,588 @@
/* The MuJS location object implementation. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "elinks.h"
#include "bfu/dialog.h"
#include "cache/cache.h"
#include "cookies/cookies.h"
#include "dialogs/menu.h"
#include "dialogs/status.h"
#include "document/html/frames.h"
#include "document/document.h"
#include "document/forms.h"
#include "document/view.h"
#include "ecmascript/ecmascript.h"
#include "ecmascript/mujs.h"
#include "ecmascript/mujs/location.h"
#include "ecmascript/mujs/window.h"
#include "intl/libintl.h"
#include "main/select.h"
#include "osdep/newwin.h"
#include "osdep/sysname.h"
#include "protocol/http/http.h"
#include "protocol/uri.h"
#include "session/history.h"
#include "session/location.h"
#include "session/session.h"
#include "session/task.h"
#include "terminal/tab.h"
#include "terminal/terminal.h"
#include "util/conv.h"
#include "util/memory.h"
#include "util/string.h"
#include "viewer/text/draw.h"
#include "viewer/text/form.h"
#include "viewer/text/link.h"
#include "viewer/text/vs.h"
static void
mjs_location_get_property_hash(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
struct string fragment;
if (!init_string(&fragment)) {
js_pushnull(J);
return;
}
if (vs->uri->fragmentlen) {
add_bytes_to_string(&fragment, vs->uri->fragment, vs->uri->fragmentlen);
}
js_pushstring(J, fragment.source);
done_string(&fragment);
}
static void
mjs_location_get_property_host(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
char *str = get_uri_string(vs->uri, URI_HOST_PORT);
if (!str) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
js_pushstring(J, str);
mem_free(str);
}
static void
mjs_location_get_property_hostname(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
char *str = get_uri_string(vs->uri, URI_HOST);
if (!str) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
js_pushstring(J, str);
mem_free(str);
}
static void
mjs_location_get_property_href(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
char *str = get_uri_string(vs->uri, URI_ORIGINAL);
if (!str) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
js_pushstring(J, str);
mem_free(str);
}
static void
mjs_location_get_property_origin(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
char *str = get_uri_string(vs->uri, URI_SERVER);
if (!str) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
js_pushstring(J, str);
mem_free(str);
}
static void
mjs_location_get_property_pathname(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
struct string pathname;
if (!init_string(&pathname)) {
js_pushnull(J);
return;
}
const char *query = (const char *)memchr(vs->uri->data, '?', vs->uri->datalen);
int len = (query ? query - vs->uri->data : vs->uri->datalen);
add_bytes_to_string(&pathname, vs->uri->data, len);
js_pushstring(J, pathname.source);
done_string(&pathname);
}
static void
mjs_location_get_property_port(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
struct string port;
if (!init_string(&port)) {
js_pushnull(J);
return;
}
if (vs->uri->portlen) {
add_bytes_to_string(&port, vs->uri->port, vs->uri->portlen);
}
js_pushstring(J, port.source);
done_string(&port);
}
static void
mjs_location_get_property_protocol(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
struct string proto;
if (!init_string(&proto)) {
js_pushnull(J);
return;
}
/* Custom or unknown keep the URI untouched. */
if (vs->uri->protocol == PROTOCOL_UNKNOWN) {
add_to_string(&proto, struri(vs->uri));
} else {
add_bytes_to_string(&proto, vs->uri->string, vs->uri->protocollen);
add_char_to_string(&proto, ':');
}
js_pushstring(J, proto.source);
done_string(&proto);
}
static void
mjs_location_get_property_search(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
struct string search;
if (!init_string(&search)) {
js_pushnull(J);
return;
}
const char *query = (const char *)memchr(vs->uri->data, '?', vs->uri->datalen);
if (query) {
add_bytes_to_string(&search, query, strcspn(query, "#" POST_CHAR_S));
}
js_pushstring(J, search.source);
done_string(&search);
}
static void
mjs_location_set_property_hash(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
const char *str = js_tostring(J, 1);
if (!str) {
js_pushnull(J);
return;
}
location_goto_const(vs->doc_view, str);
js_pushundefined(J);
}
static void
mjs_location_set_property_host(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
const char *str = js_tostring(J, 1);
if (!str) {
js_pushnull(J);
return;
}
location_goto_const(vs->doc_view, str);
js_pushundefined(J);
}
static void
mjs_location_set_property_hostname(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
const char *str = js_tostring(J, 1);
if (!str) {
js_pushnull(J);
return;
}
location_goto_const(vs->doc_view, str);
js_pushundefined(J);
}
static void
mjs_location_set_property_href(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
const char *str = js_tostring(J, 1);
if (!str) {
js_pushnull(J);
return;
}
location_goto_const(vs->doc_view, str);
js_pushundefined(J);
}
static void
mjs_location_set_property_pathname(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
const char *str = js_tostring(J, 1);
if (!str) {
js_pushnull(J);
return;
}
location_goto_const(vs->doc_view, str);
js_pushundefined(J);
}
static void
mjs_location_set_property_port(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
const char *str = js_tostring(J, 1);
if (!str) {
js_pushnull(J);
return;
}
location_goto_const(vs->doc_view, str);
js_pushundefined(J);
}
static void
mjs_location_set_property_protocol(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
const char *str = js_tostring(J, 1);
if (!str) {
js_pushnull(J);
return;
}
location_goto_const(vs->doc_view, str);
js_pushundefined(J);
}
static void
mjs_location_set_property_search(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
const char *str = js_tostring(J, 1);
if (!str) {
js_pushnull(J);
return;
}
location_goto_const(vs->doc_view, str);
js_pushundefined(J);
}
static void
mjs_location_reload(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
struct view_state *vs = interpreter->vs;
if (!vs) {
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
js_pushnull(J);
return;
}
location_goto_const(vs->doc_view, "");
js_pushundefined(J);
}
/* @location_funcs{"toString"}, @location_funcs{"toLocaleString"} */
static void
mjs_location_toString(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
mjs_location_get_property_href(J);
}
int
mjs_location_init(js_State *J)
{
js_newobject(J);
{
addmethod(J, "reload", mjs_location_reload, 0);
addmethod(J, "toString", mjs_location_toString, 0);
addmethod(J, "toLocaleString", mjs_location_toString, 0);
addproperty(J, "hash", mjs_location_get_property_hash, mjs_location_set_property_hash);
addproperty(J, "host", mjs_location_get_property_host, mjs_location_set_property_host);
addproperty(J, "hostname", mjs_location_get_property_hostname, mjs_location_set_property_hostname);
addproperty(J, "href", mjs_location_get_property_href, mjs_location_set_property_href);
addproperty(J, "origin", mjs_location_get_property_origin, NULL);
addproperty(J, "pathname", mjs_location_get_property_pathname, mjs_location_set_property_pathname);
addproperty(J, "port", mjs_location_get_property_port, mjs_location_set_property_port);
addproperty(J, "protocol", mjs_location_get_property_protocol, mjs_location_set_property_protocol);
addproperty(J, "search", mjs_location_get_property_search, mjs_location_set_property_search);
}
js_defglobal(J, "location", JS_DONTENUM);
return 0;
}
void
mjs_push_location(js_State *J)
{
mjs_location_init(J);
}

View File

@ -0,0 +1,9 @@
#ifndef EL__ECMASCRIPT_MUJS_LOCATION_H
#define EL__ECMASCRIPT_MUJS_LOCATION_H
#include <mujs.h>
int mjs_location_init(js_State *J);
void mjs_push_location(js_State *J);
#endif

View File

@ -1,3 +1,4 @@
#srcs += files('attr.cpp', 'attributes.cpp', 'collection.cpp', 'console.cpp', 'document.cpp', 'element.cpp', 'form.cpp', 'forms.cpp', 'heartbeat.cpp', 'history.cpp', 'implementation.cpp',
#'input.cpp', 'localstorage.cpp', 'location.cpp', 'navigator.cpp', 'nodelist.cpp', 'screen.cpp', 'unibar.cpp', 'window.cpp')
srcs += files('console.cpp', 'history.cpp', 'localstorage.cpp', 'navigator.cpp', 'screen.cpp', 'unibar.cpp', 'window.cpp')
srcs += files('attr.cpp', 'attributes.cpp', 'collection.cpp', 'console.cpp', 'document.cpp', 'element.cpp', 'form.cpp', 'forms.cpp', 'history.cpp', 'implementation.cpp',
'input.cpp', 'localstorage.cpp', 'location.cpp', 'navigator.cpp', 'nodelist.cpp', 'screen.cpp', 'unibar.cpp', 'window.cpp')

View File

@ -0,0 +1,174 @@
/* The MuJS nodeList object implementation. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "elinks.h"
#include "bfu/dialog.h"
#include "cache/cache.h"
#include "cookies/cookies.h"
#include "dialogs/menu.h"
#include "dialogs/status.h"
#include "document/html/frames.h"
#include "document/document.h"
#include "document/forms.h"
#include "document/view.h"
#include "ecmascript/ecmascript.h"
#include "ecmascript/mujs.h"
#include "ecmascript/mujs/element.h"
#include "ecmascript/mujs/nodelist.h"
#include "ecmascript/mujs/window.h"
#include "intl/libintl.h"
#include "main/select.h"
#include "osdep/newwin.h"
#include "osdep/sysname.h"
#include "protocol/http/http.h"
#include "protocol/uri.h"
#include "session/history.h"
#include "session/location.h"
#include "session/session.h"
#include "session/task.h"
#include "terminal/tab.h"
#include "terminal/terminal.h"
#include "util/conv.h"
#include "util/memory.h"
#include "util/string.h"
#include "viewer/text/draw.h"
#include "viewer/text/form.h"
#include "viewer/text/link.h"
#include "viewer/text/vs.h"
#include <libxml/tree.h>
#include <libxml/HTMLparser.h>
#include <libxml++/libxml++.h>
#include <libxml++/attributenode.h>
#include <libxml++/parsers/domparser.h>
#include <iostream>
#include <algorithm>
#include <string>
static std::map<void *, void *> map_nodelist;
static std::map<void *, void *> map_rev_nodelist;
#if 0
static JSValue
js_nodeList_get_property_length(JSContext *ctx, JSValueConst this_val)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
xmlpp::Node::NodeList *nl = static_cast<xmlpp::Node::NodeList *>(js_nodeList_GetOpaque(this_val));
if (!nl) {
return JS_NewInt32(ctx, 0);
}
return JS_NewInt32(ctx, nl->size());
}
#endif
static void
mjs_push_nodeList_item2(js_State *J, int idx)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
xmlpp::Node::NodeList *nl = static_cast<xmlpp::Node::NodeList *>(js_touserdata(J, 0, "nodelist"));
if (!nl) {
js_pushundefined(J);
return;
}
xmlpp::Node *element = nullptr;
auto it = nl->begin();
auto end = nl->end();
for (int i = 0; it != end; ++it, ++i) {
if (i == idx) {
element = *it;
break;
}
}
if (!element) {
js_pushundefined(J);
return;
}
mjs_push_element(J, element);
}
static void
mjs_nodeList_item(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
int index = js_toint32(J, 1);
mjs_push_nodeList_item2(J, index);
}
static void
mjs_nodeList_set_items(js_State *J, void *node)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
xmlpp::Node::NodeList *nl = static_cast<xmlpp::Node::NodeList *>(node);
if (!nl) {
return;
}
auto it = nl->begin();
auto end = nl->end();
for (int i = 0; it != end; ++it, ++i) {
xmlpp::Node *element = *it;
if (element) {
mjs_push_element(J, element);
js_setindex(J, 1, i);
}
}
}
static void
mjs_nodeList_toString(js_State *J)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
js_pushstring(J, "[nodeList object]");
}
static void
mjs_nodeList_finalizer(js_State *J, void *node)
{
map_nodelist.erase(node);
}
static void
mjs_push_nodelist(js_State *J, void *node)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
js_newobject(J);
{
js_newuserdata(J, "nodelist", node, mjs_nodeList_finalizer);
addmethod(J, "item", mjs_nodeList_item, 1);
addmethod(J, "toString", mjs_nodeList_toString, 0);
mjs_nodeList_set_items(J, node);
}
map_nodelist[node] = node;
}

View File

@ -0,0 +1,8 @@
#ifndef EL__ECMASCRIPT_MUJS_NODELIST_H
#define EL__ECMASCRIPT_MUJS_NODELIST_H
#include <mujs.h>
void mjs_push_nodelist(js_State *J, void *node);
#endif