diff --git a/Userland/Services/WebContent/ConnectionFromClient.cpp b/Userland/Services/WebContent/ConnectionFromClient.cpp index 68029a4c8a..cbcaf800f0 100644 --- a/Userland/Services/WebContent/ConnectionFromClient.cpp +++ b/Userland/Services/WebContent/ConnectionFromClient.cpp @@ -65,38 +65,66 @@ void ConnectionFromClient::die() Web::Platform::EventLoopPlugin::the().quit(); } -PageClient& ConnectionFromClient::page(u64 index) +Optional ConnectionFromClient::page(u64 index) { return m_page_host->page(index); } -PageClient const& ConnectionFromClient::page(u64 index) const +Optional ConnectionFromClient::page(u64 index) const { return m_page_host->page(index); } Messages::WebContentServer::GetWindowHandleResponse ConnectionFromClient::get_window_handle(u64 page_id) { - return page(page_id).page().top_level_traversable()->window_handle(); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::get_window_handle: No page with ID {}", page_id); + return String {}; + } + auto& page = maybe_page.release_value(); + + return page.page().top_level_traversable()->window_handle(); } void ConnectionFromClient::set_window_handle(u64 page_id, String const& handle) { - page(page_id).page().top_level_traversable()->set_window_handle(handle); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::set_window_handle: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.page().top_level_traversable()->set_window_handle(handle); } void ConnectionFromClient::connect_to_webdriver(u64 page_id, ByteString const& webdriver_ipc_path) { + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::connect_to_webdriver: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + // FIXME: Propagate this error back to the browser. - if (auto result = page(page_id).connect_to_webdriver(webdriver_ipc_path); result.is_error()) + if (auto result = page.connect_to_webdriver(webdriver_ipc_path); result.is_error()) dbgln("Unable to connect to the WebDriver process: {}", result.error()); } void ConnectionFromClient::update_system_theme(u64 page_id, Core::AnonymousBuffer const& theme_buffer) { + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::update_system_theme: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + Gfx::set_system_theme(theme_buffer); auto impl = Gfx::PaletteImpl::create_with_anonymous_buffer(theme_buffer); - page(page_id).set_palette_impl(*impl); + page.set_palette_impl(*impl); } void ConnectionFromClient::update_system_fonts(u64, ByteString const& default_font_query, ByteString const& fixed_width_font_query, ByteString const& window_title_font_query) @@ -108,12 +136,25 @@ void ConnectionFromClient::update_system_fonts(u64, ByteString const& default_fo void ConnectionFromClient::update_screen_rects(u64 page_id, Vector const& rects, u32 main_screen) { - page(page_id).set_screen_rects(rects, main_screen); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::update_screen_rects: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.set_screen_rects(rects, main_screen); } void ConnectionFromClient::load_url(u64 page_id, const URL& url) { dbgln_if(SPAM_DEBUG, "handle: WebContentServer::LoadURL: url={}", url); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::load_url: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); #if defined(AK_OS_SERENITY) ByteString process_name; @@ -125,29 +166,57 @@ void ConnectionFromClient::load_url(u64 page_id, const URL& url) pthread_setname_np(pthread_self(), process_name.characters()); #endif - page(page_id).page().load(url); + page.page().load(url); } void ConnectionFromClient::load_html(u64 page_id, ByteString const& html) { dbgln_if(SPAM_DEBUG, "handle: WebContentServer::LoadHTML: html={}", html); - page(page_id).page().load_html(html); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::load_html: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.page().load_html(html); } void ConnectionFromClient::set_viewport_rect(u64 page_id, Web::DevicePixelRect const& rect) { dbgln_if(SPAM_DEBUG, "handle: WebContentServer::SetViewportRect: rect={}", rect); - page(page_id).set_viewport_rect(rect); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::set_viewport_rect: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.set_viewport_rect(rect); } void ConnectionFromClient::add_backing_store(u64 page_id, i32 front_bitmap_id, Gfx::ShareableBitmap const& front_bitmap, i32 back_bitmap_id, Gfx::ShareableBitmap const& back_bitmap) { - page(page_id).add_backing_store(front_bitmap_id, front_bitmap, back_bitmap_id, back_bitmap); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::add_backing_store: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.add_backing_store(front_bitmap_id, front_bitmap, back_bitmap_id, back_bitmap); } void ConnectionFromClient::ready_to_paint(u64 page_id) { - page(page_id).ready_to_paint(); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::ready_to_paint: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.ready_to_paint(); } void ConnectionFromClient::process_next_input_event() @@ -158,12 +227,19 @@ void ConnectionFromClient::process_next_input_event() auto event = m_input_event_queue.dequeue(); event.visit( [&](QueuedMouseEvent const& event) { + auto maybe_page = page(event.page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::process_next_input_event: No page with ID {}", event.page_id); + return; + } + auto& page = maybe_page.release_value(); + switch (event.type) { case QueuedMouseEvent::Type::MouseDown: - report_finished_handling_input_event(event.page_id, page(event.page_id).page().handle_mousedown(event.position, event.screen_position, event.button, event.buttons, event.modifiers)); + report_finished_handling_input_event(event.page_id, page.page().handle_mousedown(event.position, event.screen_position, event.button, event.buttons, event.modifiers)); break; case QueuedMouseEvent::Type::MouseUp: - report_finished_handling_input_event(event.page_id, page(event.page_id).page().handle_mouseup(event.position, event.screen_position, event.button, event.buttons, event.modifiers)); + report_finished_handling_input_event(event.page_id, page.page().handle_mouseup(event.position, event.screen_position, event.button, event.buttons, event.modifiers)); break; case QueuedMouseEvent::Type::MouseMove: // NOTE: We have to notify the client about coalesced MouseMoves, @@ -171,26 +247,33 @@ void ConnectionFromClient::process_next_input_event() for (size_t i = 0; i < event.coalesced_event_count; ++i) { report_finished_handling_input_event(event.page_id, false); } - report_finished_handling_input_event(event.page_id, page(event.page_id).page().handle_mousemove(event.position, event.screen_position, event.buttons, event.modifiers)); + report_finished_handling_input_event(event.page_id, page.page().handle_mousemove(event.position, event.screen_position, event.buttons, event.modifiers)); break; case QueuedMouseEvent::Type::DoubleClick: - report_finished_handling_input_event(event.page_id, page(event.page_id).page().handle_doubleclick(event.position, event.screen_position, event.button, event.buttons, event.modifiers)); + report_finished_handling_input_event(event.page_id, page.page().handle_doubleclick(event.position, event.screen_position, event.button, event.buttons, event.modifiers)); break; case QueuedMouseEvent::Type::MouseWheel: for (size_t i = 0; i < event.coalesced_event_count; ++i) { report_finished_handling_input_event(event.page_id, false); } - report_finished_handling_input_event(event.page_id, page(event.page_id).page().handle_mousewheel(event.position, event.screen_position, event.button, event.buttons, event.modifiers, event.wheel_delta_x, event.wheel_delta_y)); + report_finished_handling_input_event(event.page_id, page.page().handle_mousewheel(event.position, event.screen_position, event.button, event.buttons, event.modifiers, event.wheel_delta_x, event.wheel_delta_y)); break; } }, [&](QueuedKeyboardEvent const& event) { + auto maybe_page = page(event.page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::process_next_input_event: No page with ID {}", event.page_id); + return; + } + auto& page = maybe_page.release_value(); + switch (event.type) { case QueuedKeyboardEvent::Type::KeyDown: - report_finished_handling_input_event(event.page_id, page(event.page_id).page().handle_keydown((KeyCode)event.key, event.modifiers, event.code_point)); + report_finished_handling_input_event(event.page_id, page.page().handle_keydown((KeyCode)event.key, event.modifiers, event.code_point)); break; case QueuedKeyboardEvent::Type::KeyUp: - report_finished_handling_input_event(event.page_id, page(event.page_id).page().handle_keyup((KeyCode)event.key, event.modifiers, event.code_point)); + report_finished_handling_input_event(event.page_id, page.page().handle_keyup((KeyCode)event.key, event.modifiers, event.code_point)); break; } }); @@ -333,19 +416,26 @@ void ConnectionFromClient::report_finished_handling_input_event(u64 page_id, boo void ConnectionFromClient::debug_request(u64 page_id, ByteString const& request, ByteString const& argument) { + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::debug_request: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + if (request == "dump-session-history") { - auto const& traversable = page(page_id).page().top_level_traversable(); + auto const& traversable = page.page().top_level_traversable(); Web::dump_tree(*traversable); } if (request == "dump-dom-tree") { - if (auto* doc = page(page_id).page().top_level_browsing_context().active_document()) + if (auto* doc = page.page().top_level_browsing_context().active_document()) Web::dump_tree(*doc); return; } if (request == "dump-layout-tree") { - if (auto* doc = page(page_id).page().top_level_browsing_context().active_document()) { + if (auto* doc = page.page().top_level_browsing_context().active_document()) { if (auto* viewport = doc->layout_node()) Web::dump_tree(*viewport); } @@ -353,7 +443,7 @@ void ConnectionFromClient::debug_request(u64 page_id, ByteString const& request, } if (request == "dump-paint-tree") { - if (auto* doc = page(page_id).page().top_level_browsing_context().active_document()) { + if (auto* doc = page.page().top_level_browsing_context().active_document()) { if (auto* paintable = doc->paintable()) Web::dump_tree(*paintable); } @@ -361,7 +451,7 @@ void ConnectionFromClient::debug_request(u64 page_id, ByteString const& request, } if (request == "dump-stacking-context-tree") { - if (auto* doc = page(page_id).page().top_level_browsing_context().active_document()) { + if (auto* doc = page.page().top_level_browsing_context().active_document()) { if (auto* viewport = doc->layout_node()) { if (auto* stacking_context = viewport->paintable_box()->stacking_context()) stacking_context->dump(); @@ -371,7 +461,7 @@ void ConnectionFromClient::debug_request(u64 page_id, ByteString const& request, } if (request == "dump-style-sheets") { - if (auto* doc = page(page_id).page().top_level_browsing_context().active_document()) { + if (auto* doc = page.page().top_level_browsing_context().active_document()) { for (auto& sheet : doc->style_sheets().sheets()) { if (auto result = Web::dump_sheet(sheet); result.is_error()) dbgln("Failed to dump style sheets: {}", result.error()); @@ -381,7 +471,7 @@ void ConnectionFromClient::debug_request(u64 page_id, ByteString const& request, } if (request == "dump-all-resolved-styles") { - if (auto* doc = page(page_id).page().top_level_browsing_context().active_document()) { + if (auto* doc = page.page().top_level_browsing_context().active_document()) { Queue elements_to_visit; elements_to_visit.enqueue(doc->document_element()); while (!elements_to_visit.is_empty()) { @@ -408,8 +498,8 @@ void ConnectionFromClient::debug_request(u64 page_id, ByteString const& request, if (request == "set-line-box-borders") { bool state = argument == "on"; - page(page_id).set_should_show_line_box_borders(state); - page(page_id).page().top_level_traversable()->set_needs_display(page(page_id).page().top_level_traversable()->viewport_rect()); + page.set_should_show_line_box_borders(state); + page.page().top_level_traversable()->set_needs_display(page.page().top_level_traversable()->viewport_rect()); return; } @@ -424,28 +514,28 @@ void ConnectionFromClient::debug_request(u64 page_id, ByteString const& request, } if (request == "same-origin-policy") { - page(page_id).page().set_same_origin_policy_enabled(argument == "on"); + page.page().set_same_origin_policy_enabled(argument == "on"); return; } if (request == "scripting") { - page(page_id).page().set_is_scripting_enabled(argument == "on"); + page.page().set_is_scripting_enabled(argument == "on"); return; } if (request == "block-pop-ups") { - page(page_id).page().set_should_block_pop_ups(argument == "on"); + page.page().set_should_block_pop_ups(argument == "on"); return; } if (request == "dump-local-storage") { - if (auto* document = page(page_id).page().top_level_browsing_context().active_document()) + if (auto* document = page.page().top_level_browsing_context().active_document()) document->window().local_storage().release_value_but_fixme_should_propagate_errors()->dump(); return; } if (request == "load-reference-page") { - if (auto* document = page(page_id).page().top_level_browsing_context().active_document()) { + if (auto* document = page.page().top_level_browsing_context().active_document()) { auto maybe_link = document->query_selector("link[rel=match]"sv); if (maybe_link.is_error() || !maybe_link.value()) { // To make sure that we fail the ref-test if the link is missing, load the error page. @@ -462,21 +552,42 @@ void ConnectionFromClient::debug_request(u64 page_id, ByteString const& request, void ConnectionFromClient::get_source(u64 page_id) { - if (auto* doc = page(page_id).page().top_level_browsing_context().active_document()) { + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::get_source: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + if (auto* doc = page.page().top_level_browsing_context().active_document()) { async_did_get_source(page_id, doc->url(), doc->source().to_byte_string()); } } void ConnectionFromClient::inspect_dom_tree(u64 page_id) { - if (auto* doc = page(page_id).page().top_level_browsing_context().active_document()) { + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::inspect_dom_tree: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + if (auto* doc = page.page().top_level_browsing_context().active_document()) { async_did_inspect_dom_tree(page_id, doc->dump_dom_tree_as_json().to_byte_string()); } } void ConnectionFromClient::inspect_dom_node(u64 page_id, i32 node_id, Optional const& pseudo_element) { - auto& top_context = page(page_id).page().top_level_browsing_context(); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::inspect_dom_node: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + auto& top_context = page.page().top_level_browsing_context(); top_context.for_each_in_inclusive_subtree([&](auto& ctx) { if (ctx.active_document() != nullptr) { @@ -591,7 +702,7 @@ void ConnectionFromClient::inspect_dom_node(u64 page_id, i32 node_id, Optionalstyle_computer().compute_style(element, pseudo_element)); + auto pseudo_element_style = MUST(page.page().focused_context().active_document()->style_computer().compute_style(element, pseudo_element)); ByteString computed_values = serialize_json(pseudo_element_style); ByteString resolved_values = "{}"; ByteString custom_properties_json = serialize_custom_properties_json(element, pseudo_element); @@ -616,16 +727,30 @@ void ConnectionFromClient::inspect_dom_node(u64 page_id, i32 node_id, Optionaldump_accessibility_tree_as_json().to_byte_string()); } } void ConnectionFromClient::get_hovered_node_id(u64 page_id) { + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::get_hovered_node_id: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + i32 node_id = 0; - if (auto* document = page(page_id).page().top_level_browsing_context().active_document()) { + if (auto* document = page.page().top_level_browsing_context().active_document()) { if (auto* hovered_node = document->hovered_node()) node_id = hovered_node->unique_id(); } @@ -755,7 +880,14 @@ void ConnectionFromClient::clone_dom_node(u64 page_id, i32 node_id) void ConnectionFromClient::remove_dom_node(u64 page_id, i32 node_id) { - auto* active_document = page(page_id).page().top_level_browsing_context().active_document(); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::remove_dom_node: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + auto* active_document = page.page().top_level_browsing_context().active_document(); if (!active_document) { async_did_finish_editing_dom_node(page_id, {}); return; @@ -797,33 +929,47 @@ void ConnectionFromClient::get_dom_node_html(u64 page_id, i32 node_id) void ConnectionFromClient::take_document_screenshot(u64 page_id) { - auto* document = page(page_id).page().top_level_browsing_context().active_document(); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::take_document_screenshot: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + auto* document = page.page().top_level_browsing_context().active_document(); if (!document || !document->document_element()) { async_did_take_screenshot(page_id, {}); return; } - auto const& content_size = page(page_id).content_size(); + auto const& content_size = page.content_size(); Web::DevicePixelRect rect { { 0, 0 }, content_size }; auto bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, rect.size().to_type()).release_value_but_fixme_should_propagate_errors(); - page(page_id).paint(rect, *bitmap); + page.paint(rect, *bitmap); async_did_take_screenshot(page_id, bitmap->to_shareable_bitmap()); } void ConnectionFromClient::take_dom_node_screenshot(u64 page_id, i32 node_id) { + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::take_dom_node_screenshot: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + auto* dom_node = Web::DOM::Node::from_unique_id(node_id); if (!dom_node || !dom_node->paintable_box()) { async_did_take_screenshot(page_id, {}); return; } - auto rect = page(page_id).page().enclosing_device_rect(dom_node->paintable_box()->absolute_border_box_rect()); + auto rect = page.page().enclosing_device_rect(dom_node->paintable_box()->absolute_border_box_rect()); auto bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, rect.size().to_type()).release_value_but_fixme_should_propagate_errors(); - page(page_id).paint(rect, *bitmap, { .paint_overlay = Web::PaintOptions::PaintOverlay::No }); + page.paint(rect, *bitmap, { .paint_overlay = Web::PaintOptions::PaintOverlay::No }); async_did_take_screenshot(page_id, bitmap->to_shareable_bitmap()); } @@ -836,17 +982,38 @@ Messages::WebContentServer::DumpGcGraphResponse ConnectionFromClient::dump_gc_gr Messages::WebContentServer::GetSelectedTextResponse ConnectionFromClient::get_selected_text(u64 page_id) { - return page(page_id).page().focused_context().selected_text().to_byte_string(); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::get_selected_text: No page with ID {}", page_id); + return ByteString {}; + } + auto& page = maybe_page.release_value(); + + return page.page().focused_context().selected_text().to_byte_string(); } void ConnectionFromClient::select_all(u64 page_id) { - page(page_id).page().focused_context().select_all(); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::select_all: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.page().focused_context().select_all(); } Messages::WebContentServer::DumpLayoutTreeResponse ConnectionFromClient::dump_layout_tree(u64 page_id) { - auto* document = page(page_id).page().top_level_browsing_context().active_document(); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::dump_layout_tree: No page with ID {}", page_id); + return ByteString { "(no page)" }; + } + auto& page = maybe_page.release_value(); + + auto* document = page.page().top_level_browsing_context().active_document(); if (!document) return ByteString { "(no DOM tree)" }; document->update_layout(); @@ -860,7 +1027,14 @@ Messages::WebContentServer::DumpLayoutTreeResponse ConnectionFromClient::dump_la Messages::WebContentServer::DumpPaintTreeResponse ConnectionFromClient::dump_paint_tree(u64 page_id) { - auto* document = page(page_id).page().top_level_browsing_context().active_document(); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::dump_paint_tree: No page with ID {}", page_id); + return ByteString { "(no page)" }; + } + auto& page = maybe_page.release_value(); + + auto* document = page.page().top_level_browsing_context().active_document(); if (!document) return ByteString { "(no DOM tree)" }; document->update_layout(); @@ -876,7 +1050,14 @@ Messages::WebContentServer::DumpPaintTreeResponse ConnectionFromClient::dump_pai Messages::WebContentServer::DumpTextResponse ConnectionFromClient::dump_text(u64 page_id) { - auto* document = page(page_id).page().top_level_browsing_context().active_document(); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::dump_text: No page with ID {}", page_id); + return ByteString { "(no page)" }; + } + auto& page = maybe_page.release_value(); + + auto* document = page.page().top_level_browsing_context().active_document(); if (!document) return ByteString { "(no DOM tree)" }; if (!document->body()) @@ -919,44 +1100,100 @@ void ConnectionFromClient::set_proxy_mappings(u64, Vector const& pro void ConnectionFromClient::set_preferred_color_scheme(u64 page_id, Web::CSS::PreferredColorScheme const& color_scheme) { - page(page_id).set_preferred_color_scheme(color_scheme); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::set_preferred_color_scheme: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.set_preferred_color_scheme(color_scheme); } void ConnectionFromClient::set_has_focus(u64 page_id, bool has_focus) { - page(page_id).set_has_focus(has_focus); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::set_has_focus: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.set_has_focus(has_focus); } void ConnectionFromClient::set_is_scripting_enabled(u64 page_id, bool is_scripting_enabled) { - page(page_id).set_is_scripting_enabled(is_scripting_enabled); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::set_is_scripting_enabled: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.set_is_scripting_enabled(is_scripting_enabled); } void ConnectionFromClient::set_device_pixels_per_css_pixel(u64 page_id, float device_pixels_per_css_pixel) { - page(page_id).set_device_pixels_per_css_pixel(device_pixels_per_css_pixel); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::set_device_pixels_per_css_pixel: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.set_device_pixels_per_css_pixel(device_pixels_per_css_pixel); } void ConnectionFromClient::set_window_position(u64 page_id, Web::DevicePixelPoint position) { - page(page_id).set_window_position(position); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::set_window_position: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.set_window_position(position); } void ConnectionFromClient::set_window_size(u64 page_id, Web::DevicePixelSize size) { - page(page_id).set_window_size(size); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::set_window_size: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.set_window_size(size); } Messages::WebContentServer::GetLocalStorageEntriesResponse ConnectionFromClient::get_local_storage_entries(u64 page_id) { - auto* document = page(page_id).page().top_level_browsing_context().active_document(); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::get_local_storage_entries: No page with ID {}", page_id); + return OrderedHashMap {}; + } + auto& page = maybe_page.release_value(); + + auto* document = page.page().top_level_browsing_context().active_document(); auto local_storage = document->window().local_storage().release_value_but_fixme_should_propagate_errors(); return local_storage->map(); } Messages::WebContentServer::GetSessionStorageEntriesResponse ConnectionFromClient::get_session_storage_entries(u64 page_id) { - auto* document = page(page_id).page().top_level_browsing_context().active_document(); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::get_session_storage_entries: No page with ID {}", page_id); + return OrderedHashMap {}; + } + auto& page = maybe_page.release_value(); + + auto* document = page.page().top_level_browsing_context().active_document(); auto session_storage = document->window().session_storage().release_value_but_fixme_should_propagate_errors(); return session_storage->map(); } @@ -983,7 +1220,14 @@ void ConnectionFromClient::request_file(u64 page_id, Web::FileRequest file_reque void ConnectionFromClient::set_system_visibility_state(u64 page_id, bool visible) { - page(page_id).page().top_level_traversable()->set_system_visibility_state( + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::set_system_visibility_state: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.page().top_level_traversable()->set_system_visibility_state( visible ? Web::HTML::VisibilityState::Visible : Web::HTML::VisibilityState::Hidden); @@ -991,67 +1235,158 @@ void ConnectionFromClient::set_system_visibility_state(u64 page_id, bool visible void ConnectionFromClient::js_console_input(u64 page_id, ByteString const& js_source) { - page(page_id).js_console_input(js_source); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::js_console_input: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.js_console_input(js_source); } void ConnectionFromClient::run_javascript(u64 page_id, ByteString const& js_source) { - page(page_id).run_javascript(js_source); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::run_javascript: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.run_javascript(js_source); } void ConnectionFromClient::js_console_request_messages(u64 page_id, i32 start_index) { - page(page_id).js_console_request_messages(start_index); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::js_console_request_messages: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.js_console_request_messages(start_index); } void ConnectionFromClient::alert_closed(u64 page_id) { - page(page_id).page().alert_closed(); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::alert_closed: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.page().alert_closed(); } void ConnectionFromClient::confirm_closed(u64 page_id, bool accepted) { - page(page_id).page().confirm_closed(accepted); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::confirm_closed: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.page().confirm_closed(accepted); } void ConnectionFromClient::prompt_closed(u64 page_id, Optional const& response) { - page(page_id).page().prompt_closed(response); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::prompt_closed: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.page().prompt_closed(response); } void ConnectionFromClient::color_picker_update(u64 page_id, Optional const& picked_color, Web::HTML::ColorPickerUpdateState const& state) { - page(page_id).page().color_picker_update(picked_color, state); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::color_picker_update: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.page().color_picker_update(picked_color, state); } void ConnectionFromClient::select_dropdown_closed(u64 page_id, Optional const& value) { - page(page_id).page().select_dropdown_closed(value); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::select_dropdown_closed: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.page().select_dropdown_closed(value); } void ConnectionFromClient::toggle_media_play_state(u64 page_id) { - page(page_id).page().toggle_media_play_state().release_value_but_fixme_should_propagate_errors(); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::toggle_media_play_state: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.page().toggle_media_play_state().release_value_but_fixme_should_propagate_errors(); } void ConnectionFromClient::toggle_media_mute_state(u64 page_id) { - page(page_id).page().toggle_media_mute_state(); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::toggle_media_mute_state: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.page().toggle_media_mute_state(); } void ConnectionFromClient::toggle_media_loop_state(u64 page_id) { - page(page_id).page().toggle_media_loop_state().release_value_but_fixme_should_propagate_errors(); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::toggle_media_loop_state: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.page().toggle_media_loop_state().release_value_but_fixme_should_propagate_errors(); } void ConnectionFromClient::toggle_media_controls_state(u64 page_id) { - page(page_id).page().toggle_media_controls_state().release_value_but_fixme_should_propagate_errors(); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::toggle_media_controls_state: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.page().toggle_media_controls_state().release_value_but_fixme_should_propagate_errors(); } void ConnectionFromClient::set_user_style(u64 page_id, String const& source) { - page(page_id).page().set_user_style(source); + auto maybe_page = page(page_id); + if (!maybe_page.has_value()) { + dbgln("ConnectionFromClient::set_user_style: No page with ID {}", page_id); + return; + } + auto& page = maybe_page.release_value(); + + page.page().set_user_style(source); } void ConnectionFromClient::enable_inspector_prototype(u64) diff --git a/Userland/Services/WebContent/ConnectionFromClient.h b/Userland/Services/WebContent/ConnectionFromClient.h index 7ccdd95ef5..5dd491c47f 100644 --- a/Userland/Services/WebContent/ConnectionFromClient.h +++ b/Userland/Services/WebContent/ConnectionFromClient.h @@ -44,8 +44,8 @@ public: private: explicit ConnectionFromClient(NonnullOwnPtr); - PageClient& page(u64 index); - PageClient const& page(u64 index) const; + Optional page(u64 index); + Optional page(u64 index) const; virtual Messages::WebContentServer::GetWindowHandleResponse get_window_handle(u64 page_id) override; virtual void set_window_handle(u64 page_id, String const& handle) override; diff --git a/Userland/Services/WebContent/PageHost.cpp b/Userland/Services/WebContent/PageHost.cpp index c642e50eeb..782ee37efe 100644 --- a/Userland/Services/WebContent/PageHost.cpp +++ b/Userland/Services/WebContent/PageHost.cpp @@ -34,6 +34,13 @@ void PageHost::remove_page(Badge, u64 index) m_pages.remove(index); } +Optional PageHost::page(u64 index) +{ + return m_pages.get(index).map([](auto& value) -> PageClient& { + return *value; + }); +} + PageHost::~PageHost() = default; } diff --git a/Userland/Services/WebContent/PageHost.h b/Userland/Services/WebContent/PageHost.h index f00f0858eb..f3fad3bd7c 100644 --- a/Userland/Services/WebContent/PageHost.h +++ b/Userland/Services/WebContent/PageHost.h @@ -26,7 +26,7 @@ public: Function on_webdriver_connection; - PageClient& page(u64 index) { return *m_pages.find(index)->value; } + Optional page(u64 index); PageClient& create_page(); void remove_page(Badge, u64 index);