/* * Copyright (c) 2018-2023, Andreas Kling * Copyright (c) 2024, Aliaksandr Kalenik * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Web::HTML { class HTMLImageElement final : public HTMLElement , public FormAssociatedElement , public LazyLoadingElement , public Layout::ImageProvider , public DOM::Document::ViewportClient { WEB_PLATFORM_OBJECT(HTMLImageElement, HTMLElement); GC_DECLARE_ALLOCATOR(HTMLImageElement); FORM_ASSOCIATED_ELEMENT(HTMLElement, HTMLImageElement); LAZY_LOADING_ELEMENT(HTMLImageElement); public: virtual ~HTMLImageElement() override; virtual void form_associated_element_attribute_changed(FlyString const& name, Optional const& value) override; Optional alternative_text() const override { if (auto alt = get_attribute(HTML::AttributeNames::alt); alt.has_value()) return alt.release_value(); return {}; } String alt() const { return get_attribute_value(HTML::AttributeNames::alt); } String src() const { return get_attribute_value(HTML::AttributeNames::src); } RefPtr immutable_bitmap() const; unsigned width() const; WebIDL::ExceptionOr set_width(unsigned); unsigned height() const; WebIDL::ExceptionOr set_height(unsigned); unsigned natural_width() const; unsigned natural_height() const; // https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-complete bool complete() const; // https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-currentsrc String current_src() const; // https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-decode [[nodiscard]] WebIDL::ExceptionOr> decode() const; virtual Optional default_role() const override; // https://html.spec.whatwg.org/multipage/images.html#img-environment-changes void react_to_changes_in_the_environment(); // https://html.spec.whatwg.org/multipage/images.html#update-the-image-data ErrorOr update_the_image_data(bool restart_the_animations = false, bool maybe_omit_events = false); // https://html.spec.whatwg.org/multipage/images.html#use-srcset-or-picture [[nodiscard]] bool uses_srcset_or_picture() const; // https://html.spec.whatwg.org/multipage/rendering.html#restart-the-animation void restart_the_animation(); // https://html.spec.whatwg.org/multipage/images.html#select-an-image-source [[nodiscard]] Optional select_an_image_source(); void set_source_set(SourceSet); ImageRequest& current_request() { return *m_current_request; } ImageRequest const& current_request() const { return *m_current_request; } size_t current_frame_index() const { return m_current_frame_index; } // https://html.spec.whatwg.org/multipage/images.html#upgrade-the-pending-request-to-the-current-request void upgrade_pending_request_to_current_request(); // https://html.spec.whatwg.org/multipage/embedded-content.html#allows-auto-sizes bool allows_auto_sizes() const; // ^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; virtual RefPtr current_image_bitmap(Gfx::IntSize = {}) const override; virtual void set_visible_in_viewport(bool) override; virtual GC::Ref to_html_element() const override { return *this; } virtual void visit_edges(Cell::Visitor&) override; private: HTMLImageElement(DOM::Document&, DOM::QualifiedName); virtual bool is_html_image_element() const override { return true; } virtual void initialize(JS::Realm&) override; virtual void finalize() override; virtual void adopted_from(DOM::Document&) override; virtual void apply_presentational_hints(CSS::StyleProperties&) const override; // https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element:dimension-attributes virtual bool supports_dimension_attributes() const override { return true; } virtual GC::Ptr create_layout_node(CSS::StyleProperties) override; virtual void adjust_computed_style(CSS::StyleProperties&) override; virtual void did_set_viewport_rect(CSSPixelRect const&) override; void handle_successful_fetch(URL::URL const&, StringView mime_type, ImageRequest&, ByteBuffer, bool maybe_omit_events, URL::URL const& previous_url); void handle_failed_fetch(); void add_callbacks_to_image_request(GC::Ref, bool maybe_omit_events, URL::URL const& url_string, URL::URL const& previous_url); void animate(); RefPtr m_animation_timer; size_t m_current_frame_index { 0 }; size_t m_loops_completed { 0 }; Optional m_load_event_delayer; CORSSettingAttribute m_cors_setting { CORSSettingAttribute::NoCORS }; // https://html.spec.whatwg.org/multipage/images.html#last-selected-source // Each img element has a last selected source, which must initially be null. Optional m_last_selected_source; // https://html.spec.whatwg.org/multipage/images.html#current-request GC::Ptr m_current_request; // https://html.spec.whatwg.org/multipage/images.html#pending-request GC::Ptr m_pending_request; SourceSet m_source_set; CSSPixelSize m_last_seen_viewport_size; }; } namespace Web::DOM { template<> inline bool Node::fast_is() const { return is_html_image_element(); } }