mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 06:37:35 +00:00
LibWeb: Don't force HTMLImageElement to have a legacy ImageLoader
We achieve this by adding a new Layout::ImageProvider class and having both HTMLImageElement and HTMLObjectElement inherit from it. The HTML spec is vague on how object image loading should work, which is why this first pass is focusing on image elements.
This commit is contained in:
parent
3cf73ca0b3
commit
c648e24cff
9 changed files with 84 additions and 88 deletions
|
@ -13,69 +13,27 @@
|
|||
|
||||
namespace Web::Layout {
|
||||
|
||||
ImageBox::ImageBox(DOM::Document& document, DOM::Element& element, NonnullRefPtr<CSS::StyleProperties> style, ImageLoader const& image_loader)
|
||||
ImageBox::ImageBox(DOM::Document& document, DOM::Element& element, NonnullRefPtr<CSS::StyleProperties> style, ImageProvider const& image_provider)
|
||||
: ReplacedBox(document, element, move(style))
|
||||
, m_image_loader(image_loader)
|
||||
, m_image_provider(image_provider)
|
||||
{
|
||||
}
|
||||
|
||||
ImageBox::~ImageBox() = default;
|
||||
|
||||
int ImageBox::preferred_width() const
|
||||
{
|
||||
return dom_node().attribute(HTML::AttributeNames::width).to_int().value_or(m_image_loader.width());
|
||||
}
|
||||
|
||||
int ImageBox::preferred_height() const
|
||||
{
|
||||
return dom_node().attribute(HTML::AttributeNames::height).to_int().value_or(m_image_loader.height());
|
||||
}
|
||||
|
||||
void ImageBox::prepare_for_replaced_layout()
|
||||
{
|
||||
HTML::ImageRequest const* image_request = nullptr;
|
||||
if (is<HTML::HTMLImageElement>(dom_node())) {
|
||||
image_request = &static_cast<HTML::HTMLImageElement const&>(dom_node()).current_request();
|
||||
}
|
||||
auto bitmap = m_image_provider.current_image_bitmap();
|
||||
|
||||
if (image_request) {
|
||||
if (!image_request->is_available()) {
|
||||
set_intrinsic_width(0);
|
||||
set_intrinsic_height(0);
|
||||
} else if (auto data = image_request->image_data()) {
|
||||
auto width = data->natural_width();
|
||||
if (width.has_value()) {
|
||||
set_intrinsic_width(width.value());
|
||||
}
|
||||
auto height = data->natural_height();
|
||||
if (height.has_value()) {
|
||||
set_intrinsic_height(height.value());
|
||||
}
|
||||
|
||||
if (width.has_value() && height.has_value() && height.value() != 0) {
|
||||
set_intrinsic_aspect_ratio(static_cast<float>(width.value()) / static_cast<float>(height.value()));
|
||||
} else {
|
||||
set_intrinsic_aspect_ratio({});
|
||||
}
|
||||
}
|
||||
if (!bitmap) {
|
||||
set_intrinsic_width(0);
|
||||
set_intrinsic_height(0);
|
||||
} else {
|
||||
if (!m_image_loader.has_loaded_or_failed()) {
|
||||
set_intrinsic_width(0);
|
||||
set_intrinsic_height(0);
|
||||
} else {
|
||||
if (m_image_loader.width()) {
|
||||
set_intrinsic_width(m_image_loader.width());
|
||||
}
|
||||
if (m_image_loader.height()) {
|
||||
set_intrinsic_height(m_image_loader.height());
|
||||
}
|
||||
|
||||
if (m_image_loader.width() && m_image_loader.height()) {
|
||||
set_intrinsic_aspect_ratio((float)m_image_loader.width() / (float)m_image_loader.height());
|
||||
} else {
|
||||
set_intrinsic_aspect_ratio({});
|
||||
}
|
||||
}
|
||||
auto width = bitmap->width();
|
||||
auto height = bitmap->height();
|
||||
set_intrinsic_width(width);
|
||||
set_intrinsic_height(height);
|
||||
set_intrinsic_aspect_ratio(static_cast<float>(width) / static_cast<float>(height));
|
||||
}
|
||||
|
||||
if (renders_as_alt_text()) {
|
||||
|
|
|
@ -15,7 +15,7 @@ class ImageBox final : public ReplacedBox {
|
|||
JS_CELL(ImageBox, ReplacedBox);
|
||||
|
||||
public:
|
||||
ImageBox(DOM::Document&, DOM::Element&, NonnullRefPtr<CSS::StyleProperties>, ImageLoader const&);
|
||||
ImageBox(DOM::Document&, DOM::Element&, NonnullRefPtr<CSS::StyleProperties>, ImageProvider const&);
|
||||
virtual ~ImageBox() override;
|
||||
|
||||
virtual void prepare_for_replaced_layout() override;
|
||||
|
@ -26,15 +26,13 @@ public:
|
|||
|
||||
virtual JS::GCPtr<Painting::Paintable> create_paintable() const override;
|
||||
|
||||
auto const& image_loader() const { return m_image_loader; }
|
||||
auto const& image_provider() const { return m_image_provider; }
|
||||
auto& image_provider() { return m_image_provider; }
|
||||
|
||||
void dom_node_did_update_alt_text(Badge<HTML::HTMLImageElement>);
|
||||
|
||||
private:
|
||||
int preferred_width() const;
|
||||
int preferred_height() const;
|
||||
|
||||
ImageLoader const& m_image_loader;
|
||||
ImageProvider const& m_image_provider;
|
||||
|
||||
Optional<CSSPixels> m_cached_alt_text_width;
|
||||
};
|
||||
|
|
19
Userland/Libraries/LibWeb/Layout/ImageProvider.h
Normal file
19
Userland/Libraries/LibWeb/Layout/ImageProvider.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Web::Layout {
|
||||
|
||||
class ImageProvider {
|
||||
public:
|
||||
virtual ~ImageProvider() { }
|
||||
|
||||
virtual RefPtr<Gfx::Bitmap const> current_image_bitmap() const = 0;
|
||||
virtual void set_visible_in_viewport(bool) = 0;
|
||||
};
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue