Jacek Caban : mshtml: Add window.requestAnimationFrame semi-stub implementation.

Alexandre Julliard julliard at winehq.org
Thu Apr 22 15:55:24 CDT 2021


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Apr 22 01:52:53 2021 +0200

mshtml: Add window.requestAnimationFrame semi-stub implementation.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/mshtml/htmlwindow.c          | 29 +++++++++++++++++++++++++++++
 dlls/mshtml/mshtml_private.h      |  1 +
 dlls/mshtml/task.c                | 30 +++++++++++++++++++++++++-----
 dlls/mshtml/tests/documentmode.js |  1 +
 dlls/mshtml/tests/dom.js          | 10 ++++++++++
 5 files changed, 66 insertions(+), 5 deletions(-)

diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c
index e535cd54bd6..4c57d457e41 100644
--- a/dlls/mshtml/htmlwindow.c
+++ b/dlls/mshtml/htmlwindow.c
@@ -3170,6 +3170,9 @@ HRESULT search_window_props(HTMLInnerWindow *This, BSTR bstrName, DWORD grfdex,
     return DISP_E_UNKNOWNNAME;
 }
 
+/* DISPIDs not exposed by interfaces */
+#define DISPID_IHTMLWINDOW_IE10_REQUESTANIMATIONFRAME 1300
+
 static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
 {
     HTMLWindow *This = impl_from_IDispatchEx(iface);
@@ -3186,6 +3189,13 @@ static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName,
     if(hres != DISP_E_UNKNOWNNAME)
         return hres;
 
+    if(dispex_compat_mode(&window->event_target.dispex) >= COMPAT_MODE_IE10 &&
+       !wcscmp(bstrName, L"requestAnimationFrame")) {
+        TRACE("requestAnimationFrame\n");
+        *pid = DISPID_IHTMLWINDOW_IE10_REQUESTANIMATIONFRAME;
+        return S_OK;
+    }
+
     if(This->outer_window) {
         HTMLOuterWindow *frame;
 
@@ -3272,6 +3282,25 @@ static HRESULT WINAPI WindowDispEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID
         return IDispatchEx_InvokeEx(&window->event_target.dispex.IDispatchEx_iface, id, lcid,
                 wFlags, &dp, pvarRes, pei, pspCaller);
     }
+    case DISPID_IHTMLWINDOW_IE10_REQUESTANIMATIONFRAME: {
+        HRESULT hres;
+        LONG r;
+
+        FIXME("requestAnimationFrame: semi-stub\n");
+
+        if(!(wFlags & DISPATCH_METHOD) || pdp->cArgs != 1 || pdp->cNamedArgs) {
+            FIXME("unsupported args\n");
+            return E_INVALIDARG;
+        }
+
+        hres = window_set_timer(window, pdp->rgvarg, 50, NULL, TIMER_ANIMATION_FRAME, &r);
+        if(SUCCEEDED(hres) && pvarRes) {
+            V_VT(pvarRes) = VT_I4;
+            V_I4(pvarRes) = r;
+        }
+
+        return hres;
+    }
     }
 
     return IDispatchEx_InvokeEx(&window->event_target.dispex.IDispatchEx_iface, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 9d1737cc81f..7bc645e549f 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -1217,6 +1217,7 @@ ULONGLONG get_time_stamp(void) DECLSPEC_HIDDEN;
 enum timer_type {
     TIMER_TIMEOUT,
     TIMER_INTERVAL,
+    TIMER_ANIMATION_FRAME,
 };
 
 HRESULT set_task_timer(HTMLInnerWindow*,LONG,enum timer_type,IDispatch*,LONG*) DECLSPEC_HIDDEN;
diff --git a/dlls/mshtml/task.c b/dlls/mshtml/task.c
index b7616058461..28cb88ab5f1 100644
--- a/dlls/mshtml/task.c
+++ b/dlls/mshtml/task.c
@@ -218,9 +218,20 @@ HRESULT clear_task_timer(HTMLInnerWindow *window, DWORD id)
     return S_OK;
 }
 
