Gabriel Ivăncescu : mshtml: Implement window.cancelAnimationFrame.

Alexandre Julliard julliard at winehq.org
Fri May 20 15:26:48 CDT 2022


Module: wine
Branch: master
Commit: a139d25189d203e59d7f79f31c60b73ee3d26118
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=a139d25189d203e59d7f79f31c60b73ee3d26118

Author: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Date:   Thu May 19 21:06:37 2022 +0300

mshtml: Implement window.cancelAnimationFrame.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/mshtml/htmlwindow.c             | 15 +++++++++++++++
 dlls/mshtml/mshtml_private.h         |  1 +
 dlls/mshtml/mshtml_private_iface.idl |  4 +++-
 dlls/mshtml/task.c                   | 23 ++++++++++++++++++++++-
 dlls/mshtml/tests/documentmode.js    |  1 +
 dlls/mshtml/tests/dom.js             | 10 +++++++++-
 6 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c
index ecd530db7e2..235e29a3070 100644
--- a/dlls/mshtml/htmlwindow.c
+++ b/dlls/mshtml/htmlwindow.c
@@ -3152,6 +3152,20 @@ static HRESULT WINAPI window_private_requestAnimationFrame(IWineHTMLWindowPrivat
     return hres;
 }
 
+static HRESULT WINAPI window_private_cancelAnimationFrame(IWineHTMLWindowPrivate *iface, VARIANT timer_id)
+{
+    HTMLWindow *This = impl_from_IWineHTMLWindowPrivateVtbl(iface);
+    HRESULT hres;
+
+    TRACE("iface %p, timer_id %s\n", iface, debugstr_variant(&timer_id));
+
+    hres = VariantChangeType(&timer_id, &timer_id, 0, VT_I4);
+    if(SUCCEEDED(hres))
+        clear_animation_timer(This->inner_window, V_I4(&timer_id));
+
+    return S_OK;
+}
+
 static HRESULT WINAPI window_private_get_console(IWineHTMLWindowPrivate *iface, IDispatch **console)
 {
     HTMLWindow *This = impl_from_IWineHTMLWindowPrivateVtbl(iface);
@@ -3176,6 +3190,7 @@ static const IWineHTMLWindowPrivateVtbl WineHTMLWindowPrivateVtbl = {
     window_private_GetIDsOfNames,
     window_private_Invoke,
     window_private_requestAnimationFrame,
+    window_private_cancelAnimationFrame,
     window_private_get_console,
 };
 
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index a94f1be1969..930ab3bbe19 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -1247,6 +1247,7 @@ enum timer_type {
 
 HRESULT set_task_timer(HTMLInnerWindow*,LONG,enum timer_type,IDispatch*,LONG*) DECLSPEC_HIDDEN;
 HRESULT clear_task_timer(HTMLInnerWindow*,DWORD) DECLSPEC_HIDDEN;
+HRESULT clear_animation_timer(HTMLInnerWindow*,DWORD) DECLSPEC_HIDDEN;
 
 BOOL parse_compat_version(const WCHAR*,compat_mode_t*) DECLSPEC_HIDDEN;
 
diff --git a/dlls/mshtml/mshtml_private_iface.idl b/dlls/mshtml/mshtml_private_iface.idl
index b9039c956db..a273e330665 100644
--- a/dlls/mshtml/mshtml_private_iface.idl
+++ b/dlls/mshtml/mshtml_private_iface.idl
@@ -87,7 +87,9 @@ interface IWineHTMLWindowPrivate : IDispatch
 {
     [id(50)]
     HRESULT requestAnimationFrame([in] VARIANT *expr, [retval, out] VARIANT *timer_id);
-    [propget, id(51)]
+    [id(51)]
+    HRESULT cancelAnimationFrame([in] VARIANT timer_id);
+    [propget, id(52)]
     HRESULT console([retval, out] IDispatch **console);
 }
 
diff --git a/dlls/mshtml/task.c b/dlls/mshtml/task.c
index 088742e902a..1bb761e1f0f 100644
--- a/dlls/mshtml/task.c
+++ b/dlls/mshtml/task.c
@@ -208,7 +208,8 @@ HRESULT clear_task_timer(HTMLInnerWindow *window, DWORD id)
 
     LIST_FOR_EACH_ENTRY(iter, &thread_data->timer_list, task_timer_t, entry) {
         if(iter->id == id && iter->window == window) {
-            release_task_timer(thread_data->thread_hwnd, iter);
+            if(iter->type != TIMER_ANIMATION_FRAME)
+                release_task_timer(thread_data->thread_hwnd, iter);
             return S_OK;
         }
     }
@@ -217,6 +218,26 @@ HRESULT clear_task_timer(HTMLInnerWindow *window, DWORD id)
     return S_OK;
 }
 
+HRESULT clear_animation_timer(HTMLInnerWindow *window, DWORD id)
+{
+    thread_data_t *thread_data = get_thread_data(FALSE);
+    task_timer_t *iter;
+
+    if(!thread_data)
+        return S_OK;
+
+    LIST_FOR_EACH_ENTRY(iter, &thread_data->timer_list, task_timer_t, entry) {
+        if(iter->id == id && iter->window == window) {
+            if(iter->type == TIMER_ANIMATION_FRAME)
+                release_task_timer(thread_data->thread_hwnd, iter);
+            return S_OK;
+        }
+    }
+
+    WARN("timer not found\n");
+    return S_OK;
+}
+
 static const char *debugstr_timer_type(enum timer_type type)
 {
     switch(type) {
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js
index eeeb1c88430..5f104475f0d 100644
--- a/dlls/mshtml/tests/documentmode.js
+++ b/dlls/mshtml/tests/documentmode.js
@@ -357,6 +357,7 @@ sync_test("window_props", function() {
     test_exposed("getSelection", v >= 9);
     test_exposed("onfocusout", v >= 9);
     test_exposed("getComputedStyle", v >= 9);
+    test_exposed("cancelAnimationFrame", v >= 10);
     test_exposed("requestAnimationFrame", v >= 10);
     test_exposed("Map", v >= 11);
     test_exposed("Set", v >= 11);
diff --git a/dlls/mshtml/tests/dom.js b/dlls/mshtml/tests/dom.js
index ed5f72c4376..3939dd95642 100644
--- a/dlls/mshtml/tests/dom.js
+++ b/dlls/mshtml/tests/dom.js
@@ -494,13 +494,21 @@ sync_test("elem_props", function() {
 });
 
 async_test("animation_frame", function() {
-    var id = requestAnimationFrame(function(x) {
+    var id = requestAnimationFrame(function(x) { ok(false, "request was supposed to be cancelled"); });
+    id = cancelAnimationFrame(id);
+    ok(id === undefined, "cancelAnimationFrame returned " + id);
+
+    id = requestAnimationFrame(function(x) {
         ok(this === window, "this != window");
         ok(typeof(x) === "number", "x = " + x);
         ok(arguments.length === 1, "arguments.length = " + arguments.length);
         next_test();
     });
+    cancelAnimationFrame(0);
+    clearInterval(id);
+    clearTimeout(id);
     ok(typeof(id) === "number", "id = " + id);
+    ok(id !== 0, "id = 0");
 });
 
 sync_test("title", function() {




More information about the wine-cvs mailing list