From 45a47cb32bbdb68f45734af400f3158155c61617 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Sun, 18 Feb 2024 20:10:37 -0500 Subject: [PATCH] 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. --- Userland/Libraries/LibWeb/CMakeLists.txt | 1 + .../Libraries/LibWeb/HTML/HTMLImageElement.cpp | 7 ++++++- .../Libraries/LibWeb/HTML/HTMLImageElement.h | 1 + .../Libraries/LibWeb/HTML/HTMLObjectElement.cpp | 5 +++++ .../Libraries/LibWeb/HTML/HTMLObjectElement.h | 1 + Userland/Libraries/LibWeb/Layout/ImageBox.cpp | 11 ++++++----- Userland/Libraries/LibWeb/Layout/ImageBox.h | 2 +- .../Libraries/LibWeb/Layout/ImageProvider.cpp | 17 +++++++++++++++++ .../Libraries/LibWeb/Layout/ImageProvider.h | 6 ++++++ .../LibWeb/Painting/ImagePaintable.cpp | 2 +- 10 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 Userland/Libraries/LibWeb/Layout/ImageProvider.cpp diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 0392417abf4..6a025ff0f0a 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -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 diff --git a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp index 9f5018bc3f4..c7cc1705c60 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp @@ -109,7 +109,7 @@ void HTMLImageElement::form_associated_element_attribute_changed(FlyString const if (name == HTML::AttributeNames::alt) { if (layout_node()) - verify_cast(*layout_node()).dom_node_did_update_alt_text({}); + did_update_alt_text(verify_cast(*layout_node())); } } @@ -130,6 +130,11 @@ RefPtr HTMLImageElement::bitmap() const return {}; } +bool HTMLImageElement::is_image_available() const +{ + return m_current_request && m_current_request->is_available(); +} + Optional HTMLImageElement::intrinsic_width() const { if (auto image_data = m_current_request->image_data()) diff --git a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h index 5a2821fbff3..986593a4969 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h @@ -85,6 +85,7 @@ public: void upgrade_pending_request_to_current_request(); // ^Layout::ImageProvider + virtual bool is_image_available() const override; virtual Optional intrinsic_width() const override; virtual Optional intrinsic_height() const override; virtual Optional intrinsic_aspect_ratio() const override; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.cpp index 3aa48c51849..f1d50ccb4bc 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.cpp @@ -369,6 +369,11 @@ JS::GCPtr HTMLObjectElement::image_data() const return m_image_request->image_data(); } +bool HTMLObjectElement::is_image_available() const +{ + return image_data() != nullptr; +} + Optional HTMLObjectElement::intrinsic_width() const { if (auto image_data = this->image_data()) diff --git a/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.h b/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.h index 4849df3e34e..41b2d08979c 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.h @@ -75,6 +75,7 @@ private: virtual i32 default_tab_index_value() const override; // ^Layout::ImageProvider + virtual bool is_image_available() const override; virtual Optional intrinsic_width() const override; virtual Optional intrinsic_height() const override; virtual Optional intrinsic_aspect_ratio() const override; diff --git a/Userland/Libraries/LibWeb/Layout/ImageBox.cpp b/Userland/Libraries/LibWeb/Layout/ImageBox.cpp index d1bc55b5e9c..7d5fd6f05eb 100644 --- a/Userland/Libraries/LibWeb/Layout/ImageBox.cpp +++ b/Userland/Libraries/LibWeb/Layout/ImageBox.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -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(dom_node()); + auto const& element = verify_cast(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) +void ImageBox::dom_node_did_update_alt_text(Badge) { m_cached_alt_text_width = {}; } bool ImageBox::renders_as_alt_text() const { - if (is(dom_node())) - return !static_cast(dom_node()).current_request().is_available(); + if (auto const* image_provider = dynamic_cast(&dom_node())) + return !image_provider->is_image_available(); return false; } diff --git a/Userland/Libraries/LibWeb/Layout/ImageBox.h b/Userland/Libraries/LibWeb/Layout/ImageBox.h index 0d3b2e9718c..c943da97817 100644 --- a/Userland/Libraries/LibWeb/Layout/ImageBox.h +++ b/Userland/Libraries/LibWeb/Layout/ImageBox.h @@ -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); + void dom_node_did_update_alt_text(Badge); private: ImageProvider const& m_image_provider; diff --git a/Userland/Libraries/LibWeb/Layout/ImageProvider.cpp b/Userland/Libraries/LibWeb/Layout/ImageProvider.cpp new file mode 100644 index 00000000000..bd6e123cc2c --- /dev/null +++ b/Userland/Libraries/LibWeb/Layout/ImageProvider.cpp @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024, Tim Flynn + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +namespace Web::Layout { + +void ImageProvider::did_update_alt_text(ImageBox& layout_node) +{ + layout_node.dom_node_did_update_alt_text({}); +} + +} diff --git a/Userland/Libraries/LibWeb/Layout/ImageProvider.h b/Userland/Libraries/LibWeb/Layout/ImageProvider.h index 290f38afd99..61ae4af2a44 100644 --- a/Userland/Libraries/LibWeb/Layout/ImageProvider.h +++ b/Userland/Libraries/LibWeb/Layout/ImageProvider.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include namespace Web::Layout { @@ -15,12 +16,17 @@ class ImageProvider { public: virtual ~ImageProvider() { } + virtual bool is_image_available() const = 0; + virtual Optional intrinsic_width() const = 0; virtual Optional intrinsic_height() const = 0; virtual Optional intrinsic_aspect_ratio() const = 0; virtual RefPtr current_image_bitmap(Gfx::IntSize) const = 0; virtual void set_visible_in_viewport(bool) = 0; + +protected: + static void did_update_alt_text(ImageBox&); }; } diff --git a/Userland/Libraries/LibWeb/Painting/ImagePaintable.cpp b/Userland/Libraries/LibWeb/Painting/ImagePaintable.cpp index 645f7f74dfb..876fce2c9cc 100644 --- a/Userland/Libraries/LibWeb/Painting/ImagePaintable.cpp +++ b/Userland/Libraries/LibWeb/Painting/ImagePaintable.cpp @@ -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(*dom_node()); + auto const& image_element = verify_cast(*dom_node()); auto enclosing_rect = context.enclosing_device_rect(absolute_rect()).to_type(); context.recording_painter().paint_frame(enclosing_rect, context.palette(), Gfx::FrameStyle::SunkenContainer); auto alt = image_element.get_attribute_value(HTML::AttributeNames::alt);