diff --git a/Libraries/LibWeb/Bindings/WindowObject.cpp b/Libraries/LibWeb/Bindings/WindowObject.cpp index 746a81c8fc..7c321f8661 100644 --- a/Libraries/LibWeb/Bindings/WindowObject.cpp +++ b/Libraries/LibWeb/Bindings/WindowObject.cpp @@ -45,6 +45,7 @@ namespace Bindings { WindowObject::WindowObject(Window& impl) : m_impl(impl) { + impl.set_wrapper({}, *this); } void WindowObject::initialize() diff --git a/Libraries/LibWeb/Bindings/WindowObject.h b/Libraries/LibWeb/Bindings/WindowObject.h index dff689c8e4..3bc6797249 100644 --- a/Libraries/LibWeb/Bindings/WindowObject.h +++ b/Libraries/LibWeb/Bindings/WindowObject.h @@ -26,13 +26,16 @@ #pragma once +#include #include #include namespace Web { namespace Bindings { -class WindowObject final : public JS::GlobalObject { +class WindowObject final + : public JS::GlobalObject + , public Weakable { public: explicit WindowObject(Window&); virtual void initialize() override; diff --git a/Libraries/LibWeb/DOM/Window.cpp b/Libraries/LibWeb/DOM/Window.cpp index af22ec934e..e0f7f38ab4 100644 --- a/Libraries/LibWeb/DOM/Window.cpp +++ b/Libraries/LibWeb/DOM/Window.cpp @@ -51,6 +51,11 @@ Window::~Window() { } +void Window::set_wrapper(Badge, Bindings::WindowObject& wrapper) +{ + m_wrapper = wrapper.make_weak_ptr(); +} + void Window::alert(const String& message) { GUI::MessageBox::show(message, "Alert", GUI::MessageBox::Type::Information); @@ -65,22 +70,20 @@ bool Window::confirm(const String& message) void Window::set_interval(JS::Function& callback, i32 interval) { // FIXME: This leaks the interval timer and makes it unstoppable. - (void)Core::Timer::construct(interval, [handle = make_handle(&callback)] { + (void)Core::Timer::construct(interval, [this, handle = make_handle(&callback)] { auto& function = const_cast(static_cast(*handle.cell())); auto& interpreter = function.interpreter(); - auto& window = static_cast(interpreter.global_object()); - interpreter.call(function, &window); + interpreter.call(function, wrapper()); }).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& timer = Core::Timer::construct(interval, [this, handle = make_handle(&callback)] { auto& function = const_cast(static_cast(*handle.cell())); auto& interpreter = function.interpreter(); - auto& window = static_cast(interpreter.global_object()); - interpreter.call(function, &window); + interpreter.call(function, wrapper()); }).leak_ref(); timer.set_single_shot(true); } diff --git a/Libraries/LibWeb/DOM/Window.h b/Libraries/LibWeb/DOM/Window.h index 0428dc6cfc..06b3b27f5d 100644 --- a/Libraries/LibWeb/DOM/Window.h +++ b/Libraries/LibWeb/DOM/Window.h @@ -52,10 +52,16 @@ public: void did_set_location_href(Badge, const String& new_href); void did_call_location_reload(Badge); + Bindings::WindowObject* wrapper() { return m_wrapper; } + const Bindings::WindowObject* wrapper() const { return m_wrapper; } + + void set_wrapper(Badge, Bindings::WindowObject&); + private: explicit Window(Document&); Document& m_document; + WeakPtr m_wrapper; }; }