diff --git a/src/ecmascript/mujs.c b/src/ecmascript/mujs.c index faa53cf1..0836718d 100644 --- a/src/ecmascript/mujs.c +++ b/src/ecmascript/mujs.c @@ -30,6 +30,7 @@ #include "ecmascript/mujs/element.h" #include "ecmascript/mujs/event.h" #include "ecmascript/mujs/history.h" +#include "ecmascript/mujs/keyboard.h" #include "ecmascript/mujs/localstorage.h" #include "ecmascript/mujs/location.h" #include "ecmascript/mujs/mapa.h" @@ -137,6 +138,7 @@ mujs_get_interpreter(struct ecmascript_interpreter *interpreter) mjs_document_init(J); mjs_xhr_init(J); mjs_event_init(J); + mjs_keyboardEvent_init(J); return J; #if 0 diff --git a/src/ecmascript/mujs/element.c b/src/ecmascript/mujs/element.c index 8b3f1fca..3c60f98b 100644 --- a/src/ecmascript/mujs/element.c +++ b/src/ecmascript/mujs/element.c @@ -3070,7 +3070,7 @@ check_element_event(void *interp, void *elem, const char *event_name, struct ter if (ev && ev->ev == EVENT_KBD && (!strcmp(event_name, "keydown") || !strcmp(event_name, "keyup") || !strcmp(event_name, "keypress"))) { js_getregistry(J, l->fun); /* retrieve the js function from the registry */ js_getregistry(J, el_private->thisval); - mjs_push_keyboardEvent(J, ev); + mjs_push_keyboardEvent(J, ev, event_name); js_pcall(J, 1); js_pop(J, 1); } else { diff --git a/src/ecmascript/mujs/keyboard.c b/src/ecmascript/mujs/keyboard.c index ac21844e..4fcb564e 100644 --- a/src/ecmascript/mujs/keyboard.c +++ b/src/ecmascript/mujs/keyboard.c @@ -19,10 +19,23 @@ static void mjs_keyboardEvent_get_property_key(js_State *J); static void mjs_keyboardEvent_get_property_keyCode(js_State *J); +static void mjs_keyboardEvent_get_property_bubbles(js_State *J); +static void mjs_keyboardEvent_get_property_cancelable(js_State *J); +static void mjs_keyboardEvent_get_property_composed(js_State *J); +static void mjs_keyboardEvent_get_property_defaultPrevented(js_State *J); +static void mjs_keyboardEvent_get_property_type(js_State *J); + +static void mjs_keyboardEvent_preventDefault(js_State *J); + 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; }; extern struct term_event last_event; @@ -33,12 +46,13 @@ mjs_keyboardEvent_finalizer(js_State *J, void *val) struct keyboard *keyb = (struct keyboard *)val; if (keyb) { + mem_free_if(keyb->type_); mem_free(keyb); } } void -mjs_push_keyboardEvent(js_State *J, struct term_event *ev) +mjs_push_keyboardEvent(js_State *J, struct term_event *ev, const char *type_) { struct keyboard *keyb = (struct keyboard *)mem_calloc(1, sizeof(*keyb)); @@ -47,15 +61,82 @@ mjs_push_keyboardEvent(js_State *J, struct term_event *ev) return; } keyCode = keyb->keyCode = ev ? get_kbd_key(ev) : 0; + keyb->type_ = null_or_stracpy(type_); js_newobject(J); { js_newuserdata(J, "event", keyb, mjs_keyboardEvent_finalizer); + addmethod(J, "preventDefault", mjs_keyboardEvent_preventDefault, 0); + addproperty(J, "bubbles", mjs_keyboardEvent_get_property_bubbles, NULL); + addproperty(J, "cancelable", mjs_keyboardEvent_get_property_cancelable, NULL); + addproperty(J, "composed", mjs_keyboardEvent_get_property_composed, NULL); + addproperty(J, "defaultPrevented", mjs_keyboardEvent_get_property_defaultPrevented, NULL); addproperty(J, "key", mjs_keyboardEvent_get_property_key, NULL); addproperty(J, "keyCode", mjs_keyboardEvent_get_property_keyCode, NULL); + addproperty(J, "type", mjs_keyboardEvent_get_property_type, NULL); } } +static void +mjs_keyboardEvent_get_property_bubbles(js_State *J) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + struct keyboard *keyb = (struct keyboard *)js_touserdata(J, 0, "event"); + + if (!keyb) { + js_pushnull(J); + return; + } + js_pushboolean(J, keyb->bubbles); +} + +static void +mjs_keyboardEvent_get_property_cancelable(js_State *J) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + struct keyboard *keyb = (struct keyboard *)js_touserdata(J, 0, "event"); + + if (!keyb) { + js_pushnull(J); + return; + } + js_pushboolean(J, keyb->cancelable); +} + +static void +mjs_keyboardEvent_get_property_composed(js_State *J) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + struct keyboard *keyb = (struct keyboard *)js_touserdata(J, 0, "event"); + + if (!keyb) { + js_pushnull(J); + return; + } + js_pushboolean(J, keyb->composed); +} + +static void +mjs_keyboardEvent_get_property_defaultPrevented(js_State *J) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + struct keyboard *keyb = (struct keyboard *)js_touserdata(J, 0, "event"); + + if (!keyb) { + js_pushnull(J); + return; + } + js_pushboolean(J, keyb->defaultPrevented); +} + static void mjs_keyboardEvent_get_property_key(js_State *J) { @@ -94,3 +175,94 @@ mjs_keyboardEvent_get_property_keyCode(js_State *J) } js_pushnumber(J, code); } + +static void +mjs_keyboardEvent_get_property_type(js_State *J) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + struct keyboard *keyb = (struct keyboard *)js_touserdata(J, 0, "event"); + + if (!keyb) { + js_pushnull(J); + return; + } + js_pushstring(J, keyb->type_ ?: ""); +} + +static void +mjs_keyboardEvent_preventDefault(js_State *J) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + struct keyboard *keyb = (struct keyboard *)js_touserdata(J, 0, "event"); + + if (!keyb) { + js_pushnull(J); + return; + } + if (keyb->cancelable) { + keyb->defaultPrevented = 1; + } + js_pushundefined(J); +} + +static void +mjs_keyboardEvent_fun(js_State *J) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + js_pushundefined(J); +} + +static void +mjs_keyboardEvent_constructor(js_State *J) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + struct keyboard *keyb = (struct keyboard *)mem_calloc(1, sizeof(*keyb)); + + if (!keyb) { + return; + } + keyb->type_ = null_or_stracpy(js_tostring(J, 1)); + + js_getproperty(J, 2, "bubbles"); + keyb->bubbles = js_toboolean(J, -1); + js_pop(J, 1); + js_getproperty(J, 2, "cancelable"); + keyb->cancelable = js_toboolean(J, -1); + js_pop(J, 1); + js_getproperty(J, 2, "composed"); + keyb->composed = js_toboolean(J, -1); + js_pop(J, 1); + js_getproperty(J, 2, "keyCode"); + keyb->keyCode = js_toint32(J, -1); + js_pop(J, 1); + + js_newobject(J); + { + js_newuserdata(J, "event", keyb, mjs_keyboardEvent_finalizer); + addmethod(J, "preventDefault", mjs_keyboardEvent_preventDefault, 0); + addproperty(J, "bubbles", mjs_keyboardEvent_get_property_bubbles, NULL); + addproperty(J, "cancelable", mjs_keyboardEvent_get_property_cancelable, NULL); + addproperty(J, "composed", mjs_keyboardEvent_get_property_composed, NULL); + addproperty(J, "defaultPrevented", mjs_keyboardEvent_get_property_defaultPrevented, NULL); + addproperty(J, "key", mjs_keyboardEvent_get_property_key, NULL); + addproperty(J, "keyCode", mjs_keyboardEvent_get_property_keyCode, NULL); + addproperty(J, "type", mjs_keyboardEvent_get_property_type, NULL); + } +} + +int +mjs_keyboardEvent_init(js_State *J) +{ + js_pushglobal(J); + js_newcconstructor(J, mjs_keyboardEvent_fun, mjs_keyboardEvent_constructor, "KeyboardEvent", 0); + js_defglobal(J, "KeyboardEvent", JS_DONTENUM); + return 0; +} diff --git a/src/ecmascript/mujs/keyboard.h b/src/ecmascript/mujs/keyboard.h index cc2fb2fa..17fc6468 100644 --- a/src/ecmascript/mujs/keyboard.h +++ b/src/ecmascript/mujs/keyboard.h @@ -9,7 +9,9 @@ extern "C" { struct term_event; -void mjs_push_keyboardEvent(js_State *J, struct term_event *ev); +void mjs_push_keyboardEvent(js_State *J, struct term_event *ev, const char *type_); +int mjs_keyboardEvent_init(js_State *J); + #ifdef __cplusplus } diff --git a/src/ecmascript/mujs/window.c b/src/ecmascript/mujs/window.c index 2be829d8..befb9ec5 100644 --- a/src/ecmascript/mujs/window.c +++ b/src/ecmascript/mujs/window.c @@ -110,7 +110,7 @@ mjs_window_get_property_event(js_State *J) #ifdef ECMASCRIPT_DEBUG fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); #endif - mjs_push_keyboardEvent(J, NULL); + mjs_push_keyboardEvent(J, NULL, ""); } static void