ソースを参照

LibWebView+WebContent: Add an IPC to scroll an element into view

Note that even though there is no response, this IPC has to be
synchronous to allow all scroll events to trigger before returning to
the calling WebDriver process.
Timothy Flynn 2 年 前
コミット
424e80ee75

+ 5 - 0
Userland/Libraries/LibWebView/OutOfProcessWebView.cpp

@@ -530,6 +530,11 @@ Optional<Vector<i32>> OutOfProcessWebView::query_selector_all(i32 start_node_id,
     return client().query_selector_all(start_node_id, selector);
 }
 
+void OutOfProcessWebView::scroll_element_into_view(i32 element_id)
+{
+    return client().scroll_element_into_view(element_id);
+}
+
 bool OutOfProcessWebView::is_element_selected(i32 element_id)
 {
     return client().is_element_selected(element_id);

+ 1 - 0
Userland/Libraries/LibWebView/OutOfProcessWebView.h

@@ -65,6 +65,7 @@ public:
 
     Optional<i32> get_document_element();
     Optional<Vector<i32>> query_selector_all(i32 start_node_id, String const& selector);
+    void scroll_element_into_view(i32 element_id);
     bool is_element_selected(i32 element_id);
     Optional<String> get_element_attribute(i32 element_id, String const& name);
     Optional<String> get_element_property(i32 element_id, String const& name);

+ 20 - 0
Userland/Services/WebContent/ConnectionFromClient.cpp

@@ -503,6 +503,26 @@ static Optional<Web::DOM::Element&> find_element_by_id(i32 element_id)
     return verify_cast<Web::DOM::Element>(*node);
 }
 
+// https://w3c.github.io/webdriver/#dfn-scrolls-into-view
+void ConnectionFromClient::scroll_element_into_view(i32 element_id)
+{
+    auto element = find_element_by_id(element_id);
+    if (!element.has_value())
+        return;
+
+    // 1. Let options be the following ScrollIntoViewOptions:
+    Web::DOM::ScrollIntoViewOptions options {};
+    // Logical scroll position "block"
+    //     "end"
+    options.block = Web::Bindings::ScrollLogicalPosition::End;
+    // Logical scroll position "inline"
+    //     "nearest"
+    options.inline_ = Web::Bindings::ScrollLogicalPosition::Nearest;
+
+    // 2. Run Function.[[Call]](scrollIntoView, options) with element as the this value.
+    element->scroll_into_view(options);
+}
+
 Messages::WebContentServer::IsElementSelectedResponse ConnectionFromClient::is_element_selected(i32 element_id)
 {
     auto element = find_element_by_id(element_id);

+ 1 - 0
Userland/Services/WebContent/ConnectionFromClient.h

@@ -85,6 +85,7 @@ private:
 
     virtual Messages::WebContentServer::GetDocumentElementResponse get_document_element() override;
     virtual Messages::WebContentServer::QuerySelectorAllResponse query_selector_all(i32 start_node_id, String const& selector) override;
+    virtual void scroll_element_into_view(i32 element_id) override;
     virtual Messages::WebContentServer::IsElementSelectedResponse is_element_selected(i32 element_id) override;
     virtual Messages::WebContentServer::GetElementAttributeResponse get_element_attribute(i32 element_id, String const& name) override;
     virtual Messages::WebContentServer::GetElementPropertyResponse get_element_property(i32 element_id, String const& name) override;

+ 1 - 0
Userland/Services/WebContent/WebContentServer.ipc

@@ -42,6 +42,7 @@ endpoint WebContentServer
 
     get_document_element() => (Optional<i32> node_id)
     query_selector_all(i32 start_node_id, String selector) => (Optional<Vector<i32>> elements_ids)
+    scroll_element_into_view(i32 element_id) => ()
     is_element_selected(i32 element_id) => (bool selected)
     get_element_attribute(i32 element_id, String name) => (Optional<String> attribute)
     get_element_property(i32 element_id, String name) => (Optional<String> property)