mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 20:27:34 +00:00
LibWeb: Move viewport subscriptions from BrowsingContext to Document
With this change, elements that want to receive viewport rect updates will need to register on document instead of the browsing context. This change solves the problem where a browsing context for a document is guaranteed to exist only while the document is active so browsing context might not exit by the time DOM node that want to register is constructed. This is a part of preparation work before switching to navigables where this issue becomes more visible.
This commit is contained in:
parent
48e9097aa4
commit
5ff7448fee
10 changed files with 66 additions and 61 deletions
|
@ -539,12 +539,6 @@ void BrowsingContext::set_active_document(JS::NonnullGCPtr<DOM::Document> docume
|
|||
previously_active_document->did_stop_being_active_document_in_browsing_context({});
|
||||
}
|
||||
|
||||
void BrowsingContext::inform_all_viewport_clients_about_the_current_viewport_rect()
|
||||
{
|
||||
for (auto* client : m_viewport_clients)
|
||||
client->browsing_context_did_set_viewport_rect(viewport_rect());
|
||||
}
|
||||
|
||||
void BrowsingContext::set_viewport_rect(CSSPixelRect const& rect)
|
||||
{
|
||||
bool did_change = false;
|
||||
|
@ -565,9 +559,8 @@ void BrowsingContext::set_viewport_rect(CSSPixelRect const& rect)
|
|||
did_change = true;
|
||||
}
|
||||
|
||||
if (did_change) {
|
||||
for (auto* client : m_viewport_clients)
|
||||
client->browsing_context_did_set_viewport_rect(rect);
|
||||
if (did_change && active_document()) {
|
||||
active_document()->inform_all_viewport_clients_about_the_current_viewport_rect();
|
||||
}
|
||||
|
||||
// Schedule the HTML event loop to ensure that a `resize` event gets fired.
|
||||
|
@ -585,8 +578,9 @@ void BrowsingContext::set_size(CSSPixelSize size)
|
|||
document->set_needs_layout();
|
||||
}
|
||||
|
||||
for (auto* client : m_viewport_clients)
|
||||
client->browsing_context_did_set_viewport_rect(viewport_rect());
|
||||
if (auto* document = active_document()) {
|
||||
document->inform_all_viewport_clients_about_the_current_viewport_rect();
|
||||
}
|
||||
|
||||
// Schedule the HTML event loop to ensure that a `resize` event gets fired.
|
||||
HTML::main_thread_event_loop().schedule();
|
||||
|
@ -752,18 +746,6 @@ void BrowsingContext::select_all()
|
|||
(void)selection->select_all_children(*document->body());
|
||||
}
|
||||
|
||||
void BrowsingContext::register_viewport_client(ViewportClient& client)
|
||||
{
|
||||
auto result = m_viewport_clients.set(&client);
|
||||
VERIFY(result == AK::HashSetResult::InsertedNewEntry);
|
||||
}
|
||||
|
||||
void BrowsingContext::unregister_viewport_client(ViewportClient& client)
|
||||
{
|
||||
bool was_removed = m_viewport_clients.remove(&client);
|
||||
VERIFY(was_removed);
|
||||
}
|
||||
|
||||
void BrowsingContext::register_frame_nesting(AK::URL const& url)
|
||||
{
|
||||
m_frame_nesting_levels.ensure(url)++;
|
||||
|
|
|
@ -118,14 +118,6 @@ public:
|
|||
return IterationDecision::Continue;
|
||||
}
|
||||
|
||||
class ViewportClient {
|
||||
public:
|
||||
virtual ~ViewportClient() = default;
|
||||
virtual void browsing_context_did_set_viewport_rect(CSSPixelRect const&) = 0;
|
||||
};
|
||||
void register_viewport_client(ViewportClient&);
|
||||
void unregister_viewport_client(ViewportClient&);
|
||||
|
||||
bool is_top_level() const;
|
||||
bool is_focused_context() const;
|
||||
|
||||
|
@ -277,8 +269,6 @@ public:
|
|||
virtual String const& window_handle() const override { return m_window_handle; }
|
||||
virtual void set_window_handle(String handle) override { m_window_handle = move(handle); }
|
||||
|
||||
void inform_all_viewport_clients_about_the_current_viewport_rect();
|
||||
|
||||
private:
|
||||
explicit BrowsingContext(Page&, HTML::NavigableContainer*);
|
||||
|
||||
|
@ -324,8 +314,6 @@ private:
|
|||
RefPtr<Core::Timer> m_cursor_blink_timer;
|
||||
bool m_cursor_blink_state { false };
|
||||
|
||||
HashTable<ViewportClient*> m_viewport_clients;
|
||||
|
||||
HashMap<AK::URL, size_t> m_frame_nesting_levels;
|
||||
DeprecatedString m_name;
|
||||
|
||||
|
|
|
@ -39,8 +39,7 @@ HTMLImageElement::HTMLImageElement(DOM::Document& document, DOM::QualifiedName q
|
|||
m_animation_timer = Core::Timer::try_create().release_value_but_fixme_should_propagate_errors();
|
||||
m_animation_timer->on_timeout = [this] { animate(); };
|
||||
|
||||
if (auto* browsing_context = document.browsing_context())
|
||||
browsing_context->register_viewport_client(*this);
|
||||
document.register_viewport_client(*this);
|
||||
}
|
||||
|
||||
HTMLImageElement::~HTMLImageElement() = default;
|
||||
|
@ -48,8 +47,7 @@ HTMLImageElement::~HTMLImageElement() = default;
|
|||
void HTMLImageElement::finalize()
|
||||
{
|
||||
Base::finalize();
|
||||
if (auto* browsing_context = document().browsing_context())
|
||||
browsing_context->unregister_viewport_client(*this);
|
||||
document().unregister_viewport_client(*this);
|
||||
}
|
||||
|
||||
void HTMLImageElement::initialize(JS::Realm& realm)
|
||||
|
@ -60,6 +58,12 @@ void HTMLImageElement::initialize(JS::Realm& realm)
|
|||
m_current_request = ImageRequest::create(realm, *document().page());
|
||||
}
|
||||
|
||||
void HTMLImageElement::adopted_from(DOM::Document& old_document)
|
||||
{
|
||||
old_document.unregister_viewport_client(*this);
|
||||
document().register_viewport_client(*this);
|
||||
}
|
||||
|
||||
void HTMLImageElement::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
|
@ -630,7 +634,7 @@ void HTMLImageElement::add_callbacks_to_image_request(JS::NonnullGCPtr<ImageRequ
|
|||
});
|
||||
}
|
||||
|
||||
void HTMLImageElement::browsing_context_did_set_viewport_rect(CSSPixelRect const& viewport_rect)
|
||||
void HTMLImageElement::did_set_viewport_rect(CSSPixelRect const& viewport_rect)
|
||||
{
|
||||
if (viewport_rect.size() == m_last_seen_viewport_size)
|
||||
return;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <AK/ByteBuffer.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <LibGfx/Forward.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/DocumentLoadEventDelayer.h>
|
||||
#include <LibWeb/HTML/BrowsingContext.h>
|
||||
#include <LibWeb/HTML/CORSSettingAttribute.h>
|
||||
|
@ -23,7 +24,7 @@ class HTMLImageElement final
|
|||
: public HTMLElement
|
||||
, public FormAssociatedElement
|
||||
, public Layout::ImageProvider
|
||||
, public BrowsingContext::ViewportClient {
|
||||
, public DOM::Document::ViewportClient {
|
||||
WEB_PLATFORM_OBJECT(HTMLImageElement, HTMLElement);
|
||||
FORM_ASSOCIATED_ELEMENT(HTMLElement, HTMLImageElement)
|
||||
|
||||
|
@ -99,11 +100,13 @@ private:
|
|||
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;
|
||||
|
||||
virtual JS::GCPtr<Layout::Node> create_layout_node(NonnullRefPtr<CSS::StyleProperties>) override;
|
||||
|
||||
virtual void browsing_context_did_set_viewport_rect(CSSPixelRect const&) override;
|
||||
virtual void did_set_viewport_rect(CSSPixelRect const&) override;
|
||||
|
||||
void handle_successful_fetch(AK::URL const&, StringView mime_type, ImageRequest&, ByteBuffer, bool maybe_omit_events, AK::URL const& previous_url);
|
||||
void handle_failed_fetch();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue