mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-25 14:05:15 +00:00
As it turns out, making everyone piggyback on HTML::ImageRequest had some major flaws, as HTMLImageElement may decide to abort an ongoing fetch or wipe out image data, even when someone else is using the same image request. To avoid this issue, this patch introduces SharedImageRequest, and then implements ImageRequest on top of that. Other clients of the ImageRequest API are moved to SharedImageRequest as well, and ImageRequest is now only used by HTMLImageElement. This fixes an issue with image data disappearing and leading to asserts and/or visually absent images.
66 lines
1.7 KiB
C++
66 lines
1.7 KiB
C++
/*
|
|
* Copyright (c) 2023, Andreas Kling <kling@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/Error.h>
|
|
#include <AK/OwnPtr.h>
|
|
#include <AK/URL.h>
|
|
#include <LibGfx/Size.h>
|
|
#include <LibJS/Heap/Handle.h>
|
|
#include <LibJS/SafeFunction.h>
|
|
#include <LibWeb/Forward.h>
|
|
|
|
namespace Web::HTML {
|
|
|
|
class SharedImageRequest : public RefCounted<SharedImageRequest> {
|
|
public:
|
|
static ErrorOr<NonnullRefPtr<SharedImageRequest>> get_or_create(Page&, AK::URL const&);
|
|
~SharedImageRequest();
|
|
|
|
AK::URL const& url() const { return m_url; }
|
|
|
|
[[nodiscard]] RefPtr<DecodedImageData const> image_data() const;
|
|
|
|
[[nodiscard]] JS::GCPtr<Fetch::Infrastructure::FetchController> fetch_controller();
|
|
void set_fetch_controller(JS::GCPtr<Fetch::Infrastructure::FetchController>);
|
|
|
|
void fetch_image(JS::Realm&, JS::NonnullGCPtr<Fetch::Infrastructure::Request>);
|
|
|
|
void add_callbacks(JS::SafeFunction<void()> on_finish, JS::SafeFunction<void()> on_fail);
|
|
|
|
bool is_fetching() const;
|
|
bool needs_fetching() const;
|
|
|
|
private:
|
|
explicit SharedImageRequest(Page&, AK::URL);
|
|
|
|
void handle_successful_fetch(AK::URL const&, StringView mime_type, ByteBuffer data);
|
|
void handle_failed_fetch();
|
|
|
|
enum class State {
|
|
New,
|
|
Fetching,
|
|
Finished,
|
|
Failed,
|
|
};
|
|
|
|
State m_state { State::New };
|
|
|
|
Page& m_page;
|
|
|
|
struct Callbacks {
|
|
JS::SafeFunction<void()> on_finish;
|
|
JS::SafeFunction<void()> on_fail;
|
|
};
|
|
Vector<Callbacks> m_callbacks;
|
|
|
|
AK::URL m_url;
|
|
RefPtr<DecodedImageData const> m_image_data;
|
|
JS::Handle<Fetch::Infrastructure::FetchController> m_fetch_controller;
|
|
};
|
|
|
|
}
|