-- v3: mshtml: Implement performance.timing.msFirstPaint. mshtml: Implement performance.timing.loadEventStart & loadEventEnd. mshtml: Get rid of useless window check. mshtml: Implement performance.timing.domContentLoadedEventStart & End. mshtml: Implement performance.timing.domComplete. mshtml: Implement performance.timing.domInteractive. mshtml: Implement performance.timing.domLoading. mshtml: Implement performance.timing.responseStart & responseEnd. mshtml: Implement the remaining pre-response performance.timing props. mshtml: Implement performance.timing.unloadEventStart & unloadEventEnd. mshtml: Implement performance.timing.redirectStart. mshtml: Implement performance.timing.navigationStart. mshtml: Link the performance.timing from the window at creation. mshtml: Fix performance variant leak.
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlwindow.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index baaedb6b6d4..5c5f0542ddd 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -308,6 +308,8 @@ static void release_inner_window(HTMLInnerWindow *This) IHTMLStorage_Release(This->local_storage); }
+ VariantClear(&This->performance); + if(This->mon) IMoniker_Release(This->mon);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
This avoids having to keep refs to the window from the performance timing. The dispex initialization is deferred until it's actually used, however, so it has the proper compat mode.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlwindow.c | 8 ++++++ dlls/mshtml/mshtml_private.h | 11 +++++++- dlls/mshtml/omnavigator.c | 53 ++++++++++++++++++------------------ 3 files changed, 45 insertions(+), 27 deletions(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 5c5f0542ddd..0bf1a2c6ce3 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -308,6 +308,7 @@ static void release_inner_window(HTMLInnerWindow *This) IHTMLStorage_Release(This->local_storage); }
+ IHTMLPerformanceTiming_Release(&This->performance_timing->IHTMLPerformanceTiming_iface); VariantClear(&This->performance);
if(This->mon) @@ -4056,11 +4057,18 @@ static void *alloc_window(size_t size) static HRESULT create_inner_window(HTMLOuterWindow *outer_window, IMoniker *mon, HTMLInnerWindow **ret) { HTMLInnerWindow *window; + HRESULT hres;
window = alloc_window(sizeof(HTMLInnerWindow)); if(!window) return E_OUTOFMEMORY;
+ hres = create_performance_timing(&window->performance_timing); + if(FAILED(hres)) { + heap_free(window); + return hres; + } + list_init(&window->children); list_init(&window->script_hosts); list_init(&window->bindings); diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index d9e2d93d220..744dc4c7801 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -503,6 +503,13 @@ typedef struct { HTMLInnerWindow *window; } OmHistory;
+typedef struct { + DispatchEx dispex; + IHTMLPerformanceTiming IHTMLPerformanceTiming_iface; + + LONG ref; +} HTMLPerformanceTiming; + typedef struct nsChannelBSC nsChannelBSC;
struct HTMLWindow { @@ -579,6 +586,7 @@ struct HTMLInnerWindow {
BOOL performance_initialized; VARIANT performance; + HTMLPerformanceTiming *performance_timing;
unsigned parser_callback_cnt; struct list script_queue; @@ -966,7 +974,8 @@ HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow*,HTMLXMLHttpRequestFact HRESULT HTMLLocation_Create(HTMLInnerWindow*,HTMLLocation**) DECLSPEC_HIDDEN; HRESULT create_navigator(compat_mode_t,IOmNavigator**) DECLSPEC_HIDDEN; HRESULT create_html_screen(compat_mode_t,IHTMLScreen**) DECLSPEC_HIDDEN; -HRESULT create_performance(compat_mode_t,IHTMLPerformance**) DECLSPEC_HIDDEN; +HRESULT create_performance(HTMLInnerWindow*,IHTMLPerformance**) DECLSPEC_HIDDEN; +HRESULT create_performance_timing(HTMLPerformanceTiming**) DECLSPEC_HIDDEN; HRESULT create_history(HTMLInnerWindow*,OmHistory**) DECLSPEC_HIDDEN; HRESULT create_namespace_collection(compat_mode_t,IHTMLNamespaceCollection**) DECLSPEC_HIDDEN; HRESULT create_dom_implementation(HTMLDocumentNode*,IHTMLDOMImplementation**) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index db48cc6213b..4551f4e2dc3 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -1497,13 +1497,6 @@ HRESULT create_navigator(compat_mode_t compat_mode, IOmNavigator **navigator) return S_OK; }
-typedef struct { - DispatchEx dispex; - IHTMLPerformanceTiming IHTMLPerformanceTiming_iface; - - LONG ref; -} HTMLPerformanceTiming; - static inline HTMLPerformanceTiming *impl_from_IHTMLPerformanceTiming(IHTMLPerformanceTiming *iface) { return CONTAINING_RECORD(iface, HTMLPerformanceTiming, IHTMLPerformanceTiming_iface); @@ -1549,7 +1542,8 @@ static ULONG WINAPI HTMLPerformanceTiming_Release(IHTMLPerformanceTiming *iface) TRACE("(%p) ref=%ld\n", This, ref);
if(!ref) { - release_dispex(&This->dispex); + if(This->dispex.outer) + release_dispex(&This->dispex); heap_free(This); }
@@ -1863,6 +1857,22 @@ static dispex_static_data_t HTMLPerformanceTiming_dispex = { HTMLPerformanceTiming_iface_tids };
+HRESULT create_performance_timing(HTMLPerformanceTiming **ret) +{ + HTMLPerformanceTiming *timing; + + timing = heap_alloc_zero(sizeof(*timing)); + if(!timing) + return E_OUTOFMEMORY; + + timing->IHTMLPerformanceTiming_iface.lpVtbl = &HTMLPerformanceTimingVtbl; + timing->ref = 1; + + /* Defer initializing the dispex until it's actually needed (for compat mode) */ + *ret = timing; + return S_OK; +} + typedef struct { DispatchEx dispex; IHTMLPerformanceNavigation IHTMLPerformanceNavigation_iface; @@ -2070,8 +2080,7 @@ static ULONG WINAPI HTMLPerformance_Release(IHTMLPerformance *iface) TRACE("(%p) ref=%ld\n", This, ref);
if(!ref) { - if(This->timing) - IHTMLPerformanceTiming_Release(This->timing); + IHTMLPerformanceTiming_Release(This->timing); if(This->navigation) IHTMLPerformanceNavigation_Release(This->navigation); release_dispex(&This->dispex); @@ -2148,21 +2157,6 @@ static HRESULT WINAPI HTMLPerformance_get_timing(IHTMLPerformance *iface, IHTMLP
TRACE("(%p)->(%p)\n", This, p);
- if(!This->timing) { - HTMLPerformanceTiming *timing; - - timing = heap_alloc_zero(sizeof(*timing)); - if(!timing) - return E_OUTOFMEMORY; - - timing->IHTMLPerformanceTiming_iface.lpVtbl = &HTMLPerformanceTimingVtbl; - timing->ref = 1; - init_dispatch(&timing->dispex, (IUnknown*)&timing->IHTMLPerformanceTiming_iface, - &HTMLPerformanceTiming_dispex, dispex_compat_mode(&This->dispex)); - - This->timing = &timing->IHTMLPerformanceTiming_iface; - } - IHTMLPerformanceTiming_AddRef(*p = This->timing); return S_OK; } @@ -2208,8 +2202,9 @@ static dispex_static_data_t HTMLPerformance_dispex = { HTMLPerformance_iface_tids };
-HRESULT create_performance(compat_mode_t compat_mode, IHTMLPerformance **ret) +HRESULT create_performance(HTMLInnerWindow *window, IHTMLPerformance **ret) { + compat_mode_t compat_mode = dispex_compat_mode(&window->event_target.dispex); HTMLPerformance *performance;
performance = heap_alloc_zero(sizeof(*performance)); @@ -2222,6 +2217,12 @@ HRESULT create_performance(compat_mode_t compat_mode, IHTMLPerformance **ret) init_dispatch(&performance->dispex, (IUnknown*)&performance->IHTMLPerformance_iface, &HTMLPerformance_dispex, compat_mode);
+ performance->timing = &window->performance_timing->IHTMLPerformanceTiming_iface; + IHTMLPerformanceTiming_AddRef(performance->timing); + + init_dispatch(&window->performance_timing->dispex, (IUnknown*)&window->performance_timing->IHTMLPerformanceTiming_iface, + &HTMLPerformanceTiming_dispex, compat_mode); + *ret = &performance->IHTMLPerformance_iface; return S_OK; }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlwindow.c | 2 +- dlls/mshtml/mshtml_private.h | 2 ++ dlls/mshtml/navigate.c | 4 +++- dlls/mshtml/omnavigator.c | 4 ++-- dlls/mshtml/tests/documentmode.js | 2 ++ 5 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 0bf1a2c6ce3..9f64e3526c6 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -2435,7 +2435,7 @@ static HRESULT WINAPI HTMLWindow7_get_performance(IHTMLWindow7 *iface, VARIANT * if(!This->performance_initialized) { IHTMLPerformance *performance;
- hres = create_performance(dispex_compat_mode(&This->event_target.dispex), &performance); + hres = create_performance(This, &performance); if(FAILED(hres)) return hres;
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 744dc4c7801..d80c9284168 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -508,6 +508,8 @@ typedef struct { IHTMLPerformanceTiming IHTMLPerformanceTiming_iface;
LONG ref; + + ULONGLONG navigation_start_time; } HTMLPerformanceTiming;
typedef struct nsChannelBSC nsChannelBSC; diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index 5825e0f27c0..241d790f9e6 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -1357,8 +1357,10 @@ static HRESULT nsChannelBSC_start_binding(BSCallback *bsc) { nsChannelBSC *This = nsChannelBSC_from_BSCallback(bsc);
- if(This->is_doc_channel) + if(This->is_doc_channel) { This->bsc.window->base.outer_window->base.inner_window->doc->skip_mutation_notif = FALSE; + This->bsc.window->performance_timing->navigation_start_time = get_time_stamp(); + }
return S_OK; } diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 4551f4e2dc3..9b67c69d6e7 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -1591,9 +1591,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_navigationStart(IHTMLPerformance { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p) returning fake value\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = This->navigation_start_time; return S_OK; }
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 33d60f7e835..f83597d305a 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -19,6 +19,8 @@ var compat_version; var tests = [];
+ok(performance.timing.navigationStart > 0, "navigationStart <= 0"); + var pageshow_fired = false, pagehide_fired = false; document.doc_unload_events_called = false; window.onbeforeunload = function() { ok(false, "beforeunload fired"); };
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/navigate.c | 2 ++ dlls/mshtml/omnavigator.c | 4 ++-- dlls/mshtml/tests/documentmode.js | 1 + 4 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index d80c9284168..db72f29e1a3 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -510,6 +510,7 @@ typedef struct { LONG ref;
ULONGLONG navigation_start_time; + ULONGLONG redirect_time; } HTMLPerformanceTiming;
typedef struct nsChannelBSC nsChannelBSC; diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index 241d790f9e6..f53348b7721 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -1717,6 +1717,8 @@ static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG progress, ULONG t This->nschannel->content_type = heap_strdupWtoA(status_text); break; case BINDSTATUS_REDIRECTING: + if(This->is_doc_channel && !This->bsc.window->performance_timing->redirect_time) + This->bsc.window->performance_timing->redirect_time = get_time_stamp(); return handle_redirect(This, status_text); case BINDSTATUS_BEGINDOWNLOADDATA: { IWinInetHttpInfo *http_info; diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 9b67c69d6e7..9777830bd90 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -1621,9 +1621,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_redirectStart(IHTMLPerformanceTi { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = This->redirect_time; return S_OK; }
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index f83597d305a..f0a91fea545 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -20,6 +20,7 @@ var compat_version; var tests = [];
ok(performance.timing.navigationStart > 0, "navigationStart <= 0"); +ok(performance.timing.redirectStart === 0, "redirectStart != 0");
var pageshow_fired = false, pagehide_fired = false; document.doc_unload_events_called = false;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlwindow.c | 3 +++ dlls/mshtml/mshtml_private.h | 2 ++ dlls/mshtml/nsevents.c | 10 ++++++++++ dlls/mshtml/omnavigator.c | 8 ++++---- dlls/mshtml/tests/documentmode.js | 2 ++ 5 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 9f64e3526c6..ec7fc0d43f2 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -4125,6 +4125,9 @@ HRESULT create_outer_window(GeckoBrowser *browser, mozIDOMWindowProxy *mozwindow return hres; }
+ /* Initial empty doc does not have unload events or timings */ + window->base.inner_window->doc->unload_sent = TRUE; + if(parent) { IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index db72f29e1a3..ef21507d553 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -510,6 +510,8 @@ typedef struct { LONG ref;
ULONGLONG navigation_start_time; + ULONGLONG unload_event_start_time; + ULONGLONG unload_event_end_time; ULONGLONG redirect_time; } HTMLPerformanceTiming;
diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c index 0248737b012..1c4bdee4e1d 100644 --- a/dlls/mshtml/nsevents.c +++ b/dlls/mshtml/nsevents.c @@ -384,6 +384,7 @@ static nsresult NSAPI handle_unload(nsIDOMEventListener *iface, nsIDOMEvent *nse { nsEventListener *This = impl_from_nsIDOMEventListener(iface); HTMLDocumentNode *doc = This->This->doc; + HTMLPerformanceTiming *timing = NULL; HTMLInnerWindow *window; DOMEvent *event; HRESULT hres; @@ -392,12 +393,21 @@ static nsresult NSAPI handle_unload(nsIDOMEventListener *iface, nsIDOMEvent *nse return NS_OK; doc->unload_sent = TRUE;
+ if(window->base.outer_window->pending_window) + timing = window->base.outer_window->pending_window->performance_timing; + + if(timing) + timing->unload_event_start_time = get_time_stamp(); + hres = create_event_from_nsevent(nsevent, dispex_compat_mode(&doc->node.event_target.dispex), &event); if(SUCCEEDED(hres)) { dispatch_event(&window->event_target, event); IDOMEvent_Release(&event->IDOMEvent_iface); }
+ if(timing) + timing->unload_event_end_time = get_time_stamp(); + return NS_OK; }
diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 9777830bd90..accfa12913c 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -1601,9 +1601,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_unloadEventStart(IHTMLPerformanc { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = This->unload_event_start_time; return S_OK; }
@@ -1611,9 +1611,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_unloadEventEnd(IHTMLPerformanceT { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = This->unload_event_end_time; return S_OK; }
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index f0a91fea545..a9c2b36ceee 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -20,6 +20,8 @@ var compat_version; var tests = [];
ok(performance.timing.navigationStart > 0, "navigationStart <= 0"); +ok(performance.timing.unloadEventStart === 0, "unloadEventStart != 0"); +ok(performance.timing.unloadEventEnd === 0, "unloadEventEnd != 0"); ok(performance.timing.redirectStart === 0, "redirectStart != 0");
var pageshow_fired = false, pagehide_fired = false;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mshtml_private.h | 3 ++ dlls/mshtml/navigate.c | 12 +++++++ dlls/mshtml/omnavigator.c | 52 ++++++++++++++++++++++--------- dlls/mshtml/tests/documentmode.js | 7 +++++ 4 files changed, 60 insertions(+), 14 deletions(-)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index ef21507d553..6fe28252f64 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -513,6 +513,9 @@ typedef struct { ULONGLONG unload_event_start_time; ULONGLONG unload_event_end_time; ULONGLONG redirect_time; + ULONGLONG dns_lookup_time; + ULONGLONG connect_time; + ULONGLONG request_time; } HTMLPerformanceTiming;
typedef struct nsChannelBSC nsChannelBSC; diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index f53348b7721..fe3c823d508 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -1720,6 +1720,18 @@ static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG progress, ULONG t if(This->is_doc_channel && !This->bsc.window->performance_timing->redirect_time) This->bsc.window->performance_timing->redirect_time = get_time_stamp(); return handle_redirect(This, status_text); + case BINDSTATUS_FINDINGRESOURCE: + if(This->is_doc_channel && !This->bsc.window->performance_timing->dns_lookup_time) + This->bsc.window->performance_timing->dns_lookup_time = get_time_stamp(); + break; + case BINDSTATUS_CONNECTING: + if(This->is_doc_channel) + This->bsc.window->performance_timing->connect_time = get_time_stamp(); + break; + case BINDSTATUS_SENDINGREQUEST: + if(This->is_doc_channel) + This->bsc.window->performance_timing->request_time = get_time_stamp(); + break; case BINDSTATUS_BEGINDOWNLOADDATA: { IWinInetHttpInfo *http_info; DWORD status, size = sizeof(DWORD); diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index accfa12913c..a2da1177a50 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -1587,6 +1587,24 @@ static HRESULT WINAPI HTMLPerformanceTiming_Invoke(IHTMLPerformanceTiming *iface
#define TIMING_FAKE_TIMESTAMP 0xdeadbeef
+static ULONGLONG get_fetch_time(HTMLPerformanceTiming *This) +{ + /* If there's no prior doc unloaded and no redirects, fetch time == navigationStart time */ + if(!This->unload_event_end_time && !This->redirect_time) + return This->navigation_start_time; + + if(This->dns_lookup_time) + return This->dns_lookup_time; + if(This->connect_time) + return This->connect_time; + if(This->request_time) + return This->request_time; + if(This->unload_event_end_time) + return This->unload_event_end_time; + + return This->redirect_time; +} + static HRESULT WINAPI HTMLPerformanceTiming_get_navigationStart(IHTMLPerformanceTiming *iface, ULONGLONG *p) { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface); @@ -1631,9 +1649,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_redirectEnd(IHTMLPerformanceTimi { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = This->redirect_time ? get_fetch_time(This) : 0; return S_OK; }
@@ -1641,9 +1659,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_fetchStart(IHTMLPerformanceTimin { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = get_fetch_time(This); return S_OK; }
@@ -1651,9 +1669,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domainLookupStart(IHTMLPerforman { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = This->dns_lookup_time ? This->dns_lookup_time : get_fetch_time(This); return S_OK; }
@@ -1661,9 +1679,10 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domainLookupEnd(IHTMLPerformance { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = This->connect_time ? This->connect_time : + This->dns_lookup_time ? This->dns_lookup_time : get_fetch_time(This); return S_OK; }
@@ -1671,9 +1690,10 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_connectStart(IHTMLPerformanceTim { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = This->connect_time ? This->connect_time : + This->dns_lookup_time ? This->dns_lookup_time : get_fetch_time(This); return S_OK; }
@@ -1681,9 +1701,11 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_connectEnd(IHTMLPerformanceTimin { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = This->request_time ? This->request_time : + This->connect_time ? This->connect_time : + This->dns_lookup_time ? This->dns_lookup_time : get_fetch_time(This); return S_OK; }
@@ -1691,9 +1713,11 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_requestStart(IHTMLPerformanceTim { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = This->request_time ? This->request_time : + This->connect_time ? This->connect_time : + This->dns_lookup_time ? This->dns_lookup_time : get_fetch_time(This); return S_OK; }
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index a9c2b36ceee..e933ea0ff54 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -20,9 +20,16 @@ var compat_version; var tests = [];
ok(performance.timing.navigationStart > 0, "navigationStart <= 0"); +ok(performance.timing.fetchStart == performance.timing.navigationStart, "fetchStart != navigationStart"); +ok(performance.timing.domainLookupStart >= performance.timing.fetchStart, "domainLookupStart < fetchStart"); +ok(performance.timing.domainLookupEnd >= performance.timing.domainLookupStart, "domainLookupEnd < domainLookupStart"); +ok(performance.timing.connectStart >= performance.timing.domainLookupEnd, "connectStart < domainLookupEnd"); +ok(performance.timing.connectEnd >= performance.timing.connectStart, "connectEnd < connectStart"); +ok(performance.timing.requestStart >= performance.timing.connectEnd, "requestStart < connectEnd"); ok(performance.timing.unloadEventStart === 0, "unloadEventStart != 0"); ok(performance.timing.unloadEventEnd === 0, "unloadEventEnd != 0"); ok(performance.timing.redirectStart === 0, "redirectStart != 0"); +ok(performance.timing.redirectEnd === 0, "redirectEnd != 0");
var pageshow_fired = false, pagehide_fired = false; document.doc_unload_events_called = false;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mshtml_private.h | 2 ++ dlls/mshtml/navigate.c | 23 ++++++++++++++++------- dlls/mshtml/omnavigator.c | 8 ++++---- dlls/mshtml/tests/documentmode.js | 2 ++ 4 files changed, 24 insertions(+), 11 deletions(-)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 6fe28252f64..96042e60ff8 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -516,6 +516,8 @@ typedef struct { ULONGLONG dns_lookup_time; ULONGLONG connect_time; ULONGLONG request_time; + ULONGLONG response_start_time; + ULONGLONG response_end_time; } HTMLPerformanceTiming;
typedef struct nsChannelBSC nsChannelBSC; diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index fe3c823d508..469bd0d1e07 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -1107,6 +1107,9 @@ static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream) if(!This->response_processed) { IWinInetHttpInfo *wininet_info;
+ if(This->is_doc_channel) + This->bsc.window->performance_timing->response_start_time = get_time_stamp(); + This->response_processed = TRUE; if(This->bsc.binding) { hres = IBinding_QueryInterface(This->bsc.binding, &IID_IWinInetHttpInfo, (void**)&wininet_info); @@ -1522,13 +1525,16 @@ static HRESULT nsChannelBSC_stop_binding(BSCallback *bsc, HRESULT result) { nsChannelBSC *This = nsChannelBSC_from_BSCallback(bsc);
- if(result != E_ABORT && This->is_doc_channel && This->bsc.window) { - if(FAILED(result)) - handle_navigation_error(This, result); - else if(This->nschannel) { - result = async_stop_request(This); - if(SUCCEEDED(result)) - return S_OK; + if(This->is_doc_channel && This->bsc.window) { + This->bsc.window->performance_timing->response_end_time = get_time_stamp(); + if(result != E_ABORT) { + if(FAILED(result)) + handle_navigation_error(This, result); + else if(This->nschannel) { + result = async_stop_request(This); + if(SUCCEEDED(result)) + return S_OK; + } } }
@@ -1786,6 +1792,9 @@ static HRESULT nsChannelBSC_on_response(BSCallback *bsc, DWORD response_code, char *str; HRESULT hres;
+ if(This->is_doc_channel) + This->bsc.window->performance_timing->response_start_time = get_time_stamp(); + This->response_processed = TRUE; This->nschannel->response_status = response_code;
diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index a2da1177a50..609b2cbc8c2 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -1725,9 +1725,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_responseStart(IHTMLPerformanceTi { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = This->response_start_time; return S_OK; }
@@ -1735,9 +1735,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_responseEnd(IHTMLPerformanceTimi { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = This->response_end_time; return S_OK; }
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index e933ea0ff54..881a08e9a54 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -26,6 +26,8 @@ ok(performance.timing.domainLookupEnd >= performance.timing.domainLookupStart, " ok(performance.timing.connectStart >= performance.timing.domainLookupEnd, "connectStart < domainLookupEnd"); ok(performance.timing.connectEnd >= performance.timing.connectStart, "connectEnd < connectStart"); ok(performance.timing.requestStart >= performance.timing.connectEnd, "requestStart < connectEnd"); +ok(performance.timing.responseStart >= performance.timing.requestStart, "responseStart < requestStart"); +ok(performance.timing.responseEnd >= performance.timing.responseStart, "responseEnd < responseStart"); ok(performance.timing.unloadEventStart === 0, "unloadEventStart != 0"); ok(performance.timing.unloadEventEnd === 0, "unloadEventEnd != 0"); ok(performance.timing.redirectStart === 0, "redirectStart != 0");
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/omnavigator.c | 5 +++-- dlls/mshtml/tests/documentmode.js | 1 + 2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 609b2cbc8c2..81209be1a23 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -1745,9 +1745,10 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domLoading(IHTMLPerformanceTimin { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + /* Make sure this is after responseEnd, when the Gecko parser starts */ + *p = This->response_end_time; return S_OK; }
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 881a08e9a54..c09f10ae54a 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -28,6 +28,7 @@ ok(performance.timing.connectEnd >= performance.timing.connectStart, "connectEnd ok(performance.timing.requestStart >= performance.timing.connectEnd, "requestStart < connectEnd"); ok(performance.timing.responseStart >= performance.timing.requestStart, "responseStart < requestStart"); ok(performance.timing.responseEnd >= performance.timing.responseStart, "responseEnd < responseStart"); +ok(performance.timing.domLoading >= performance.timing.responseEnd, "domLoading < responseEnd"); ok(performance.timing.unloadEventStart === 0, "unloadEventStart != 0"); ok(performance.timing.unloadEventEnd === 0, "unloadEventEnd != 0"); ok(performance.timing.redirectStart === 0, "redirectStart != 0");
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/mutation.c | 2 + dlls/mshtml/omnavigator.c | 4 +- dlls/mshtml/tests/documentmode.js | 5 ++ dlls/mshtml/tests/htmldoc.c | 84 +++++++++++++++++++++++++++++++ 5 files changed, 94 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 96042e60ff8..7d50a3b962f 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -518,6 +518,7 @@ typedef struct { ULONGLONG request_time; ULONGLONG response_start_time; ULONGLONG response_end_time; + ULONGLONG dom_interactive_time; } HTMLPerformanceTiming;
typedef struct nsChannelBSC nsChannelBSC; diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c index 7166d74cf0c..a311c2a0ba8 100644 --- a/dlls/mshtml/mutation.c +++ b/dlls/mshtml/mutation.c @@ -305,6 +305,8 @@ static nsresult run_end_load(HTMLDocumentNode *This, nsISupports *arg1, nsISuppo }
bind_event_scripts(This); + + This->window->performance_timing->dom_interactive_time = get_time_stamp(); set_ready_state(This->outer_window, READYSTATE_INTERACTIVE); return NS_OK; } diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 81209be1a23..5d1533f84b0 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -1756,9 +1756,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domInteractive(IHTMLPerformanceT { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = This->dom_interactive_time; return S_OK; }
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index c09f10ae54a..2c6a800d8cf 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -29,6 +29,7 @@ ok(performance.timing.requestStart >= performance.timing.connectEnd, "requestSta ok(performance.timing.responseStart >= performance.timing.requestStart, "responseStart < requestStart"); ok(performance.timing.responseEnd >= performance.timing.responseStart, "responseEnd < responseStart"); ok(performance.timing.domLoading >= performance.timing.responseEnd, "domLoading < responseEnd"); +ok(performance.timing.domInteractive === 0, "domInteractive != 0"); ok(performance.timing.unloadEventStart === 0, "unloadEventStart != 0"); ok(performance.timing.unloadEventEnd === 0, "unloadEventEnd != 0"); ok(performance.timing.redirectStart === 0, "redirectStart != 0"); @@ -75,6 +76,10 @@ if(window.addEventListener) { document.attachEvent("onunload", function() { ok(false, "unload fired on document"); }); }
+sync_test("performance timing", function() { + ok(performance.timing.domInteractive >= performance.timing.domLoading, "domInteractive < domLoading"); +}); + sync_test("page transition events", function() { if(document.documentMode < 11) ok(pageshow_fired === false, "pageshow fired"); diff --git a/dlls/mshtml/tests/htmldoc.c b/dlls/mshtml/tests/htmldoc.c index 49c0ddfe5c4..25d7dac2c9a 100644 --- a/dlls/mshtml/tests/htmldoc.c +++ b/dlls/mshtml/tests/htmldoc.c @@ -450,6 +450,85 @@ static void _test_current_url(unsigned line, IUnknown *unk, const WCHAR *exurl) IHTMLDocument2_Release(doc); }
+#define test_performance_timing(a,b) _test_performance_timing(__LINE__,a,b) +static void _test_performance_timing(unsigned line, IUnknown *unk, const WCHAR *prop) +{ + BOOL expect_non_zero = FALSE; + DISPPARAMS dp = { 0 }; + IHTMLWindow2 *window; + IHTMLDocument2 *doc; + IDispatchEx *dispex; + DISPID dispid; + HRESULT hres; + VARIANT var; + BSTR bstr; + + hres = IUnknown_QueryInterface(unk, &IID_IHTMLDocument2, (void**)&doc); + ok_(__FILE__,line)(hres == S_OK, "QueryInterface(IID_IHTMLDocument2) failed: %08lx\n", hres); + + hres = IHTMLDocument2_get_readyState(doc, &bstr); + ok_(__FILE__,line)(hres == S_OK, "get_readyState failed: %08lx\n", hres); + if(!wcscmp(bstr, L"interactive")) + expect_non_zero = !wcscmp(prop, L"domInteractive"); + else if(!wcscmp(bstr, L"complete")) + expect_non_zero = !wcscmp(prop, L"domInteractive") || !wcscmp(prop, L"domComplete"); + SysFreeString(bstr); + + hres = IHTMLDocument2_get_parentWindow(doc, &window); + ok_(__FILE__,line)(hres == S_OK, "get_parentWindow failed: %08lx\n", hres); + IHTMLDocument2_Release(doc); + + hres = IHTMLWindow2_QueryInterface(window, &IID_IDispatchEx, (void**)&dispex); + ok_(__FILE__,line)(hres == S_OK, "QueryInterface(IID_IDispatchEx) failed: %08lx\n", hres); + IHTMLWindow2_Release(window); + + bstr = SysAllocString(L"performance"); + hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &dispid); + ok_(__FILE__,line)(hres == S_OK, "GetDispID(performance) failed: %08lx\n", hres); + SysFreeString(bstr); + + V_VT(&var) = VT_EMPTY; + hres = IDispatchEx_InvokeEx(dispex, dispid, 0, DISPATCH_PROPERTYGET, &dp, &var, NULL, NULL); + ok_(__FILE__,line)(hres == S_OK, "InvokeEx(performance) failed: %08lx\n", hres); + ok_(__FILE__,line)(V_VT(&var) == VT_DISPATCH, "V_VT(performance) = %d\n", V_VT(&var)); + ok_(__FILE__,line)(V_DISPATCH(&var) != NULL, "V_DISPATCH(performance) = NULL\n"); + IDispatchEx_Release(dispex); + + hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IDispatchEx, (void**)&dispex); + ok_(__FILE__,line)(hres == S_OK, "QueryInterface(IID_IDispatchEx) failed: %08lx\n", hres); + VariantClear(&var); + + bstr = SysAllocString(L"timing"); + hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &dispid); + ok_(__FILE__,line)(hres == S_OK, "GetDispID(timing) failed: %08lx\n", hres); + SysFreeString(bstr); + + hres = IDispatchEx_InvokeEx(dispex, dispid, 0, DISPATCH_PROPERTYGET, &dp, &var, NULL, NULL); + ok_(__FILE__,line)(hres == S_OK, "InvokeEx(timing) failed: %08lx\n", hres); + ok_(__FILE__,line)(V_VT(&var) == VT_DISPATCH, "V_VT(timing) = %d\n", V_VT(&var)); + ok_(__FILE__,line)(V_DISPATCH(&var) != NULL, "V_DISPATCH(timing) = NULL\n"); + IDispatchEx_Release(dispex); + + hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IDispatchEx, (void**)&dispex); + ok_(__FILE__,line)(hres == S_OK, "QueryInterface(IID_IDispatchEx) failed: %08lx\n", hres); + VariantClear(&var); + + bstr = SysAllocString(prop); + hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &dispid); + ok_(__FILE__,line)(hres == S_OK, "GetDispID(%s) failed: %08lx\n", wine_dbgstr_w(prop), hres); + SysFreeString(bstr); + + hres = IDispatchEx_InvokeEx(dispex, dispid, 0, DISPATCH_PROPERTYGET, &dp, &var, NULL, NULL); + ok_(__FILE__,line)(hres == S_OK, "InvokeEx(%s) failed: %08lx\n", wine_dbgstr_w(prop), hres); + ok_(__FILE__,line)(V_VT(&var) == VT_UI8, "V_VT(%s) = %d\n", wine_dbgstr_w(prop), V_VT(&var)); + IDispatchEx_Release(dispex); + + if(expect_non_zero) + ok_(__FILE__,line)(V_UI8(&var) != 0, "%s is 0\n", wine_dbgstr_w(prop)); + else + ok_(__FILE__,line)(V_UI8(&var) == 0, "%s is not 0\n", wine_dbgstr_w(prop)); +} + static BSTR get_mime_type_display_name(const WCHAR *content_type) { WCHAR buffer[128], ext[128], *str, *progid; @@ -1039,6 +1118,10 @@ static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, D if(!editmode) test_readyState(NULL); readystate_set_interactive = (load_state != LD_INTERACTIVE); + + /* w10pro64_ja has it set to zero despite readyState being interactive, for whatever reason */ + if(!is_mhtml) + test_performance_timing(doc_unk, L"domInteractive"); return S_OK; case 1012: CHECK_EXPECT2(OnChanged_1012); @@ -3574,6 +3657,7 @@ static HRESULT WINAPI DocObjectService_FireNavigateComplete2( { CHECK_EXPECT(FireNavigateComplete2); test_readyState(NULL); + test_performance_timing(doc_unk, L"domInteractive");
if(loading_hash) ok(dwFlags == 0x10 || broken(!dwFlags), "dwFlags = %lx, expected 0x10\n", dwFlags);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/nsevents.c | 1 + dlls/mshtml/omnavigator.c | 4 ++-- dlls/mshtml/tests/documentmode.js | 2 ++ dlls/mshtml/tests/htmldoc.c | 3 +++ 5 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 7d50a3b962f..45532902bd4 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -519,6 +519,7 @@ typedef struct { ULONGLONG response_start_time; ULONGLONG response_end_time; ULONGLONG dom_interactive_time; + ULONGLONG dom_complete_time; } HTMLPerformanceTiming;
typedef struct nsChannelBSC nsChannelBSC; diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c index 1c4bdee4e1d..1fc7ccca377 100644 --- a/dlls/mshtml/nsevents.c +++ b/dlls/mshtml/nsevents.c @@ -319,6 +319,7 @@ static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event if(doc_obj) handle_docobj_load(doc_obj);
+ doc->window->performance_timing->dom_complete_time = get_time_stamp(); set_ready_state(doc->outer_window, READYSTATE_COMPLETE);
if(doc_obj) { diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 5d1533f84b0..cdf38e5b3a5 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -1786,9 +1786,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domComplete(IHTMLPerformanceTimi { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = This->dom_complete_time; return S_OK; }
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 2c6a800d8cf..72311d5903b 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -30,6 +30,7 @@ ok(performance.timing.responseStart >= performance.timing.requestStart, "respons ok(performance.timing.responseEnd >= performance.timing.responseStart, "responseEnd < responseStart"); ok(performance.timing.domLoading >= performance.timing.responseEnd, "domLoading < responseEnd"); ok(performance.timing.domInteractive === 0, "domInteractive != 0"); +ok(performance.timing.domComplete === 0, "domComplete != 0"); ok(performance.timing.unloadEventStart === 0, "unloadEventStart != 0"); ok(performance.timing.unloadEventEnd === 0, "unloadEventEnd != 0"); ok(performance.timing.redirectStart === 0, "redirectStart != 0"); @@ -78,6 +79,7 @@ if(window.addEventListener) {
sync_test("performance timing", function() { ok(performance.timing.domInteractive >= performance.timing.domLoading, "domInteractive < domLoading"); + ok(performance.timing.domComplete >= performance.timing.domInteractive, "domComplete < domInteractive"); });
sync_test("page transition events", function() { diff --git a/dlls/mshtml/tests/htmldoc.c b/dlls/mshtml/tests/htmldoc.c index 25d7dac2c9a..ff3c208f466 100644 --- a/dlls/mshtml/tests/htmldoc.c +++ b/dlls/mshtml/tests/htmldoc.c @@ -2986,6 +2986,7 @@ static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID ok(nCmdexecopt == 0, "nCmdexecopts=%08lx\n", nCmdexecopt); ok(pvaOut == NULL, "pvaOut=%p\n", pvaOut); ok(pvaIn == NULL, "pvaIn=%p\n", pvaIn); + test_performance_timing(doc_unk, L"domComplete"); readystate_set_loading = FALSE; readystate_set_interactive = FALSE; load_state = LD_COMPLETE; @@ -3133,6 +3134,7 @@ static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID ok(pvaOut == NULL, "pvaOut != NULL\n");
test_readyState(NULL); + test_performance_timing(doc_unk, L"domComplete"); return E_NOTIMPL;
case 105: @@ -3195,6 +3197,7 @@ static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID CHECK_EXPECT(Exec_MSHTML_PARSECOMPLETE); ok(pvaIn == NULL, "pvaIn != NULL\n"); ok(pvaOut == NULL, "pvaOut != NULL\n"); + test_performance_timing(doc_unk, L"domComplete"); return S_OK; default: ok(0, "unexpected command %ld\n", nCmdID);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 2 +- dlls/mshtml/mshtml_private.h | 2 ++ dlls/mshtml/nsevents.c | 43 +++++++++++++++++++++++++------ dlls/mshtml/omnavigator.c | 8 +++--- dlls/mshtml/tests/documentmode.js | 6 ++++- 5 files changed, 47 insertions(+), 14 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 01a385130b1..fec280d9a70 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -117,7 +117,7 @@ typedef struct { /* Keep these sorted case sensitively */ static const event_info_t event_info[] = { {L"DOMContentLoaded", EVENT_TYPE_EVENT, 0, - EVENT_DEFAULTLISTENER | EVENT_BUBBLES | EVENT_CANCELABLE}, + EVENT_BUBBLES | EVENT_CANCELABLE}, {L"abort", EVENT_TYPE_EVENT, DISPID_EVMETH_ONABORT, EVENT_BIND_TO_TARGET}, {L"animationend", EVENT_TYPE_EVENT, DISPID_EVPROP_ONANIMATIONEND, diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 45532902bd4..c0197195ad4 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -520,6 +520,8 @@ typedef struct { ULONGLONG response_end_time; ULONGLONG dom_interactive_time; ULONGLONG dom_complete_time; + ULONGLONG dom_content_loaded_event_start_time; + ULONGLONG dom_content_loaded_event_end_time; } HTMLPerformanceTiming;
typedef struct nsChannelBSC nsChannelBSC; diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c index 1fc7ccca377..6ae34321573 100644 --- a/dlls/mshtml/nsevents.c +++ b/dlls/mshtml/nsevents.c @@ -56,6 +56,7 @@ typedef struct { static nsresult NSAPI handle_blur(nsIDOMEventListener*,nsIDOMEvent*); static nsresult NSAPI handle_focus(nsIDOMEventListener*,nsIDOMEvent*); static nsresult NSAPI handle_keypress(nsIDOMEventListener*,nsIDOMEvent*); +static nsresult NSAPI handle_dom_content_loaded(nsIDOMEventListener*,nsIDOMEvent*); static nsresult NSAPI handle_pageshow(nsIDOMEventListener*,nsIDOMEvent*); static nsresult NSAPI handle_pagehide(nsIDOMEventListener*,nsIDOMEvent*); static nsresult NSAPI handle_load(nsIDOMEventListener*,nsIDOMEvent*); @@ -72,14 +73,15 @@ static const struct { enum doc_event_listener_flags flags; nsIDOMEventListenerVtbl vtbl; } doc_event_listeners[] = { - { EVENTID_BLUR, 0, EVENTLISTENER_VTBL(handle_blur) }, - { EVENTID_FOCUS, 0, EVENTLISTENER_VTBL(handle_focus) }, - { EVENTID_KEYPRESS, BUBBLES, EVENTLISTENER_VTBL(handle_keypress) }, - { EVENTID_PAGESHOW, OVERRIDE, EVENTLISTENER_VTBL(handle_pageshow), }, - { EVENTID_PAGEHIDE, OVERRIDE, EVENTLISTENER_VTBL(handle_pagehide), }, - { EVENTID_LOAD, OVERRIDE, EVENTLISTENER_VTBL(handle_load), }, - { EVENTID_BEFOREUNLOAD, OVERRIDE, EVENTLISTENER_VTBL(handle_beforeunload), }, - { EVENTID_UNLOAD, OVERRIDE, EVENTLISTENER_VTBL(handle_unload) }, + { EVENTID_BLUR, 0, EVENTLISTENER_VTBL(handle_blur) }, + { EVENTID_FOCUS, 0, EVENTLISTENER_VTBL(handle_focus) }, + { EVENTID_KEYPRESS, BUBBLES, EVENTLISTENER_VTBL(handle_keypress) }, + { EVENTID_DOMCONTENTLOADED, OVERRIDE, EVENTLISTENER_VTBL(handle_dom_content_loaded) }, + { EVENTID_PAGESHOW, OVERRIDE, EVENTLISTENER_VTBL(handle_pageshow) }, + { EVENTID_PAGEHIDE, OVERRIDE, EVENTLISTENER_VTBL(handle_pagehide) }, + { EVENTID_LOAD, OVERRIDE, EVENTLISTENER_VTBL(handle_load) }, + { EVENTID_BEFOREUNLOAD, OVERRIDE, EVENTLISTENER_VTBL(handle_beforeunload) }, + { EVENTID_UNLOAD, OVERRIDE, EVENTLISTENER_VTBL(handle_unload) }, };
struct nsDocumentEventListener { @@ -216,6 +218,31 @@ static nsresult NSAPI handle_keypress(nsIDOMEventListener *iface, return NS_OK; }
+static nsresult NSAPI handle_dom_content_loaded(nsIDOMEventListener *iface, nsIDOMEvent *nsevent) +{ + nsEventListener *This = impl_from_nsIDOMEventListener(iface); + HTMLDocumentNode *doc = This->This->doc; + DOMEvent *event; + HRESULT hres; + + if(!doc) + return NS_OK; + + if(doc->window) + doc->window->performance_timing->dom_content_loaded_event_start_time = get_time_stamp(); + + hres = create_event_from_nsevent(nsevent, dispex_compat_mode(&doc->node.event_target.dispex), &event); + if(SUCCEEDED(hres)) { + dispatch_event(&doc->node.event_target, event); + IDOMEvent_Release(&event->IDOMEvent_iface); + } + + if(doc->window) + doc->window->performance_timing->dom_content_loaded_event_end_time = get_time_stamp(); + + return NS_OK; +} + static nsresult NSAPI handle_pageshow(nsIDOMEventListener *iface, nsIDOMEvent *nsevent) { nsEventListener *This = impl_from_nsIDOMEventListener(iface); diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index cdf38e5b3a5..983596f9bfa 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -1766,9 +1766,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domContentLoadedEventStart(IHTML { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = This->dom_content_loaded_event_start_time; return S_OK; }
@@ -1776,9 +1776,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domContentLoadedEventEnd(IHTMLPe { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = This->dom_content_loaded_event_end_time; return S_OK; }
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 72311d5903b..237ac224cbb 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -31,6 +31,8 @@ ok(performance.timing.responseEnd >= performance.timing.responseStart, "response ok(performance.timing.domLoading >= performance.timing.responseEnd, "domLoading < responseEnd"); ok(performance.timing.domInteractive === 0, "domInteractive != 0"); ok(performance.timing.domComplete === 0, "domComplete != 0"); +ok(performance.timing.domContentLoadedEventStart === 0, "domContentLoadedEventStart != 0"); +ok(performance.timing.domContentLoadedEventEnd === 0, "domContentLoadedEventEnd != 0"); ok(performance.timing.unloadEventStart === 0, "unloadEventStart != 0"); ok(performance.timing.unloadEventEnd === 0, "unloadEventEnd != 0"); ok(performance.timing.redirectStart === 0, "redirectStart != 0"); @@ -79,7 +81,9 @@ if(window.addEventListener) {
sync_test("performance timing", function() { ok(performance.timing.domInteractive >= performance.timing.domLoading, "domInteractive < domLoading"); - ok(performance.timing.domComplete >= performance.timing.domInteractive, "domComplete < domInteractive"); + ok(performance.timing.domContentLoadedEventStart >= performance.timing.domInteractive, "domContentLoadedEventStart < domInteractive"); + ok(performance.timing.domContentLoadedEventEnd >= performance.timing.domContentLoadedEventStart, "domContentLoadedEventEnd < domContentLoadedEventStart"); + ok(performance.timing.domComplete >= performance.timing.domContentLoadedEventEnd, "domComplete < domContentLoadedEventEnd"); });
sync_test("page transition events", function() {
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
connect_scripts at the top of the function already uses the window unconditionally, so if it was NULL it would crash there anyway. --- dlls/mshtml/nsevents.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c index 6ae34321573..e35e4d7ae80 100644 --- a/dlls/mshtml/nsevents.c +++ b/dlls/mshtml/nsevents.c @@ -373,14 +373,10 @@ static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event WARN("no dom_document\n"); }
- if(doc->window) { - hres = create_event_from_nsevent(event, dispex_compat_mode(&doc->node.event_target.dispex), &load_event); - if(SUCCEEDED(hres)) { - dispatch_event(&doc->window->event_target, load_event); - IDOMEvent_Release(&load_event->IDOMEvent_iface); - } - }else { - WARN("no window\n"); + hres = create_event_from_nsevent(event, dispex_compat_mode(&doc->node.event_target.dispex), &load_event); + if(SUCCEEDED(hres)) { + dispatch_event(&doc->window->event_target, load_event); + IDOMEvent_Release(&load_event->IDOMEvent_iface); }
IHTMLDOMNode_Release(&doc->node.IHTMLDOMNode_iface);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mshtml_private.h | 2 ++ dlls/mshtml/nsevents.c | 4 ++++ dlls/mshtml/omnavigator.c | 8 ++++---- dlls/mshtml/tests/documentmode.js | 5 +++++ 4 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index c0197195ad4..342c064bec9 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -522,6 +522,8 @@ typedef struct { ULONGLONG dom_complete_time; ULONGLONG dom_content_loaded_event_start_time; ULONGLONG dom_content_loaded_event_end_time; + ULONGLONG load_event_start_time; + ULONGLONG load_event_end_time; } HTMLPerformanceTiming;
typedef struct nsChannelBSC nsChannelBSC; diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c index e35e4d7ae80..b0f55dfe35f 100644 --- a/dlls/mshtml/nsevents.c +++ b/dlls/mshtml/nsevents.c @@ -363,6 +363,8 @@ static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event IDocObjectService_FireDocumentComplete(doc_obj->doc_object_service, &doc->outer_window->base.IHTMLWindow2_iface, 0);
+ doc->window->performance_timing->load_event_start_time = get_time_stamp(); + if(doc->dom_document) { hres = create_document_event(doc, EVENTID_LOAD, &load_event); if(SUCCEEDED(hres)) { @@ -379,6 +381,8 @@ static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event IDOMEvent_Release(&load_event->IDOMEvent_iface); }
+ doc->window->performance_timing->load_event_end_time = get_time_stamp(); + IHTMLDOMNode_Release(&doc->node.IHTMLDOMNode_iface); return NS_OK; } diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 983596f9bfa..b7d1732be05 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -1796,9 +1796,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_loadEventStart(IHTMLPerformanceT { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = This->load_event_start_time; return S_OK; }
@@ -1806,9 +1806,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_loadEventEnd(IHTMLPerformanceTim { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = This->load_event_end_time; return S_OK; }
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 237ac224cbb..30d4a790261 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -33,6 +33,8 @@ ok(performance.timing.domInteractive === 0, "domInteractive != 0"); ok(performance.timing.domComplete === 0, "domComplete != 0"); ok(performance.timing.domContentLoadedEventStart === 0, "domContentLoadedEventStart != 0"); ok(performance.timing.domContentLoadedEventEnd === 0, "domContentLoadedEventEnd != 0"); +ok(performance.timing.loadEventStart === 0, "loadEventStart != 0"); +ok(performance.timing.loadEventEnd === 0, "loadEventEnd != 0"); ok(performance.timing.unloadEventStart === 0, "unloadEventStart != 0"); ok(performance.timing.unloadEventEnd === 0, "unloadEventEnd != 0"); ok(performance.timing.redirectStart === 0, "redirectStart != 0"); @@ -59,6 +61,7 @@ if(window.addEventListener) { ok(r === "[object PageTransitionEvent]", "pageshow toString = " + r); ok("persisted" in e, "'persisted' not in pageshow event"); ok(document.readyState === "complete", "pageshow readyState = " + document.readyState); + ok(performance.timing.loadEventEnd > 0, "loadEventEnd <= 0 in pageshow handler"); }, true);
window.addEventListener("pagehide", function(e) { @@ -84,6 +87,8 @@ sync_test("performance timing", function() { ok(performance.timing.domContentLoadedEventStart >= performance.timing.domInteractive, "domContentLoadedEventStart < domInteractive"); ok(performance.timing.domContentLoadedEventEnd >= performance.timing.domContentLoadedEventStart, "domContentLoadedEventEnd < domContentLoadedEventStart"); ok(performance.timing.domComplete >= performance.timing.domContentLoadedEventEnd, "domComplete < domContentLoadedEventEnd"); + ok(performance.timing.loadEventStart >= performance.timing.domComplete, "loadEventStart < domComplete"); + ok(performance.timing.loadEventEnd >= performance.timing.loadEventStart, "loadEventEnd < loadEventStart"); });
sync_test("page transition events", function() {
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/omnavigator.c | 6 ++---- dlls/mshtml/tests/documentmode.js | 1 + dlls/mshtml/view.c | 3 +++ 4 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 342c064bec9..c5c3549ce71 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -524,6 +524,7 @@ typedef struct { ULONGLONG dom_content_loaded_event_end_time; ULONGLONG load_event_start_time; ULONGLONG load_event_end_time; + ULONGLONG first_paint_time; } HTMLPerformanceTiming;
typedef struct nsChannelBSC nsChannelBSC; diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index b7d1732be05..247e920c1f0 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -1585,8 +1585,6 @@ static HRESULT WINAPI HTMLPerformanceTiming_Invoke(IHTMLPerformanceTiming *iface pDispParams, pVarResult, pExcepInfo, puArgErr); }
-#define TIMING_FAKE_TIMESTAMP 0xdeadbeef - static ULONGLONG get_fetch_time(HTMLPerformanceTiming *This) { /* If there's no prior doc unloaded and no redirects, fetch time == navigationStart time */ @@ -1816,9 +1814,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_msFirstPaint(IHTMLPerformanceTim { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface);
- FIXME("(%p)->(%p) returning fake value\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = TIMING_FAKE_TIMESTAMP; + *p = This->first_paint_time; return S_OK; }
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 30d4a790261..157a7337c04 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -39,6 +39,7 @@ ok(performance.timing.unloadEventStart === 0, "unloadEventStart != 0"); ok(performance.timing.unloadEventEnd === 0, "unloadEventEnd != 0"); ok(performance.timing.redirectStart === 0, "redirectStart != 0"); ok(performance.timing.redirectEnd === 0, "redirectEnd != 0"); +ok(performance.timing.msFirstPaint === 0, "msFirstPaint != 0");
var pageshow_fired = false, pagehide_fired = false; document.doc_unload_events_called = false; diff --git a/dlls/mshtml/view.c b/dlls/mshtml/view.c index 063f7afab9d..eaf3a822c2b 100644 --- a/dlls/mshtml/view.c +++ b/dlls/mshtml/view.c @@ -50,6 +50,9 @@ static void paint_document(HTMLDocumentObj *This) RECT rect; HDC hdc;
+ if(This->window && This->window->base.inner_window && !This->window->base.inner_window->performance_timing->first_paint_time) + This->window->base.inner_window->performance_timing->first_paint_time = get_time_stamp(); + GetClientRect(This->hwnd, &rect);
hdc = BeginPaint(This->hwnd, &ps);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=126568
Your paranoid android.
=== w10pro64 (testbot log) ===
WineRunTask.pl:error: The previous 1 run(s) terminated abnormally
=== debian11 (32 bit report) ===
d3d8: stateblock: Timeout visual: Timeout
d3d9: d3d9ex: Timeout device: Timeout stateblock: Timeout visual: Timeout
d3dcompiler_43: asm: Timeout blob: Timeout hlsl_d3d11: Timeout hlsl_d3d9: Timeout reflection: Timeout
d3dcompiler_46: asm: Timeout blob: Timeout hlsl_d3d11: Timeout hlsl_d3d9: Timeout reflection: Timeout
d3dcompiler_47: asm: Timeout blob: Timeout hlsl_d3d11: Timeout hlsl_d3d9: Timeout reflection: Timeout
d3drm: d3drm: Timeout vector: Timeout
d3dx10_34: d3dx10: Timeout
d3dx10_35: d3dx10: Timeout
d3dx10_36: d3dx10: Timeout
d3dx10_37: d3dx10: Timeout
d3dx10_38: d3dx10: Timeout
d3dx10_39: d3dx10: Timeout
d3dx10_40: d3dx10: Timeout
d3dx10_41: d3dx10: Timeout
d3dx10_42: d3dx10: Timeout
d3dx10_43: d3dx10: Timeout
d3dx11_42: d3dx11: Timeout
d3dx11_43: d3dx11: Timeout
d3dx9_36: asm: Timeout
Report validation errors: d3dx9_36:core timeout
=== debian11 (build log) ===
WineRunWineTest.pl:error: The task timed out