1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 10:38:11 +00:00

LibWeb: Make Document::page() return a Page&

Now that Document always has a Page, and always keeps it alive, we can
make this return a Page&, exposing various unnecessary null checks.
This commit is contained in:
Andreas Kling 2023-12-15 15:41:28 +01:00
parent 70193c0009
commit 7c95ebc302
17 changed files with 43 additions and 78 deletions

View file

@ -33,7 +33,7 @@ CSSImportRule::CSSImportRule(AK::URL url, DOM::Document& document)
, m_document(document) , m_document(document)
{ {
dbgln_if(CSS_LOADER_DEBUG, "CSSImportRule: Loading import URL: {}", m_url); dbgln_if(CSS_LOADER_DEBUG, "CSSImportRule: Loading import URL: {}", m_url);
auto request = LoadRequest::create_for_url_on_page(m_url, document.page()); auto request = LoadRequest::create_for_url_on_page(m_url, &document.page());
// NOTE: Mark this rule as delaying the document load event *before* calling set_resource() // NOTE: Mark this rule as delaying the document load event *before* calling set_resource()
// as it may trigger a synchronous resource_did_load() callback. // as it may trigger a synchronous resource_did_load() callback.

View file

@ -2334,11 +2334,8 @@ NonnullOwnPtr<StyleComputer::RuleCache> StyleComputer::make_rule_cache_for_casca
void StyleComputer::build_rule_cache() void StyleComputer::build_rule_cache()
{ {
// FIXME: How are we sometimes calculating style before the Document has a Page? if (auto user_style_source = document().page().user_style(); user_style_source.has_value()) {
if (document().page()) { m_user_style_sheet = JS::make_handle(parse_css_stylesheet(CSS::Parser::ParsingContext(document()), user_style_source.value()));
if (auto user_style_source = document().page()->user_style(); user_style_source.has_value()) {
m_user_style_sheet = JS::make_handle(parse_css_stylesheet(CSS::Parser::ParsingContext(document()), user_style_source.value()));
}
} }
m_author_rule_cache = make_rule_cache_for_cascade_origin(CascadeOrigin::Author); m_author_rule_cache = make_rule_cache_for_cascade_origin(CascadeOrigin::Author);

View file

@ -217,10 +217,7 @@ Color IdentifierStyleValue::to_color(Optional<Layout::NodeWithStyle const&> node
if (id() == CSS::ValueID::LibwebLink || id() == ValueID::Linktext) if (id() == CSS::ValueID::LibwebLink || id() == ValueID::Linktext)
return document.link_color(); return document.link_color();
if (!document.page()) auto palette = document.page().palette();
return {};
auto palette = document.page()->palette();
switch (id()) { switch (id()) {
case CSS::ValueID::LibwebPaletteDesktopBackground: case CSS::ValueID::LibwebPaletteDesktopBackground:
return palette.color(ColorRole::DesktopBackground); return palette.color(ColorRole::DesktopBackground);

View file

@ -32,7 +32,7 @@ void ImageStyleValue::load_any_resources(DOM::Document& document)
return; return;
m_document = &document; m_document = &document;
m_image_request = HTML::SharedImageRequest::get_or_create(document.realm(), *document.page(), m_url); m_image_request = HTML::SharedImageRequest::get_or_create(document.realm(), document.page(), m_url);
m_image_request->add_callbacks( m_image_request->add_callbacks(
[this, weak_this = make_weak_ptr()] { [this, weak_this = make_weak_ptr()] {
if (!weak_this) if (!weak_this)

View file

@ -803,10 +803,8 @@ WebIDL::ExceptionOr<void> Document::set_title(String const& title)
return {}; return {};
} }
if (auto* page = this->page()) { if (browsing_context() == &page().top_level_browsing_context())
if (browsing_context() == &page->top_level_browsing_context()) page().client().page_did_change_title(title.to_deprecated_string());
page->client().page_did_change_title(title.to_deprecated_string());
}
return {}; return {};
} }
@ -1040,8 +1038,7 @@ void Document::update_layout()
navigable()->set_needs_display(); navigable()->set_needs_display();
if (navigable()->is_traversable()) { if (navigable()->is_traversable()) {
if (auto* page = this->page()) page().client().page_did_layout();
page->client().page_did_layout();
} }
m_layout_root->recompute_selection_states(); m_layout_root->recompute_selection_states();
@ -1909,12 +1906,12 @@ void Document::update_readiness(HTML::DocumentReadyState readiness_value)
} }
} }
Page* Document::page() Page& Document::page()
{ {
return m_page; return m_page;
} }
Page const* Document::page() const Page const& Document::page() const
{ {
return m_page; return m_page;
} }
@ -1977,9 +1974,7 @@ void Document::completely_finish_loading()
String Document::cookie(Cookie::Source source) String Document::cookie(Cookie::Source source)
{ {
if (auto* page = this->page()) return MUST(String::from_deprecated_string(page().client().page_did_request_cookie(m_url, source)));
return MUST(String::from_deprecated_string(page->client().page_did_request_cookie(m_url, source)));
return String {};
} }
void Document::set_cookie(StringView cookie_string, Cookie::Source source) void Document::set_cookie(StringView cookie_string, Cookie::Source source)
@ -1988,8 +1983,7 @@ void Document::set_cookie(StringView cookie_string, Cookie::Source source)
if (!cookie.has_value()) if (!cookie.has_value())
return; return;
if (auto* page = this->page()) page().client().page_did_set_cookie(m_url, cookie.value(), source);
page->client().page_did_set_cookie(m_url, cookie.value(), source);
} }
String Document::dump_dom_tree_as_json() const String Document::dump_dom_tree_as_json() const
@ -2372,8 +2366,7 @@ void Document::increment_number_of_things_delaying_the_load_event(Badge<Document
{ {
++m_number_of_things_delaying_the_load_event; ++m_number_of_things_delaying_the_load_event;
if (auto* page = this->page()) page().client().page_did_update_resource_count(m_number_of_things_delaying_the_load_event);
page->client().page_did_update_resource_count(m_number_of_things_delaying_the_load_event);
} }
void Document::decrement_number_of_things_delaying_the_load_event(Badge<DocumentLoadEventDelayer>) void Document::decrement_number_of_things_delaying_the_load_event(Badge<DocumentLoadEventDelayer>)
@ -2381,8 +2374,7 @@ void Document::decrement_number_of_things_delaying_the_load_event(Badge<Document
VERIFY(m_number_of_things_delaying_the_load_event); VERIFY(m_number_of_things_delaying_the_load_event);
--m_number_of_things_delaying_the_load_event; --m_number_of_things_delaying_the_load_event;
if (auto* page = this->page()) page().client().page_did_update_resource_count(m_number_of_things_delaying_the_load_event);
page->client().page_did_update_resource_count(m_number_of_things_delaying_the_load_event);
} }
bool Document::anything_is_delaying_the_load_event() const bool Document::anything_is_delaying_the_load_event() const
@ -2726,7 +2718,7 @@ void Document::run_unloading_cleanup_steps()
// https://html.spec.whatwg.org/multipage/document-lifecycle.html#destroy-a-document // https://html.spec.whatwg.org/multipage/document-lifecycle.html#destroy-a-document
void Document::destroy() void Document::destroy()
{ {
page()->client().page_did_destroy_document(*this); page().client().page_did_destroy_document(*this);
// NOTE: Abort needs to happen before destory. There is currently bug in the spec: https://github.com/whatwg/html/issues/9148 // NOTE: Abort needs to happen before destory. There is currently bug in the spec: https://github.com/whatwg/html/issues/9148
// 4. Abort document. // 4. Abort document.

View file

@ -181,8 +181,8 @@ public:
void set_browsing_context(HTML::BrowsingContext*); void set_browsing_context(HTML::BrowsingContext*);
Page* page(); Page& page();
Page const* page() const; Page const& page() const;
Color background_color() const; Color background_color() const;
Vector<CSS::BackgroundLayerData> const* background_layers() const; Vector<CSS::BackgroundLayerData> const* background_layers() const;

View file

@ -1188,22 +1188,16 @@ void Element::set_scroll_left(double x)
// 8. If the element is the root element invoke scroll() on window with x as first argument and scrollY on window as second argument, and terminate these steps. // 8. If the element is the root element invoke scroll() on window with x as first argument and scrollY on window as second argument, and terminate these steps.
if (document.document_element() == this) { if (document.document_element() == this) {
// FIXME: Implement this in terms of invoking scroll() on window. // FIXME: Implement this in terms of invoking scroll() on window.
if (auto* page = document.page()) { if (document.browsing_context() == &document.page().top_level_browsing_context())
if (document.browsing_context() == &page->top_level_browsing_context()) document.page().client().page_did_request_scroll_to({ static_cast<float>(x), static_cast<float>(window->scroll_y()) });
page->client().page_did_request_scroll_to({ static_cast<float>(x), static_cast<float>(window->scroll_y()) });
}
return; return;
} }
// 9. If the element is the body element, document is in quirks mode, and the element is not potentially scrollable, invoke scroll() on window with x as first argument and scrollY on window as second argument, and terminate these steps. // 9. If the element is the body element, document is in quirks mode, and the element is not potentially scrollable, invoke scroll() on window with x as first argument and scrollY on window as second argument, and terminate these steps.
if (document.body() == this && document.in_quirks_mode() && !is_potentially_scrollable()) { if (document.body() == this && document.in_quirks_mode() && !is_potentially_scrollable()) {
// FIXME: Implement this in terms of invoking scroll() on window. // FIXME: Implement this in terms of invoking scroll() on window.
if (auto* page = document.page()) { if (document.browsing_context() == &document.page().top_level_browsing_context())
if (document.browsing_context() == &page->top_level_browsing_context()) document.page().client().page_did_request_scroll_to({ static_cast<float>(x), static_cast<float>(window->scroll_y()) });
page->client().page_did_request_scroll_to({ static_cast<float>(x), static_cast<float>(window->scroll_y()) });
}
return; return;
} }
@ -1256,22 +1250,16 @@ void Element::set_scroll_top(double y)
// 8. If the element is the root element invoke scroll() on window with scrollX on window as first argument and y as second argument, and terminate these steps. // 8. If the element is the root element invoke scroll() on window with scrollX on window as first argument and y as second argument, and terminate these steps.
if (document.document_element() == this) { if (document.document_element() == this) {
// FIXME: Implement this in terms of invoking scroll() on window. // FIXME: Implement this in terms of invoking scroll() on window.
if (auto* page = document.page()) { if (document.browsing_context() == &document.page().top_level_browsing_context())
if (document.browsing_context() == &page->top_level_browsing_context()) document.page().client().page_did_request_scroll_to({ static_cast<float>(window->scroll_x()), static_cast<float>(y) });
page->client().page_did_request_scroll_to({ static_cast<float>(window->scroll_x()), static_cast<float>(y) });
}
return; return;
} }
// 9. If the element is the body element, document is in quirks mode, and the element is not potentially scrollable, invoke scroll() on window with scrollX as first argument and y as second argument, and terminate these steps. // 9. If the element is the body element, document is in quirks mode, and the element is not potentially scrollable, invoke scroll() on window with scrollX as first argument and y as second argument, and terminate these steps.
if (document.body() == this && document.in_quirks_mode() && !is_potentially_scrollable()) { if (document.body() == this && document.in_quirks_mode() && !is_potentially_scrollable()) {
// FIXME: Implement this in terms of invoking scroll() on window. // FIXME: Implement this in terms of invoking scroll() on window.
if (auto* page = document.page()) { if (document.browsing_context() == &document.page().top_level_browsing_context())
if (document.browsing_context() == &page->top_level_browsing_context()) document.page().client().page_did_request_scroll_to({ static_cast<float>(window->scroll_x()), static_cast<float>(y) });
page->client().page_did_request_scroll_to({ static_cast<float>(window->scroll_x()), static_cast<float>(y) });
}
return; return;
} }

View file

@ -1425,10 +1425,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_network_or_cache_fet
auto document = Bindings::host_defined_environment_settings_object(realm).responsible_document(); auto document = Bindings::host_defined_environment_settings_object(realm).responsible_document();
if (!document) if (!document)
return DeprecatedString::empty(); return DeprecatedString::empty();
auto* page = document->page(); return document->page().client().page_did_request_cookie(http_request->current_url(), Cookie::Source::Http);
if (!page)
return DeprecatedString::empty();
return page->client().page_did_request_cookie(http_request->current_url(), Cookie::Source::Http);
})(); })();
// 2. If cookies is not the empty string, then append (`Cookie`, cookies) to httpRequests header list. // 2. If cookies is not the empty string, then append (`Cookie`, cookies) to httpRequests header list.

