mirror of
https://github.com/rkd77/elinks.git
synced 2025-06-30 22:19:29 -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)
|
ecmascript_detach_form_view(struct form_view *fv)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_QUICKJS
|
#ifdef CONFIG_QUICKJS
|
||||||
|
quickjs_detach_form_view(fv);
|
||||||
#else
|
#else
|
||||||
spidermonkey_detach_form_view(fv);
|
spidermonkey_detach_form_view(fv);
|
||||||
#endif
|
#endif
|
||||||
@ -410,6 +411,7 @@ ecmascript_detach_form_view(struct form_view *fv)
|
|||||||
void ecmascript_detach_form_state(struct form_state *fs)
|
void ecmascript_detach_form_state(struct form_state *fs)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_QUICKJS
|
#ifdef CONFIG_QUICKJS
|
||||||
|
quickjs_detach_form_state(fs);
|
||||||
#else
|
#else
|
||||||
spidermonkey_detach_form_state(fs);
|
spidermonkey_detach_form_state(fs);
|
||||||
#endif
|
#endif
|
||||||
@ -418,6 +420,7 @@ void ecmascript_detach_form_state(struct form_state *fs)
|
|||||||
void ecmascript_moved_form_state(struct form_state *fs)
|
void ecmascript_moved_form_state(struct form_state *fs)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_QUICKJS
|
#ifdef CONFIG_QUICKJS
|
||||||
|
quickjs_moved_form_state(fs);
|
||||||
#else
|
#else
|
||||||
spidermonkey_moved_form_state(fs);
|
spidermonkey_moved_form_state(fs);
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#include "document/view.h"
|
#include "document/view.h"
|
||||||
#include "ecmascript/ecmascript.h"
|
#include "ecmascript/ecmascript.h"
|
||||||
#include "ecmascript/quickjs.h"
|
#include "ecmascript/quickjs.h"
|
||||||
//#include "ecmascript/spidermonkey/document.h"
|
#include "ecmascript/quickjs/document.h"
|
||||||
#include "ecmascript/quickjs/form.h"
|
#include "ecmascript/quickjs/form.h"
|
||||||
#include "ecmascript/quickjs/forms.h"
|
#include "ecmascript/quickjs/forms.h"
|
||||||
#include "ecmascript/quickjs/input.h"
|
#include "ecmascript/quickjs/input.h"
|
||||||
@ -47,59 +47,14 @@
|
|||||||
#include "viewer/text/vs.h"
|
#include "viewer/text/vs.h"
|
||||||
|
|
||||||
#include <libxml++/libxml++.h>
|
#include <libxml++/libxml++.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#define countof(x) (sizeof(x) / sizeof((x)[0]))
|
#define countof(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
|
||||||
static JSClassID js_form_elements_class_id;
|
static JSClassID js_form_elements_class_id;
|
||||||
static JSClassID js_form_class_id;
|
static JSClassID js_form_class_id;
|
||||||
|
static std::map<struct form_view *, JSValueConst> map_form_elements;
|
||||||
#if 0
|
JSValue getForm(JSContext *ctx, struct form *form);
|
||||||
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 JSValue
|
static JSValue
|
||||||
js_get_form_control_object(JSContext *ctx,
|
js_get_form_control_object(JSContext *ctx,
|
||||||
@ -132,7 +87,6 @@ js_get_form_control_object(JSContext *ctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
js_form_set_items(JSContext *ctx, JSValueConst this_val, void *node)
|
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);
|
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 (fc->id) {
|
||||||
if (strcmp(fc->id, "item") && strcmp(fc->id, "namedItem")) {
|
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) {
|
} else if (fc->name) {
|
||||||
if (strcmp(fc->name, "item") && strcmp(fc->name, "namedItem")) {
|
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++;
|
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);
|
JSValue obj = js_get_form_control_object(ctx, fc->type, fs);
|
||||||
|
JS_SetPropertyUint32(ctx, this_val, counter, obj);
|
||||||
|
|
||||||
if (fc->id) {
|
if (fc->id) {
|
||||||
if (strcmp(fc->id, "item") && strcmp(fc->id, "namedItem")) {
|
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) {
|
} else if (fc->name) {
|
||||||
if (strcmp(fc->name, "item") && strcmp(fc->name, "namedItem")) {
|
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;
|
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
|
JSValue
|
||||||
getFormElements(JSContext *ctx, struct form_view *fv)
|
getFormElements(JSContext *ctx, struct form_view *fv)
|
||||||
{
|
{
|
||||||
// TODO
|
#ifdef ECMASCRIPT_DEBUG
|
||||||
return JS_NULL;
|
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
|
static JSValue
|
||||||
@ -494,23 +513,6 @@ js_form_get_property_elements(JSContext *ctx, JSValueConst this_val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return getFormElements(ctx, fv);
|
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
|
static JSValue
|
||||||
@ -870,12 +872,6 @@ js_form_submit(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *ar
|
|||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSValue
|
|
||||||
getForm(JSContext *ctx, struct form *form)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return JS_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSValue
|
JSValue
|
||||||
js_get_form_object(JSContext *ctx, JSValueConst jsdoc, struct form *form)
|
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
|
#ifdef ECMASCRIPT_DEBUG
|
||||||
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
||||||
#endif
|
#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);
|
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
|
static JSValue
|
||||||
js_elements_ctor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv)
|
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 */
|
/* create the elements class */
|
||||||
JS_NewClassID(&js_form_elements_class_id);
|
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);
|
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);
|
elements_class = JS_NewCFunction2(ctx, js_elements_ctor, "elements", 0, JS_CFUNC_constructor, 0);
|
||||||
/* set proto.constructor and ctor.prototype */
|
/* 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),
|
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 = {
|
static JSClassDef js_form_class = {
|
||||||
"form",
|
"form",
|
||||||
|
js_form_finalizer
|
||||||
};
|
};
|
||||||
|
|
||||||
static JSValue
|
static JSValue
|
||||||
@ -1081,3 +1002,34 @@ js_form_init(JSContext *ctx, JSValue global_obj)
|
|||||||
JS_SetPropertyStr(ctx, global_obj, "form", form_proto);
|
JS_SetPropertyStr(ctx, global_obj, "form", form_proto);
|
||||||
return 0;
|
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/document.h"
|
||||||
#include "ecmascript/quickjs/form.h"
|
#include "ecmascript/quickjs/form.h"
|
||||||
#include "ecmascript/quickjs/forms.h"
|
#include "ecmascript/quickjs/forms.h"
|
||||||
//#include "ecmascript/quickjs/input.h"
|
#include "ecmascript/quickjs/input.h"
|
||||||
#include "ecmascript/quickjs/window.h"
|
#include "ecmascript/quickjs/window.h"
|
||||||
#include "intl/libintl.h"
|
#include "intl/libintl.h"
|
||||||
#include "main/select.h"
|
#include "main/select.h"
|
||||||
@ -47,6 +47,7 @@
|
|||||||
#include "viewer/text/vs.h"
|
#include "viewer/text/vs.h"
|
||||||
|
|
||||||
#include <libxml++/libxml++.h>
|
#include <libxml++/libxml++.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#define countof(x) (sizeof(x) / sizeof((x)[0]))
|
#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 (form->name) {
|
||||||
if (strcmp(form->name, "item") && strcmp(form->name, "namedItem")) {
|
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++;
|
counter++;
|
||||||
@ -272,8 +273,20 @@ static const JSCFunctionListEntry js_forms_proto_funcs[] = {
|
|||||||
JS_CFUNC_DEF("namedItem", 1, js_forms_namedItem),
|
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 = {
|
static JSClassDef js_forms_class = {
|
||||||
"forms",
|
"forms",
|
||||||
|
js_forms_finalizer
|
||||||
};
|
};
|
||||||
|
|
||||||
static JSValue
|
static JSValue
|
||||||
@ -328,13 +341,26 @@ getForms(JSContext *ctx, void *node)
|
|||||||
#ifdef ECMASCRIPT_DEBUG
|
#ifdef ECMASCRIPT_DEBUG
|
||||||
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
||||||
#endif
|
#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));
|
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_SetClassProto(ctx, js_forms_class_id, forms_obj);
|
||||||
JS_SetOpaque(forms_obj, node);
|
JS_SetOpaque(forms_obj, node);
|
||||||
js_forms_set_items(ctx, 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 "document/view.h"
|
||||||
#include "ecmascript/ecmascript.h"
|
#include "ecmascript/ecmascript.h"
|
||||||
#include "ecmascript/quickjs.h"
|
#include "ecmascript/quickjs.h"
|
||||||
//#include "ecmascript/quickjs/document.h"
|
#include "ecmascript/quickjs/document.h"
|
||||||
#include "ecmascript/quickjs/form.h"
|
#include "ecmascript/quickjs/form.h"
|
||||||
#include "ecmascript/quickjs/forms.h"
|
#include "ecmascript/quickjs/forms.h"
|
||||||
#include "ecmascript/quickjs/input.h"
|
#include "ecmascript/quickjs/input.h"
|
||||||
@ -47,10 +47,13 @@
|
|||||||
#include "viewer/text/vs.h"
|
#include "viewer/text/vs.h"
|
||||||
|
|
||||||
#include <libxml++/libxml++.h>
|
#include <libxml++/libxml++.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#define countof(x) (sizeof(x) / sizeof((x)[0]))
|
#define countof(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
|
||||||
static JSClassID js_input_class_id;
|
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
|
/* 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
|
* 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;
|
return JS_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSValue
|
|
||||||
getInput(JSContext *ctx, struct form_state *fs)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return JS_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSValue
|
JSValue
|
||||||
js_get_input_object(JSContext *ctx, struct form_state *fs)
|
js_get_input_object(JSContext *ctx, struct form_state *fs)
|
||||||
{
|
{
|
||||||
#ifdef ECMASCRIPT_DEBUG
|
#ifdef ECMASCRIPT_DEBUG
|
||||||
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
||||||
#endif
|
#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);
|
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[] = {
|
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),
|
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 = {
|
static JSClassDef js_input_class = {
|
||||||
"input",
|
"input",
|
||||||
|
js_input_finalizer
|
||||||
};
|
};
|
||||||
|
|
||||||
static JSValue
|
static JSValue
|
||||||
@ -1460,26 +1471,30 @@ js_input_init(JSContext *ctx, JSValue global_obj)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
JSValue
|
||||||
static void
|
getInput(JSContext *ctx, struct form_state *fs)
|
||||||
input_finalize(JSFreeOp *op, JSObject *jsinput)
|
|
||||||
{
|
{
|
||||||
#ifdef ECMASCRIPT_DEBUG
|
#ifdef ECMASCRIPT_DEBUG
|
||||||
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
||||||
#endif
|
#endif
|
||||||
struct form_state *fs = JS_GetPrivate(jsinput);
|
auto node_find = map_inputs.find(fs);
|
||||||
|
|
||||||
if (fs) {
|
if (node_find != map_inputs.end()) {
|
||||||
/* If this assertion fails, leave fs->ecmascript_obj
|
return JS_DupValue(ctx, node_find->second);
|
||||||
* 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. */
|
|
||||||
}
|
}
|
||||||
|
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…
x
Reference in New Issue
Block a user