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.
if (m_focused_element)
m_focused_element->scroll_into_view();
(void)m_focused_element->scroll_into_view();
}
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
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.
// 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_;
if (!element.document().browsing_context())
return;
Error::from_string_view("Element has no browsing context."sv);
auto* page = element.document().browsing_context()->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.
element.document().update_layout();
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)
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();
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());
return {};
}
// 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".
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.
document().update_layout();
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.
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.
}

View file

@ -175,7 +175,7 @@ public:
WebIDL::ExceptionOr<void> insert_adjacent_text(DeprecatedString const& where, DeprecatedString const& data);
// 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:
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
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:
Web::DOM::ScrollIntoViewOptions options {};
@ -211,7 +211,9 @@ static void scroll_element_into_view(Web::DOM::Element& element)
options.inline_ = Web::Bindings::ScrollLogicalPosition::Nearest;
// 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>
@ -1543,7 +1545,7 @@ Messages::WebDriverClient::TakeElementScreenshotResponse WebDriverConnection::ta
auto* element = TRY(get_known_connected_element(element_id));
// 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:
// a. Let element rect be elements rectangle.