LibWeb: Handle media elements being painted before their duration is set

It can take some time to download / decode a media resource. During this
time, its duration is set to NaN. The media control box would then have
some odd rendering glitches as it tried to treat NaN as an actual time.
Once we do have a duration, we also must ensure the media control box is
updated.
This commit is contained in:
Timothy Flynn 2023-06-14 15:35:20 -04:00 committed by Andreas Kling
parent 8cb0197eeb
commit 55b61724a0
Notes: sideshowbarker 2024-07-17 11:33:34 +09:00
2 changed files with 6 additions and 2 deletions

View File

@ -303,6 +303,9 @@ void HTMLMediaElement::set_duration(double duration)
}
m_duration = duration;
if (auto* layout_node = this->layout_node())
layout_node->set_needs_display();
}
WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> HTMLMediaElement::play()

View File

@ -132,7 +132,7 @@ DevicePixelRect MediaPaintable::paint_control_bar_timeline(PaintContext& context
timeline_rect.set_width(min(control_box_rect.width() * 6 / 10, timeline_rect.width()));
media_element.cached_layout_boxes({}).timeline_rect = context.scale_to_css_rect(timeline_rect);
auto playback_percentage = media_element.current_time() / media_element.duration();
auto playback_percentage = isnan(media_element.duration()) ? 0.0 : media_element.current_time() / media_element.duration();
auto playback_position = static_cast<double>(static_cast<int>(timeline_rect.width())) * playback_percentage;
auto timeline_button_size = min(maximum_timeline_button_size, timeline_rect.height() / 2);
@ -166,7 +166,8 @@ DevicePixelRect MediaPaintable::paint_control_bar_timeline(PaintContext& context
DevicePixelRect MediaPaintable::paint_control_bar_timestamp(PaintContext& context, HTML::HTMLMediaElement const& media_element, DevicePixelRect control_box_rect) const
{
auto current_time = human_readable_digital_time(round(media_element.current_time()));
auto duration = human_readable_digital_time(round(media_element.duration()));
auto duration = human_readable_digital_time(isnan(media_element.duration()) ? 0 : round(media_element.duration()));
auto timestamp = String::formatted("{} / {}", current_time, duration).release_value_but_fixme_should_propagate_errors();
auto const& scaled_font = layout_node().scaled_font(context);