mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
LibWeb/HTML: Port Window.scrollBy() to IDL
This commit is contained in:
parent
2b6d9cca1a
commit
3d075e55f5
Notes:
sideshowbarker
2024-07-17 03:03:37 +09:00
Author: https://github.com/linusg Commit: https://github.com/SerenityOS/serenity/commit/3d075e55f5 Pull-request: https://github.com/SerenityOS/serenity/pull/17752 Reviewed-by: https://github.com/awesomekling
3 changed files with 43 additions and 54 deletions
|
@ -1017,8 +1017,6 @@ WebIDL::ExceptionOr<void> Window::initialize_web_interfaces(Badge<WindowEnvironm
|
|||
define_native_function(realm, "fetch", Bindings::fetch, 1, attr);
|
||||
|
||||
// FIXME: These properties should be [Replaceable] according to the spec, but [Writable+Configurable] is the closest we have.
|
||||
define_native_function(realm, "scrollBy", scroll_by, 2, attr);
|
||||
|
||||
define_native_accessor(realm, "screenX", screen_x_getter, {}, attr);
|
||||
define_native_accessor(realm, "screenY", screen_y_getter, {}, attr);
|
||||
define_native_accessor(realm, "screenLeft", screen_left_getter, {}, attr);
|
||||
|
@ -1417,12 +1415,51 @@ void Window::scroll(double x, double y)
|
|||
auto options = ScrollToOptions {};
|
||||
|
||||
// 2. Let x and y be the arguments, respectively.
|
||||
|
||||
options.left = x;
|
||||
options.top = y;
|
||||
|
||||
scroll(options);
|
||||
}
|
||||
|
||||
// https://w3c.github.io/csswg-drafts/cssom-view/#dom-window-scrollby
|
||||
void Window::scroll_by(ScrollToOptions options)
|
||||
{
|
||||
// 2. Normalize non-finite values for the left and top dictionary members of options.
|
||||
auto x = options.left.value_or(0);
|
||||
auto y = options.top.value_or(0);
|
||||
x = JS::Value(x).is_finite_number() ? x : 0;
|
||||
y = JS::Value(y).is_finite_number() ? y : 0;
|
||||
|
||||
// 3. Add the value of scrollX to the left dictionary member.
|
||||
options.left = x + scroll_x();
|
||||
|
||||
// 4. Add the value of scrollY to the top dictionary member.
|
||||
options.top = y + scroll_y();
|
||||
|
||||
// 5. Act as if the scroll() method was invoked with options as the only argument.
|
||||
scroll(options);
|
||||
}
|
||||
|
||||
// https://w3c.github.io/csswg-drafts/cssom-view/#dom-window-scrollby
|
||||
void Window::scroll_by(double x, double y)
|
||||
{
|
||||
// 1. If invoked with two arguments, follow these substeps:
|
||||
|
||||
// 1. Let options be null converted to a ScrollToOptions dictionary. [WEBIDL]
|
||||
auto options = ScrollToOptions {};
|
||||
|
||||
// 2. Let x and y be the arguments, respectively.
|
||||
|
||||
// 3. Let the left dictionary member of options have the value x.
|
||||
options.left = x;
|
||||
|
||||
// 4. Let the top dictionary member of options have the value y.
|
||||
options.top = y;
|
||||
|
||||
scroll_by(options);
|
||||
}
|
||||
|
||||
// https://w3c.github.io/hr-time/#dom-windoworworkerglobalscope-performance
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<HighResolutionTime::Performance>> Window::performance()
|
||||
{
|
||||
|
@ -1643,56 +1680,6 @@ JS_DEFINE_NATIVE_FUNCTION(Window::get_selection)
|
|||
return impl->associated_document().get_selection();
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/cssom-view/#dom-window-scrollby
|
||||
JS_DEFINE_NATIVE_FUNCTION(Window::scroll_by)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
auto* impl = TRY(impl_from(vm));
|
||||
if (!impl->page())
|
||||
return JS::js_undefined();
|
||||
auto& page = *impl->page();
|
||||
|
||||
JS::Object* options = nullptr;
|
||||
|
||||
if (vm.argument_count() == 0) {
|
||||
options = JS::Object::create(realm, nullptr);
|
||||
} else if (vm.argument_count() == 1) {
|
||||
options = TRY(vm.argument(0).to_object(vm));
|
||||
} else if (vm.argument_count() >= 2) {
|
||||
// We ignore arguments 2+ in line with behavior of Chrome and Firefox
|
||||
options = JS::Object::create(realm, nullptr);
|
||||
MUST(options->set("left", vm.argument(0), ShouldThrowExceptions::No));
|
||||
MUST(options->set("top", vm.argument(1), ShouldThrowExceptions::No));
|
||||
MUST(options->set("behavior", MUST_OR_THROW_OOM(JS::PrimitiveString::create(vm, "auto"sv)), ShouldThrowExceptions::No));
|
||||
}
|
||||
|
||||
auto left_value = TRY(options->get("left"));
|
||||
auto left = TRY(left_value.to_double(vm));
|
||||
|
||||
auto top_value = TRY(options->get("top"));
|
||||
auto top = TRY(top_value.to_double(vm));
|
||||
|
||||
left = JS::Value(left).is_finite_number() ? left : 0.0;
|
||||
top = JS::Value(top).is_finite_number() ? top : 0.0;
|
||||
|
||||
auto current_scroll_position = page.top_level_browsing_context().viewport_scroll_offset().to_type<float>();
|
||||
left = left + static_cast<double>(current_scroll_position.x());
|
||||
top = top + static_cast<double>(current_scroll_position.y());
|
||||
|
||||
auto behavior_string_value = TRY(options->get("behavior"));
|
||||
auto behavior_string = behavior_string_value.is_undefined() ? "auto" : TRY(behavior_string_value.to_deprecated_string(vm));
|
||||
if (behavior_string != "smooth" && behavior_string != "auto")
|
||||
return vm.throw_completion<JS::TypeError>("Behavior is not one of 'smooth' or 'auto'"sv);
|
||||
auto behavior = (behavior_string == "smooth") ? Bindings::ScrollBehavior::Smooth : Bindings::ScrollBehavior::Auto;
|
||||
|
||||
// FIXME: Spec wants us to call scroll(options) here.
|
||||
// The only difference is that would invoke the viewport calculations that scroll()
|
||||
// is not actually doing yet, so this is the same for now.
|
||||
perform_a_scroll(page, left, top, nullptr, behavior);
|
||||
return JS::js_undefined();
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(Window::screen_left_getter)
|
||||
{
|
||||
auto* impl = TRY(impl_from(vm));
|
||||
|
|
|
@ -177,6 +177,8 @@ public:
|
|||
double scroll_y() const;
|
||||
void scroll(ScrollToOptions const&);
|
||||
void scroll(double x, double y);
|
||||
void scroll_by(ScrollToOptions);
|
||||
void scroll_by(double x, double y);
|
||||
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<HighResolutionTime::Performance>> performance();
|
||||
|
||||
|
@ -246,8 +248,6 @@ private:
|
|||
|
||||
JS_DECLARE_NATIVE_FUNCTION(device_pixel_ratio_getter);
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(scroll_by);
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(screen_x_getter);
|
||||
JS_DECLARE_NATIVE_FUNCTION(screen_y_getter);
|
||||
JS_DECLARE_NATIVE_FUNCTION(screen_left_getter);
|
||||
|
|
|
@ -61,6 +61,8 @@ interface Window : EventTarget {
|
|||
undefined scroll(unrestricted double x, unrestricted double y);
|
||||
[ImplementedAs=scroll] undefined scrollTo(optional ScrollToOptions options = {});
|
||||
[ImplementedAs=scroll] undefined scrollTo(unrestricted double x, unrestricted double y);
|
||||
undefined scrollBy(optional ScrollToOptions options = {});
|
||||
undefined scrollBy(unrestricted double x, unrestricted double y);
|
||||
|
||||
// FIXME: Everything from here on should be shared through WindowOrWorkerGlobalScope
|
||||
// https://w3c.github.io/hr-time/#the-performance-attribute
|
||||
|
|
Loading…
Reference in a new issue