1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-20 00:15:31 +00:00

[quickjs] clearTimeout

This commit is contained in:
Witold Filipczyk 2021-12-01 19:27:50 +01:00
parent 29fba4bb33
commit adddbf53fb
6 changed files with 113 additions and 5 deletions

View File

@ -23,6 +23,7 @@
#else
#include "ecmascript/spidermonkey.h"
#endif
#include "ecmascript/timer.h"
#include "intl/libintl.h"
#include "main/module.h"
#include "main/select.h"
@ -45,6 +46,10 @@
#include <libxml/HTMLparser.h>
#include <libxml++/libxml++.h>
#include <map>
std::map<struct timer *, bool> map_timer;
/* TODO: We should have some kind of ACL for the scripts - i.e. ability to
* disallow the scripts to open new windows (or so that the windows are always
* directed to tabs, this particular option would be a tristate), disallow
@ -608,15 +613,19 @@ ecmascript_set_timeout2(struct ecmascript_interpreter *interpreter, JS::HandleVa
#endif
#ifdef CONFIG_QUICKJS
void
timer_id_T
ecmascript_set_timeout2q(struct ecmascript_interpreter *interpreter, JSValueConst fun, int timeout)
{
assert(interpreter && interpreter->vs->doc_view->document);
done_string(&interpreter->code);
init_string(&interpreter->code);
kill_timer(&interpreter->vs->doc_view->document->timeout);
if (check_in_map_timer(interpreter->vs->doc_view->document->timeout)) {
kill_timer(&interpreter->vs->doc_view->document->timeout);
}
interpreter->fun = fun;
install_timer(&interpreter->vs->doc_view->document->timeout, timeout, ecmascript_timeout_handler2, interpreter);
return interpreter->vs->doc_view->document->timeout;
}
#endif

View File

@ -20,6 +20,7 @@
#ifdef CONFIG_ECMASCRIPT
#include "main/module.h"
#include "main/timer.h"
#include "util/time.h"
//#define ECMASCRIPT_DEBUG 1
@ -141,7 +142,7 @@ void ecmascript_set_timeout2(struct ecmascript_interpreter *interpreter, JS::Han
#endif
#ifdef CONFIG_QUICKJS
void ecmascript_set_timeout2q(struct ecmascript_interpreter *interpreter, JSValue f, int timeout);
timer_id_T ecmascript_set_timeout2q(struct ecmascript_interpreter *interpreter, JSValue f, int timeout);
#endif
int get_ecmascript_enable(struct ecmascript_interpreter *interpreter);

View File

@ -22,6 +22,7 @@
#include "ecmascript/ecmascript.h"
#include "ecmascript/quickjs.h"
#include "ecmascript/quickjs/window.h"
#include "ecmascript/timer.h"
#include "intl/libintl.h"
#include "main/select.h"
#include "osdep/newwin.h"
@ -214,8 +215,36 @@ js_window_setTimeout(JSContext *ctx, JSValueConst this_val, int argc, JSValueCon
if (timeout <= 0) {
return JS_UNDEFINED;
}
timer_id_T id = ecmascript_set_timeout2q(interpreter, func, timeout);
add_to_map_timer(id);
return JS_NewInt64(ctx, reinterpret_cast<int64_t>(id));
}
/* @window_funcs{"clearTimeout"} */
JSValue
js_window_clearTimeout(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
{
#ifdef ECMASCRIPT_DEBUG
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
#endif
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)JS_GetContextOpaque(ctx);
if (argc != 1) {
return JS_UNDEFINED;
}
int64_t number;
if (JS_ToInt64(ctx, &number, argv[0])) {
return JS_UNDEFINED;
}
timer_id_T id = reinterpret_cast<timer_id_T>(number);
if (check_in_map_timer(id)) {
kill_timer(&id);
}
ecmascript_set_timeout2q(interpreter, func, timeout);
return JS_UNDEFINED;
}
@ -381,6 +410,7 @@ static const JSCFunctionListEntry js_window_proto_funcs[] = {
JS_CGETSET_DEF("top", js_window_get_property_top, nullptr),
JS_CGETSET_DEF("window", js_window_get_property_self, nullptr),
JS_CFUNC_DEF("alert", 1, js_window_alert),
JS_CFUNC_DEF("clearTimeout", 1, js_window_clearTimeout),
JS_CFUNC_DEF("open", 3, js_window_open),
JS_CFUNC_DEF("setTimeout", 2, js_window_setTimeout),
};

28
src/ecmascript/timer.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef EL__ECMASCRIPT_TIMER_H
#define EL__ECMASCRIPT_TIMER_H
#include <map>
struct timer;
extern std::map<struct timer *, bool> map_timer;
inline void
add_to_map_timer(struct timer *timer)
{
map_timer[timer] = true;
}
inline void
del_from_map_timer(struct timer *timer)
{
map_timer.erase(timer);
}
inline bool
check_in_map_timer(struct timer *timer)
{
return map_timer.find(timer) != map_timer.end();
}
#endif

View File

@ -33,6 +33,9 @@
#include "util/memory.h"
#include "util/time.h"
#ifdef CONFIG_ECMASCRIPT
#include "ecmascript/timer.h"
#endif
struct timer {
LIST_HEAD(struct timer);
@ -53,7 +56,6 @@ get_timers_count(void)
}
#ifdef HAVE_EVENT_BASE_SET
extern struct event_base *event_base;
#endif
@ -104,6 +106,9 @@ check_timers(timeval_T *last_time)
break;
del_from_list(timer);
#ifdef CONFIG_ECMASCRIPT
del_from_map_timer(timer);
#endif
/* At this point, *@timer is to be considered invalid
* outside timers.c; if anything e.g. passes it to
* @kill_timer, that's a bug. However, @timer->func
@ -187,6 +192,9 @@ install_timer(timer_id_T *id, milliseconds_T delay, void (*func)(void *), void *
add_at_pos(timer->prev, new_timer);
}
#ifdef CONFIG_ECMASCRIPT
add_to_map_timer(new_timer);
#endif
}
void
@ -198,6 +206,9 @@ kill_timer(timer_id_T *id)
if (*id == TIMER_ID_UNDEF) return;
timer = *id;
del_from_list(timer);
#ifdef CONFIG_ECMASCRIPT
del_from_map_timer(timer);
#endif
#ifdef USE_LIBEVENT
if (event_enabled) {

View File

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<body>
<p>Click the first button to alert "Hello" after waiting 5 seconds.</p>
<p>Click the second button to prevent the first function to execute. (You must click it before the 5 seconds are up.)</p>
<button onclick="myFunction()">Try it</button>
<button onclick="myStopFunction()">Stop the alert</button>
<script>
var myVar;
function tt() {
window.alert("Hello");
}
function myFunction() {
myVar = setTimeout(tt, 5000);
}
function myStopFunction() {
clearTimeout(myVar);
}
</script>
</body>
</html>