diff --git a/src/ecmascript/spidermonkey.cpp b/src/ecmascript/spidermonkey.cpp index a4f8c2ab..fbbc585a 100644 --- a/src/ecmascript/spidermonkey.cpp +++ b/src/ecmascript/spidermonkey.cpp @@ -29,6 +29,7 @@ #include "ecmascript/spidermonkey.h" #include "ecmascript/spidermonkey/console.h" #include "ecmascript/spidermonkey/document.h" +#include "ecmascript/spidermonkey/event.h" #include "ecmascript/spidermonkey/form.h" #include "ecmascript/spidermonkey/heartbeat.h" #include "ecmascript/spidermonkey/history.h" @@ -146,7 +147,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; + *xhr_obj, *event_obj; assert(interpreter); if (!js_module_init_ok) return NULL; @@ -285,6 +286,17 @@ spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter) goto release_and_fail; } + event_obj = spidermonkey_InitClass(ctx, global, NULL, + &event_class, event_constructor, 0, + event_props, + NULL, + NULL, NULL, "Event"); + + if (!event_obj) { + goto release_and_fail; + } + + JS::SetRealmPrivate(js::GetContextRealm(ctx), interpreter); return ctx; diff --git a/src/ecmascript/spidermonkey/Makefile b/src/ecmascript/spidermonkey/Makefile index f99400b8..9ea52b6b 100644 --- a/src/ecmascript/spidermonkey/Makefile +++ b/src/ecmascript/spidermonkey/Makefile @@ -2,7 +2,7 @@ top_builddir=../../.. include $(top_builddir)/Makefile.config INCLUDES += $(SPIDERMONKEY_CFLAGS) -OBJS = attr.obj attributes.obj collection.obj console.obj css.obj document.obj element.obj form.obj forms.obj heartbeat.obj history.obj implementation.obj input.obj \ +OBJS = attr.obj attributes.obj collection.obj console.obj css.obj document.obj element.obj event.obj form.obj forms.obj heartbeat.obj history.obj implementation.obj input.obj \ keyboard.obj localstorage.obj location.obj message.obj navigator.obj nodelist.obj screen.obj style.obj unibar.obj window.obj xhr.obj include $(top_srcdir)/Makefile.lib diff --git a/src/ecmascript/spidermonkey/event.cpp b/src/ecmascript/spidermonkey/event.cpp new file mode 100644 index 00000000..cd1e2fa4 --- /dev/null +++ b/src/ecmascript/spidermonkey/event.cpp @@ -0,0 +1,192 @@ +/* The SpiderMonkey Event object implementation. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "elinks.h" + +#include "ecmascript/spidermonkey/util.h" +#include +#include + +#include "bfu/dialog.h" +#include "cache/cache.h" +#include "cookies/cookies.h" +#include "dialogs/menu.h" +#include "dialogs/status.h" +#include "document/html/frames.h" +#include "document/document.h" +#include "document/forms.h" +#include "document/view.h" +#include "ecmascript/ecmascript.h" +#include "ecmascript/spidermonkey.h" +#include "ecmascript/spidermonkey/heartbeat.h" +#include "ecmascript/spidermonkey/event.h" +#include "ecmascript/timer.h" +#include "intl/libintl.h" +#include "main/select.h" +#include "main/timer.h" +#include "network/connection.h" +#include "osdep/newwin.h" +#include "osdep/sysname.h" +#include "protocol/http/http.h" +#include "protocol/uri.h" +#include "session/download.h" +#include "session/history.h" +#include "session/location.h" +#include "session/session.h" +#include "session/task.h" +#include "terminal/tab.h" +#include "terminal/terminal.h" +#include "util/conv.h" +#include "util/memory.h" +#include "util/string.h" +#include "viewer/text/draw.h" +#include "viewer/text/form.h" +#include "viewer/text/link.h" +#include "viewer/text/vs.h" + +#include +#include +#include +#include +#include +#include + +struct eljs_event { + char *type_; +}; + +static bool event_get_property_type(JSContext *ctx, unsigned int argc, JS::Value *vp); + + +static void +event_finalize(JS::GCContext *op, JSObject *event_obj) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + + struct eljs_event *event = JS::GetMaybePtrFromReservedSlot(event_obj, 0); + + if (event) { + mem_free_if(event->type_); + mem_free(event); + } +} + +JSClassOps event_ops = { + nullptr, // addProperty + nullptr, // deleteProperty + nullptr, // enumerate + nullptr, // newEnumerate + nullptr, // resolve + nullptr, // mayResolve + event_finalize, // finalize + nullptr, // call + nullptr, // construct + JS_GlobalObjectTraceHook // trace +}; + +JSClass event_class = { + "Event", + JSCLASS_HAS_RESERVED_SLOTS(1), + &event_ops +}; + +bool +event_constructor(JSContext* ctx, unsigned argc, JS::Value* vp) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + JS::RootedObject newObj(ctx, JS_NewObjectForConstructor(ctx, &event_class, args)); + JS::Realm *comp = js::GetContextRealm(ctx); + + if (!comp) { +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__); +#endif + return false; + } + if (!newObj) { + return false; + } + struct eljs_event *event = (struct eljs_event *)mem_calloc(1, sizeof(*event)); + + if (!event) { + return false; + } + JS::SetReservedSlot(newObj, 0, JS::PrivateValue(event)); + + if (argc > 0) { + event->type_ = jsval_to_string(ctx, args[0]); + } + + args.rval().setObject(*newObj); + + return true; +} + +JSPropertySpec event_props[] = { + JS_PSG("type", event_get_property_type, JSPROP_ENUMERATE), + JS_PS_END +}; + +static bool +event_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 eljs_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; +} + +JSObject * +get_Event(JSContext *ctx) +{ + JSObject *k = JS_NewObject(ctx, &event_class); + + if (!k) { + return NULL; + } + JS::RootedObject r_event(ctx, k); + JS_DefineProperties(ctx, r_event, (JSPropertySpec *)event_props); + + struct eljs_event *event = (struct eljs_event *)mem_calloc(1, sizeof(*event)); + + if (!event) { + return NULL; + } + JS::SetReservedSlot(k, 0, JS::PrivateValue(event)); + + return k; +} diff --git a/src/ecmascript/spidermonkey/event.h b/src/ecmascript/spidermonkey/event.h new file mode 100644 index 00000000..1aabc66c --- /dev/null +++ b/src/ecmascript/spidermonkey/event.h @@ -0,0 +1,10 @@ +#ifndef EL__ECMASCRIPT_SPIDERMONKEY_EVENT_H +#define EL__ECMASCRIPT_SPIDERMONKEY_EVENT_H + +#include "ecmascript/spidermonkey/util.h" + +extern JSClass event_class; +extern JSPropertySpec event_props[]; +bool event_constructor(JSContext* ctx, unsigned argc, JS::Value* vp); + +#endif diff --git a/src/ecmascript/spidermonkey/meson.build b/src/ecmascript/spidermonkey/meson.build index 5fe14e94..323e54a8 100644 --- a/src/ecmascript/spidermonkey/meson.build +++ b/src/ecmascript/spidermonkey/meson.build @@ -1,2 +1,3 @@ -srcs += files('attr.cpp', 'attributes.cpp', 'collection.cpp', 'console.cpp', 'css.cpp', 'document.cpp', 'element.cpp', 'form.cpp', 'forms.cpp', 'heartbeat.cpp', 'history.cpp', 'implementation.cpp', 'input.cpp', 'keyboard.cpp', +srcs += files('attr.cpp', 'attributes.cpp', 'collection.cpp', 'console.cpp', 'css.cpp', 'document.cpp', 'element.cpp', 'event.cpp', +'form.cpp', 'forms.cpp', 'heartbeat.cpp', 'history.cpp', 'implementation.cpp', 'input.cpp', 'keyboard.cpp', 'localstorage.cpp', 'location.cpp', 'message.cpp', 'navigator.cpp', 'nodelist.cpp', 'screen.cpp', 'style.cpp', 'unibar.cpp', 'window.cpp', 'xhr.cpp')