View file

@ -57,7 +57,7 @@ void HTMLImageElement::initialize(JS::Realm& realm)
Base::initialize(realm); Base::initialize(realm);
set_prototype(&Bindings::ensure_web_prototype<Bindings::HTMLImageElementPrototype>(realm, "HTMLImageElement"_fly_string)); set_prototype(&Bindings::ensure_web_prototype<Bindings::HTMLImageElementPrototype>(realm, "HTMLImageElement"_fly_string));
m_current_request = ImageRequest::create(realm, *document().page()); m_current_request = ImageRequest::create(realm, document().page());
} }
void HTMLImageElement::adopted_from(DOM::Document& old_document) void HTMLImageElement::adopted_from(DOM::Document& old_document)
@ -385,7 +385,7 @@ ErrorOr<void> HTMLImageElement::update_the_image_data(bool restart_animations, b
m_pending_request = nullptr; m_pending_request = nullptr;
// 4. Let current request be a new image request whose image data is that of the entry and whose state is completely available. // 4. Let current request be a new image request whose image data is that of the entry and whose state is completely available.
m_current_request = ImageRequest::create(realm(), *document().page()); m_current_request = ImageRequest::create(realm(), document().page());
m_current_request->set_image_data(entry->image_data); m_current_request->set_image_data(entry->image_data);
m_current_request->set_state(ImageRequest::State::CompletelyAvailable); m_current_request->set_state(ImageRequest::State::CompletelyAvailable);
@ -512,7 +512,7 @@ after_step_7:
// multiple image elements (as well as CSS background-images, etc.) // multiple image elements (as well as CSS background-images, etc.)
// 16. Set image request to a new image request whose current URL is urlString. // 16. Set image request to a new image request whose current URL is urlString.
auto image_request = ImageRequest::create(realm(), *document().page()); auto image_request = ImageRequest::create(realm(), document().page());
image_request->set_current_url(realm(), url_string); image_request->set_current_url(realm(), url_string);
// 17. If current request's state is unavailable or broken, then set the current request to image request. // 17. If current request's state is unavailable or broken, then set the current request to image request.
@ -707,7 +707,7 @@ void HTMLImageElement::react_to_changes_in_the_environment()
key.origin = document().origin(); key.origin = document().origin();
// 11. ⌛ Let image request be a new image request whose current URL is urlString // 11. ⌛ Let image request be a new image request whose current URL is urlString
auto image_request = ImageRequest::create(realm(), *document().page()); auto image_request = ImageRequest::create(realm(), document().page());
image_request->set_current_url(realm(), url_string); image_request->set_current_url(realm(), url_string);
// 12. ⌛ Let the element's pending request be image request. // 12. ⌛ Let the element's pending request be image request.

View file

@ -70,7 +70,7 @@ void HTMLLinkElement::inserted()
ResourceLoader::the().preconnect(document().parse_url(deprecated_attribute(HTML::AttributeNames::href))); ResourceLoader::the().preconnect(document().parse_url(deprecated_attribute(HTML::AttributeNames::href)));
} else if (m_relationship & Relationship::Icon) { } else if (m_relationship & Relationship::Icon) {
auto favicon_url = document().parse_url(href()); auto favicon_url = document().parse_url(href());
auto favicon_request = LoadRequest::create_for_url_on_page(favicon_url, document().page()); auto favicon_request = LoadRequest::create_for_url_on_page(favicon_url, &document().page());
set_resource(ResourceLoader::the().load_resource(Resource::Type::Generic, favicon_request)); set_resource(ResourceLoader::the().load_resource(Resource::Type::Generic, favicon_request));
} }
} }

