From a139d25189d203e59d7f79f31c60b73ee3d26118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Iv=C4=83ncescu?= Date: Thu, 19 May 2022 21:06:37 +0300 Subject: [PATCH] mshtml: Implement window.cancelAnimationFrame. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gabriel Ivăncescu Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- 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() {