diff --git a/src/ecmascript/libdom/mujs/Makefile b/src/ecmascript/libdom/mujs/Makefile index a89bf8c5..eab8edcc 100644 --- a/src/ecmascript/libdom/mujs/Makefile +++ b/src/ecmascript/libdom/mujs/Makefile @@ -1,6 +1,6 @@ top_builddir=../../../.. include $(top_builddir)/Makefile.config -OBJS = attr.o attributes.o collection.o console.o mapa.obj +OBJS = attr.o attributes.o collection.o console.o forms.o mapa.obj include $(top_srcdir)/Makefile.lib diff --git a/src/ecmascript/libdom/mujs/forms.c b/src/ecmascript/libdom/mujs/forms.c new file mode 100644 index 00000000..e4355d3a --- /dev/null +++ b/src/ecmascript/libdom/mujs/forms.c @@ -0,0 +1,202 @@ +/* The MuJS forms implementation. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "elinks.h" + +#include "document/document.h" +#include "document/forms.h" +#include "document/view.h" +#include "ecmascript/ecmascript.h" +#include "ecmascript/libdom/mujs/mapa.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 "viewer/text/form.h" +#include "viewer/text/vs.h" + +void *map_forms; +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_setindex(J, -2, counter); + + if (form->name) { + if (js_try(J)) { + js_pop(J, 1); + goto next; + } + mjs_push_form_object(J, form); + js_setproperty(J, -2, form->name); + js_endtry(J); + } +next: + 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_error(J, "!str"); + 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_newarray(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); + } + attr_save_in_map(map_forms, node, node); +} diff --git a/src/ecmascript/libdom/mujs/meson.build b/src/ecmascript/libdom/mujs/meson.build index e0fbb03a..d4e74fee 100644 --- a/src/ecmascript/libdom/mujs/meson.build +++ b/src/ecmascript/libdom/mujs/meson.build @@ -1 +1 @@ -srcs += files('attr.c', 'attributes.c', 'collection.c', 'console.c', 'mapa.cpp') +srcs += files('attr.c', 'attributes.c', 'collection.c', 'console.c', 'forms.c', 'mapa.cpp') diff --git a/src/ecmascript/mujs/document.h b/src/ecmascript/mujs/document.h index 2802647b..89833930 100644 --- a/src/ecmascript/mujs/document.h +++ b/src/ecmascript/mujs/document.h @@ -3,7 +3,15 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + void mjs_push_document(js_State *J, void *doc); int mjs_document_init(js_State *J); +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/ecmascript/mujs/form.h b/src/ecmascript/mujs/form.h index 96e97fa6..f2c6958b 100644 --- a/src/ecmascript/mujs/form.h +++ b/src/ecmascript/mujs/form.h @@ -3,8 +3,16 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + struct form; void mjs_push_form_object(js_State *J, struct form *form); +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/ecmascript/mujs/forms.cpp b/src/ecmascript/mujs/forms.cpp index 3644d186..7d4df251 100644 --- a/src/ecmascript/mujs/forms.cpp +++ b/src/ecmascript/mujs/forms.cpp @@ -49,6 +49,8 @@ #include #include +#ifndef CONFIG_LIBDOM + static std::map map_forms; static std::map map_rev_forms; @@ -225,3 +227,4 @@ mjs_push_forms(js_State *J, void *node) } map_forms[node] = node; } +#endif diff --git a/src/ecmascript/mujs/forms.h b/src/ecmascript/mujs/forms.h index fb104d6e..087b11b1 100644 --- a/src/ecmascript/mujs/forms.h +++ b/src/ecmascript/mujs/forms.h @@ -3,9 +3,17 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + struct form; void mjs_push_form_object(js_State *J, struct form *form); void mjs_push_forms(js_State *J, void *node); +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/ecmascript/mujs/input.h b/src/ecmascript/mujs/input.h index 8efa0754..9515097d 100644 --- a/src/ecmascript/mujs/input.h +++ b/src/ecmascript/mujs/input.h @@ -3,8 +3,16 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + struct form_state; void mjs_push_input_object(js_State *J, struct form_state *fs); +#ifdef __cplusplus +} +#endif + #endif