1 /* ECMAScript browser scripting module */
9 #include "ecmascript/spidermonkey/util.h"
10 #include "network/connection.h"
11 #include "protocol/uri.h"
12 #include "scripting/smjs/core.h"
13 #include "scripting/smjs/cache_object.h"
14 #include "scripting/smjs/elinks_object.h"
15 #include "session/download.h"
18 struct smjs_load_uri_hop
{
21 /* SpiderMonkey versions earlier than 1.8 cannot properly call
22 * a closure if given just a JSFunction pointer. They need a
23 * jsval that points to the corresponding JSObject. Besides,
24 * JS_AddNamedRoot is not documented to support JSFunction
30 smjs_loading_callback(struct download
*download
, void *data
)
32 struct session
*saved_smjs_ses
= smjs_ses
;
33 struct smjs_load_uri_hop
*hop
= data
;
35 JSObject
*cache_entry_object
;
37 if (is_in_progress_state(download
->state
)) return;
39 if (!download
->cached
) goto end
;
41 /* download->cached->object.refcount is typically 0 here
42 * because no struct document uses the cache entry. Because
43 * the connection is no longer using the cache entry either,
44 * it can be garbage collected. Don't let that happen while
45 * the script is using it. */
46 object_lock(download
->cached
);
50 cache_entry_object
= smjs_get_cache_entry_object(download
->cached
);
51 if (!cache_entry_object
) goto end
;
53 args
[0] = OBJECT_TO_JSVAL(cache_entry_object
);
54 JS_CallFunctionValue(smjs_ctx
, NULL
, hop
->callback
, 1, args
, &rval
);
58 object_unlock(download
->cached
);
59 JS_RemoveRoot(smjs_ctx
, &hop
->callback
);
60 mem_free(download
->data
);
63 smjs_ses
= saved_smjs_ses
;
67 smjs_load_uri(JSContext
*ctx
, JSObject
*obj
, uintN argc
, jsval
*argv
,
70 struct smjs_load_uri_hop
*hop
;
71 struct download
*download
;
73 unsigned char *uri_string
;
76 if (argc
< 2) return JS_FALSE
;
78 jsstr
= JS_ValueToString(smjs_ctx
, argv
[0]);
79 uri_string
= JS_GetStringBytes(jsstr
);
81 uri
= get_uri(uri_string
, 0);
82 if (!uri
) return JS_FALSE
;
84 download
= mem_alloc(sizeof(*download
));
90 hop
= mem_alloc(sizeof(*hop
));
97 hop
->callback
= argv
[1];
99 if (!JS_AddNamedRoot(smjs_ctx
, &hop
->callback
,
100 "smjs_load_uri_hop.callback")) {
107 download
->data
= hop
;
108 download
->callback
= (download_callback_T
*) smjs_loading_callback
;
110 load_uri(uri
, NULL
, download
, PRI_MAIN
, CACHE_MODE_NORMAL
, -1);
118 smjs_init_load_uri_interface(void)
120 if (!smjs_ctx
|| !smjs_elinks_object
)
123 JS_DefineFunction(smjs_ctx
, smjs_elinks_object
, "load_uri",
124 &smjs_load_uri
, 2, 0);