Bug 846: Comments on the relations between JSClasses and functions.
[elinks.git] / src / scripting / smjs / action_object.c
blob49d78685523ae80fa69d6b8521e6a6d0b8f3bd5d
1 /* "elinks.action" */
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
7 #include "elinks.h"
9 #include "config/kbdbind.h"
10 #include "ecmascript/spidermonkey/util.h"
11 #include "scripting/smjs/core.h"
12 #include "scripting/smjs/elinks_object.h"
13 #include "session/session.h"
14 #include "util/memory.h"
15 #include "viewer/action.h"
17 /*** action method object ***/
19 struct smjs_action_fn_callback_hop {
20 struct session *ses;
21 action_id_T action_id;
24 /* @action_fn_class.finalize */
25 static void
26 smjs_action_fn_finalize(JSContext *ctx, JSObject *obj)
28 struct smjs_action_fn_callback_hop *hop = JS_GetPrivate(ctx, obj);
30 if (hop) mem_free(hop);
33 /* @action_fn_class.call */
34 static JSBool
35 smjs_action_fn_callback(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv,
36 jsval *rval)
38 struct smjs_action_fn_callback_hop *hop;
39 JSObject *fn_obj;
41 assert(smjs_ctx);
43 *rval = JS_FALSE;
45 if (JS_TRUE != JS_ValueToObject(ctx, argv[-2], &fn_obj))
46 return JS_TRUE;
48 hop = JS_GetPrivate(ctx, fn_obj);
49 if (!hop) return JS_TRUE;
51 if (argc >= 1) {
52 int32 val;
54 if (JS_TRUE == JS_ValueToInt32(smjs_ctx, argv[0], &val)) {
55 hop->ses->kbdprefix.repeat_count = val;
59 do_action(hop->ses, hop->action_id, 1);
61 *rval = JS_TRUE;
63 return JS_TRUE;
66 static const JSClass action_fn_class = {
67 "action_fn",
68 JSCLASS_HAS_PRIVATE, /* struct smjs_action_fn_callback_hop * */
69 JS_PropertyStub, JS_PropertyStub,
70 JS_PropertyStub, JS_PropertyStub,
71 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
72 smjs_action_fn_finalize,
73 NULL, NULL,
74 smjs_action_fn_callback,
77 static JSObject *
78 smjs_get_action_fn_object(unsigned char *action_str)
80 unsigned char *c;
81 struct smjs_action_fn_callback_hop *hop;
82 JSObject *obj;
84 if (!smjs_ses) return NULL;
86 obj = JS_NewObject(smjs_ctx, (JSClass *) &action_fn_class, NULL, NULL);
87 if (!obj) return NULL;
89 hop = mem_alloc(sizeof(*hop));
90 if (!hop) return NULL;
92 hop->ses = smjs_ses;
94 /* ECMAScript methods cannot have hyphens in the name, so one should
95 * use underscores instead; here, we must convert them back to hyphens
96 * for the action code. */
97 for (c = action_str; *c; ++c) if (*c == '_') *c = '-';
99 hop->action_id = get_action_from_string(KEYMAP_MAIN, action_str);
101 if (-1 != hop->action_id
102 && JS_TRUE == JS_SetPrivate(smjs_ctx, obj, hop)) {
103 return obj;
106 mem_free(hop);
107 return NULL;
111 /*** elinks.action object ***/
113 /* @action_class.getProperty */
114 static JSBool
115 action_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
117 JSObject *action_fn;
118 unsigned char *action_str;
120 *vp = JSVAL_NULL;
122 action_str = JS_GetStringBytes(JS_ValueToString(ctx, id));
123 if (!action_str) return JS_TRUE;
125 action_fn = smjs_get_action_fn_object(action_str);
126 if (!action_fn) return JS_TRUE;
128 *vp = OBJECT_TO_JSVAL(action_fn);
130 return JS_TRUE;
133 static const JSClass action_class = {
134 "action",
136 JS_PropertyStub, JS_PropertyStub,
137 action_get_property, JS_PropertyStub,
138 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
141 static JSObject *
142 smjs_get_action_object(void)
144 JSObject *obj;
146 assert(smjs_ctx);
148 obj = JS_NewObject(smjs_ctx, (JSClass *) &action_class, NULL, NULL);
150 return obj;
153 void
154 smjs_init_action_interface(void)
156 jsval val;
157 struct JSObject *action_object;
159 if (!smjs_ctx || !smjs_elinks_object)
160 return;
162 action_object = smjs_get_action_object();
163 if (!action_object) return;
165 val = OBJECT_TO_JSVAL(action_object);
167 JS_SetProperty(smjs_ctx, smjs_elinks_object, "action", &val);