mshtml: Add window.requestAnimationFrame semi-stub implementation.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2021-04-22 01:52:53 +02:00 committed by Alexandre Julliard
parent 37a2368703
commit 101822c04b
5 changed files with 66 additions and 5 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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 = &timestamp;
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));

View File

@ -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);

View File

@ -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);
});