mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 22:27:42 +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
8 changed files with 65 additions and 30 deletions
|
@ -23,13 +23,25 @@
|
||||||
|
|
||||||
namespace Web {
|
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)
|
: m_client(client)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Page::~Page() = default;
|
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()
|
HTML::BrowsingContext& Page::focused_context()
|
||||||
{
|
{
|
||||||
if (m_focused_context)
|
if (m_focused_context)
|
||||||
|
@ -56,13 +68,13 @@ void Page::load_html(StringView html)
|
||||||
|
|
||||||
Gfx::Palette Page::palette() const
|
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
|
// https://w3c.github.io/csswg-drafts/cssom-view-1/#web-exposed-screen-area
|
||||||
CSSPixelRect Page::web_exposed_screen_area() const
|
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();
|
auto scale = client().device_pixels_per_css_pixel();
|
||||||
return {
|
return {
|
||||||
device_pixel_rect.x().value() / scale,
|
device_pixel_rect.x().value() / scale,
|
||||||
|
@ -74,7 +86,7 @@ CSSPixelRect Page::web_exposed_screen_area() const
|
||||||
|
|
||||||
CSS::PreferredColorScheme Page::preferred_color_scheme() 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
|
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)
|
void Page::did_request_alert(String const& message)
|
||||||
{
|
{
|
||||||
m_pending_dialog = PendingDialog::Alert;
|
m_pending_dialog = PendingDialog::Alert;
|
||||||
m_client.page_did_request_alert(message);
|
m_client->page_did_request_alert(message);
|
||||||
|
|
||||||
if (!message.is_empty())
|
if (!message.is_empty())
|
||||||
m_pending_dialog_text = message;
|
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()
|
void Page::alert_closed()
|
||||||
|
@ -230,12 +242,12 @@ void Page::alert_closed()
|
||||||
bool Page::did_request_confirm(String const& message)
|
bool Page::did_request_confirm(String const& message)
|
||||||
{
|
{
|
||||||
m_pending_dialog = PendingDialog::Confirm;
|
m_pending_dialog = PendingDialog::Confirm;
|
||||||
m_client.page_did_request_confirm(message);
|
m_client->page_did_request_confirm(message);
|
||||||
|
|
||||||
if (!message.is_empty())
|
if (!message.is_empty())
|
||||||
m_pending_dialog_text = message;
|
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)
|
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_)
|
Optional<String> Page::did_request_prompt(String const& message, String const& default_)
|
||||||
{
|
{
|
||||||
m_pending_dialog = PendingDialog::Prompt;
|
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())
|
if (!message.is_empty())
|
||||||
m_pending_dialog_text = message;
|
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)
|
void Page::prompt_closed(Optional<String> response)
|
||||||
|
@ -273,11 +285,11 @@ void Page::dismiss_dialog()
|
||||||
case PendingDialog::None:
|
case PendingDialog::None:
|
||||||
break;
|
break;
|
||||||
case PendingDialog::Alert:
|
case PendingDialog::Alert:
|
||||||
m_client.page_did_request_accept_dialog();
|
m_client->page_did_request_accept_dialog();
|
||||||
break;
|
break;
|
||||||
case PendingDialog::Confirm:
|
case PendingDialog::Confirm:
|
||||||
case PendingDialog::Prompt:
|
case PendingDialog::Prompt:
|
||||||
m_client.page_did_request_dismiss_dialog();
|
m_client->page_did_request_dismiss_dialog();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,7 +302,7 @@ void Page::accept_dialog()
|
||||||
case PendingDialog::Alert:
|
case PendingDialog::Alert:
|
||||||
case PendingDialog::Confirm:
|
case PendingDialog::Confirm:
|
||||||
case PendingDialog::Prompt:
|
case PendingDialog::Prompt:
|
||||||
m_client.page_did_request_accept_dialog();
|
m_client->page_did_request_accept_dialog();
|
||||||
break;
|
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 = PendingNonBlockingDialog::ColorPicker;
|
||||||
m_pending_non_blocking_dialog_target = move(target);
|
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) 2021-2022, Linus Groh <linusg@serenityos.org>
|
||||||
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
|
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
|
||||||
|
* Copyright (c) 2023, Shannon Booth <shannon@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -36,12 +37,14 @@ namespace Web {
|
||||||
|
|
||||||
class PageClient;
|
class PageClient;
|
||||||
|
|
||||||
class Page : public Weakable<Page> {
|
class Page final
|
||||||
AK_MAKE_NONCOPYABLE(Page);
|
: public JS::Cell
|
||||||
AK_MAKE_NONMOVABLE(Page);
|
, public Weakable<Page> {
|
||||||
|
JS_CELL(Page, JS::Cell);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Page(PageClient&);
|
static JS::NonnullGCPtr<Page> create(JS::VM&, JS::NonnullGCPtr<PageClient>);
|
||||||
|
|
||||||
~Page();
|
~Page();
|
||||||
|
|
||||||
PageClient& client() { return m_client; }
|
PageClient& client() { return m_client; }
|
||||||
|
@ -152,13 +155,16 @@ public:
|
||||||
bool pdf_viewer_supported() const { return m_pdf_viewer_supported; }
|
bool pdf_viewer_supported() const { return m_pdf_viewer_supported; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
explicit Page(JS::NonnullGCPtr<PageClient>);
|
||||||
|
virtual void visit_edges(Visitor&) override;
|
||||||
|
|
||||||
JS::GCPtr<HTML::HTMLMediaElement> media_context_menu_element();
|
JS::GCPtr<HTML::HTMLMediaElement> media_context_menu_element();
|
||||||
|
|
||||||
PageClient& m_client;
|
JS::NonnullGCPtr<PageClient> m_client;
|
||||||
|
|
||||||
WeakPtr<HTML::BrowsingContext> m_focused_context;
|
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.
|
// FIXME: Enable this by default once CORS preflight checks are supported.
|
||||||
bool m_same_origin_policy_enabled { false };
|
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)
|
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_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_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"))));
|
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();
|
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));
|
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(move(page))
|
||||||
, m_page_client(move(page_client))
|
, m_page_client(move(page_client))
|
||||||
, m_document(move(document))
|
, m_document(move(document))
|
||||||
|
|
|
@ -32,12 +32,12 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class SVGPageClient;
|
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;
|
RefPtr<Gfx::Bitmap> render(Gfx::IntSize) const;
|
||||||
mutable RefPtr<Gfx::ImmutableBitmap> m_immutable_bitmap;
|
mutable RefPtr<Gfx::ImmutableBitmap> m_immutable_bitmap;
|
||||||
|
|
||||||
NonnullOwnPtr<Page> m_page;
|
JS::Handle<Page> m_page;
|
||||||
JS::Handle<SVGPageClient> m_page_client;
|
JS::Handle<SVGPageClient> m_page_client;
|
||||||
|
|
||||||
JS::Handle<DOM::Document> m_document;
|
JS::Handle<DOM::Document> m_document;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <LibGfx/ShareableBitmap.h>
|
#include <LibGfx/ShareableBitmap.h>
|
||||||
#include <LibGfx/SystemTheme.h>
|
#include <LibGfx/SystemTheme.h>
|
||||||
|
#include <LibWeb/Bindings/MainThreadVM.h>
|
||||||
#include <LibWeb/CSS/SystemColor.h>
|
#include <LibWeb/CSS/SystemColor.h>
|
||||||
#include <LibWeb/Cookie/ParsedCookie.h>
|
#include <LibWeb/Cookie/ParsedCookie.h>
|
||||||
#include <LibWeb/DOM/Attr.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)
|
PageClient::PageClient(PageHost& owner, u64 id)
|
||||||
: m_owner(owner)
|
: m_owner(owner)
|
||||||
, m_page(make<Web::Page>(*this))
|
, m_page(Web::Page::create(Web::Bindings::main_thread_vm(), *this))
|
||||||
, m_id(id)
|
, m_id(id)
|
||||||
{
|
{
|
||||||
setup_palette();
|
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
|
ConnectionFromClient& PageClient::client() const
|
||||||
{
|
{
|
||||||
return m_owner.client();
|
return m_owner.client();
|
||||||
|
|
|
@ -61,6 +61,8 @@ public:
|
||||||
private:
|
private:
|
||||||
PageClient(PageHost&, u64 id);
|
PageClient(PageHost&, u64 id);
|
||||||
|
|
||||||
|
virtual void visit_edges(JS::Cell::Visitor&) override;
|
||||||
|
|
||||||
// ^PageClient
|
// ^PageClient
|
||||||
virtual bool is_connection_open() const override;
|
virtual bool is_connection_open() const override;
|
||||||
virtual Gfx::Palette palette() const override;
|
virtual Gfx::Palette palette() const override;
|
||||||
|
@ -131,7 +133,7 @@ private:
|
||||||
ConnectionFromClient& client() const;
|
ConnectionFromClient& client() const;
|
||||||
|
|
||||||
PageHost& m_owner;
|
PageHost& m_owner;
|
||||||
NonnullOwnPtr<Web::Page> m_page;
|
JS::NonnullGCPtr<Web::Page> m_page;
|
||||||
RefPtr<Gfx::PaletteImpl> m_palette_impl;
|
RefPtr<Gfx::PaletteImpl> m_palette_impl;
|
||||||
Web::DevicePixelRect m_screen_rect;
|
Web::DevicePixelRect m_screen_rect;
|
||||||
Web::DevicePixelSize m_content_size;
|
Web::DevicePixelSize m_content_size;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <LibJS/Runtime/VM.h>
|
#include <LibJS/Runtime/VM.h>
|
||||||
|
#include <LibWeb/Bindings/MainThreadVM.h>
|
||||||
#include <WebWorker/ConnectionFromClient.h>
|
#include <WebWorker/ConnectionFromClient.h>
|
||||||
#include <WebWorker/PageHost.h>
|
#include <WebWorker/PageHost.h>
|
||||||
|
|
||||||
|
@ -75,9 +76,15 @@ void PageHost::request_file(Web::FileRequest request)
|
||||||
|
|
||||||
PageHost::PageHost(ConnectionFromClient& client)
|
PageHost::PageHost(ConnectionFromClient& client)
|
||||||
: m_client(client)
|
: m_client(client)
|
||||||
, m_page(make<Web::Page>(*this))
|
, m_page(Web::Page::create(Web::Bindings::main_thread_vm(), *this))
|
||||||
{
|
{
|
||||||
setup_palette();
|
setup_palette();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PageHost::visit_edges(JS::Cell::Visitor& visitor)
|
||||||
|
{
|
||||||
|
Base::visit_edges(visitor);
|
||||||
|
visitor.visit(m_page);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,11 +33,12 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit PageHost(ConnectionFromClient&);
|
explicit PageHost(ConnectionFromClient&);
|
||||||
|
virtual void visit_edges(JS::Cell::Visitor&) override;
|
||||||
|
|
||||||
void setup_palette();
|
void setup_palette();
|
||||||
|
|
||||||
ConnectionFromClient& m_client;
|
ConnectionFromClient& m_client;
|
||||||
NonnullOwnPtr<Web::Page> m_page;
|
JS::NonnullGCPtr<Web::Page> m_page;
|
||||||
RefPtr<Gfx::PaletteImpl> m_palette_impl;
|
RefPtr<Gfx::PaletteImpl> m_palette_impl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue