1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-20 14:45:07 +00:00

LibWeb: Create a basic layout node for HTMLVideoElement

This commit is contained in:
Timothy Flynn 2023-04-04 18:32:09 -04:00 committed by Linus Groh
parent 725d7c3699
commit f156d3d5e5
10 changed files with 338 additions and 0 deletions

View file

@ -4,11 +4,19 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibGfx/Bitmap.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/HTML/HTMLVideoElement.h>
#include <LibWeb/HTML/VideoTrack.h>
#include <LibWeb/Layout/VideoBox.h>
#include <LibWeb/Platform/Timer.h>
namespace Web::HTML {
// FIXME: Determine a reasonable framerate somehow. For now, this is roughly 24fps.
static constexpr int s_frame_delay_ms = 42;
HTMLVideoElement::HTMLVideoElement(DOM::Document& document, DOM::QualifiedName qualified_name)
: HTMLMediaElement(document, move(qualified_name))
{
@ -24,6 +32,27 @@ JS::ThrowCompletionOr<void> HTMLVideoElement::initialize(JS::Realm& realm)
return {};
}
void HTMLVideoElement::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_video_track);
}
JS::GCPtr<Layout::Node> HTMLVideoElement::create_layout_node(NonnullRefPtr<CSS::StyleProperties> style)
{
return heap().allocate_without_realm<Layout::VideoBox>(document(), *this, move(style));
}
Layout::VideoBox* HTMLVideoElement::layout_node()
{
return static_cast<Layout::VideoBox*>(Node::layout_node());
}
Layout::VideoBox const* HTMLVideoElement::layout_node() const
{
return static_cast<Layout::VideoBox const*>(Node::layout_node());
}
// https://html.spec.whatwg.org/multipage/media.html#dom-video-videowidth
u32 HTMLVideoElement::video_width() const
{
@ -46,4 +75,30 @@ u32 HTMLVideoElement::video_height() const
return m_video_height;
}
void HTMLVideoElement::set_video_track(JS::GCPtr<HTML::VideoTrack> video_track)
{
set_needs_style_update(true);
document().set_needs_layout();
if (m_video_timer)
m_video_timer->stop();
m_video_track = video_track;
if (!m_video_track)
return;
if (!m_video_timer) {
m_video_timer = Platform::Timer::create_repeating(s_frame_delay_ms, [this]() {
if (auto frame = m_video_track->next_frame())
m_current_frame = move(frame);
else
m_video_timer->stop();
layout_node()->set_needs_display();
});
}
m_video_timer->start();
}
}