mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-29 08:11:13 +00:00
LibWeb: Make Web::Page GC-allocated
This is a first step towards removing the various Page& and Page* we have littering the engine with "trust me bro" safety guarantees. Co-Authored-By: Andreas Kling <kling@serenityos.org>
This commit is contained in:
parent
6e6f3a9a8f
commit
0ae5c070c7
Notes:
sideshowbarker
2024-07-17 02:29:45 +09:00
Author: https://github.com/shannonbooth Commit: https://github.com/SerenityOS/serenity/commit/0ae5c070c7 Pull-request: https://github.com/SerenityOS/serenity/pull/22142 Issue: https://github.com/SerenityOS/serenity/issues/22091
|
@ -23,13 +23,25 @@
|
|||
|
||||
namespace Web {
|
||||
|
||||
Page::Page(PageClient& client)
|
||||
JS::NonnullGCPtr<Page> Page::create(JS::VM& vm, JS::NonnullGCPtr<PageClient> page_client)
|
||||
{
|
||||
return vm.heap().allocate_without_realm<Page>(page_client);
|
||||
}
|
||||
|
||||
Page::Page(JS::NonnullGCPtr<PageClient> client)
|
||||
: m_client(client)
|
||||
{
|
||||
}
|
||||
|
||||
Page::~Page() = default;
|
||||
|
||||
void Page::visit_edges(JS::Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_top_level_traversable);
|
||||
visitor.visit(m_client);
|
||||
}
|
||||
|
||||
HTML::BrowsingContext& Page::focused_context()
|
||||
{
|
||||
if (m_focused_context)
|
||||
|
@ -56,13 +68,13 @@ void Page::load_html(StringView html)
|
|||
|
||||
Gfx::Palette Page::palette() const
|
||||
{
|
||||
return m_client.palette();
|
||||
return m_client->palette();
|
||||
}
|
||||
|
||||
// https://w3c.github.io/csswg-drafts/cssom-view-1/#web-exposed-screen-area
|
||||
CSSPixelRect Page::web_exposed_screen_area() const
|
||||
{
|
||||
auto device_pixel_rect = m_client.screen_rect();
|
||||
auto device_pixel_rect = m_client->screen_rect();
|
||||
auto scale = client().device_pixels_per_css_pixel();
|
||||
return {
|
||||
device_pixel_rect.x().value() / scale,
|
||||
|
@ -74,7 +86,7 @@ CSSPixelRect Page::web_exposed_screen_area() const
|
|||
|
||||
CSS::PreferredColorScheme Page::preferred_color_scheme() const
|
||||
{
|
||||
return m_client.preferred_color_scheme();
|
||||
return m_client->preferred_color_scheme();
|
||||
}
|
||||
|
||||
CSSPixelPoint Page::device_to_css_point(DevicePixelPoint point) const
|
||||
|
@ -210,12 +222,12 @@ static ResponseType spin_event_loop_until_dialog_closed(PageClient& client, Opti
|
|||
void Page::did_request_alert(String const& message)
|
||||
{
|
||||
m_pending_dialog = PendingDialog::Alert;
|
||||
m_client.page_did_request_alert(message);
|
||||
m_client->page_did_request_alert(message);
|
||||
|
||||
if (!message.is_empty())
|
||||
m_pending_dialog_text = message;
|
||||
|
||||
spin_event_loop_until_dialog_closed(m_client, m_pending_alert_response);
|
||||
spin_event_loop_until_dialog_closed(*m_client, m_pending_alert_response);
|
||||
}
|
||||
|
||||
void Page::alert_closed()
|
||||
|
@ -230,12 +242,12 @@ void Page::alert_closed()
|
|||
bool Page::did_request_confirm(String const& message)
|
||||
{
|
||||
m_pending_dialog = PendingDialog::Confirm;
|
||||
m_client.page_did_request_confirm(message);
|
||||
m_client->page_did_request_confirm(message);
|
||||
|
||||
if (!message.is_empty())
|
||||
m_pending_dialog_text = message;
|
||||
|
||||
return spin_event_loop_until_dialog_closed(m_client, m_pending_confirm_response);
|
||||
return spin_event_loop_until_dialog_closed(*m_client, m_pending_confirm_response);
|
||||
}
|
||||
|
||||
void Page::confirm_closed(bool accepted)
|
||||
|
@ -250,12 +262,12 @@ void Page::confirm_closed(bool accepted)
|
|||
Optional<String> Page::did_request_prompt(String const& message, String const& default_)
|
||||
{
|
||||
m_pending_dialog = PendingDialog::Prompt;
|
||||
m_client.page_did_request_prompt(message, default_);
|
||||
m_client->page_did_request_prompt(message, default_);
|
||||
|
||||
if (!message.is_empty())
|
||||
m_pending_dialog_text = message;
|
||||
|
||||
return spin_event_loop_until_dialog_closed(m_client, m_pending_prompt_response);
|
||||
return spin_event_loop_until_dialog_closed(*m_client, m_pending_prompt_response);
|
||||
}
|
||||
|
||||
void Page::prompt_closed(Optional<String> response)
|
||||
|
@ -273,11 +285,11 @@ void Page::dismiss_dialog()
|
|||
case PendingDialog::None:
|
||||
break;
|
||||
case PendingDialog::Alert:
|
||||
m_client.page_did_request_accept_dialog();
|
||||
m_client->page_did_request_accept_dialog();
|
||||
break;
|
||||
case PendingDialog::Confirm:
|
||||
case PendingDialog::Prompt:
|
||||
m_client.page_did_request_dismiss_dialog();
|
||||
m_client->page_did_request_dismiss_dialog();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -290,7 +302,7 @@ void Page::accept_dialog()
|
|||
case PendingDialog::Alert:
|
||||
case PendingDialog::Confirm:
|
||||
case PendingDialog::Prompt:
|
||||
m_client.page_did_request_accept_dialog();
|
||||
m_client->page_did_request_accept_dialog();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -301,7 +313,7 @@ void Page::did_request_color_picker(WeakPtr<HTML::HTMLInputElement> target, Colo
|
|||
m_pending_non_blocking_dialog = PendingNonBlockingDialog::ColorPicker;
|
||||
m_pending_non_blocking_dialog_target = move(target);
|
||||
|
||||
m_client.page_did_request_color_picker(current_color);
|
||||
m_client->page_did_request_color_picker(current_color);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2020-2023, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
|
||||
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
|
||||
* Copyright (c) 2023, Shannon Booth <shannon@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -36,12 +37,14 @@ namespace Web {
|
|||
|
||||
class PageClient;
|
||||
|
||||
class Page : public Weakable<Page> {
|
||||
AK_MAKE_NONCOPYABLE(Page);
|
||||
AK_MAKE_NONMOVABLE(Page);
|
||||
class Page final
|
||||
: public JS::Cell
|
||||
, public Weakable<Page> {
|
||||
JS_CELL(Page, JS::Cell);
|
||||
|
||||
public:
|
||||
explicit Page(PageClient&);
|
||||
static JS::NonnullGCPtr<Page> create(JS::VM&, JS::NonnullGCPtr<PageClient>);
|
||||
|
||||
~Page();
|
||||
|
||||
PageClient& client() { return m_client; }
|
||||
|
@ -152,13 +155,16 @@ public:
|
|||
bool pdf_viewer_supported() const { return m_pdf_viewer_supported; }
|
||||
|
||||
private:
|
||||
explicit Page(JS::NonnullGCPtr<PageClient>);
|
||||
virtual void visit_edges(Visitor&) override;
|
||||
|
||||
JS::GCPtr<HTML::HTMLMediaElement> media_context_menu_element();
|
||||
|
||||
PageClient& m_client;
|
||||
JS::NonnullGCPtr<PageClient> m_client;
|
||||
|
||||
WeakPtr<HTML::BrowsingContext> m_focused_context;
|
||||
|
||||
JS::Handle<HTML::TraversableNavigable> m_top_level_traversable;
|
||||
JS::GCPtr<HTML::TraversableNavigable> m_top_level_traversable;
|
||||
|
||||
// FIXME: Enable this by default once CORS preflight checks are supported.
|
||||
bool m_same_origin_policy_enabled { false };
|
||||
|
|
|
@ -57,7 +57,7 @@ private:
|
|||
ErrorOr<NonnullRefPtr<SVGDecodedImageData>> SVGDecodedImageData::create(Page& host_page, AK::URL const& url, ByteBuffer data)
|
||||
{
|
||||
auto page_client = SVGPageClient::create(Bindings::main_thread_vm(), host_page);
|
||||
auto page = make<Page>(*page_client);
|
||||
auto page = Page::create(Bindings::main_thread_vm(), *page_client);
|
||||
page_client->m_svg_page = page.ptr();
|
||||
page->set_top_level_traversable(MUST(Web::HTML::TraversableNavigable::create_a_fresh_top_level_traversable(*page, AK::URL("about:blank"))));
|
||||
JS::NonnullGCPtr<HTML::Navigable> navigable = page->top_level_traversable();
|
||||
|
@ -98,10 +98,10 @@ ErrorOr<NonnullRefPtr<SVGDecodedImageData>> SVGDecodedImageData::create(Page& ho
|
|||
|
||||
MUST(document->append_child(*svg_root));
|
||||
|
||||
return adopt_nonnull_ref_or_enomem(new (nothrow) SVGDecodedImageData(move(page), move(page_client), move(document), move(svg_root)));
|
||||
return adopt_nonnull_ref_or_enomem(new (nothrow) SVGDecodedImageData(page, move(page_client), move(document), move(svg_root)));
|
||||
}
|
||||
|
||||
SVGDecodedImageData::SVGDecodedImageData(NonnullOwnPtr<Page> page, JS::Handle<SVGPageClient> page_client, JS::Handle<DOM::Document> document, JS::Handle<SVG::SVGSVGElement> root_element)
|
||||
SVGDecodedImageData::SVGDecodedImageData(JS::NonnullGCPtr<Page> page, JS::Handle<SVGPageClient> page_client, JS::Handle<DOM::Document> document, JS::Handle<SVG::SVGSVGElement> root_element)
|
||||
: m_page(move(page))
|
||||
, m_page_client(move(page_client))
|
||||
, m_document(move(document))
|
||||
|
|
|
@ -32,12 +32,12 @@ public:
|
|||
|
||||
private:
|
||||
class SVGPageClient;
|
||||
SVGDecodedImageData(NonnullOwnPtr<Page>, JS::Handle<SVGPageClient>, JS::Handle<DOM::Document>, JS::Handle<SVG::SVGSVGElement>);
|
||||
SVGDecodedImageData(JS::NonnullGCPtr<Page>, JS::Handle<SVGPageClient>, JS::Handle<DOM::Document>, JS::Handle<SVG::SVGSVGElement>);
|
||||
|
||||
RefPtr<Gfx::Bitmap> render(Gfx::IntSize) const;
|
||||
mutable RefPtr<Gfx::ImmutableBitmap> m_immutable_bitmap;
|
||||
|
||||
NonnullOwnPtr<Page> m_page;
|
||||
JS::Handle<Page> m_page;
|
||||
JS::Handle<SVGPageClient> m_page_client;
|
||||
|
||||
JS::Handle<DOM::Document> m_document;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <LibGfx/ShareableBitmap.h>
|
||||
#include <LibGfx/SystemTheme.h>
|
||||
#include <LibWeb/Bindings/MainThreadVM.h>
|
||||
#include <LibWeb/CSS/SystemColor.h>
|
||||
#include <LibWeb/Cookie/ParsedCookie.h>
|
||||
#include <LibWeb/DOM/Attr.h>
|
||||
|
@ -46,7 +47,7 @@ JS::NonnullGCPtr<PageClient> PageClient::create(JS::VM& vm, PageHost& page_host,
|
|||
|
||||
PageClient::PageClient(PageHost& owner, u64 id)
|
||||
: m_owner(owner)
|
||||
, m_page(make<Web::Page>(*this))
|
||||
, m_page(Web::Page::create(Web::Bindings::main_thread_vm(), *this))
|
||||
, m_id(id)
|
||||
{
|
||||
setup_palette();
|
||||
|
@ -56,6 +57,12 @@ PageClient::PageClient(PageHost& owner, u64 id)
|
|||
});
|
||||
}
|
||||
|
||||
void PageClient::visit_edges(JS::Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_page);
|
||||
}
|
||||
|
||||
ConnectionFromClient& PageClient::client() const
|
||||
{
|
||||
return m_owner.client();
|
||||
|
|
|
@ -61,6 +61,8 @@ public:
|
|||
private:
|
||||
PageClient(PageHost&, u64 id);
|
||||
|
||||
virtual void visit_edges(JS::Cell::Visitor&) override;
|
||||
|
||||
// ^PageClient
|
||||
virtual bool is_connection_open() const override;
|
||||
virtual Gfx::Palette palette() const override;
|
||||
|
@ -131,7 +133,7 @@ private:
|
|||
ConnectionFromClient& client() const;
|
||||
|
||||
PageHost& m_owner;
|
||||
NonnullOwnPtr<Web::Page> m_page;
|
||||
JS::NonnullGCPtr<Web::Page> m_page;
|
||||
RefPtr<Gfx::PaletteImpl> m_palette_impl;
|
||||
Web::DevicePixelRect m_screen_rect;
|
||||
Web::DevicePixelSize m_content_size;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <LibJS/Runtime/VM.h>
|
||||
#include <LibWeb/Bindings/MainThreadVM.h>
|
||||
#include <WebWorker/ConnectionFromClient.h>
|
||||
#include <WebWorker/PageHost.h>
|
||||
|
||||
|
@ -75,9 +76,15 @@ void PageHost::request_file(Web::FileRequest request)
|
|||
|
||||
PageHost::PageHost(ConnectionFromClient& client)
|
||||
: m_client(client)
|
||||
, m_page(make<Web::Page>(*this))
|
||||
, m_page(Web::Page::create(Web::Bindings::main_thread_vm(), *this))
|
||||
{
|
||||
setup_palette();
|
||||
}
|
||||
|
||||
void PageHost::visit_edges(JS::Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_page);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,11 +33,12 @@ public:
|
|||
|
||||
private:
|
||||
explicit PageHost(ConnectionFromClient&);
|
||||
virtual void visit_edges(JS::Cell::Visitor&) override;
|
||||
|
||||
void setup_palette();
|
||||
|
||||
ConnectionFromClient& m_client;
|
||||
NonnullOwnPtr<Web::Page> m_page;
|
||||
JS::NonnullGCPtr<Web::Page> m_page;
|
||||
RefPtr<Gfx::PaletteImpl> m_palette_impl;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue