Repository: LadybirdBrowser/ladybird
File: Libraries/LibWeb/HTML/HTMLImageElement.cpp (C++)

Code before:
{
    if (auto image_data = m_current_request->image_data())
        return image_data->intrinsic_width();
    return {};
}

Optional<CSSPixels> HTMLImageElement::intrinsic_height() const
{
    if (auto image_data = m_current_request->image_data())
        return image_data->intrinsic_height();
    return {};
}

Optional<CSSPixelFraction> HTMLImageElement::intrinsic_aspect_ratio() const
{
    if (auto image_data = m_current_request->image_data())
        return image_data->intrinsic_aspect_ratio();
    return {};
}

RefPtr<Gfx::ImmutableBitmap> HTMLImageElement::current_image_bitmap() const
{
    int w = intrinsic_width().value_or({}).to_int();
    int h = intrinsic_height().value_or({}).to_int();
    return current_image_bitmap_sized({ w, h });
}

RefPtr<Gfx::ImmutableBitmap> HTMLImageElement::current_image_bitmap_sized(Gfx::IntSize size) const
{
    if (auto data = m_current_request->image_data())
        return data->bitmap(m_current_frame_index, size);
    return nullptr;
}

void HTMLImageElement::set_visible_in_viewport(bool)
{
    // FIXME: Loosen grip on image data when it's not visible, e.g via volatile memory.
}

// https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-width
WebIDL::UnsignedLong HTMLImageElement::width() const
{
    const_cast<DOM::Document&>(document()).update_layout(DOM::UpdateLayoutReason::HTMLImageElementWidth);

    // Return the rendered width of the image, in CSS pixels, if the image is being rendered.
    if (auto* paintable_box = this->paintable_box())
        return paintable_box->content_width().to_int();

    // On setting [the width or height IDL attribute], they must act as if they reflected the respective content attributes of the same name.
    if (auto width_attr = get_attribute(HTML::AttributeNames::width); width_attr.has_value()) {
        if (auto converted = parse_non_negative_integer(*width_attr); converted.has_value() && *converted <= 2147483647)

Review comment (suggestion):
As this is the same code for every class, it could go in `Web::Layout::ImageProvider` instead to avoid repeating it.

Code after:
{
    if (auto image_data = m_current_request->image_data())
        return image_data->intrinsic_width();
    return {};
}

Optional<CSSPixels> HTMLImageElement::intrinsic_height() const
{
    if (auto image_data = m_current_request->image_data())
        return image_data->intrinsic_height();
    return {};
}

Optional<CSSPixelFraction> HTMLImageElement::intrinsic_aspect_ratio() const
{
    if (auto image_data = m_current_request->image_data())
        return image_data->intrinsic_aspect_ratio();
    return {};
}

RefPtr<Gfx::ImmutableBitmap> HTMLImageElement::current_image_bitmap_sized(Gfx::IntSize size) const
{
    if (auto data = m_current_request->image_data())
        return data->bitmap(m_current_frame_index, size);
    return nullptr;
}

void HTMLImageElement::set_visible_in_viewport(bool)
{
    // FIXME: Loosen grip on image data when it's not visible, e.g via volatile memory.
}

// https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-width
WebIDL::UnsignedLong HTMLImageElement::width() const
{
    const_cast<DOM::Document&>(document()).update_layout(DOM::UpdateLayoutReason::HTMLImageElementWidth);

    // Return the rendered width of the image, in CSS pixels, if the image is being rendered.
    if (auto* paintable_box = this->paintable_box())
        return paintable_box->content_width().to_int();

    // On setting [the width or height IDL attribute], they must act as if they reflected the respective content attributes of the same name.
    if (auto width_attr = get_attribute(HTML::AttributeNames::width); width_attr.has_value()) {
        if (auto converted = parse_non_negative_integer(*width_attr); converted.has_value() && *converted <= 2147483647)
            return *converted;
    }

    // ...or else the density-corrected intrinsic width and height of the image, in CSS pixels,
    // if the image has intrinsic dimensions and is available but not being rendered.
    if (auto bitmap = current_image_bitmap())
        return bitmap->width();