1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 01:17:34 +00:00

LibWeb: Propagate errors in Element::scroll_into_view()

This patch will allow us to handle scrolling errors in the WebDriver
implementation :)
This commit is contained in:
Baitinq 2022-12-24 13:15:12 +01:00 committed by Andreas Kling
parent 9a66a9ac4a
commit 6a72a4df96
4 changed files with 19 additions and 13 deletions

View file

@ -1475,7 +1475,7 @@ void Document::set_focused_element(Element* element)
// Scroll the viewport if necessary to make the newly focused element visible. // Scroll the viewport if necessary to make the newly focused element visible.
if (m_focused_element) if (m_focused_element)
m_focused_element->scroll_into_view(); (void)m_focused_element->scroll_into_view();
} }
void Document::set_active_element(Element* element) void Document::set_active_element(Element* element)

View file

@ -1183,7 +1183,7 @@ WebIDL::ExceptionOr<void> Element::insert_adjacent_text(DeprecatedString const&
} }
// https://w3c.github.io/csswg-drafts/cssom-view-1/#scroll-an-element-into-view // https://w3c.github.io/csswg-drafts/cssom-view-1/#scroll-an-element-into-view
static void scroll_an_element_into_view(DOM::Element& element, Bindings::ScrollBehavior behavior, Bindings::ScrollLogicalPosition block, Bindings::ScrollLogicalPosition inline_) static ErrorOr<void> scroll_an_element_into_view(DOM::Element& element, Bindings::ScrollBehavior behavior, Bindings::ScrollLogicalPosition block, Bindings::ScrollLogicalPosition inline_)
{ {
// FIXME: The below is ad-hoc, since we don't yet have scrollable elements. // FIXME: The below is ad-hoc, since we don't yet have scrollable elements.
// Return here and implement this according to spec once all overflow is made scrollable. // Return here and implement this according to spec once all overflow is made scrollable.
@ -1193,16 +1193,16 @@ static void scroll_an_element_into_view(DOM::Element& element, Bindings::ScrollB
(void)inline_; (void)inline_;
if (!element.document().browsing_context()) if (!element.document().browsing_context())
return; Error::from_string_view("Element has no browsing context."sv);
auto* page = element.document().browsing_context()->page(); auto* page = element.document().browsing_context()->page();
if (!page) if (!page)
return; return Error::from_string_view("Element has no page."sv);
// If this element doesn't have a layout node, we can't scroll it into view. // If this element doesn't have a layout node, we can't scroll it into view.
element.document().update_layout(); element.document().update_layout();
if (!element.layout_node()) if (!element.layout_node())
return; return Error::from_string_view("Element has no layout node."sv);
// Find the nearest layout node that is a box (since we need a box to get a usable rect) // Find the nearest layout node that is a box (since we need a box to get a usable rect)
auto* layout_node = element.layout_node(); auto* layout_node = element.layout_node();
@ -1210,13 +1210,15 @@ static void scroll_an_element_into_view(DOM::Element& element, Bindings::ScrollB
layout_node = layout_node->parent(); layout_node = layout_node->parent();
if (!layout_node) if (!layout_node)
return; return Error::from_string_view("Element has no parent layout node that is a box."sv);
page->client().page_did_request_scroll_into_view(verify_cast<Layout::Box>(*layout_node).paint_box()->absolute_padding_box_rect()); page->client().page_did_request_scroll_into_view(verify_cast<Layout::Box>(*layout_node).paint_box()->absolute_padding_box_rect());
return {};
} }
// https://w3c.github.io/csswg-drafts/cssom-view-1/#dom-element-scrollintoview // https://w3c.github.io/csswg-drafts/cssom-view-1/#dom-element-scrollintoview
void Element::scroll_into_view(Optional<Variant<bool, ScrollIntoViewOptions>> arg) ErrorOr<void> Element::scroll_into_view(Optional<Variant<bool, ScrollIntoViewOptions>> arg)
{ {
// 1. Let behavior be "auto". // 1. Let behavior be "auto".
auto behavior = Bindings::ScrollBehavior::Auto; auto behavior = Bindings::ScrollBehavior::Auto;
@ -1246,10 +1248,12 @@ void Element::scroll_into_view(Optional<Variant<bool, ScrollIntoViewOptions>> ar
// 6. If the element does not have any associated box, or is not available to user-agent features, then return. // 6. If the element does not have any associated box, or is not available to user-agent features, then return.
document().update_layout(); document().update_layout();
if (!layout_node()) if (!layout_node())
return; return Error::from_string_view("Element has no associated box"sv);
// 7. Scroll the element into view with behavior, block, and inline. // 7. Scroll the element into view with behavior, block, and inline.
scroll_an_element_into_view(*this, behavior, block, inline_); TRY(scroll_an_element_into_view(*this, behavior, block, inline_));
return {};
// FIXME: 8. Optionally perform some other action that brings the element to the users attention. // FIXME: 8. Optionally perform some other action that brings the element to the users attention.
} }

View file

@ -175,7 +175,7 @@ public:
WebIDL::ExceptionOr<void> insert_adjacent_text(DeprecatedString const& where, DeprecatedString const& data); WebIDL::ExceptionOr<void> insert_adjacent_text(DeprecatedString const& where, DeprecatedString const& data);
// https://w3c.github.io/csswg-drafts/cssom-view-1/#dom-element-scrollintoview // https://w3c.github.io/csswg-drafts/cssom-view-1/#dom-element-scrollintoview
void scroll_into_view(Optional<Variant<bool, ScrollIntoViewOptions>> = {}); ErrorOr<void> scroll_into_view(Optional<Variant<bool, ScrollIntoViewOptions>> = {});
protected: protected:
Element(Document&, DOM::QualifiedName); Element(Document&, DOM::QualifiedName);

View file

@ -199,7 +199,7 @@ static ErrorOr<Web::DOM::ShadowRoot*, Web::WebDriver::Error> get_known_shadow_ro
} }
// https://w3c.github.io/webdriver/#dfn-scrolls-into-view // https://w3c.github.io/webdriver/#dfn-scrolls-into-view
static void scroll_element_into_view(Web::DOM::Element& element) static ErrorOr<void> scroll_element_into_view(Web::DOM::Element& element)
{ {
// 1. Let options be the following ScrollIntoViewOptions: // 1. Let options be the following ScrollIntoViewOptions:
Web::DOM::ScrollIntoViewOptions options {}; Web::DOM::ScrollIntoViewOptions options {};
@ -211,7 +211,9 @@ static void scroll_element_into_view(Web::DOM::Element& element)
options.inline_ = Web::Bindings::ScrollLogicalPosition::Nearest; options.inline_ = Web::Bindings::ScrollLogicalPosition::Nearest;
// 2. Run Function.[[Call]](scrollIntoView, options) with element as the this value. // 2. Run Function.[[Call]](scrollIntoView, options) with element as the this value.
element.scroll_into_view(options); TRY(element.scroll_into_view(options));
return {};
} }
template<typename PropertyType = DeprecatedString> template<typename PropertyType = DeprecatedString>
@ -1543,7 +1545,7 @@ Messages::WebDriverClient::TakeElementScreenshotResponse WebDriverConnection::ta
auto* element = TRY(get_known_connected_element(element_id)); auto* element = TRY(get_known_connected_element(element_id));
// 4. Scroll into view the element. // 4. Scroll into view the element.
scroll_element_into_view(*element); (void)scroll_element_into_view(*element);
// 5. When the user agent is next to run the animation frame callbacks: // 5. When the user agent is next to run the animation frame callbacks:
// a. Let element rect be elements rectangle. // a. Let element rect be elements rectangle.