-static void call_timer_disp(IDispatch *disp)
+static const char *debugstr_timer_type(enum timer_type type)
+{
+    switch(type) {
+    case TIMER_TIMEOUT:  return "timeout";
+    case TIMER_INTERVAL: return "interval";
+    case TIMER_ANIMATION_FRAME: return "animation-frame";
+    DEFAULT_UNREACHABLE;
+    }
+}
+
+static void call_timer_disp(IDispatch *disp, enum timer_type timer_type)
 {
     DISPPARAMS dp = {NULL, NULL, 0, 0};
+    VARIANT timestamp;
     EXCEPINFO ei;
     VARIANT res;
     HRESULT hres;
@@ -228,12 +239,19 @@ static void call_timer_disp(IDispatch *disp)
     V_VT(&res) = VT_EMPTY;
     memset(&ei, 0, sizeof(ei));
 
-    TRACE(">>>\n");
+    if(timer_type == TIMER_ANIMATION_FRAME) {
+        dp.cArgs = 1;
+        dp.rgvarg = ×tamp;
+        V_VT(&timestamp) = VT_R8;
+        V_R8(&timestamp) = get_time_stamp();
+    }
+
+    TRACE("%p %s >>>\n", disp, debugstr_timer_type(timer_type));
     hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dp, &res, &ei, NULL);
     if(hres == S_OK)
-        TRACE("<<<\n");
+        TRACE("%p %s <<<\n", disp, debugstr_timer_type(timer_type));
     else
-        WARN("<<< %08x\n", hres);
+        WARN("%p %s <<< %08x\n", disp, debugstr_timer_type(timer_type), hres);
 
     VariantClear(&res);
 }
@@ -241,6 +259,7 @@ static void call_timer_disp(IDispatch *disp)
 static LRESULT process_timer(void)
 {
     thread_data_t *thread_data;
+    enum timer_type timer_type;
     IDispatch *disp;
     DWORD tc;
     task_timer_t *timer=NULL, *last_timer;
@@ -273,6 +292,7 @@ static LRESULT process_timer(void)
 
         disp = timer->disp;
         IDispatch_AddRef(disp);
+        timer_type = timer->type;
 
         if(timer->interval) {
             timer->time += timer->interval;
@@ -281,7 +301,7 @@ static LRESULT process_timer(void)
             release_task_timer(thread_data->thread_hwnd, timer);
         }
 
-        call_timer_disp(disp);
+        call_timer_disp(disp, timer_type);
 
         IDispatch_Release(disp);
     }while(!list_empty(&thread_data->timer_list));
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js
index 35b4a001fed..7074b1f62f2 100644
--- a/dlls/mshtml/tests/documentmode.js
+++ b/dlls/mshtml/tests/documentmode.js
@@ -115,6 +115,7 @@ sync_test("window_props", function() {
     test_exposed("getSelection", v >= 9);
     test_exposed("onfocusout", v >= 9);
     test_exposed("getComputedStyle", v >= 9);
+    test_exposed("requestAnimationFrame", v >= 10);
     test_exposed("Set", v >= 11);
     if(v >= 9) /* FIXME: native exposes it in all compat modes */
         test_exposed("performance", true);
diff --git a/dlls/mshtml/tests/dom.js b/dlls/mshtml/tests/dom.js
index f5e4f393b58..b30d1a8fbed 100644
--- a/dlls/mshtml/tests/dom.js
+++ b/dlls/mshtml/tests/dom.js
@@ -448,3 +448,13 @@ sync_test("elem_props", function() {
     elem.accessKey = "q";
     ok(elem.accessKey === "q", "accessKey = " + elem.accessKey + " expected q");
 });
+
+async_test("animation_frame", function() {
+    var id = requestAnimationFrame(function(x) {
+        ok(this === window, "this != window");
+        ok(typeof(x) === "number", "x = " + x);
+        ok(arguments.length === 1, "arguments.lenght = " + arguments.length);
+        next_test();
+    });
+    ok(typeof(id) === "number", "id = " + id);
+});




More information about the wine-cvs mailing list