diff --git a/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.cpp b/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.cpp index 2d4c99c226..e622477d62 100644 --- a/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.cpp +++ b/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.cpp @@ -51,6 +51,7 @@ XMLHttpRequest::XMLHttpRequest(HTML::Window& window) , m_window(window) , m_response_type(Bindings::XMLHttpRequestResponseType::Empty) { + set_overrides_must_survive_garbage_collection(true); set_prototype(&Bindings::cached_web_prototype(window.realm(), "XMLHttpRequest")); } @@ -587,4 +588,37 @@ WebIDL::ExceptionOr XMLHttpRequest::set_timeout(u32 timeout) // https://xhr.spec.whatwg.org/#dom-xmlhttprequest-timeout u32 XMLHttpRequest::timeout() const { return m_timeout; } +// https://xhr.spec.whatwg.org/#garbage-collection +bool XMLHttpRequest::must_survive_garbage_collection() const +{ + // An XMLHttpRequest object must not be garbage collected + // if its state is either opened with the send() flag set, headers received, or loading, + // and it has one or more event listeners registered whose type is one of + // readystatechange, progress, abort, error, load, timeout, and loadend. + if ((m_ready_state == ReadyState::Opened && m_send) + || m_ready_state == ReadyState::HeadersReceived + || m_ready_state == ReadyState::Loading) { + if (has_event_listener(EventNames::readystatechange)) + return true; + if (has_event_listener(EventNames::progress)) + return true; + if (has_event_listener(EventNames::abort)) + return true; + if (has_event_listener(EventNames::error)) + return true; + if (has_event_listener(EventNames::load)) + return true; + if (has_event_listener(EventNames::timeout)) + return true; + if (has_event_listener(EventNames::loadend)) + return true; + } + + // FIXME: If an XMLHttpRequest object is garbage collected while its connection is still open, + // the user agent must terminate the XMLHttpRequest object’s fetch controller. + // NOTE: This would go in XMLHttpRequest::finalize(). + + return false; +} + } diff --git a/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h b/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h index 77037dc230..a9db911a40 100644 --- a/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h +++ b/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h @@ -65,6 +65,7 @@ public: private: virtual void visit_edges(Cell::Visitor&) override; + virtual bool must_survive_garbage_collection() const override; void set_ready_state(ReadyState); void set_status(Fetch::Infrastructure::Status status) { m_status = status; }