From f6ca5b8ce856d0b3b4faa66ece6b26749de77dac Mon Sep 17 00:00:00 2001 From: Witold Filipczyk Date: Mon, 11 Mar 2024 16:14:19 +0100 Subject: [PATCH] [quikcjs] Copied props from Event to KeyboardEvent --- src/ecmascript/quickjs.c | 2 + src/ecmascript/quickjs/event.c | 1 - src/ecmascript/quickjs/keyboard.c | 240 +++++++++++++++++++++++++++++- 3 files changed, 241 insertions(+), 2 deletions(-) diff --git a/src/ecmascript/quickjs.c b/src/ecmascript/quickjs.c index bcab6e31d..fcd75a9f3 100644 --- a/src/ecmascript/quickjs.c +++ b/src/ecmascript/quickjs.c @@ -31,6 +31,7 @@ #include "ecmascript/quickjs/event.h" #include "ecmascript/quickjs/heartbeat.h" #include "ecmascript/quickjs/history.h" +#include "ecmascript/quickjs/keyboard.h" #include "ecmascript/quickjs/localstorage.h" #include "ecmascript/quickjs/location.h" #include "ecmascript/quickjs/mapa.h" @@ -176,6 +177,7 @@ quickjs_get_interpreter(struct ecmascript_interpreter *interpreter) js_element_init(ctx); js_xhr_init(ctx); js_event_init(ctx); + js_keyboardEvent_init(ctx); interpreter->document_obj = js_document_init(ctx); diff --git a/src/ecmascript/quickjs/event.c b/src/ecmascript/quickjs/event.c index 0eb6e8206..cc777f59d 100644 --- a/src/ecmascript/quickjs/event.c +++ b/src/ecmascript/quickjs/event.c @@ -223,7 +223,6 @@ js_event_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueC return obj; } - static void JS_NewGlobalCConstructor2(JSContext *ctx, JSValue func_obj, const char *name, JSValueConst proto) { diff --git a/src/ecmascript/quickjs/keyboard.c b/src/ecmascript/quickjs/keyboard.c index 1a7dbd441..cf1354690 100644 --- a/src/ecmascript/quickjs/keyboard.c +++ b/src/ecmascript/quickjs/keyboard.c @@ -23,10 +23,24 @@ static JSClassID js_keyboardEvent_class_id; static JSValue js_keyboardEvent_get_property_key(JSContext *ctx, JSValueConst this_val); static JSValue js_keyboardEvent_get_property_keyCode(JSContext *ctx, JSValueConst this_val); +static JSValue js_keyboardEvent_get_property_bubbles(JSContext *ctx, JSValueConst this_val); +static JSValue js_keyboardEvent_get_property_cancelable(JSContext *ctx, JSValueConst this_val); +static JSValue js_keyboardEvent_get_property_composed(JSContext *ctx, JSValueConst this_val); +static JSValue js_keyboardEvent_get_property_defaultPrevented(JSContext *ctx, JSValueConst this_val); +static JSValue js_keyboardEvent_get_property_type(JSContext *ctx, JSValueConst this_val); + +static JSValue js_keyboardEvent_preventDefault(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv); + + static unicode_val_T keyCode; struct keyboard { unicode_val_T keyCode; + char *type_; + unsigned int bubbles:1; + unsigned int cancelable:1; + unsigned int composed:1; + unsigned int defaultPrevented:1; }; static @@ -37,6 +51,7 @@ void js_keyboardEvent_finalizer(JSRuntime *rt, JSValue val) struct keyboard *keyb = (struct keyboard *)JS_GetOpaque(val, js_keyboardEvent_class_id); if (keyb) { + mem_free_if(keyb->type_); mem_free(keyb); } } @@ -47,10 +62,88 @@ static JSClassDef js_keyboardEvent_class = { }; static const JSCFunctionListEntry js_keyboardEvent_proto_funcs[] = { + JS_CGETSET_DEF("bubbles", js_keyboardEvent_get_property_bubbles, NULL), + JS_CGETSET_DEF("cancelable", js_keyboardEvent_get_property_cancelable, NULL), + JS_CGETSET_DEF("composed", js_keyboardEvent_get_property_composed, NULL), + JS_CGETSET_DEF("defaultPrevented", js_keyboardEvent_get_property_defaultPrevented, NULL), JS_CGETSET_DEF("key", js_keyboardEvent_get_property_key, NULL), - JS_CGETSET_DEF("keyCode", js_keyboardEvent_get_property_keyCode, NULL) + JS_CGETSET_DEF("keyCode", js_keyboardEvent_get_property_keyCode, NULL), + JS_CGETSET_DEF("type", js_keyboardEvent_get_property_type, NULL), + JS_CFUNC_DEF("preventDefault", 0, js_keyboardEvent_preventDefault) }; +static JSValue +js_keyboardEvent_get_property_bubbles(JSContext *ctx, JSValueConst this_val) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + REF_JS(this_val); + + struct keyboard *keyb = (struct keyboard *)(JS_GetOpaque(this_val, js_keyboardEvent_class_id)); + + if (!keyb) { + return JS_NULL; + } + JSValue r = JS_NewBool(ctx, keyb->bubbles); + + RETURN_JS(r); +} + +static JSValue +js_keyboardEvent_get_property_cancelable(JSContext *ctx, JSValueConst this_val) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + REF_JS(this_val); + + struct keyboard *keyb = (struct keyboard *)(JS_GetOpaque(this_val, js_keyboardEvent_class_id)); + + if (!keyb) { + return JS_NULL; + } + JSValue r = JS_NewBool(ctx, keyb->cancelable); + + RETURN_JS(r); +} + +static JSValue +js_keyboardEvent_get_property_composed(JSContext *ctx, JSValueConst this_val) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + REF_JS(this_val); + + struct keyboard *keyb = (struct keyboard *)(JS_GetOpaque(this_val, js_keyboardEvent_class_id)); + + if (!keyb) { + return JS_NULL; + } + JSValue r = JS_NewBool(ctx, keyb->composed); + + RETURN_JS(r); +} + +static JSValue +js_keyboardEvent_get_property_defaultPrevented(JSContext *ctx, JSValueConst this_val) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + REF_JS(this_val); + + struct keyboard *keyb = (struct keyboard *)(JS_GetOpaque(this_val, js_keyboardEvent_class_id)); + + if (!keyb) { + return JS_NULL; + } + JSValue r = JS_NewBool(ctx, keyb->defaultPrevented); + + RETURN_JS(r); +} + static JSValue js_keyboardEvent_get_property_key(JSContext *ctx, JSValueConst this_val) { @@ -88,6 +181,47 @@ js_keyboardEvent_get_property_keyCode(JSContext *ctx, JSValueConst this_val) return JS_NewUint32(ctx, keyb->keyCode); } +static JSValue +js_keyboardEvent_get_property_type(JSContext *ctx, JSValueConst this_val) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + REF_JS(this_val); + + struct keyboard *keyb = (struct keyboard *)(JS_GetOpaque(this_val, js_keyboardEvent_class_id)); + + if (!keyb) { + return JS_NULL; + } + if (!keyb->type_) { + JSValue r = JS_NewString(ctx, ""); + RETURN_JS(r); + } + JSValue r = JS_NewString(ctx, keyb->type_); + + RETURN_JS(r); +} + +static JSValue +js_keyboardEvent_preventDefault(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + REF_JS(this_val); + + struct keyboard *keyb = (struct keyboard *)(JS_GetOpaque(this_val, js_keyboardEvent_class_id)); + + if (!keyb) { + return JS_NULL; + } + if (keyb->cancelable) { + keyb->defaultPrevented = 1; + } + return JS_UNDEFINED; +} + JSValue get_keyboardEvent(JSContext *ctx, struct term_event *ev) { @@ -121,3 +255,107 @@ get_keyboardEvent(JSContext *ctx, struct term_event *ev) JSValue rr = JS_DupValue(ctx, keyb_obj); RETURN_JS(rr); } + +static JSValue +js_keyboardEvent_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + REF_JS(new_target); + + JSValue obj = JS_NewObjectClass(ctx, js_keyboardEvent_class_id); + REF_JS(obj); + + if (JS_IsException(obj)) { + return obj; + } + struct keyboard *keyb = (struct keyboard *)mem_calloc(1, sizeof(*keyb)); + + if (!keyb) { + return JS_NULL; + } + + if (argc > 0) { + const char *str; + size_t len; + + str = JS_ToCStringLen(ctx, &len, argv[0]); + + if (str) { + keyb->type_ = memacpy(str, len); + JS_FreeCString(ctx, str); + } + } + + if (argc > 1) { + JSValue r = JS_GetPropertyStr(ctx, argv[1], "bubbles"); + keyb->bubbles = JS_ToBool(ctx, r); + r = JS_GetPropertyStr(ctx, argv[1], "cancelable"); + keyb->cancelable = JS_ToBool(ctx, r); + r = JS_GetPropertyStr(ctx, argv[1], "composed"); + keyb->composed = JS_ToBool(ctx, r); + r = JS_GetPropertyStr(ctx, argv[1], "keyCode"); + int keyCode; + if (JS_ToInt32(ctx, &keyCode, argv[1])) { + keyb->keyCode = keyCode; + } + } + JS_SetOpaque(obj, keyb); + + return obj; +} + +static void +JS_NewGlobalCConstructor2(JSContext *ctx, JSValue func_obj, const char *name, JSValueConst proto) +{ + REF_JS(func_obj); + REF_JS(proto); + + JSValue global_object = JS_GetGlobalObject(ctx); + + JS_DefinePropertyValueStr(ctx, global_object, name, + JS_DupValue(ctx, func_obj), JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); + JS_SetConstructor(ctx, func_obj, proto); + JS_FreeValue(ctx, func_obj); + JS_FreeValue(ctx, global_object); +} + +static JSValueConst +JS_NewGlobalCConstructor(JSContext *ctx, const char *name, JSCFunction *func, int length, JSValueConst proto) +{ + JSValue func_obj; + func_obj = JS_NewCFunction2(ctx, func, name, length, JS_CFUNC_constructor_or_func, 0); + REF_JS(func_obj); + REF_JS(proto); + + JS_NewGlobalCConstructor2(ctx, func_obj, name, proto); + + return func_obj; +} + +int +js_keyboardEvent_init(JSContext *ctx) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + JSValue proto, obj; + + /* Event class */ + JS_NewClassID(&js_keyboardEvent_class_id); + JS_NewClass(JS_GetRuntime(ctx), js_keyboardEvent_class_id, &js_keyboardEvent_class); + proto = JS_NewObject(ctx); + REF_JS(proto); + + JS_SetPropertyFunctionList(ctx, proto, js_keyboardEvent_proto_funcs, countof(js_keyboardEvent_proto_funcs)); + JS_SetClassProto(ctx, js_keyboardEvent_class_id, proto); + + /* Event object */ + obj = JS_NewGlobalCConstructor(ctx, "KeyboardEvent", js_keyboardEvent_constructor, 1, proto); + REF_JS(obj); + +// JS_SetPropertyFunctionList(ctx, obj, js_keyboardEvent_class_funcs, countof(js_keyboardEvent_class_funcs)); + + return 0; +}