View file

@ -57,9 +57,6 @@ void HTMLMetaElement::inserted()
auto name = attribute(AttributeNames::name); auto name = attribute(AttributeNames::name);
auto content = attribute(AttributeNames::content); auto content = attribute(AttributeNames::content);
if (name.has_value() && name->bytes_as_string_view().equals_ignoring_ascii_case("theme-color"sv) && content.has_value()) { if (name.has_value() && name->bytes_as_string_view().equals_ignoring_ascii_case("theme-color"sv) && content.has_value()) {
auto* page = document().page();
if (!page)
return;
auto context = CSS::Parser::ParsingContext { document() }; auto context = CSS::Parser::ParsingContext { document() };
// 2. For each element in candidate elements: // 2. For each element in candidate elements:
@ -82,7 +79,7 @@ void HTMLMetaElement::inserted()
auto color = css_value->as_color().color(); auto color = css_value->as_color().color();
// 4. If color is not failure, then return color. // 4. If color is not failure, then return color.
page->client().page_did_change_theme_color(color); document().page().client().page_did_change_theme_color(color);
return; return;
} }

View file

@ -138,7 +138,7 @@ void HTMLObjectElement::queue_element_task_to_run_object_representation_steps()
} }
// 4. Let request be a new request whose URL is the resulting URL record, client is the element's node document's relevant settings object, destination is "object", credentials mode is "include", mode is "navigate", and whose use-URL-credentials flag is set. // 4. Let request be a new request whose URL is the resulting URL record, client is the element's node document's relevant settings object, destination is "object", credentials mode is "include", mode is "navigate", and whose use-URL-credentials flag is set.
auto request = LoadRequest::create_for_url_on_page(url, document().page()); auto request = LoadRequest::create_for_url_on_page(url, &document().page());
// 5. Fetch request, with processResponseEndOfBody given response res set to finalize and report timing with res, the element's node document's relevant global object, and "object". // 5. Fetch request, with processResponseEndOfBody given response res set to finalize and report timing with res, the element's node document's relevant global object, and "object".
// Fetching the resource must delay the load event of the element's node document until the task that is queued by the networking task source once the resource has been fetched (defined next) has been run. // Fetching the resource must delay the load event of the element's node document until the task that is queued by the networking task source once the resource has been fetched (defined next) has been run.
@ -316,7 +316,7 @@ void HTMLObjectElement::load_image()
// NOTE: This currently reloads the image instead of reusing the resource we've already downloaded. // NOTE: This currently reloads the image instead of reusing the resource we've already downloaded.
auto data = deprecated_attribute(HTML::AttributeNames::data); auto data = deprecated_attribute(HTML::AttributeNames::data);
auto url = document().parse_url(data); auto url = document().parse_url(data);
m_image_request = HTML::SharedImageRequest::get_or_create(realm(), *document().page(), url); m_image_request = HTML::SharedImageRequest::get_or_create(realm(), document().page(), url);
m_image_request->add_callbacks( m_image_request->add_callbacks(
[this] { [this] {
run_object_representation_completed_steps(Representation::Image); run_object_representation_completed_steps(Representation::Image);

View file

@ -69,9 +69,8 @@ WebIDL::ExceptionOr<void> NavigableContainer::create_new_child_navigable()
VERIFY(group); VERIFY(group);
// 3. Let browsingContext and document be the result of creating a new browsing context and document given element's node document, element, and group. // 3. Let browsingContext and document be the result of creating a new browsing context and document given element's node document, element, and group.
auto* page = document().page(); auto& page = document().page();
VERIFY(page); auto [browsing_context, document] = TRY(BrowsingContext::create_a_new_browsing_context_and_document(page, this->document(), *this, *group));
auto [browsing_context, document] = TRY(BrowsingContext::create_a_new_browsing_context_and_document(*page, this->document(), *this, *group));
// 4. Let targetName be null. // 4. Let targetName be null.
Optional<String> target_name; Optional<String> target_name;

View file

@ -292,7 +292,7 @@ bool EnvironmentSettingsObject::is_scripting_enabled() const
// The user has not disabled scripting for settings at this time. (User agents may provide users with the option to disable scripting globally, or in a finer-grained manner, e.g., on a per-origin basis, down to the level of individual environment settings objects.) // The user has not disabled scripting for settings at this time. (User agents may provide users with the option to disable scripting globally, or in a finer-grained manner, e.g., on a per-origin basis, down to the level of individual environment settings objects.)
auto document = const_cast<EnvironmentSettingsObject&>(*this).responsible_document(); auto document = const_cast<EnvironmentSettingsObject&>(*this).responsible_document();
VERIFY(document); VERIFY(document);
if (!document->page() || !document->page()->is_scripting_enabled()) if (!document->page().is_scripting_enabled())
return false; return false;
// FIXME: Either settings's global object is not a Window object, or settings's global object's associated Document's active sandboxing flag set does not have its sandboxed scripts browsing context flag set. // FIXME: Either settings's global object is not a Window object, or settings's global object's associated Document's active sandboxing flag set does not have its sandboxed scripts browsing context flag set.

View file

@ -429,12 +429,12 @@ bool Window::dispatch_event(DOM::Event& event)
Page* Window::page() Page* Window::page()
{ {
return associated_document().page(); return &associated_document().page();
} }
Page const* Window::page() const Page const* Window::page() const
{ {
return associated_document().page(); return &associated_document().page();
} }
Optional<CSS::MediaFeatureValue> Window::query_media_feature(CSS::MediaFeatureID media_feature) const Optional<CSS::MediaFeatureValue> Window::query_media_feature(CSS::MediaFeatureID media_feature) const

View file

@ -752,7 +752,7 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& computed_style)
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
}; };
border.width = snap_a_length_as_a_border_width(document().page()->client().device_pixels_per_css_pixel(), resolve_border_width()); border.width = snap_a_length_as_a_border_width(document().page().client().device_pixels_per_css_pixel(), resolve_border_width());
} }
}; };

View file

@ -33,16 +33,14 @@ void SVGTitleElement::children_changed()
{ {
Base::children_changed(); Base::children_changed();
auto* page = document().page(); auto& page = document().page();
if (!page) if (document().browsing_context() != &page.top_level_browsing_context())
return;
if (document().browsing_context() != &page->top_level_browsing_context())
return; return;
auto* document_element = document().document_element(); auto* document_element = document().document_element();
if (document_element == parent() && is<SVGElement>(document_element)) if (document_element == parent() && is<SVGElement>(document_element))
page->client().page_did_change_title(document().title().to_deprecated_string()); page.client().page_did_change_title(document().title().to_deprecated_string());
} }
} }