1 /* "elinks.globhist" */
9 #include "globhist/globhist.h"
10 #include "ecmascript/spidermonkey/util.h"
11 #include "scripting/smjs/core.h"
12 #include "scripting/smjs/elinks_object.h"
13 #include "util/memory.h"
16 /* @smjs_globhist_item_class.finalize */
18 smjs_globhist_item_finalize(JSContext
*ctx
, JSObject
*obj
)
20 struct global_history_item
*history_item
;
22 history_item
= JS_GetPrivate(ctx
, obj
); /* from @smjs_globhist_item_class */
24 if (history_item
) object_unlock(history_item
);
27 enum smjs_globhist_item_prop
{
33 static const JSPropertySpec smjs_globhist_item_props
[] = {
34 { "title", GLOBHIST_TITLE
, JSPROP_ENUMERATE
},
35 { "url", GLOBHIST_URL
, JSPROP_ENUMERATE
},
36 { "last_visit", GLOBHIST_LAST_VISIT
, JSPROP_ENUMERATE
},
40 /* @smjs_globhist_item_class.getProperty */
42 smjs_globhist_item_get_property(JSContext
*ctx
, JSObject
*obj
, jsval id
,
45 struct global_history_item
*history_item
;
47 history_item
= JS_GetPrivate(ctx
, obj
); /* from @smjs_globhist_item_class */
49 if (!history_item
) return JS_FALSE
;
51 undef_to_jsval(ctx
, vp
);
53 if (!JSVAL_IS_INT(id
))
56 switch (JSVAL_TO_INT(id
)) {
58 *vp
= STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx
,
59 history_item
->title
));
63 *vp
= STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx
,
67 case GLOBHIST_LAST_VISIT
:
68 /* TODO: I'd rather return a date object, but that introduces
69 * synchronisation issues:
71 * - How do we cause a change to that date object to affect
72 * the actual global history item?
73 * - How do we get a change to that global history item
74 * to affect all date objects?
76 * The biggest obstacle is that we have no way to trigger code
77 * when one messes with the date object.
80 /* XXX: Currently, ECMAScript gets seconds since the epoch.
81 * Since the Date object uses milliseconds since the epoch,
82 * I'd rather export that, but SpiderMonkey doesn't provide
83 * a suitable type. -- Miciah */
84 JS_NewNumberValue(smjs_ctx
, history_item
->last_visit
, vp
);
88 INTERNAL("Invalid ID %d in globhist_get_property().",
95 /* @smjs_globhist_item_class.setProperty */
97 smjs_globhist_item_set_property(JSContext
*ctx
, JSObject
*obj
, jsval id
, jsval
*vp
)
99 struct global_history_item
*history_item
;
101 history_item
= JS_GetPrivate(ctx
, obj
); /* from @smjs_globhist_item_class */
103 if (!history_item
) return JS_FALSE
;
105 if (!JSVAL_IS_INT(id
))
108 switch (JSVAL_TO_INT(id
)) {
109 case GLOBHIST_TITLE
: {
110 JSString
*jsstr
= JS_ValueToString(smjs_ctx
, *vp
);
111 unsigned char *str
= JS_GetStringBytes(jsstr
);
113 mem_free_set(&history_item
->title
, stracpy(str
));
118 JSString
*jsstr
= JS_ValueToString(smjs_ctx
, *vp
);
119 unsigned char *str
= JS_GetStringBytes(jsstr
);
121 mem_free_set(&history_item
->url
, stracpy(str
));
125 case GLOBHIST_LAST_VISIT
: {
128 JS_ValueToECMAUint32(smjs_ctx
, *vp
, &seconds
);
129 history_item
->last_visit
= seconds
;
134 INTERNAL("Invalid ID %d in bookmark_set_property().",
141 static const JSClass smjs_globhist_item_class
= {
142 "global_history_item",
143 JSCLASS_HAS_PRIVATE
, /* struct global_history_item * */
144 JS_PropertyStub
, JS_PropertyStub
,
145 smjs_globhist_item_get_property
, smjs_globhist_item_set_property
,
146 JS_EnumerateStub
, JS_ResolveStub
, JS_ConvertStub
,
147 smjs_globhist_item_finalize
,
151 smjs_get_globhist_item_object(struct global_history_item
*history_item
)
155 jsobj
= JS_NewObject(smjs_ctx
, (JSClass
*) &smjs_globhist_item_class
,
158 || JS_TRUE
!= JS_DefineProperties(smjs_ctx
, jsobj
,
159 (JSPropertySpec
*) smjs_globhist_item_props
)
160 || JS_TRUE
!= JS_SetPrivate(smjs_ctx
, jsobj
, history_item
)) /* to @smjs_globhist_item_class */
163 object_lock(history_item
);
169 /* @smjs_globhist_class.getProperty */
171 smjs_globhist_get_property(JSContext
*ctx
, JSObject
*obj
, jsval id
, jsval
*vp
)
174 unsigned char *uri_string
;
175 struct global_history_item
*history_item
;
177 uri_string
= JS_GetStringBytes(JS_ValueToString(ctx
, id
));
178 if (!uri_string
) goto ret_null
;
180 history_item
= get_global_history_item(uri_string
);
181 if (!history_item
) goto ret_null
;
183 jsobj
= smjs_get_globhist_item_object(history_item
);
184 if (!jsobj
) goto ret_null
;
186 *vp
= OBJECT_TO_JSVAL(jsobj
);
196 static const JSClass smjs_globhist_class
= {
198 JS_PropertyStub
, JS_PropertyStub
,
199 smjs_globhist_get_property
, JS_PropertyStub
,
200 JS_EnumerateStub
, JS_ResolveStub
, JS_ConvertStub
, JS_FinalizeStub
,
204 smjs_get_globhist_object(void)
208 globhist
= JS_NewObject(smjs_ctx
, (JSClass
*) &smjs_globhist_class
,
210 if (!globhist
) return NULL
;
216 smjs_init_globhist_interface(void)
219 struct JSObject
*globhist
;
221 if (!smjs_ctx
|| !smjs_elinks_object
)
224 globhist
= smjs_get_globhist_object();
225 if (!globhist
) return;
227 val
= OBJECT_TO_JSVAL(globhist
);
229 JS_SetProperty(smjs_ctx
, smjs_elinks_object
, "globhist", &val
);