diff --git a/src/ecmascript/spidermonkey.cpp b/src/ecmascript/spidermonkey.cpp index 0fb62bda3..7994a231e 100644 --- a/src/ecmascript/spidermonkey.cpp +++ b/src/ecmascript/spidermonkey.cpp @@ -36,6 +36,7 @@ #include "ecmascript/spidermonkey/keyboard.h" #include "ecmascript/spidermonkey/location.h" #include "ecmascript/spidermonkey/localstorage.h" +#include "ecmascript/spidermonkey/message.h" #include "ecmascript/spidermonkey/navigator.h" #include "ecmascript/spidermonkey/screen.h" #include "ecmascript/spidermonkey/unibar.h" @@ -148,7 +149,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, *keyboardEvent_obj; + *xhr_obj, *event_obj, *keyboardEvent_obj, *messageEvent_obj; assert(interpreter); if (!js_module_init_ok) return NULL; @@ -307,6 +308,16 @@ spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter) goto release_and_fail; } + messageEvent_obj = spidermonkey_InitClass(ctx, global, NULL, + &messageEvent_class, messageEvent_constructor, 0, + messageEvent_props, + messageEvent_funcs, + NULL, NULL, "MessageEvent"); + + if (!messageEvent_obj) { + goto release_and_fail; + } + JS::SetRealmPrivate(js::GetContextRealm(ctx), interpreter); return ctx; diff --git a/src/ecmascript/spidermonkey/message.cpp b/src/ecmascript/spidermonkey/message.cpp index 5830f723e..212dd988a 100644 --- a/src/ecmascript/spidermonkey/message.cpp +++ b/src/ecmascript/spidermonkey/message.cpp @@ -64,11 +64,26 @@ static bool messageEvent_get_property_lastEventId(JSContext *cx, unsigned int ar static bool messageEvent_get_property_origin(JSContext *cx, unsigned int argc, JS::Value *vp); static bool messageEvent_get_property_source(JSContext *cx, unsigned int argc, JS::Value *vp); +static bool messageEvent_get_property_bubbles(JSContext *ctx, unsigned int argc, JS::Value *vp); +static bool messageEvent_get_property_cancelable(JSContext *ctx, unsigned int argc, JS::Value *vp); +static bool messageEvent_get_property_composed(JSContext *ctx, unsigned int argc, JS::Value *vp); +static bool messageEvent_get_property_defaultPrevented(JSContext *ctx, unsigned int argc, JS::Value *vp); +static bool messageEvent_get_property_type(JSContext *ctx, unsigned int argc, JS::Value *vp); + +static bool messageEvent_preventDefault(JSContext *ctx, unsigned int argc, JS::Value *vp); + + struct message_event { char *data; char *lastEventId; char *origin; char *source; + + char *type_; + unsigned int bubbles:1; + unsigned int cancelable:1; + unsigned int composed:1; + unsigned int defaultPrevented:1; }; static void @@ -84,6 +99,7 @@ messageEvent_finalize(JS::GCContext *op, JSObject *obj) mem_free_if(event->lastEventId); mem_free_if(event->origin); mem_free_if(event->source); + mem_free_if(event->type_); mem_free(event); } } @@ -131,6 +147,37 @@ messageEvent_constructor(JSContext* ctx, unsigned argc, JS::Value* vp) if (!event) { return false; } + + if (argc > 0) { + event->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)) { + event->bubbles = (unsigned int)v.toBoolean(); + } + if (JS_GetProperty(ctx, v_obj, "cancelable", &v)) { + event->cancelable = (unsigned int)v.toBoolean(); + } + if (JS_GetProperty(ctx, v_obj, "composed", &v)) { + event->composed = (unsigned int)v.toBoolean(); + } + if (JS_GetProperty(ctx, v_obj, "data", &v)) { + event->data = jsval_to_string(ctx, v); + } + if (JS_GetProperty(ctx, v_obj, "lastEventId", &v)) { + event->lastEventId = jsval_to_string(ctx, v); + } + if (JS_GetProperty(ctx, v_obj, "origin", &v)) { + event->origin = jsval_to_string(ctx, v); + } + if (JS_GetProperty(ctx, v_obj, "source", &v)) { + event->source = jsval_to_string(ctx, v); + } + } JS::SetReservedSlot(newObj, 0, JS::PrivateValue(event)); args.rval().setObject(*newObj); @@ -138,13 +185,101 @@ messageEvent_constructor(JSContext* ctx, unsigned argc, JS::Value* vp) } JSPropertySpec messageEvent_props[] = { + JS_PSG("bubbles", messageEvent_get_property_bubbles, JSPROP_ENUMERATE), + JS_PSG("cancelable", messageEvent_get_property_cancelable, JSPROP_ENUMERATE), + JS_PSG("composed", messageEvent_get_property_composed, JSPROP_ENUMERATE), JS_PSG("data", messageEvent_get_property_data, JSPROP_ENUMERATE), + JS_PSG("defaultPrevented", messageEvent_get_property_defaultPrevented, JSPROP_ENUMERATE), JS_PSG("lastEventId", messageEvent_get_property_lastEventId, JSPROP_ENUMERATE), JS_PSG("origin", messageEvent_get_property_origin, JSPROP_ENUMERATE), JS_PSG("source", messageEvent_get_property_source, JSPROP_ENUMERATE), + JS_PSG("type", messageEvent_get_property_type, JSPROP_ENUMERATE), JS_PS_END }; +const spidermonkeyFunctionSpec messageEvent_funcs[] = { + { "preventDefault", messageEvent_preventDefault, 0 }, + { NULL } +}; + +static bool +messageEvent_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 message_event *event = JS::GetMaybePtrFromReservedSlot(hobj, 0); + + if (!event) { + return false; + } + args.rval().setBoolean(event->bubbles); + + return true; +} + +static bool +messageEvent_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 message_event *event = JS::GetMaybePtrFromReservedSlot(hobj, 0); + + if (!event) { + return false; + } + args.rval().setBoolean(event->cancelable); + + return true; +} + +static bool +messageEvent_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 message_event *event = JS::GetMaybePtrFromReservedSlot(hobj, 0); + + if (!event) { + return false; + } + args.rval().setBoolean(event->composed); + + return true; +} + static bool messageEvent_get_property_data(JSContext *ctx, unsigned int argc, JS::Value *vp) { @@ -176,6 +311,32 @@ messageEvent_get_property_data(JSContext *ctx, unsigned int argc, JS::Value *vp) return true; } +static bool +messageEvent_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 message_event *event = JS::GetMaybePtrFromReservedSlot(hobj, 0); + + if (!event) { + return false; + } + args.rval().setBoolean(event->defaultPrevented); + + return true; +} + static bool messageEvent_get_property_lastEventId(JSContext *ctx, unsigned int argc, JS::Value *vp) { @@ -270,6 +431,66 @@ messageEvent_get_property_source(JSContext *ctx, unsigned int argc, JS::Value *v return true; } +static bool +messageEvent_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 message_event *event = JS::GetMaybePtrFromReservedSlot(hobj, 0); + + if (!event) { + return false; + } + if (event->cancelable) { + event->defaultPrevented = 1; + } + args.rval().setUndefined(); + + return true; +} + +static bool +messageEvent_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 message_event *event = JS::GetMaybePtrFromReservedSlot(hobj, 0); + + if (!event) { + return false; + } + + if (!event->type_) { + args.rval().setString(JS_NewStringCopyZ(ctx, "")); + return true; + } + args.rval().setString(JS_NewStringCopyZ(ctx, event->type_)); + + return true; +} + static int lastEventId; JSObject * diff --git a/src/ecmascript/spidermonkey/message.h b/src/ecmascript/spidermonkey/message.h index 263fc2970..ff47401b0 100644 --- a/src/ecmascript/spidermonkey/message.h +++ b/src/ecmascript/spidermonkey/message.h @@ -5,6 +5,8 @@ extern JSClass messageEvent_class; extern JSPropertySpec messageEvent_props[]; +extern const spidermonkeyFunctionSpec messageEvent_funcs[]; + bool messageEvent_constructor(JSContext* ctx, unsigned argc, JS::Value* vp); JSObject *get_messageEvent(JSContext *ctx, char *data, char *origin, char *source);