ladybird/Libraries/LibWeb/Layout/VideoBox.cpp
Andreas Kling ed26fdaa81 LibWeb: Remove ViewportClient from ImagePaintable and VideoBox
Neither of these classes did anything useful as ViewportClients:

- ImagePaintable called set_visible_in_viewport() which is a FIXME
  no-op in every ImageProvider implementation.
- VideoBox had an empty did_set_viewport_rect() with a FIXME comment.

More importantly, they caused a crash when a DOM node was adopted into
a different document: the old ImagePaintable/VideoBox would still be
registered with the old document, but their document() accessor (which
goes through the DOM node) would return the new document. During GC
finalization, unregister_viewport_client() would fail because it was
trying to unregister from the wrong document.

The only meaningful ViewportClient is HTMLImageElement (for responsive
image source selection), which already handles document adoption
correctly in adopted_from().

Fixes crash when loading https://msn.com/
2026-02-26 09:25:25 +01:00

50 lines
1.3 KiB
C++

/*
* Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/HTML/HTMLVideoElement.h>
#include <LibWeb/Layout/VideoBox.h>
#include <LibWeb/Painting/VideoPaintable.h>
namespace Web::Layout {
GC_DEFINE_ALLOCATOR(VideoBox);
VideoBox::VideoBox(DOM::Document& document, DOM::Element& element, GC::Ref<CSS::ComputedProperties> style)
: ReplacedBox(document, element, style)
{
}
HTML::HTMLVideoElement& VideoBox::dom_node()
{
return static_cast<HTML::HTMLVideoElement&>(*ReplacedBox::dom_node());
}
HTML::HTMLVideoElement const& VideoBox::dom_node() const
{
return static_cast<HTML::HTMLVideoElement const&>(*ReplacedBox::dom_node());
}
bool VideoBox::can_have_children() const
{
// If we allow children when controls are disabled, innerText may be non-empty.
return dom_node().shadow_root() != nullptr;
}
CSS::SizeWithAspectRatio VideoBox::natural_size() const
{
CSSPixels width = dom_node().video_width();
CSSPixels height = dom_node().video_height();
if (width > 0 && height > 0)
return { width, height, CSSPixelFraction(width, height) };
return { width, height, {} };
}
GC::Ptr<Painting::Paintable> VideoBox::create_paintable() const
{
return Painting::VideoPaintable::create(*this);
}
}