summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2022-11-03 12:51:44 -0400
committerLinus Groh <mail@linusgroh.de>2022-11-03 19:15:43 +0000
commit995f3db3848b9f6b6661b0738b7308d925147c50 (patch)
treefb1b164a936f818f2aa482ae40657533e3cc54de /Userland
parent77b6d0bf166b0b0deca80e6791c0f1054ad57f6e (diff)
downloadserenity-995f3db3848b9f6b6661b0738b7308d925147c50.zip
LibWebView+WebConent: Add an IPC to get an element's absolute rect
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibWebView/OutOfProcessWebView.cpp5
-rw-r--r--Userland/Libraries/LibWebView/OutOfProcessWebView.h1
-rw-r--r--Userland/Services/WebContent/ConnectionFromClient.cpp31
-rw-r--r--Userland/Services/WebContent/ConnectionFromClient.h1
-rw-r--r--Userland/Services/WebContent/WebContentServer.ipc2
5 files changed, 40 insertions, 0 deletions
diff --git a/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp b/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp
index 59e4ece875..151ba6f264 100644
--- a/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp
+++ b/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp
@@ -560,6 +560,11 @@ String OutOfProcessWebView::get_element_tag_name(i32 element_id)
return client().get_element_tag_name(element_id);
}
+Gfx::IntRect OutOfProcessWebView::get_element_rect(i32 element_id)
+{
+ return client().get_element_rect(element_id);
+}
+
void OutOfProcessWebView::set_content_filters(Vector<String> filters)
{
client().async_set_content_filters(filters);
diff --git a/Userland/Libraries/LibWebView/OutOfProcessWebView.h b/Userland/Libraries/LibWebView/OutOfProcessWebView.h
index eb95879329..6b8b90a14a 100644
--- a/Userland/Libraries/LibWebView/OutOfProcessWebView.h
+++ b/Userland/Libraries/LibWebView/OutOfProcessWebView.h
@@ -71,6 +71,7 @@ public:
String get_computed_value_for_element(i32 element_id, String const& property_name);
String get_element_text(i32 element_id);
String get_element_tag_name(i32 element_id);
+ Gfx::IntRect get_element_rect(i32 element_id);
void set_content_filters(Vector<String>);
void set_proxy_mappings(Vector<String> proxies, HashMap<String, size_t> mappings);
diff --git a/Userland/Services/WebContent/ConnectionFromClient.cpp b/Userland/Services/WebContent/ConnectionFromClient.cpp
index 38f9211276..7f38ef8e7d 100644
--- a/Userland/Services/WebContent/ConnectionFromClient.cpp
+++ b/Userland/Services/WebContent/ConnectionFromClient.cpp
@@ -24,6 +24,7 @@
#include <LibWeb/DOM/Document.h>
#include <LibWeb/DOM/NodeList.h>
#include <LibWeb/Dump.h>
+#include <LibWeb/Geometry/DOMRect.h>
#include <LibWeb/HTML/BrowsingContext.h>
#include <LibWeb/HTML/Scripting/ClassicScript.h>
#include <LibWeb/HTML/Storage.h>
@@ -585,6 +586,36 @@ Messages::WebContentServer::GetElementTagNameResponse ConnectionFromClient::get_
return { element->tag_name() };
}
+// https://w3c.github.io/webdriver/#dfn-calculate-the-absolute-position
+static Gfx::IntPoint calculate_absolute_position_of_element(Web::Page const& page, JS::NonnullGCPtr<Web::Geometry::DOMRect> rect)
+{
+ // 1. Let rect be the value returned by calling getBoundingClientRect().
+
+ // 2. Let window be the associated window of current top-level browsing context.
+ auto const* window = page.top_level_browsing_context().active_window();
+
+ // 3. Let x be (scrollX of window + rect’s x coordinate).
+ auto x = (window ? static_cast<int>(window->scroll_x()) : 0) + static_cast<int>(rect->x());
+
+ // 4. Let y be (scrollY of window + rect’s y coordinate).
+ auto y = (window ? static_cast<int>(window->scroll_y()) : 0) + static_cast<int>(rect->y());
+
+ // 5. Return a pair of (x, y).
+ return { x, y };
+}
+
+Messages::WebContentServer::GetElementRectResponse ConnectionFromClient::get_element_rect(i32 element_id)
+{
+ auto element = find_element_by_id(element_id);
+ if (!element.has_value())
+ return { {} };
+
+ auto bounding_rect = element->get_bounding_client_rect();
+ auto coordinates = calculate_absolute_position_of_element(page(), bounding_rect);
+
+ return { { coordinates.x(), coordinates.y(), static_cast<int>(bounding_rect->width()), static_cast<int>(bounding_rect->height()) } };
+}
+
Messages::WebContentServer::GetSelectedTextResponse ConnectionFromClient::get_selected_text()
{
return page().focused_context().selected_text();
diff --git a/Userland/Services/WebContent/ConnectionFromClient.h b/Userland/Services/WebContent/ConnectionFromClient.h
index 3edf6cf432..b1b23efb26 100644
--- a/Userland/Services/WebContent/ConnectionFromClient.h
+++ b/Userland/Services/WebContent/ConnectionFromClient.h
@@ -90,6 +90,7 @@ private:
virtual Messages::WebContentServer::GetComputedValueForElementResponse get_computed_value_for_element(i32 element_id, String const& property_name) override;
virtual Messages::WebContentServer::GetElementTextResponse get_element_text(i32 element_id) override;
virtual Messages::WebContentServer::GetElementTagNameResponse get_element_tag_name(i32 element_id) override;
+ virtual Messages::WebContentServer::GetElementRectResponse get_element_rect(i32 element_id) override;
virtual Messages::WebContentServer::GetLocalStorageEntriesResponse get_local_storage_entries() override;
virtual Messages::WebContentServer::GetSessionStorageEntriesResponse get_session_storage_entries() override;
diff --git a/Userland/Services/WebContent/WebContentServer.ipc b/Userland/Services/WebContent/WebContentServer.ipc
index db011480a0..e943d6cd51 100644
--- a/Userland/Services/WebContent/WebContentServer.ipc
+++ b/Userland/Services/WebContent/WebContentServer.ipc
@@ -1,6 +1,7 @@
#include <AK/URL.h>
#include <LibIPC/File.h>
#include <LibCore/AnonymousBuffer.h>
+#include <LibGfx/Rect.h>
#include <LibGfx/ShareableBitmap.h>
#include <LibWeb/CSS/PreferredColorScheme.h>
#include <LibWeb/CSS/Selector.h>
@@ -47,6 +48,7 @@ endpoint WebContentServer
get_computed_value_for_element(i32 element_id, String property_name) => (String computed_value)
get_element_text(i32 element_id) => (String text)
get_element_tag_name(i32 element_id) => (String tag_name)
+ get_element_rect(i32 element_id) => (Gfx::IntRect rect)
webdriver_execute_script(String body, Vector<String> json_arguments, Optional<u64> timeout, bool async) => (Web::WebDriver::ExecuteScriptResultType result_type, String json_result)