PageHost.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*
  2. * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "PageHost.h"
  7. #include "ClientConnection.h"
  8. #include <LibGfx/Painter.h>
  9. #include <LibGfx/ShareableBitmap.h>
  10. #include <LibGfx/SystemTheme.h>
  11. #include <LibWeb/Cookie/ParsedCookie.h>
  12. #include <LibWeb/HTML/BrowsingContext.h>
  13. #include <LibWeb/Layout/InitialContainingBlock.h>
  14. #include <WebContent/WebContentClientEndpoint.h>
  15. namespace WebContent {
  16. PageHost::PageHost(ClientConnection& client)
  17. : m_client(client)
  18. , m_page(make<Web::Page>(*this))
  19. {
  20. setup_palette();
  21. m_invalidation_coalescing_timer = Core::Timer::create_single_shot(0, [this] {
  22. m_client.async_did_invalidate_content_rect(m_invalidation_rect);
  23. m_invalidation_rect = {};
  24. });
  25. }
  26. PageHost::~PageHost()
  27. {
  28. }
  29. void PageHost::set_has_focus(bool has_focus)
  30. {
  31. m_has_focus = has_focus;
  32. }
  33. void PageHost::setup_palette()
  34. {
  35. // FIXME: Get the proper palette from our peer somehow
  36. auto buffer_or_error = Core::AnonymousBuffer::create_with_size(sizeof(Gfx::SystemTheme));
  37. VERIFY(!buffer_or_error.is_error());
  38. auto buffer = buffer_or_error.release_value();
  39. auto* theme = buffer.data<Gfx::SystemTheme>();
  40. theme->color[(int)Gfx::ColorRole::Window] = Color::Magenta;
  41. theme->color[(int)Gfx::ColorRole::WindowText] = Color::Cyan;
  42. m_palette_impl = Gfx::PaletteImpl::create_with_anonymous_buffer(buffer);
  43. }
  44. Gfx::Palette PageHost::palette() const
  45. {
  46. return Gfx::Palette(*m_palette_impl);
  47. }
  48. void PageHost::set_palette_impl(const Gfx::PaletteImpl& impl)
  49. {
  50. m_palette_impl = impl;
  51. }
  52. void PageHost::set_preferred_color_scheme(Web::CSS::PreferredColorScheme color_scheme)
  53. {
  54. m_preferred_color_scheme = color_scheme;
  55. if (auto* document = page().top_level_browsing_context().active_document())
  56. document->invalidate_style();
  57. }
  58. Web::Layout::InitialContainingBlock* PageHost::layout_root()
  59. {
  60. auto* document = page().top_level_browsing_context().active_document();
  61. if (!document)
  62. return nullptr;
  63. return document->layout_node();
  64. }
  65. void PageHost::paint(const Gfx::IntRect& content_rect, Gfx::Bitmap& target)
  66. {
  67. Gfx::Painter painter(target);
  68. Gfx::IntRect bitmap_rect { {}, content_rect.size() };
  69. if (auto* document = page().top_level_browsing_context().active_document())
  70. document->update_layout();
  71. auto* layout_root = this->layout_root();
  72. if (!layout_root) {
  73. painter.fill_rect(bitmap_rect, Color::White);
  74. return;
  75. }
  76. Web::PaintContext context(painter, palette(), content_rect.top_left());
  77. context.set_should_show_line_box_borders(m_should_show_line_box_borders);
  78. context.set_viewport_rect(content_rect);
  79. context.set_has_focus(m_has_focus);
  80. layout_root->paint_all_phases(context);
  81. }
  82. void PageHost::set_viewport_rect(const Gfx::IntRect& rect)
  83. {
  84. page().top_level_browsing_context().set_viewport_rect(rect);
  85. }
  86. void PageHost::page_did_invalidate(Gfx::IntRect const& content_rect)
  87. {
  88. m_invalidation_rect = m_invalidation_rect.united(content_rect);
  89. if (!m_invalidation_coalescing_timer->is_active())
  90. m_invalidation_coalescing_timer->start();
  91. }
  92. void PageHost::page_did_change_selection()
  93. {
  94. m_client.async_did_change_selection();
  95. }
  96. void PageHost::page_did_request_cursor_change(Gfx::StandardCursor cursor)
  97. {
  98. m_client.async_did_request_cursor_change((u32)cursor);
  99. }
  100. void PageHost::page_did_layout()
  101. {
  102. auto* layout_root = this->layout_root();
  103. VERIFY(layout_root);
  104. Gfx::IntSize content_size;
  105. if (layout_root->has_overflow())
  106. content_size = enclosing_int_rect(layout_root->scrollable_overflow_rect().value()).size();
  107. else
  108. content_size = enclosing_int_rect(layout_root->absolute_rect()).size();
  109. m_client.async_did_layout(content_size);
  110. }
  111. void PageHost::page_did_change_title(const String& title)
  112. {
  113. m_client.async_did_change_title(title);
  114. }
  115. void PageHost::page_did_request_scroll(i32 x_delta, i32 y_delta)
  116. {
  117. m_client.async_did_request_scroll(x_delta, y_delta);
  118. }
  119. void PageHost::page_did_request_scroll_to(Gfx::IntPoint const& scroll_position)
  120. {
  121. m_client.async_did_request_scroll_to(scroll_position);
  122. }
  123. void PageHost::page_did_request_scroll_into_view(const Gfx::IntRect& rect)
  124. {
  125. m_client.async_did_request_scroll_into_view(rect);
  126. }
  127. void PageHost::page_did_enter_tooltip_area(const Gfx::IntPoint& content_position, const String& title)
  128. {
  129. m_client.async_did_enter_tooltip_area(content_position, title);
  130. }
  131. void PageHost::page_did_leave_tooltip_area()
  132. {
  133. m_client.async_did_leave_tooltip_area();
  134. }
  135. void PageHost::page_did_hover_link(const URL& url)
  136. {
  137. m_client.async_did_hover_link(url);
  138. }
  139. void PageHost::page_did_unhover_link()
  140. {
  141. m_client.async_did_unhover_link();
  142. }
  143. void PageHost::page_did_click_link(const URL& url, const String& target, unsigned modifiers)
  144. {
  145. m_client.async_did_click_link(url, target, modifiers);
  146. }
  147. void PageHost::page_did_middle_click_link(const URL& url, [[maybe_unused]] const String& target, [[maybe_unused]] unsigned modifiers)
  148. {
  149. m_client.async_did_middle_click_link(url, target, modifiers);
  150. }
  151. void PageHost::page_did_start_loading(const URL& url)
  152. {
  153. m_client.async_did_start_loading(url);
  154. }
  155. void PageHost::page_did_finish_loading(const URL& url)
  156. {
  157. // FIXME: This is called after the page has finished loading, which means any log messages
  158. // that happen *while* it is loading (such as inline <script>s) will be lost.
  159. m_client.initialize_js_console({});
  160. m_client.async_did_finish_loading(url);
  161. }
  162. void PageHost::page_did_request_context_menu(const Gfx::IntPoint& content_position)
  163. {
  164. m_client.async_did_request_context_menu(content_position);
  165. }
  166. void PageHost::page_did_request_link_context_menu(const Gfx::IntPoint& content_position, const URL& url, const String& target, unsigned modifiers)
  167. {
  168. m_client.async_did_request_link_context_menu(content_position, url, target, modifiers);
  169. }
  170. void PageHost::page_did_request_alert(const String& message)
  171. {
  172. m_client.did_request_alert(message);
  173. }
  174. bool PageHost::page_did_request_confirm(const String& message)
  175. {
  176. return m_client.did_request_confirm(message);
  177. }
  178. String PageHost::page_did_request_prompt(const String& message, const String& default_)
  179. {
  180. return m_client.did_request_prompt(message, default_);
  181. }
  182. void PageHost::page_did_change_favicon(const Gfx::Bitmap& favicon)
  183. {
  184. m_client.async_did_change_favicon(favicon.to_shareable_bitmap());
  185. }
  186. void PageHost::page_did_request_image_context_menu(const Gfx::IntPoint& content_position, const URL& url, const String& target, unsigned modifiers, const Gfx::Bitmap* bitmap_pointer)
  187. {
  188. auto bitmap = bitmap_pointer ? bitmap_pointer->to_shareable_bitmap() : Gfx::ShareableBitmap();
  189. m_client.async_did_request_image_context_menu(content_position, url, target, modifiers, bitmap);
  190. }
  191. String PageHost::page_did_request_cookie(const URL& url, Web::Cookie::Source source)
  192. {
  193. return m_client.did_request_cookie(url, static_cast<u8>(source));
  194. }
  195. void PageHost::page_did_set_cookie(const URL& url, const Web::Cookie::ParsedCookie& cookie, Web::Cookie::Source source)
  196. {
  197. m_client.async_did_set_cookie(url, cookie, static_cast<u8>(source));
  198. }
  199. }