Pārlūkot izejas kodu

LibWeb: Make requestAnimationFrame() callback IDs sequential

This is required by the spec, so let's stop returning random IDs in
favor of a simple sequential integer sequence.
Andreas Kling 11 mēneši atpakaļ
vecāks
revīzija
0e1256e5a4

+ 1 - 0
Tests/LibWeb/Text/expected/HTML/requestAnimationFrame-sequential.txt

@@ -0,0 +1 @@
+1,2,3

+ 14 - 0
Tests/LibWeb/Text/input/HTML/requestAnimationFrame-sequential.html

@@ -0,0 +1,14 @@
+<script src="../include.js"></script>
+<script>
+    var rafIds = [];
+    asyncTest((done) => {
+        rafIds.push(requestAnimationFrame(function() {
+            rafIds.push(requestAnimationFrame(function() {
+                rafIds.push(requestAnimationFrame(function() {
+                    println(rafIds);
+                    done();
+                }));
+            }));
+        }));
+    });
+</script>

+ 9 - 7
Userland/Libraries/LibWeb/HTML/AnimationFrameCallbackDriver.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2022, the SerenityOS developers.
+ * Copyright (c) 2024, Andreas Kling <andreas@ladybird.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -8,9 +9,9 @@
 
 #include <AK/Function.h>
 #include <AK/HashMap.h>
-#include <AK/IDAllocator.h>
 #include <LibCore/Timer.h>
 #include <LibWeb/HTML/EventLoop/EventLoop.h>
+#include <LibWeb/WebIDL/Types.h>
 
 namespace Web::HTML {
 
@@ -24,22 +25,21 @@ struct AnimationFrameCallbackDriver {
         });
     }
 
-    i32 add(Callback handler)
+    [[nodiscard]] WebIDL::UnsignedLong add(Callback handler)
     {
-        auto id = m_id_allocator.allocate();
+        auto id = ++m_animation_frame_callback_identifier;
         m_callbacks.set(id, move(handler));
         if (!m_timer->is_active())
             m_timer->start();
         return id;
     }
 
-    bool remove(i32 id)
+    bool remove(WebIDL::UnsignedLong id)
     {
         auto it = m_callbacks.find(id);
         if (it == m_callbacks.end())
             return false;
         m_callbacks.remove(it);
-        m_id_allocator.deallocate(id);
         return true;
     }
 
@@ -56,8 +56,10 @@ struct AnimationFrameCallbackDriver {
     }
 
 private:
-    OrderedHashMap<i32, Callback> m_callbacks;
-    IDAllocator m_id_allocator;
+    // https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#animation-frame-callback-identifier
+    WebIDL::UnsignedLong m_animation_frame_callback_identifier { 0 };
+
+    OrderedHashMap<WebIDL::UnsignedLong, Callback> m_callbacks;
     RefPtr<Core::Timer> m_timer;
 };
 

+ 3 - 3
Userland/Libraries/LibWeb/HTML/Window.cpp

@@ -1438,7 +1438,7 @@ double Window::device_pixel_ratio() const
 }
 
 // https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#dom-animationframeprovider-requestanimationframe
-i32 Window::request_animation_frame(WebIDL::CallbackType& callback)
+WebIDL::UnsignedLong Window::request_animation_frame(WebIDL::CallbackType& callback)
 {
     // FIXME: Make this fully spec compliant. Currently implements a mix of 'requestAnimationFrame()' and 'run the animation frame callbacks'.
     return m_animation_frame_callback_driver.add([this, callback = JS::make_handle(callback)](double now) {
@@ -1450,14 +1450,14 @@ i32 Window::request_animation_frame(WebIDL::CallbackType& callback)
 }
 
 // https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#animationframeprovider-cancelanimationframe
-void Window::cancel_animation_frame(i32 handle)
+void Window::cancel_animation_frame(WebIDL::UnsignedLong handle)
 {
     // 1. If this is not supported, then throw a "NotSupportedError" DOMException.
     // NOTE: Doesn't apply in this Window-specific implementation.
 
     // 2. Let callbacks be this's target object's map of animation frame callbacks.
     // 3. Remove callbacks[handle].
-    m_animation_frame_callback_driver.remove(handle);
+    (void)m_animation_frame_callback_driver.remove(handle);
 }
 
 // https://w3c.github.io/requestidlecallback/#dom-window-requestidlecallback

+ 4 - 3
Userland/Libraries/LibWeb/HTML/Window.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2020-2024, Andreas Kling <andreas@ladybird.org>
  * Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
@@ -27,6 +27,7 @@
 #include <LibWeb/HTML/WindowEventHandlers.h>
 #include <LibWeb/HTML/WindowOrWorkerGlobalScope.h>
 #include <LibWeb/RequestIdleCallback/IdleRequest.h>
+#include <LibWeb/WebIDL/Types.h>
 
 namespace Web::HTML {
 
@@ -201,8 +202,8 @@ public:
     i32 outer_height() const;
     double device_pixel_ratio() const;
 
-    i32 request_animation_frame(WebIDL::CallbackType&);
-    void cancel_animation_frame(i32 handle);
+    WebIDL::UnsignedLong request_animation_frame(WebIDL::CallbackType&);
+    void cancel_animation_frame(WebIDL::UnsignedLong handle);
 
     u32 request_idle_callback(WebIDL::CallbackType&, RequestIdleCallback::IdleRequestOptions const&);
     void cancel_idle_callback(u32 handle);

+ 1 - 1
Userland/Libraries/LibWeb/WebDriver/Screenshot.cpp

@@ -54,7 +54,7 @@ Response capture_element_screenshot(Painter const& painter, Page& page, DOM::Ele
 {
     Optional<Response> encoded_string_or_error;
 
-    element.document().window()->animation_frame_callback_driver().add([&](auto) {
+    (void)element.document().window()->animation_frame_callback_driver().add([&](auto) {
         auto viewport_rect = page.top_level_traversable()->viewport_rect();
         rect.intersect(page.enclosing_device_rect(viewport_rect).to_type<int>());