LibWeb: Generalize ImageBox and ImagePaintable for any ImageProvider

They currently assume the DOM node is an HTMLImageElement with respect
to handling the alt attribute. The HTMLInputElement will require the
same behavior.
This commit is contained in:
Timothy Flynn 2024-02-18 20:10:37 -05:00 committed by Andreas Kling
parent c4295edc81
commit 45a47cb32b
Notes: sideshowbarker 2024-07-17 00:25:35 +09:00
10 changed files with 45 additions and 8 deletions

View file

@ -439,6 +439,7 @@ set(SOURCES
Layout/FrameBox.cpp
Layout/GridFormattingContext.cpp
Layout/ImageBox.cpp
Layout/ImageProvider.cpp
Layout/Viewport.cpp
Layout/InlineFormattingContext.cpp
Layout/InlineLevelIterator.cpp

View file

@ -109,7 +109,7 @@ void HTMLImageElement::form_associated_element_attribute_changed(FlyString const
if (name == HTML::AttributeNames::alt) {
if (layout_node())
verify_cast<Layout::ImageBox>(*layout_node()).dom_node_did_update_alt_text({});
did_update_alt_text(verify_cast<Layout::ImageBox>(*layout_node()));
}
}
@ -130,6 +130,11 @@ RefPtr<Gfx::Bitmap const> HTMLImageElement::bitmap() const
return {};
}
bool HTMLImageElement::is_image_available() const
{
return m_current_request && m_current_request->is_available();
}
Optional<CSSPixels> HTMLImageElement::intrinsic_width() const
{
if (auto image_data = m_current_request->image_data())

View file

@ -85,6 +85,7 @@ public:
void upgrade_pending_request_to_current_request();
// ^Layout::ImageProvider
virtual bool is_image_available() const override;
virtual Optional<CSSPixels> intrinsic_width() const override;
virtual Optional<CSSPixels> intrinsic_height() const override;
virtual Optional<CSSPixelFraction> intrinsic_aspect_ratio() const override;

View file

@ -369,6 +369,11 @@ JS::GCPtr<DecodedImageData> HTMLObjectElement::image_data() const
return m_image_request->image_data();
}
bool HTMLObjectElement::is_image_available() const
{
return image_data() != nullptr;
}
Optional<CSSPixels> HTMLObjectElement::intrinsic_width() const
{
if (auto image_data = this->image_data())

View file

@ -75,6 +75,7 @@ private:
virtual i32 default_tab_index_value() const override;
// ^Layout::ImageProvider
virtual bool is_image_available() const override;
virtual Optional<CSSPixels> intrinsic_width() const override;
virtual Optional<CSSPixels> intrinsic_height() const override;
virtual Optional<CSSPixelFraction> intrinsic_aspect_ratio() const override;

View file

@ -8,6 +8,7 @@
#include <LibWeb/HTML/DecodedImageData.h>
#include <LibWeb/HTML/ImageRequest.h>
#include <LibWeb/Layout/ImageBox.h>
#include <LibWeb/Layout/ImageProvider.h>
#include <LibWeb/Painting/ImagePaintable.h>
#include <LibWeb/Platform/FontPlugin.h>
@ -28,9 +29,9 @@ void ImageBox::prepare_for_replaced_layout()
set_natural_aspect_ratio(m_image_provider.intrinsic_aspect_ratio());
if (renders_as_alt_text()) {
auto& image_element = verify_cast<HTML::HTMLImageElement>(dom_node());
auto const& element = verify_cast<HTML::HTMLElement>(dom_node());
auto& font = Platform::FontPlugin::the().default_font();
auto alt = image_element.alt();
auto alt = element.get_attribute_value(HTML::AttributeNames::alt);
CSSPixels alt_text_width = 0;
if (!m_cached_alt_text_width.has_value())
@ -46,15 +47,15 @@ void ImageBox::prepare_for_replaced_layout()
}
}
void ImageBox::dom_node_did_update_alt_text(Badge<HTML::HTMLImageElement>)
void ImageBox::dom_node_did_update_alt_text(Badge<ImageProvider>)
{
m_cached_alt_text_width = {};
}
bool ImageBox::renders_as_alt_text() const
{
if (is<HTML::HTMLImageElement>(dom_node()))
return !static_cast<HTML::HTMLImageElement const&>(dom_node()).current_request().is_available();
if (auto const* image_provider = dynamic_cast<ImageProvider const*>(&dom_node()))
return !image_provider->is_image_available();
return false;
}

View file

@ -29,7 +29,7 @@ public:
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>);
void dom_node_did_update_alt_text(Badge<ImageProvider>);
private:
ImageProvider const& m_image_provider;

View file

@ -0,0 +1,17 @@
/*
* Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/Layout/ImageBox.h>
#include <LibWeb/Layout/ImageProvider.h>
namespace Web::Layout {
void ImageProvider::did_update_alt_text(ImageBox& layout_node)
{
layout_node.dom_node_did_update_alt_text({});
}
}

View file

@ -7,6 +7,7 @@
#pragma once
#include <LibGfx/Size.h>
#include <LibWeb/Forward.h>
#include <LibWeb/PixelUnits.h>
namespace Web::Layout {
@ -15,12 +16,17 @@ class ImageProvider {
public:
virtual ~ImageProvider() { }
virtual bool is_image_available() const = 0;
virtual Optional<CSSPixels> intrinsic_width() const = 0;
virtual Optional<CSSPixels> intrinsic_height() const = 0;
virtual Optional<CSSPixelFraction> intrinsic_aspect_ratio() const = 0;
virtual RefPtr<Gfx::ImmutableBitmap> current_image_bitmap(Gfx::IntSize) const = 0;
virtual void set_visible_in_viewport(bool) = 0;
protected:
static void did_update_alt_text(ImageBox&);
};
}

View file

@ -53,7 +53,7 @@ void ImagePaintable::paint(PaintContext& context, PaintPhase phase) const
if (phase == PaintPhase::Foreground) {
auto image_rect = context.rounded_device_rect(absolute_rect());
if (layout_box().renders_as_alt_text()) {
auto& image_element = verify_cast<HTML::HTMLImageElement>(*dom_node());
auto const& image_element = verify_cast<HTML::HTMLElement>(*dom_node());
auto enclosing_rect = context.enclosing_device_rect(absolute_rect()).to_type<int>();
context.recording_painter().paint_frame(enclosing_rect, context.palette(), Gfx::FrameStyle::SunkenContainer);
auto alt = image_element.get_attribute_value(HTML::AttributeNames::alt);