mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2026-04-19 02:10:26 +00:00
LibWeb: Don't keep HTMLMediaElement alive in its fetch callbacks
This isn't strictly necessary to allow the element to be collected, but it doesn't make sense for a fetch to keep the media element alive.
This commit is contained in:
parent
a3619cd995
commit
d146adfd66
Notes:
github-actions[bot]
2026-02-18 19:15:44 +00:00
Author: https://github.com/Zaggy1024
Commit: d146adfd66
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/7922
1 changed files with 19 additions and 12 deletions
|
|
@ -1084,13 +1084,16 @@ void HTMLMediaElement::fetch_resource(NonnullRefPtr<FetchData> const& fetch_data
|
|||
// 8. Fetch request, with processResponse set to the following steps given response response:
|
||||
Fetch::Infrastructure::FetchAlgorithms::Input fetch_algorithms_input {};
|
||||
|
||||
fetch_algorithms_input.process_response = [this, byte_range = move(byte_range), fetch_data, fetch_generation](auto response) mutable {
|
||||
fetch_algorithms_input.process_response = [weak_self = GC::Weak(*this), byte_range = move(byte_range), fetch_data, fetch_generation](auto response) mutable {
|
||||
if (!weak_self)
|
||||
return;
|
||||
|
||||
// FIXME: If the response is CORS cross-origin, we must use its internal response to query any of its data. See:
|
||||
// https://github.com/whatwg/html/issues/9355
|
||||
response = response->unsafe_response();
|
||||
|
||||
// 1. Let global be the media element's node document's relevant global object.
|
||||
auto& global = document().realm().global_object();
|
||||
auto& global = weak_self->document().realm().global_object();
|
||||
|
||||
if (auto content_length = response->header_list()->extract_length(); content_length.template has<u64>()) {
|
||||
auto actual_length = fetch_data->offset + content_length.template get<u64>();
|
||||
|
|
@ -1102,7 +1105,7 @@ void HTMLMediaElement::fetch_resource(NonnullRefPtr<FetchData> const& fetch_data
|
|||
|
||||
// 4. If the result of verifying response given the current media resource and byteRange is false, then abort these steps.
|
||||
// NOTE: We do this step before creating the updateMedia task so that we can invoke the failure callback.
|
||||
auto maybe_verify_response_failure = verify_response_or_get_failure_reason(response, byte_range, fetch_data);
|
||||
auto maybe_verify_response_failure = weak_self->verify_response_or_get_failure_reason(response, byte_range, fetch_data);
|
||||
if (maybe_verify_response_failure.has_value()) {
|
||||
fetch_data->failure_callback(maybe_verify_response_failure.value());
|
||||
return;
|
||||
|
|
@ -1111,8 +1114,10 @@ void HTMLMediaElement::fetch_resource(NonnullRefPtr<FetchData> const& fetch_data
|
|||
// 2. Let updateMedia be to queue a media element task given the media element to run the first appropriate steps from the media data processing
|
||||
// steps list below. (A new task is used for this so that the work described below occurs relative to the appropriate media element event task
|
||||
// source rather than using the networking task source.)
|
||||
auto update_media = GC::create_function(heap(), [this, fetch_data, fetch_generation](ByteBuffer media_data) mutable {
|
||||
if (fetch_generation != m_current_fetch_generation)
|
||||
auto update_media = GC::create_function(weak_self->heap(), [weak_self, fetch_data, fetch_generation](ByteBuffer media_data) mutable {
|
||||
if (!weak_self)
|
||||
return;
|
||||
if (fetch_generation != weak_self->m_current_fetch_generation)
|
||||
return;
|
||||
|
||||
// 6. Update the media data with the contents of response's unsafe response obtained in this fashion. response can be CORS-same-origin or
|
||||
|
|
@ -1121,8 +1126,8 @@ void HTMLMediaElement::fetch_resource(NonnullRefPtr<FetchData> const& fetch_data
|
|||
fetch_data->stream->add_chunk_at(fetch_data->offset, media_data.bytes());
|
||||
fetch_data->offset += media_data.size();
|
||||
|
||||
queue_a_media_element_task([this] {
|
||||
process_media_data(FetchingStatus::Ongoing).release_value_but_fixme_should_propagate_errors();
|
||||
weak_self->queue_a_media_element_task([&self = *weak_self] {
|
||||
self.process_media_data(FetchingStatus::Ongoing).release_value_but_fixme_should_propagate_errors();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -1130,18 +1135,20 @@ void HTMLMediaElement::fetch_resource(NonnullRefPtr<FetchData> const& fetch_data
|
|||
// and if all of the data is available to the user agent without network access, then, the user agent must move on to the final step below.
|
||||
// This might never happen, e.g. when streaming an infinite resource such as web radio, or if the resource is longer than the user agent's
|
||||
// ability to cache data.
|
||||
auto process_end_of_media = GC::create_function(heap(), [this, fetch_data, fetch_generation] {
|
||||
if (fetch_generation != m_current_fetch_generation)
|
||||
auto process_end_of_media = GC::create_function(weak_self->heap(), [weak_self, fetch_data, fetch_generation] {
|
||||
if (!weak_self)
|
||||
return;
|
||||
if (fetch_generation != weak_self->m_current_fetch_generation)
|
||||
return;
|
||||
|
||||
fetch_data->stream->reached_end_of_body();
|
||||
queue_a_media_element_task([this] {
|
||||
process_media_data(FetchingStatus::Complete).release_value_but_fixme_should_propagate_errors();
|
||||
weak_self->queue_a_media_element_task([&self = *weak_self] {
|
||||
self.process_media_data(FetchingStatus::Complete).release_value_but_fixme_should_propagate_errors();
|
||||
});
|
||||
});
|
||||
|
||||
VERIFY(response->body());
|
||||
auto empty_algorithm = GC::create_function(heap(), [](JS::Value) { });
|
||||
auto empty_algorithm = GC::create_function(weak_self->heap(), [](JS::Value) { });
|
||||
|
||||
// 5. Otherwise, incrementally read response's body given updateMedia, processEndOfMedia, an empty algorithm, and global.
|
||||
response->body()->incrementally_read(update_media, process_end_of_media, empty_algorithm, GC::Ref { global });
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue