Forráskód Böngészése

LibWeb: Add window.setTimeout()

This also leaks the timer just like setInterval() (FIXME).
Andreas Kling 5 éve
szülő
commit
ca90f88d4e

+ 18 - 0
Libraries/LibWeb/Bindings/WindowObject.cpp

@@ -44,6 +44,7 @@ WindowObject::WindowObject(Window& impl)
     put_native_property("document", document_getter, document_setter);
     put_native_function("alert", alert);
     put_native_function("setInterval", set_interval, 1);
+    put_native_function("setTimeout", set_timeout, 1);
     put_native_function("requestAnimationFrame", request_animation_frame, 1);
     put_native_function("cancelAnimationFrame", cancel_animation_frame, 1);
 
@@ -97,6 +98,23 @@ JS::Value WindowObject::set_interval(JS::Interpreter& interpreter)
     return {};
 }
 
+JS::Value WindowObject::set_timeout(JS::Interpreter& interpreter)
+{
+    auto* impl = impl_from(interpreter);
+    if (!impl)
+        return {};
+    auto& arguments = interpreter.call_frame().arguments;
+    if (arguments.size() < 2)
+        return {};
+    auto* callback_object = arguments[0].to_object(interpreter.heap());
+    if (!callback_object)
+        return {};
+    if (!callback_object->is_function())
+        return interpreter.throw_exception<JS::Error>("TypeError", "Not a function");
+    impl->set_timeout(*static_cast<JS::Function*>(callback_object), arguments[1].to_i32());
+    return {};
+}
+
 JS::Value WindowObject::request_animation_frame(JS::Interpreter& interpreter)
 {
     auto* impl = impl_from(interpreter);

+ 1 - 0
Libraries/LibWeb/Bindings/WindowObject.h

@@ -48,6 +48,7 @@ private:
 
     static JS::Value alert(JS::Interpreter&);
     static JS::Value set_interval(JS::Interpreter&);
+    static JS::Value set_timeout(JS::Interpreter&);
     static JS::Value request_animation_frame(JS::Interpreter&);
     static JS::Value cancel_animation_frame(JS::Interpreter&);
 

+ 11 - 0
Libraries/LibWeb/DOM/Window.cpp

@@ -62,6 +62,17 @@ void Window::set_interval(JS::Function& callback, i32 interval)
     }).leak_ref();
 }
 
+void Window::set_timeout(JS::Function& callback, i32 interval)
+{
+    // FIXME: This leaks the interval timer and makes it unstoppable.
+    auto& timer = Core::Timer::construct(interval, [handle = make_handle(&callback)] {
+        auto* function = const_cast<JS::Function*>(static_cast<const JS::Function*>(handle.cell()));
+        auto& interpreter = function->interpreter();
+        interpreter.call(function);
+    }).leak_ref();
+    timer.set_single_shot(true);
+}
+
 i32 Window::request_animation_frame(JS::Function& callback)
 {
     i32 link_id = GUI::DisplayLink::register_callback([handle = make_handle(&callback)](i32 link_id) {

+ 1 - 0
Libraries/LibWeb/DOM/Window.h

@@ -46,6 +46,7 @@ public:
     i32 request_animation_frame(JS::Function&);
     void cancel_animation_frame(i32);
     void set_interval(JS::Function&, i32);
+    void set_timeout(JS::Function&, i32);
 
 private:
     explicit Window(Document&);