diff --git a/src/ecmascript/spidermonkey.cpp b/src/ecmascript/spidermonkey.cpp index cb06b359..0fb62bda 100644 --- a/src/ecmascript/spidermonkey.cpp +++ b/src/ecmascript/spidermonkey.cpp @@ -33,6 +33,7 @@ #include "ecmascript/spidermonkey/form.h" #include "ecmascript/spidermonkey/heartbeat.h" #include "ecmascript/spidermonkey/history.h" +#include "ecmascript/spidermonkey/keyboard.h" #include "ecmascript/spidermonkey/location.h" #include "ecmascript/spidermonkey/localstorage.h" #include "ecmascript/spidermonkey/navigator.h" @@ -147,7 +148,7 @@ spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter) JSContext *ctx; JSObject *console_obj, *document_obj, /* *forms_obj,*/ *history_obj, *statusbar_obj, *menubar_obj, *navigator_obj, *localstorage_obj, *screen_obj, - *xhr_obj, *event_obj; + *xhr_obj, *event_obj, *keyboardEvent_obj; assert(interpreter); if (!js_module_init_ok) return NULL; @@ -296,6 +297,15 @@ spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter) goto release_and_fail; } + keyboardEvent_obj = spidermonkey_InitClass(ctx, global, NULL, + &keyboardEvent_class, keyboardEvent_constructor, 0, + keyboardEvent_props, + keyboardEvent_funcs, + NULL, NULL, "KeyboardEvent"); + + if (!keyboardEvent_obj) { + goto release_and_fail; + } JS::SetRealmPrivate(js::GetContextRealm(ctx), interpreter); diff --git a/src/ecmascript/spidermonkey/keyboard.cpp b/src/ecmascript/spidermonkey/keyboard.cpp index bf7ed4b0..4259b6c5 100644 --- a/src/ecmascript/spidermonkey/keyboard.cpp +++ b/src/ecmascript/spidermonkey/keyboard.cpp @@ -62,10 +62,24 @@ static bool keyboardEvent_get_property_key(JSContext *cx, unsigned int argc, JS::Value *vp); static bool keyboardEvent_get_property_keyCode(JSContext *cx, unsigned int argc, JS::Value *vp); +static bool keyboardEvent_get_property_bubbles(JSContext *ctx, unsigned int argc, JS::Value *vp); +static bool keyboardEvent_get_property_cancelable(JSContext *ctx, unsigned int argc, JS::Value *vp); +static bool keyboardEvent_get_property_composed(JSContext *ctx, unsigned int argc, JS::Value *vp); +static bool keyboardEvent_get_property_defaultPrevented(JSContext *ctx, unsigned int argc, JS::Value *vp); +static bool keyboardEvent_get_property_type(JSContext *ctx, unsigned int argc, JS::Value *vp); + +static bool keyboardEvent_preventDefault(JSContext *ctx, unsigned int argc, JS::Value *vp); + + 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 void @@ -77,6 +91,7 @@ keyboardEvent_finalize(JS::GCContext *op, JSObject *keyb_obj) struct keyboard *keyb = JS::GetMaybePtrFromReservedSlot(keyb_obj, 0); if (keyb) { + mem_free_if(keyb->type_); mem_free(keyb); } } @@ -124,19 +139,156 @@ keyboardEvent_constructor(JSContext* ctx, unsigned argc, JS::Value* vp) if (!keyb) { return false; } + + if (argc > 0) { + keyb->type_ = jsval_to_string(ctx, args[0]); + } + + if (argc > 1) { + JS::RootedValue v(ctx); + JS::RootedObject v_obj(ctx, &args[1].toObject()); + + if (JS_GetProperty(ctx, v_obj, "bubbles", &v)) { + keyb->bubbles = (unsigned int)v.toBoolean(); + } + if (JS_GetProperty(ctx, v_obj, "cancelable", &v)) { + keyb->cancelable = (unsigned int)v.toBoolean(); + } + if (JS_GetProperty(ctx, v_obj, "composed", &v)) { + keyb->composed = (unsigned int)v.toBoolean(); + } + if (JS_GetProperty(ctx, v_obj, "keyCode", &v)) { + keyb->keyCode = v.toInt32(); + } else { + keyb->keyCode = 0; + } + } JS::SetReservedSlot(newObj, 0, JS::PrivateValue(keyb)); - keyb->keyCode = keyCode; args.rval().setObject(*newObj); return true; } JSPropertySpec keyboardEvent_props[] = { + JS_PSG("bubbles", keyboardEvent_get_property_bubbles, JSPROP_ENUMERATE), + JS_PSG("cancelable", keyboardEvent_get_property_cancelable, JSPROP_ENUMERATE), + JS_PSG("composed", keyboardEvent_get_property_composed, JSPROP_ENUMERATE), + JS_PSG("defaultPrevented", keyboardEvent_get_property_defaultPrevented, JSPROP_ENUMERATE), JS_PSG("key", keyboardEvent_get_property_key, JSPROP_ENUMERATE), JS_PSG("keyCode", keyboardEvent_get_property_keyCode, JSPROP_ENUMERATE), + JS_PSG("type", keyboardEvent_get_property_type, JSPROP_ENUMERATE), JS_PS_END }; +const spidermonkeyFunctionSpec keyboardEvent_funcs[] = { + { "preventDefault", keyboardEvent_preventDefault, 0 }, + { NULL } +}; + +static bool +keyboardEvent_get_property_bubbles(JSContext *ctx, unsigned int argc, JS::Value *vp) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + JS::RootedObject hobj(ctx, &args.thisv().toObject()); + JS::Realm *comp = js::GetContextRealm(ctx); + + if (!comp) { +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__); +#endif + return false; + } + struct keyboard *keyb = JS::GetMaybePtrFromReservedSlot(hobj, 0); + + if (!keyb) { + return false; + } + args.rval().setBoolean(keyb->bubbles); + + return true; +} + +static bool +keyboardEvent_get_property_cancelable(JSContext *ctx, unsigned int argc, JS::Value *vp) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + JS::RootedObject hobj(ctx, &args.thisv().toObject()); + JS::Realm *comp = js::GetContextRealm(ctx); + + if (!comp) { +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__); +#endif + return false; + } + struct keyboard *keyb = JS::GetMaybePtrFromReservedSlot(hobj, 0); + + if (!keyb) { + return false; + } + args.rval().setBoolean(keyb->cancelable); + + return true; +} + +static bool +keyboardEvent_get_property_composed(JSContext *ctx, unsigned int argc, JS::Value *vp) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + JS::RootedObject hobj(ctx, &args.thisv().toObject()); + JS::Realm *comp = js::GetContextRealm(ctx); + + if (!comp) { +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__); +#endif + return false; + } + struct keyboard *keyb = JS::GetMaybePtrFromReservedSlot(hobj, 0); + + if (!keyb) { + return false; + } + args.rval().setBoolean(keyb->composed); + + return true; +} + +static bool +keyboardEvent_get_property_defaultPrevented(JSContext *ctx, unsigned int argc, JS::Value *vp) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + JS::RootedObject hobj(ctx, &args.thisv().toObject()); + JS::Realm *comp = js::GetContextRealm(ctx); + + if (!comp) { +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__); +#endif + return false; + } + struct keyboard *keyb = JS::GetMaybePtrFromReservedSlot(hobj, 0); + + if (!keyb) { + return false; + } + args.rval().setBoolean(keyb->defaultPrevented); + + return true; +} + static bool keyboardEvent_get_property_key(JSContext *ctx, unsigned int argc, JS::Value *vp) { @@ -192,6 +344,65 @@ keyboardEvent_get_property_keyCode(JSContext *ctx, unsigned int argc, JS::Value return true; } +static bool +keyboardEvent_get_property_type(JSContext *ctx, unsigned int argc, JS::Value *vp) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + JS::RootedObject hobj(ctx, &args.thisv().toObject()); + JS::Realm *comp = js::GetContextRealm(ctx); + + if (!comp) { +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__); +#endif + return false; + } + struct keyboard *keyb = JS::GetMaybePtrFromReservedSlot(hobj, 0); + + if (!keyb) { + return false; + } + + if (!keyb->type_) { + args.rval().setString(JS_NewStringCopyZ(ctx, "")); + return true; + } + args.rval().setString(JS_NewStringCopyZ(ctx, keyb->type_)); + + return true; +} + +static bool +keyboardEvent_preventDefault(JSContext *ctx, unsigned int argc, JS::Value *vp) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + JS::RootedObject hobj(ctx, &args.thisv().toObject()); + JS::Realm *comp = js::GetContextRealm(ctx); + + if (!comp) { +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__); +#endif + return false; + } + struct keyboard *keyb = JS::GetMaybePtrFromReservedSlot(hobj, 0); + + if (!keyb) { + return false; + } + if (keyb->cancelable) { + keyb->defaultPrevented = 1; + } + args.rval().setUndefined(); + + return true; +} JSObject * get_keyboardEvent(JSContext *ctx, struct term_event *ev) diff --git a/src/ecmascript/spidermonkey/keyboard.h b/src/ecmascript/spidermonkey/keyboard.h index c59733eb..9121ebbf 100644 --- a/src/ecmascript/spidermonkey/keyboard.h +++ b/src/ecmascript/spidermonkey/keyboard.h @@ -7,6 +7,8 @@ struct term_event; extern JSClass keyboardEvent_class; extern JSPropertySpec keyboardEvent_props[]; +extern const spidermonkeyFunctionSpec keyboardEvent_funcs[]; + bool keyboardEvent_constructor(JSContext* ctx, unsigned argc, JS::Value* vp); JSObject *get_keyboardEvent(JSContext *ctx, struct term_event *ev);