mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 22:07:36 +00:00
LibWeb: Implement setTimeout/setInterval with ESO according to the spec
Our setInterval implementation currently crashes on DuckDuckGo when it's invoked with a string argument. In this path, we were creating a native function to evaluate and execute that string. That evaluation was always returning a Completion, but NativeFunction expects ThrowCompletionOr. The conversion from Completion to ThrowCompletionOr would fail a VERIFY because that conversion is only valid if the Completion is an error; but we would trigger this conversion even on success. This change re-implements setTimeout & setInterval in direct accordance with the spec. So we avoid making that NativeFunction altogether, and DDG can progress past its invocation to the timer. With this change, we also have other features we did not previously support, such as passing any number of arguments to the timers. This does not implement handling of nesting levels yet.
This commit is contained in:
parent
8156ec5da8
commit
18b9d02edd
6 changed files with 184 additions and 138 deletions
|
@ -7,38 +7,25 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Forward.h>
|
||||
#include <AK/Function.h>
|
||||
#include <LibCore/Forward.h>
|
||||
#include <LibJS/Heap/Handle.h>
|
||||
#include <LibJS/Runtime/FunctionObject.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
class Timer final : public RefCounted<Timer> {
|
||||
public:
|
||||
enum class Type {
|
||||
Interval,
|
||||
Timeout,
|
||||
};
|
||||
|
||||
static NonnullRefPtr<Timer> create_interval(Window&, int milliseconds, NonnullOwnPtr<Bindings::CallbackType> callback);
|
||||
static NonnullRefPtr<Timer> create_timeout(Window&, int milliseconds, NonnullOwnPtr<Bindings::CallbackType> callback);
|
||||
|
||||
static NonnullRefPtr<Timer> create(Window& window, i32 milliseconds, Function<void()> callback, i32 id);
|
||||
~Timer();
|
||||
|
||||
i32 id() const { return m_id; }
|
||||
Type type() const { return m_type; }
|
||||
|
||||
Bindings::CallbackType& callback() { return *m_callback; }
|
||||
void start();
|
||||
|
||||
private:
|
||||
Timer(Window&, Type, int ms, NonnullOwnPtr<Bindings::CallbackType> callback);
|
||||
Timer(Window& window, i32 milliseconds, Function<void()> callback, i32 id);
|
||||
|
||||
Window& m_window;
|
||||
RefPtr<Core::Timer> m_timer;
|
||||
Type m_type;
|
||||
int m_id { 0 };
|
||||
NonnullOwnPtr<Bindings::CallbackType> m_callback;
|
||||
Window& m_window;
|
||||
i32 m_id { 0 };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue