mirror of
https://github.com/rkd77/elinks.git
synced 2024-09-27 02:56:18 -04:00
[quicksjs] changed forms code, but still does not work
This commit is contained in:
parent
7d51951d5f
commit
28fba3eab3
@ -402,6 +402,7 @@ void
|
||||
ecmascript_detach_form_view(struct form_view *fv)
|
||||
{
|
||||
#ifdef CONFIG_QUICKJS
|
||||
quickjs_detach_form_view(fv);
|
||||
#else
|
||||
spidermonkey_detach_form_view(fv);
|
||||
#endif
|
||||
@ -410,6 +411,7 @@ ecmascript_detach_form_view(struct form_view *fv)
|
||||
void ecmascript_detach_form_state(struct form_state *fs)
|
||||
{
|
||||
#ifdef CONFIG_QUICKJS
|
||||
quickjs_detach_form_state(fs);
|
||||
#else
|
||||
spidermonkey_detach_form_state(fs);
|
||||
#endif
|
||||
@ -418,6 +420,7 @@ void ecmascript_detach_form_state(struct form_state *fs)
|
||||
void ecmascript_moved_form_state(struct form_state *fs)
|
||||
{
|
||||
#ifdef CONFIG_QUICKJS
|
||||
quickjs_moved_form_state(fs);
|
||||
#else
|
||||
spidermonkey_moved_form_state(fs);
|
||||
#endif
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "document/view.h"
|
||||
#include "ecmascript/ecmascript.h"
|
||||
#include "ecmascript/quickjs.h"
|
||||
//#include "ecmascript/spidermonkey/document.h"
|
||||
#include "ecmascript/quickjs/document.h"
|
||||
#include "ecmascript/quickjs/form.h"
|
||||
#include "ecmascript/quickjs/forms.h"
|
||||
#include "ecmascript/quickjs/input.h"
|
||||
@ -47,59 +47,14 @@
|
||||
#include "viewer/text/vs.h"
|
||||
|
||||
#include <libxml++/libxml++.h>
|
||||
#include <map>
|
||||
|
||||
#define countof(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
static JSClassID js_form_elements_class_id;
|
||||
static JSClassID js_form_class_id;
|
||||
|
||||
#if 0
|
||||
void
|
||||
spidermonkey_detach_form_state(struct form_state *fs)
|
||||
{
|
||||
#ifdef ECMASCRIPT_DEBUG
|
||||
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
||||
#endif
|
||||
JSObject *jsinput = fs->ecmascript_obj;
|
||||
|
||||
if (jsinput) {
|
||||
// JS::RootedObject r_jsinput(spidermonkey_empty_context, jsinput);
|
||||
/* This assumes JS_GetInstancePrivate and JS_SetPrivate
|
||||
* cannot GC. */
|
||||
|
||||
/* If this assertion fails, it is not clear whether
|
||||
* the private pointer of jsinput should be reset;
|
||||
* crashes seem possible either way. Resetting it is
|
||||
* easiest. */
|
||||
// assert(JS_GetInstancePrivate(spidermonkey_empty_context,
|
||||
// r_jsinput,
|
||||
// &input_class, NULL)
|
||||
// == fs);
|
||||
// if_assert_failed {}
|
||||
|
||||
JS_SetPrivate(jsinput, NULL);
|
||||
fs->ecmascript_obj = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
spidermonkey_moved_form_state(struct form_state *fs)
|
||||
{
|
||||
#ifdef ECMASCRIPT_DEBUG
|
||||
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
||||
#endif
|
||||
JSObject *jsinput = fs->ecmascript_obj;
|
||||
|
||||
if (jsinput) {
|
||||
/* This assumes JS_SetPrivate cannot GC. If it could,
|
||||
* then the GC might call input_finalize for some
|
||||
* other object whose struct form_state has also been
|
||||
* reallocated, and an assertion would fail in
|
||||
* input_finalize. */
|
||||
JS_SetPrivate(jsinput, fs);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
static std::map<struct form_view *, JSValueConst> map_form_elements;
|
||||
JSValue getForm(JSContext *ctx, struct form *form);
|
||||
|
||||
static JSValue
|
||||
js_get_form_control_object(JSContext *ctx,
|
||||
@ -132,7 +87,6 @@ js_get_form_control_object(JSContext *ctx,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
js_form_set_items(JSContext *ctx, JSValueConst this_val, void *node)
|
||||
{
|
||||
@ -169,15 +123,15 @@ js_form_set_items(JSContext *ctx, JSValueConst this_val, void *node)
|
||||
}
|
||||
|
||||
JSValue obj = js_get_form_control_object(ctx, fc->type, fs);
|
||||
JS_SetPropertyUint32(ctx, this_val, counter, obj);
|
||||
JS_SetPropertyUint32(ctx, this_val, counter, JS_DupValue(ctx, obj));
|
||||
|
||||
if (fc->id) {
|
||||
if (strcmp(fc->id, "item") && strcmp(fc->id, "namedItem")) {
|
||||
JS_DefinePropertyValueStr(ctx, this_val, fc->id, obj, 0);
|
||||
JS_SetPropertyStr(ctx, this_val, fc->id, JS_DupValue(ctx, obj));
|
||||
}
|
||||
} else if (fc->name) {
|
||||
if (strcmp(fc->name, "item") && strcmp(fc->name, "namedItem")) {
|
||||
JS_DefinePropertyValueStr(ctx, this_val, fc->name, obj, 0);
|
||||
JS_SetPropertyStr(ctx, this_val, fc->name, JS_DupValue(ctx, obj));
|
||||
}
|
||||
}
|
||||
counter++;
|
||||
@ -212,16 +166,18 @@ js_form_set_items2(JSContext *ctx, JSValueConst this_val, void *node)
|
||||
}
|
||||
|
||||
JSValue obj = js_get_form_control_object(ctx, fc->type, fs);
|
||||
JS_SetPropertyUint32(ctx, this_val, counter, obj);
|
||||
|
||||
if (fc->id) {
|
||||
if (strcmp(fc->id, "item") && strcmp(fc->id, "namedItem")) {
|
||||
JS_DefinePropertyValueStr(ctx, this_val, fc->id, obj, 0);
|
||||
JS_SetPropertyStr(ctx, this_val, fc->id, obj);
|
||||
}
|
||||
} else if (fc->name) {
|
||||
if (strcmp(fc->name, "item") && strcmp(fc->name, "namedItem")) {
|
||||
JS_DefinePropertyValueStr(ctx, this_val, fc->name, obj, 0);
|
||||
JS_SetPropertyStr(ctx, this_val, fc->name, obj);
|
||||
}
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -470,11 +426,74 @@ js_form_set_property_action(JSContext *ctx, JSValueConst this_val, JSValue val)
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
static const JSCFunctionListEntry js_form_elements_proto_funcs[] = {
|
||||
JS_CGETSET_DEF("length", js_form_elements_get_property_length, nullptr),
|
||||
JS_CFUNC_DEF("item", 1, js_form_elements_item),
|
||||
JS_CFUNC_DEF("namedItem", 1, js_form_elements_namedItem),
|
||||
};
|
||||
|
||||
void
|
||||
quickjs_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);
|
||||
JS_SetOpaque(jsform, nullptr);
|
||||
fv->ecmascript_obj = JS_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void js_elements_finalizer(JSRuntime *rt, JSValue val)
|
||||
{
|
||||
#ifdef ECMASCRIPT_DEBUG
|
||||
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
||||
#endif
|
||||
struct form_view *fv = JS_GetOpaque(val, js_form_elements_class_id);
|
||||
|
||||
JS_SetOpaque(val, nullptr);
|
||||
fv->ecmascript_obj = JS_NULL;
|
||||
map_form_elements.erase(fv);
|
||||
}
|
||||
|
||||
static JSClassDef js_form_elements_class = {
|
||||
"elements",
|
||||
js_elements_finalizer
|
||||
};
|
||||
|
||||
JSValue
|
||||
getFormElements(JSContext *ctx, struct form_view *fv)
|
||||
{
|
||||
// TODO
|
||||
return JS_NULL;
|
||||
#ifdef ECMASCRIPT_DEBUG
|
||||
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
||||
#endif
|
||||
auto node_find = map_form_elements.find(fv);
|
||||
|
||||
if (false && node_find != map_form_elements.end()) {
|
||||
return JS_DupValue(ctx, node_find->second);
|
||||
}
|
||||
static int initialized;
|
||||
/* create the element class */
|
||||
if (!initialized) {
|
||||
JS_NewClassID(&js_form_elements_class_id);
|
||||
JS_NewClass(JS_GetRuntime(ctx), js_form_elements_class_id, &js_form_elements_class);
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
JSValue form_elements_obj = JS_NewObjectClass(ctx, js_form_elements_class_id);
|
||||
|
||||
JS_SetPropertyFunctionList(ctx, form_elements_obj, js_form_elements_proto_funcs, countof(js_form_elements_proto_funcs));
|
||||
JS_SetClassProto(ctx, js_form_elements_class_id, form_elements_obj);
|
||||
JS_SetOpaque(form_elements_obj, fv);
|
||||
fv->ecmascript_obj = form_elements_obj;
|
||||
js_form_set_items(ctx, form_elements_obj, fv);
|
||||
map_form_elements[fv] = form_elements_obj;
|
||||
|
||||
return JS_DupValue(ctx, form_elements_obj);
|
||||
}
|
||||
|
||||
static JSValue
|
||||
@ -494,23 +513,6 @@ js_form_get_property_elements(JSContext *ctx, JSValueConst this_val)
|
||||
}
|
||||
|
||||
return getFormElements(ctx, fv);
|
||||
#if 0
|
||||
/* jsform ('form') is form_elements' parent; who knows is that's correct */
|
||||
JSObject *jsform_elems = JS_NewObjectWithGivenProto(ctx, &form_elements_class, hobj);
|
||||
JS::RootedObject r_jsform_elems(ctx, jsform_elems);
|
||||
|
||||
JS_DefineProperties(ctx, r_jsform_elems, (JSPropertySpec *) form_elements_props);
|
||||
spidermonkey_DefineFunctions(ctx, jsform_elems,
|
||||
form_elements_funcs);
|
||||
JS_SetPrivate(jsform_elems, fv);
|
||||
fv->ecmascript_obj = jsform_elems;
|
||||
|
||||
form_set_items(ctx, r_jsform_elems, fv);
|
||||
|
||||
args.rval().setObject(*r_jsform_elems);
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
static JSValue
|
||||
@ -870,12 +872,6 @@ js_form_submit(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *ar
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JSValue
|
||||
getForm(JSContext *ctx, struct form *form)
|
||||
{
|
||||
// TODO
|
||||
return JS_NULL;
|
||||
}
|
||||
|
||||
JSValue
|
||||
js_get_form_object(JSContext *ctx, JSValueConst jsdoc, struct form *form)
|
||||
@ -883,96 +879,9 @@ js_get_form_object(JSContext *ctx, JSValueConst jsdoc, struct form *form)
|
||||
#ifdef ECMASCRIPT_DEBUG
|
||||
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
||||
#endif
|
||||
|
||||
JSValueConst jsform = form->ecmascript_obj;
|
||||
|
||||
if (!JS_IsNull(jsform)) {
|
||||
assert(JS_GetOpaque(jsform, js_form_class_id) == form);
|
||||
if_assert_failed return JS_NULL;
|
||||
|
||||
return jsform;
|
||||
}
|
||||
|
||||
/* jsdoc ('document') is fv's parent */
|
||||
/* FIXME: That is NOT correct since the real containing element
|
||||
* should be its parent, but gimme DOM first. --pasky */
|
||||
return getForm(ctx, form);
|
||||
#if 0
|
||||
jsform = JS_NewObject(ctx, &form_class);
|
||||
if (jsform == NULL)
|
||||
return NULL;
|
||||
JS::RootedObject r_jsform(ctx, jsform);
|
||||
JS_DefineProperties(ctx, r_jsform, form_props);
|
||||
spidermonkey_DefineFunctions(ctx, jsform, form_funcs);
|
||||
JS_SetPrivate(jsform, form); /* to @form_class */
|
||||
form->ecmascript_obj = jsform;
|
||||
form_set_items2(ctx, r_jsform, form);
|
||||
|
||||
return jsform;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
form_finalize(JSFreeOp *op, JSObject *jsform)
|
||||
{
|
||||
#ifdef ECMASCRIPT_DEBUG
|
||||
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
||||
#endif
|
||||
struct form *form = JS_GetPrivate(jsform);
|
||||
|
||||
if (form) {
|
||||
/* If this assertion fails, leave fv->ecmascript_obj
|
||||
* unchanged, because it may point to a different
|
||||
* JSObject whose private pointer will later have to
|
||||
* be updated to avoid crashes. */
|
||||
assert(form->ecmascript_obj == jsform);
|
||||
if_assert_failed return;
|
||||
|
||||
form->ecmascript_obj = NULL;
|
||||
/* No need to JS_SetPrivate, because the object is
|
||||
* being destroyed. */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
js_spidermonkey_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)) {
|
||||
// JS::RootedObject r_jsform(spidermonkey_empty_context, jsform);
|
||||
/* This assumes JS_GetInstancePrivate and JS_SetPrivate
|
||||
* cannot GC. */
|
||||
|
||||
/* If this assertion fails, it is not clear whether
|
||||
* the private pointer of jsform should be reset;
|
||||
* crashes seem possible either way. Resetting it is
|
||||
* easiest. */
|
||||
// assert(JS_GetInstancePrivate(spidermonkey_empty_context,
|
||||
// r_jsform,
|
||||
// &form_class, NULL)
|
||||
// == fv);
|
||||
// if_assert_failed {}
|
||||
|
||||
JS_SetOpaque(jsform, nullptr);
|
||||
fv->ecmascript_obj = JS_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const JSCFunctionListEntry js_elements_proto_funcs[] = {
|
||||
JS_CGETSET_DEF("length", js_form_elements_get_property_length, nullptr),
|
||||
JS_CFUNC_DEF("item", 1, js_form_elements_item),
|
||||
JS_CFUNC_DEF("namedItem", 1, js_form_elements_namedItem),
|
||||
};
|
||||
|
||||
static JSClassDef js_elements_class = {
|
||||
"elements",
|
||||
};
|
||||
|
||||
static JSValue
|
||||
js_elements_ctor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv)
|
||||
@ -1006,10 +915,10 @@ js_elements_init(JSContext *ctx, JSValue global_obj)
|
||||
|
||||
/* create the elements class */
|
||||
JS_NewClassID(&js_form_elements_class_id);
|
||||
JS_NewClass(JS_GetRuntime(ctx), js_form_elements_class_id, &js_elements_class);
|
||||
JS_NewClass(JS_GetRuntime(ctx), js_form_elements_class_id, &js_form_elements_class);
|
||||
|
||||
elements_proto = JS_NewObject(ctx);
|
||||
JS_SetPropertyFunctionList(ctx, elements_proto, js_elements_proto_funcs, countof(js_elements_proto_funcs));
|
||||
JS_SetPropertyFunctionList(ctx, elements_proto, js_form_elements_proto_funcs, countof(js_form_elements_proto_funcs));
|
||||
|
||||
elements_class = JS_NewCFunction2(ctx, js_elements_ctor, "elements", 0, JS_CFUNC_constructor, 0);
|
||||
/* set proto.constructor and ctor.prototype */
|
||||
@ -1032,8 +941,20 @@ static const JSCFunctionListEntry js_form_proto_funcs[] = {
|
||||
JS_CFUNC_DEF("submit", 0, js_form_submit),
|
||||
};
|
||||
|
||||
static std::map<struct form *, JSValueConst> map_form;
|
||||
|
||||
static
|
||||
void js_form_finalizer(JSRuntime *rt, JSValue val)
|
||||
{
|
||||
struct form *form = JS_GetOpaque(val, js_form_class_id);
|
||||
|
||||
form->ecmascript_obj = JS_NULL;
|
||||
map_form.erase(form);
|
||||
}
|
||||
|
||||
static JSClassDef js_form_class = {
|
||||
"form",
|
||||
js_form_finalizer
|
||||
};
|
||||
|
||||
static JSValue
|
||||
@ -1081,3 +1002,34 @@ js_form_init(JSContext *ctx, JSValue global_obj)
|
||||
JS_SetPropertyStr(ctx, global_obj, "form", form_proto);
|
||||
return 0;
|
||||
}
|
||||
|
||||
JSValue
|
||||
getForm(JSContext *ctx, struct form *form)
|
||||
{
|
||||
#ifdef ECMASCRIPT_DEBUG
|
||||
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
||||
#endif
|
||||
auto node_find = map_form.find(form);
|
||||
|
||||
if (node_find != map_form.end()) {
|
||||
return JS_DupValue(ctx, node_find->second);
|
||||
}
|
||||
static int initialized;
|
||||
/* create the element class */
|
||||
if (!initialized) {
|
||||
JS_NewClassID(&js_form_class_id);
|
||||
JS_NewClass(JS_GetRuntime(ctx), js_form_class_id, &js_form_class);
|
||||
initialized = 1;
|
||||
}
|
||||
JSValue form_obj = JS_NewObjectClass(ctx, js_form_class_id);
|
||||
|
||||
JS_SetPropertyFunctionList(ctx, form_obj, js_form_proto_funcs, countof(js_form_proto_funcs));
|
||||
JS_SetClassProto(ctx, js_form_class_id, form_obj);
|
||||
JS_SetOpaque(form_obj, form);
|
||||
js_form_set_items2(ctx, form_obj, form);
|
||||
form->ecmascript_obj = form_obj;
|
||||
|
||||
map_form[form] = form_obj;
|
||||
|
||||
return JS_DupValue(ctx, form_obj);
|
||||
}
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "ecmascript/quickjs/document.h"
|
||||
#include "ecmascript/quickjs/form.h"
|
||||
#include "ecmascript/quickjs/forms.h"
|
||||
//#include "ecmascript/quickjs/input.h"
|
||||
#include "ecmascript/quickjs/input.h"
|
||||
#include "ecmascript/quickjs/window.h"
|
||||
#include "intl/libintl.h"
|
||||
#include "main/select.h"
|
||||
@ -47,6 +47,7 @@
|
||||
#include "viewer/text/vs.h"
|
||||
|
||||
#include <libxml++/libxml++.h>
|
||||
#include <map>
|
||||
|
||||
#define countof(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
@ -100,7 +101,7 @@ js_forms_set_items(JSContext *ctx, JSValueConst this_val, void *node)
|
||||
|
||||
if (form->name) {
|
||||
if (strcmp(form->name, "item") && strcmp(form->name, "namedItem")) {
|
||||
JS_DefinePropertyValueStr(ctx, this_val, form->name, v, 0);
|
||||
JS_SetPropertyStr(ctx, this_val, form->name, v);
|
||||
}
|
||||
}
|
||||
counter++;
|
||||
@ -272,8 +273,20 @@ static const JSCFunctionListEntry js_forms_proto_funcs[] = {
|
||||
JS_CFUNC_DEF("namedItem", 1, js_forms_namedItem),
|
||||
};
|
||||
|
||||
static std::map<void *, JSValueConst> map_forms;
|
||||
|
||||
static
|
||||
void js_forms_finalizer(JSRuntime *rt, JSValue val)
|
||||
{
|
||||
void *node = JS_GetOpaque(val, js_forms_class_id);
|
||||
|
||||
map_forms.erase(node);
|
||||
}
|
||||
|
||||
|
||||
static JSClassDef js_forms_class = {
|
||||
"forms",
|
||||
js_forms_finalizer
|
||||
};
|
||||
|
||||
static JSValue
|
||||
@ -328,13 +341,26 @@ getForms(JSContext *ctx, void *node)
|
||||
#ifdef ECMASCRIPT_DEBUG
|
||||
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
||||
#endif
|
||||
JSValue forms_obj = JS_NewObject(ctx);
|
||||
auto node_find = map_forms.find(node);
|
||||
|
||||
if (node_find != map_forms.end()) {
|
||||
return JS_DupValue(ctx, node_find->second);
|
||||
}
|
||||
static int initialized;
|
||||
/* create the element class */
|
||||
if (!initialized) {
|
||||
JS_NewClassID(&js_forms_class_id);
|
||||
JS_NewClass(JS_GetRuntime(ctx), js_forms_class_id, &js_forms_class);
|
||||
initialized = 1;
|
||||
}
|
||||
JSValue forms_obj = JS_NewObjectClass(ctx, js_forms_class_id);
|
||||
|
||||
JS_SetPropertyFunctionList(ctx, forms_obj, js_forms_proto_funcs, countof(js_forms_proto_funcs));
|
||||
// forms_class = JS_NewCFunction2(ctx, js_forms_ctor, "forms", 0, JS_CFUNC_constructor, 0);
|
||||
// JS_SetConstructor(ctx, forms_class, forms_obj);
|
||||
JS_SetClassProto(ctx, js_forms_class_id, forms_obj);
|
||||
JS_SetOpaque(forms_obj, node);
|
||||
js_forms_set_items(ctx, forms_obj, node);
|
||||
|
||||
return forms_obj;
|
||||
map_forms[node] = forms_obj;
|
||||
|
||||
return JS_DupValue(ctx, forms_obj);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "document/view.h"
|
||||
#include "ecmascript/ecmascript.h"
|
||||
#include "ecmascript/quickjs.h"
|
||||
//#include "ecmascript/quickjs/document.h"
|
||||
#include "ecmascript/quickjs/document.h"
|
||||
#include "ecmascript/quickjs/form.h"
|
||||
#include "ecmascript/quickjs/forms.h"
|
||||
#include "ecmascript/quickjs/input.h"
|
||||
@ -47,10 +47,13 @@
|
||||
#include "viewer/text/vs.h"
|
||||
|
||||
#include <libxml++/libxml++.h>
|
||||
#include <map>
|
||||
|
||||
#define countof(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
static JSClassID js_input_class_id;
|
||||
JSValue getInput(JSContext *ctx, struct form_state *fs);
|
||||
|
||||
|
||||
/* Accordingly to the JS specs, each input type should own object. That'd be a
|
||||
* huge PITA though, however DOM comes to the rescue and defines just a single
|
||||
@ -1342,49 +1345,13 @@ js_input_select(JSContext *ctx, JSValueConst this_val, unsigned int argc, JSValu
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
JSValue
|
||||
getInput(JSContext *ctx, struct form_state *fs)
|
||||
{
|
||||
// TODO
|
||||
return JS_NULL;
|
||||
}
|
||||
|
||||
JSValue
|
||||
js_get_input_object(JSContext *ctx, struct form_state *fs)
|
||||
{
|
||||
#ifdef ECMASCRIPT_DEBUG
|
||||
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
||||
#endif
|
||||
|
||||
JSValue jsinput = fs->ecmascript_obj;
|
||||
|
||||
if (!JS_IsNull(jsinput)) {
|
||||
assert(JS_GetOpaque(jsinput, js_input_class_id) == fs);
|
||||
if_assert_failed return JS_NULL;
|
||||
|
||||
return jsinput;
|
||||
}
|
||||
|
||||
/* jsform ('form') is input's parent */
|
||||
/* FIXME: That is NOT correct since the real containing element
|
||||
* should be its parent, but gimme DOM first. --pasky */
|
||||
|
||||
return getInput(ctx, fs);
|
||||
#if 0
|
||||
jsinput = JS_NewObject(ctx, &input_class);
|
||||
if (!jsinput)
|
||||
return NULL;
|
||||
|
||||
JS::RootedObject r_jsinput(ctx, jsinput);
|
||||
|
||||
JS_DefineProperties(ctx, r_jsinput, (JSPropertySpec *) input_props);
|
||||
spidermonkey_DefineFunctions(ctx, jsinput, input_funcs);
|
||||
|
||||
JS_SetPrivate(jsinput, fs); /* to @input_class */
|
||||
fs->ecmascript_obj = jsinput;
|
||||
|
||||
return jsinput;
|
||||
#endif
|
||||
}
|
||||
|
||||
static const JSCFunctionListEntry js_input_proto_funcs[] = {
|
||||
@ -1410,8 +1377,52 @@ static const JSCFunctionListEntry js_input_proto_funcs[] = {
|
||||
JS_CFUNC_DEF("select", 0 , js_input_select),
|
||||
};
|
||||
|
||||
static std::map<struct form_state *, JSValueConst> map_inputs;
|
||||
|
||||
void
|
||||
quickjs_detach_form_state(struct form_state *fs)
|
||||
{
|
||||
#ifdef ECMASCRIPT_DEBUG
|
||||
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
||||
#endif
|
||||
JSValue jsinput = fs->ecmascript_obj;
|
||||
|
||||
if (!JS_IsNull(jsinput)) {
|
||||
map_inputs.erase(fs);
|
||||
JS_SetOpaque(jsinput, nullptr);
|
||||
fs->ecmascript_obj = JS_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
quickjs_moved_form_state(struct form_state *fs)
|
||||
{
|
||||
#ifdef ECMASCRIPT_DEBUG
|
||||
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
||||
#endif
|
||||
JSValue jsinput = fs->ecmascript_obj;
|
||||
|
||||
if (!JS_IsNull(jsinput)) {
|
||||
map_inputs.erase(fs);
|
||||
JS_SetOpaque(jsinput, fs);
|
||||
map_inputs[fs] = jsinput;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void js_input_finalizer(JSRuntime *rt, JSValue val)
|
||||
{
|
||||
struct form_state *fs = JS_GetOpaque(val, js_input_class_id);
|
||||
|
||||
JS_SetOpaque(val, nullptr);
|
||||
fs->ecmascript_obj = JS_NULL;
|
||||
map_inputs.erase(fs);
|
||||
}
|
||||
|
||||
|
||||
static JSClassDef js_input_class = {
|
||||
"input",
|
||||
js_input_finalizer
|
||||
};
|
||||
|
||||
static JSValue
|
||||
@ -1460,26 +1471,30 @@ js_input_init(JSContext *ctx, JSValue global_obj)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
input_finalize(JSFreeOp *op, JSObject *jsinput)
|
||||
JSValue
|
||||
getInput(JSContext *ctx, struct form_state *fs)
|
||||
{
|
||||
#ifdef ECMASCRIPT_DEBUG
|
||||
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
||||
#endif
|
||||
struct form_state *fs = JS_GetPrivate(jsinput);
|
||||
auto node_find = map_inputs.find(fs);
|
||||
|
||||
if (fs) {
|
||||
/* If this assertion fails, leave fs->ecmascript_obj
|
||||
* unchanged, because it may point to a different
|
||||
* JSObject whose private pointer will later have to
|
||||
* be updated to avoid crashes. */
|
||||
assert(fs->ecmascript_obj == jsinput);
|
||||
if_assert_failed return;
|
||||
|
||||
fs->ecmascript_obj = NULL;
|
||||
/* No need to JS_SetPrivate, because jsinput is being
|
||||
* destroyed. */
|
||||
if (node_find != map_inputs.end()) {
|
||||
return JS_DupValue(ctx, node_find->second);
|
||||
}
|
||||
static int initialized;
|
||||
if (!initialized) {
|
||||
JS_NewClassID(&js_input_class_id);
|
||||
JS_NewClass(JS_GetRuntime(ctx), js_input_class_id, &js_input_class);
|
||||
initialized = 1;
|
||||
}
|
||||
JSValue input_obj = JS_NewObjectClass(ctx, js_input_class_id);
|
||||
|
||||
JS_SetPropertyFunctionList(ctx, input_obj, js_input_proto_funcs, countof(js_input_proto_funcs));
|
||||
JS_SetClassProto(ctx, js_input_class_id, input_obj);
|
||||
JS_SetOpaque(input_obj, fs);
|
||||
fs->ecmascript_obj = input_obj;
|
||||
map_inputs[fs] = input_obj;
|
||||
|
||||
return JS_DupValue(ctx, input_obj);
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user